/*
* Copyright (c) 2008-2013, Hazelcast, Inc. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hazelcast.multimap;
import com.hazelcast.config.
EntryListenerConfig;
import com.hazelcast.core.
EntryListener;
import com.hazelcast.core.
HazelcastInstanceAware;
import com.hazelcast.core.
MultiMap;
import com.hazelcast.monitor.
LocalMultiMapStats;
import com.hazelcast.multimap.operations.
EntrySetResponse;
import com.hazelcast.multimap.operations.
MultiMapResponse;
import com.hazelcast.nio.
ClassLoaderUtil;
import com.hazelcast.nio.serialization.
Data;
import com.hazelcast.spi.
InitializingObject;
import com.hazelcast.spi.
NodeEngine;
import com.hazelcast.util.
ExceptionUtil;
import java.util.
Collection;
import java.util.
HashSet;
import java.util.
LinkedList;
import java.util.
List;
import java.util.
Map;
import java.util.
Set;
import java.util.concurrent.
TimeUnit;
import static com.hazelcast.util.
ValidationUtil.shouldBePositive;
/**
* @author ali 1/2/13
*/
public class
ObjectMultiMapProxy<K, V> extends
MultiMapProxySupport implements
MultiMap<K, V>,
InitializingObject {
public
ObjectMultiMapProxy(
MultiMapService service,
NodeEngine nodeEngine,
String name) {
super(
service,
nodeEngine,
name);
}
public
String getName() {
return
name;
}
@
Override
public void
initialize() {
final
NodeEngine nodeEngine =
getNodeEngine();
List<
EntryListenerConfig>
listenerConfigs =
config.
getEntryListenerConfigs();
for (
EntryListenerConfig listenerConfig :
listenerConfigs) {
EntryListener listener = null;
if (
listenerConfig.
getImplementation() != null) {
listener =
listenerConfig.
getImplementation();
} else if (
listenerConfig.
getClassName() != null) {
try {
listener =
ClassLoaderUtil.
newInstance(
nodeEngine.
getConfigClassLoader(),
listenerConfig.
getClassName());
} catch (
Exception e) {
throw
ExceptionUtil.
rethrow(
e);
}
}
if (
listener != null) {
if (
listener instanceof
HazelcastInstanceAware) {
((
HazelcastInstanceAware)
listener).
setHazelcastInstance(
nodeEngine.
getHazelcastInstance());
}
if (
listenerConfig.
isLocal()) {
addLocalEntryListener(
listener);
} else {
addEntryListener(
listener,
listenerConfig.
isIncludeValue());
}
}
}
}
public boolean
put(K
key, V
value) {
final
NodeEngine nodeEngine =
getNodeEngine();
Data dataKey =
nodeEngine.
toData(
key);
Data dataValue =
nodeEngine.
toData(
value);
return
putInternal(
dataKey,
dataValue, -1);
}
public
Collection<V>
get(K
key) {
final
NodeEngine nodeEngine =
getNodeEngine();
Data dataKey =
nodeEngine.
toData(
key);
MultiMapResponse result =
getAllInternal(
dataKey);
return
result.
getObjectCollection(
nodeEngine);
}
public boolean
remove(
Object key,
Object value) {
final
NodeEngine nodeEngine =
getNodeEngine();
Data dataKey =
nodeEngine.
toData(
key);
Data dataValue =
nodeEngine.
toData(
value);
return
removeInternal(
dataKey,
dataValue);
}
public
Collection<V>
remove(
Object key) {
final
NodeEngine nodeEngine =
getNodeEngine();
Data dataKey =
nodeEngine.
toData(
key);
MultiMapResponse result =
removeInternal(
dataKey);
return
result.
getObjectCollection(
nodeEngine);
}
public
Set<K>
localKeySet() {
Set<
Data>
dataKeySet =
localKeySetInternal();
return
toObjectSet(
dataKeySet);
}
public
Set<K>
keySet() {
Set<
Data>
dataKeySet =
keySetInternal();
return
toObjectSet(
dataKeySet);
}
public
Collection<V>
values() {
final
NodeEngine nodeEngine =
getNodeEngine();
Map map =
valuesInternal();
Collection values = new
LinkedList();
for (
Object obj :
map.
values()) {
if (
obj == null) {
continue;
}
MultiMapResponse response =
nodeEngine.
toObject(
obj);
values.
addAll(
response.
getObjectCollection(
nodeEngine));
}
return
values;
}
public
Set<
Map.
Entry<K, V>>
entrySet() {
final
NodeEngine nodeEngine =
getNodeEngine();
Map map =
entrySetInternal();
Set<
Map.
Entry<K, V>>
entrySet = new
HashSet<
Map.
Entry<K, V>>();
for (
Object obj :
map.
values()) {
if (
obj == null) {
continue;
}
EntrySetResponse response =
nodeEngine.
toObject(
obj);
Set<
Map.
Entry<K, V>>
entries =
response.
getObjectEntrySet(
nodeEngine);
entrySet.
addAll(
entries);
}
return
entrySet;
}
public boolean
containsKey(K
key) {
final
NodeEngine nodeEngine =
getNodeEngine();
Data dataKey =
nodeEngine.
toData(
key);
return
containsInternal(
dataKey, null);
}
public boolean
containsValue(
Object value) {
final
NodeEngine nodeEngine =
getNodeEngine();
Data valueKey =
nodeEngine.
toData(
value);
return
containsInternal(null,
valueKey);
}
public boolean
containsEntry(K
key, V
value) {
final
NodeEngine nodeEngine =
getNodeEngine();
Data dataKey =
nodeEngine.
toData(
key);
Data valueKey =
nodeEngine.
toData(
value);
return
containsInternal(
dataKey,
valueKey);
}
public int
valueCount(K
key) {
final
NodeEngine nodeEngine =
getNodeEngine();
Data dataKey =
nodeEngine.
toData(
key);
return
countInternal(
dataKey);
}
public
String addLocalEntryListener(
EntryListener<K, V>
listener) {
return
getService().
addListener(
name,
listener, null, false, true);
}
public
String addEntryListener(
EntryListener<K, V>
listener, boolean
includeValue) {
return
getService().
addListener(
name,
listener, null,
includeValue, false);
}
public boolean
removeEntryListener(
String registrationId) {
return
getService().
removeListener(
name,
registrationId);
}
public
String addEntryListener(
EntryListener<K, V>
listener, K
key, boolean
includeValue) {
final
NodeEngine nodeEngine =
getNodeEngine();
Data dataKey =
nodeEngine.
toData(
key);
return
getService().
addListener(
name,
listener,
dataKey,
includeValue, false);
}
public void
lock(K
key) {
final
NodeEngine nodeEngine =
getNodeEngine();
Data dataKey =
nodeEngine.
toData(
key);
lockSupport.
lock(
nodeEngine,
dataKey);
}
public void
lock(K
key, long
leaseTime,
TimeUnit timeUnit) {
shouldBePositive(
leaseTime, "leaseTime");
final
NodeEngine nodeEngine =
getNodeEngine();
Data dataKey =
nodeEngine.
toData(
key);
lockSupport.
lock(
nodeEngine,
dataKey,
timeUnit.
toMillis(
leaseTime));
}
public boolean
isLocked(K
key) {
final
NodeEngine nodeEngine =
getNodeEngine();
Data dataKey =
nodeEngine.
toData(
key);
return
lockSupport.
isLocked(
nodeEngine,
dataKey);
}
public boolean
tryLock(K
key) {
try {
return
tryLock(
key, 0,
TimeUnit.
MILLISECONDS);
} catch (
InterruptedException e) {
return false;
}
}
public boolean
tryLock(K
key, long
time,
TimeUnit timeunit) throws
InterruptedException {
final
NodeEngine nodeEngine =
getNodeEngine();
Data dataKey =
nodeEngine.
toData(
key);
return
lockSupport.
tryLock(
nodeEngine,
dataKey,
time,
timeunit);
}
public void
unlock(K
key) {
final
NodeEngine nodeEngine =
getNodeEngine();
Data dataKey =
nodeEngine.
toData(
key);
lockSupport.
unlock(
nodeEngine,
dataKey);
}
public void
forceUnlock(K
key) {
final
NodeEngine nodeEngine =
getNodeEngine();
Data dataKey =
nodeEngine.
toData(
key);
lockSupport.
forceUnlock(
nodeEngine,
dataKey);
}
public
LocalMultiMapStats getLocalMultiMapStats() {
return (
LocalMultiMapStats)
getService().
createStats(
name);
}
private
Set<K>
toObjectSet(
Set<
Data>
dataSet) {
final
NodeEngine nodeEngine =
getNodeEngine();
Set<K>
keySet = new
HashSet<K>(
dataSet.
size());
for (
Data dataKey :
dataSet) {
keySet.
add((K)
nodeEngine.
toObject(
dataKey));
}
return
keySet;
}
@
Override
public
String toString() {
final
StringBuilder sb = new
StringBuilder("MultiMap{");
sb.
append("name=").
append(
getName());
sb.
append('}');
return
sb.
toString();
}
}