1 /******************************************************************
3 * Copyright 2015 Samsung Electronics All Rights Reserved.
7 * Licensed under the Apache License, Version 2.0 (the "License");
8 * you may not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS,
15 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
19 ******************************************************************/
21 package org.iotivity.service.resourcecontainer.server;
23 import java.util.Collections;
24 import java.util.HashMap;
25 import java.util.HashSet;
29 import org.iotivity.service.resourcecontainer.RcsException;
30 import org.iotivity.service.resourcecontainer.RcsObject;
31 import org.iotivity.service.resourcecontainer.RcsResourceAttributes;
32 import org.iotivity.service.resourcecontainer.RcsValue;
34 public final class RcsLockedAttributes extends RcsObject {
36 private static native boolean nativeIsEmpty(RcsResourceObject resourceObj);
38 private static native int nativeSize(RcsResourceObject resourceObj);
40 private static native boolean nativeRemove(RcsResourceObject resourceObj,
43 private static native boolean nativeClear(RcsResourceObject resourceObj);
45 private static native boolean nativeContains(RcsResourceObject resourceObj,
48 private static native void nativeAddKeys(RcsResourceObject resourceObj,
51 private static native RcsValue nativeAsJavaObject(
52 RcsResourceObject resourceObj, String key);
54 private static native void nativeApply(RcsResourceObject resourceObj,
55 Map<String, RcsValue> cache);
57 private native void nativeLock(RcsResourceObject resourceObj);
59 private native void nativeUnlock();
61 private final RcsResourceObject mResourceObject;
63 private boolean mIsUnlocked;
65 private Map<String, RcsValue> mCache = new HashMap<>();
67 RcsLockedAttributes(RcsResourceObject resourceObject) throws RcsException {
68 if (resourceObject == null) {
69 throw new RcsException("Illegal opertaion!");
72 mResourceObject = resourceObject;
74 nativeLock(resourceObject);
77 void setUnlockState() {
85 nativeApply(mResourceObject, mCache);
89 private void ensureLocked() throws RcsException {
91 throw new RcsUnlockedException("This attributes is unlocked!");
96 * Returns a unmodifiable Set view of the keys contained in this attributes.
98 * @return an unmodifiable set view of the keys in this attributes
100 * @throws RcsUnlockedException
101 * if the {@link RcsResourceObject.AttributesLock} for this
104 public Set<String> keySet() throws RcsException {
107 final Set<String> keySet = new HashSet<>(mCache.keySet());
109 nativeAddKeys(mResourceObject, keySet);
111 return Collections.unmodifiableSet(keySet);
115 * Returns the value to which the specified key is mapped, or null if this
116 * contains no mapping for the key.
119 * the key whose associated value is to be returned
121 * @return the value to which the specified key is mapped, or null if this
122 * contains no mapping for the key
124 * @throws NullPointerException
126 * @throws RcsUnlockedException
127 * if the {@link RcsResourceObject.AttributesLock} for this
130 public RcsValue get(String key) throws RcsException {
133 if (key == null) throw new NullPointerException("key is null");
135 if (!mCache.containsKey(key) && nativeContains(mResourceObject, key)) {
136 mCache.put(key, nativeAsJavaObject(mResourceObject, key));
138 return mCache.get(key);
142 * Copies all of the mappings from the specified to this
145 * attributes to be copied
147 * @throws RcsUnlockedException
148 * if the {@link RcsResourceObject.AttributesLock} for this
152 public RcsLockedAttributes putAll(RcsResourceAttributes attributes)
153 throws RcsException {
156 final Set<String> keys = attributes.keySet();
158 for (final String k : keys) {
159 mCache.put(k, attributes.get(k));
165 * Sets the specified value with the specified key.
166 * If the object previously contained a mapping for the key, the old value
167 * is replaced by the specified value.
170 * key with which the specified value is to be associated
173 * value to be associated with the specified key
175 * @throws NullPointerException
176 * if key or value is null
177 * @throws RcsUnlockedException
178 * if the {@link RcsResourceObject.AttributesLock} for this
182 public RcsLockedAttributes put(String key, RcsValue value)
183 throws RcsException {
186 if (key == null) throw new NullPointerException("key is null");
187 if (value == null) throw new NullPointerException("value is null");
189 mCache.put(key, value);
195 * Sets the specified value with the specified key.
196 * If the object previously contained a mapping for the key, the old value
197 * is replaced by the specified value.
200 * key with which the specified value is to be associated
203 * value to be associated with the specified key
205 * @throws NullPointerException
206 * if key or value is null
207 * @throws IllegalArgumentException
208 * if object is not supported type by {@link RcsValue}
209 * @throws RcsUnlockedException
210 * if the {@link RcsResourceObject.AttributesLock} for this
213 public void put(String key, Object value) throws RcsException {
214 if (key == null) throw new NullPointerException("key is null");
216 put(key, new RcsValue(value));
220 * Returns whether attribute is empty.
222 * @throws RcsUnlockedException
223 * if the {@link RcsResourceObject.AttributesLock} for this
226 public boolean isEmpty() throws RcsException {
229 return mCache.isEmpty() && nativeIsEmpty(mResourceObject);
233 * Returns the number of key-value mappings.
235 * @throws RcsUnlockedException
236 * if the {@link RcsResourceObject.AttributesLock} for this
239 public int size() throws RcsException {
242 return mCache.size() + nativeSize(mResourceObject);
246 * Removes the mapping for a key from this attributes if it is present.
249 * key whose mapping is to be removed
251 * @return true if the key is present and the the value mapped is removed.
253 * @throws RcsUnlockedException
254 * if the {@link RcsResourceObject.AttributesLock} for this
257 public boolean remove(String key) throws RcsException {
260 if (key == null) throw new NullPointerException("key is null");
262 // XXX make sure both cache and native values to be removed.
263 final boolean cacheRemove = mCache.remove(key) != null;
264 final boolean nativeRemove = nativeRemove(mResourceObject, key);
266 return cacheRemove || nativeRemove;
270 * Removes all elements.
272 * @throws RcsUnlockedException
273 * if the {@link RcsResourceObject.AttributesLock} for this
276 public void clear() throws RcsException {
279 nativeClear(mResourceObject);
283 * Returns true if this contains a mapping for the specified key.
286 * key whose presence is to be tested
288 * @return true if this contains a mapping for the specified key.
290 * @throws NullPointerException
292 * @throws RcsUnlockedException
293 * if the {@link RcsResourceObject.AttributesLock} for this
296 public boolean contains(String key) throws RcsException {
299 if (key == null) throw new NullPointerException("key is null");
301 return mCache.containsKey(key) || nativeContains(mResourceObject, key);