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;
23 import java.util.Collections;
24 import java.util.HashMap;
28 * Value holds a value among various types at a time.
30 * Type helps identify type information of Value.
32 * @see RcsResourceAttributes
35 public final class RcsValue {
37 private static class NullType {
39 public String toString() {
45 * Identifiers for types of Value.
49 public static enum TypeId {
50 NULL, BOOLEAN, INTEGER, DOUBLE, STRING, BYTESTRING, ATTRIBUTES, ARRAY;
54 * A Helper class to identify types of Value.
56 * @see RcsResourceAttributes
60 public static class Type {
61 private final TypeId mTypeId;
68 * Returns type identifier.
70 * @return Identifier of type
72 * @see #getBaseTypeId(RcsValue.Type)
74 public final TypeId getId() {
78 protected TypeId getBaseTypeId() {
82 protected int getDepth() {
87 * Returns the type identifier of a base type of sequence.
89 * For non sequence types, it is equivalent to calling {@link #getId()}.
91 * @return identifier of type
96 public static TypeId getBaseTypeId(Type t) {
97 return t.getBaseTypeId();
101 * Returns the depth of a type.
103 * The return will be zero for non sequence types.
107 public static int getDepth(Type t) {
112 * Factory method to create Type instance from an object.
113 * Note that object must be a supported type by RcsValue.
115 * @return An instance that has TypeId for obj.
117 * @throws NullPointerException
119 * @throws IllegalArgumentException
120 * if obj is not supported type.
123 public static Type typeOf(Object obj) {
125 throw new NullPointerException("object is null");
128 return typeOf(obj.getClass());
132 * Factory method to create Type instance from a class.
133 * Note that class must be a supported type by RcsValue.
135 * @return An instance that has TypeId for class.
137 * @throws NullPointerException
139 * @throws IllegalArgumentException
140 * if cls is not supported type.
143 public static Type typeOf(Class<?> cls) {
145 throw new NullPointerException("class is null");
148 if (sTypes.containsKey(cls)) return sTypes.get(cls);
150 throw new IllegalArgumentException(
151 cls.getSimpleName() + " is not supported type.");
155 private static class ArrayType extends Type {
156 private final TypeId mBaseTypeId;
157 private final int mDimension;
159 ArrayType(TypeId baseTypeId, int dimension) {
162 mBaseTypeId = baseTypeId;
163 mDimension = dimension;
167 protected TypeId getBaseTypeId() {
172 protected int getDepth() {
177 private static final NullType sNullValue = new NullType();
179 private static Map<Class<?>, Type> sTypes;
181 private final Object mObject;
185 final Map<Class<?>, Type> types = new HashMap<Class<?>, Type>();
187 types.put(NullType.class, new Type(TypeId.NULL));
188 types.put(Boolean.class, new Type(TypeId.BOOLEAN));
189 types.put(Integer.class, new Type(TypeId.INTEGER));
190 types.put(Double.class, new Type(TypeId.DOUBLE));
191 types.put(String.class, new Type(TypeId.STRING));
192 types.put(RcsByteString.class, new Type(TypeId.BYTESTRING));
193 types.put(RcsResourceAttributes.class, new Type(TypeId.ATTRIBUTES));
195 types.put(boolean[].class, new ArrayType(TypeId.BOOLEAN, 1));
196 types.put(int[].class, new ArrayType(TypeId.INTEGER, 1));
197 types.put(double[].class, new ArrayType(TypeId.DOUBLE, 1));
198 types.put(String[].class, new ArrayType(TypeId.STRING, 1));
199 types.put(RcsByteString[].class, new ArrayType(TypeId.BYTESTRING, 1));
200 types.put(RcsResourceAttributes[].class,
201 new ArrayType(TypeId.ATTRIBUTES, 1));
203 types.put(boolean[][].class, new ArrayType(TypeId.BOOLEAN, 2));
204 types.put(int[][].class, new ArrayType(TypeId.INTEGER, 2));
205 types.put(double[][].class, new ArrayType(TypeId.DOUBLE, 2));
206 types.put(String[][].class, new ArrayType(TypeId.STRING, 2));
207 types.put(RcsByteString[][].class, new ArrayType(TypeId.BYTESTRING, 2));
208 types.put(RcsResourceAttributes[][].class,
209 new ArrayType(TypeId.ATTRIBUTES, 2));
211 types.put(boolean[][][].class, new ArrayType(TypeId.BOOLEAN, 3));
212 types.put(int[][][].class, new ArrayType(TypeId.INTEGER, 3));
213 types.put(double[][][].class, new ArrayType(TypeId.DOUBLE, 3));
214 types.put(String[][][].class, new ArrayType(TypeId.STRING, 3));
215 types.put(RcsByteString[][][].class, new ArrayType(TypeId.BYTESTRING, 3));
216 types.put(RcsResourceAttributes[][][].class,
217 new ArrayType(TypeId.ATTRIBUTES, 3));
219 sTypes = Collections.unmodifiableMap(types);
223 static boolean isSupportedType(Class<?> cls) {
224 return sTypes.containsKey(cls);
227 static void verifySupportedType(Class<?> cls) {
228 if (!isSupportedType(cls)) {
229 throw new IllegalArgumentException(
230 cls.getSimpleName() + " is not supported type.");
235 * Constructs a new value with an object.
240 * @throws NullPointerException
242 * @throws IllegalArgumentException
243 * if value is not supported type.
245 public RcsValue(Object value) {
246 if (value == null) throw new NullPointerException("value is null!");
248 verifySupportedType(value.getClass());
254 * Constructs a new value that holds null value.
262 * Constructs a new value that holds a boolean value.
267 public RcsValue(boolean value) {
268 this((Object) value);
272 * Constructs a new value that holds an int value.
277 public RcsValue(int value) {
278 this((Object) value);
282 * Constructs a new value that holds a double value.
287 public RcsValue(double value) {
288 this((Object) value);
292 * Constructs a new value that holds a String value.
297 * @throws NullPointerException
300 public RcsValue(String value) {
301 this((Object) value);
305 * Constructs a new value that holds a RcsResourceAttributes value.
308 * a RcsResourceAttributes
310 * @throws NullPointerException
313 public RcsValue(RcsResourceAttributes value) {
314 this((Object) value);
318 * Constructs a new value that holds a boolean array.
323 * @throws NullPointerException
326 public RcsValue(boolean[] value) {
327 this((Object) value);
331 * Constructs a new value that holds a two-dimensional boolean array.
334 * a two-dimensional boolean array
336 * @throws NullPointerException
339 public RcsValue(boolean[][] value) {
340 this((Object) value);
344 * Constructs a new value that holds a three-dimensional boolean array.
347 * a three-dimensional boolean array
349 * @throws NullPointerException
352 public RcsValue(boolean[][][] value) {
353 this((Object) value);
357 * Constructs a new value that holds an int array.
362 * @throws NullPointerException
365 public RcsValue(int[] value) {
366 this((Object) value);
370 * Constructs a new value that holds a two-dimensional int array.
373 * a two-dimensional int array
375 * @throws NullPointerException
378 public RcsValue(int[][] value) {
379 this((Object) value);
383 * Constructs a new value that holds a three-dimensional int array.
386 * a three-dimensional int array
388 * @throws NullPointerException
391 public RcsValue(int[][][] value) {
392 this((Object) value);
396 * Constructs a new value that holds a double array.
401 * @throws NullPointerException
404 public RcsValue(double[] value) {
405 this((Object) value);
409 * Constructs a new value that holds a two-dimensional double array.
412 * a two-dimensional double array
414 * @throws NullPointerException
417 public RcsValue(double[][] value) {
418 this((Object) value);
422 * Constructs a new value that holds a three-dimensional double array.
425 * a three-dimensional double array
427 * @throws NullPointerException
430 public RcsValue(double[][][] value) {
431 this((Object) value);
435 * Constructs a new value that holds a String array.
440 * @throws NullPointerException
443 public RcsValue(String[] value) {
444 this((Object) value);
448 * Constructs a new value that holds a two-dimensional String array.
451 * a two-dimensional String array
453 * @throws NullPointerException
456 public RcsValue(String[][] value) {
457 this((Object) value);
461 * Constructs a new value that holds a three-dimensional String array.
464 * a three-dimensional String array
466 * @throws NullPointerException
469 public RcsValue(String[][][] value) {
470 this((Object) value);
474 * Constructs a new value that holds a RcsResourceAttributes array.
476 * @param value a RcsByteString array
477 * @throws NullPointerException if value is null.
479 public RcsValue(RcsByteString[] value) {
480 this((Object) value);
484 * Constructs a new value that holds a two-dimensional RcsByteString array.
486 * @param value a two-dimensional RcsByteString array
487 * @throws NullPointerException if value is null.
489 public RcsValue(RcsByteString[][] value) {
490 this((Object) value);
494 * Constructs a new value that holds a three-dimensional RcsByteString array.
496 * @param value a three-dimensional RcsByteString array
497 * @throws NullPointerException if value is null.
499 public RcsValue(RcsByteString[][][] value) {
500 this((Object) value);
504 * Constructs a new value that holds a RcsResourceAttributes array.
506 * @throws NullPointerException
509 public RcsValue(RcsResourceAttributes[] value) {
510 this((Object) value);
514 * Constructs a new value that holds a two-dimensional RcsResourceAttributes
518 * a two-dimensional RcsResourceAttributes array
520 * @throws NullPointerException
523 public RcsValue(RcsResourceAttributes[][] value) {
524 this((Object) value);
528 * Constructs a new value that holds a three-dimensional
529 * RcsResourceAttributes array.
532 * a three-dimensional RcsResourceAttributes array
534 * @throws NullPointerException
537 public RcsValue(RcsResourceAttributes[][][] value) {
538 this((Object) value);
542 * Returns whether the value is null.
544 * @return true if the value is null.
546 public boolean isNull() {
547 return isNullObject(mObject);
551 * Returns whether the object represents null for RcsValue.
554 * an object to be tested
556 * @return true if the object represents null.
558 public static boolean isNullObject(Object o) {
559 return o == sNullValue;
563 * Returns type information.
565 * @return type information for the value.
567 public Type getType() {
568 if (mType == null) mType = Type.typeOf(mObject);
573 * Returns the value as T.
575 * @return a value as T
577 * @throws ClassCastException
578 * if the value is not of T.
580 @SuppressWarnings("unchecked")
585 @SuppressWarnings("unchecked")
586 private <T> T getOrNull() {
589 } catch (final ClassCastException e) {
595 * Returns the value as an Object.
599 public Object asObject() {
604 * Returns the value as a boolean, false if the value is not the desired
607 * @return a boolean value
610 public boolean asBoolean() {
611 return asBoolean(false);
615 * Returns the value as a boolean.
617 * @param defaultValue
618 * value to return if the value is not boolean.
620 * @return a boolean value
623 public boolean asBoolean(boolean defaultValue) {
626 } catch (final ClassCastException e) {
632 * Returns the value as an int, 0 if the value is not the desired type.
634 * @return an int value
642 * Returns the value as an int.
644 * @param defaultValue
645 * value to return if the value is not int.
647 * @return an int value
650 public int asInt(int defaultValue) {
653 } catch (final ClassCastException e) {
659 * Returns the value as a double, 0 if the value is not the desired type.
661 * @return a double value
664 public double asDouble() {
669 * Returns the value as a double.
671 * @param defaultValue
672 * value to return if the value is not double.
674 * @return a double value
677 public double asDouble(double defaultValue) {
680 } catch (final ClassCastException e) {
686 * Returns the value as a string, null if the value is not the desired type.
688 * @return a string value
691 public String asString() {
692 return asString(null);
696 * Returns the value as a String.
698 * @param defaultValue
699 * value to return if the value is not String.
701 * @return a String value
704 public String asString(String defaultValue) {
707 } catch (final ClassCastException e) {
713 * Returns the value as a RcsResourceAttributes,
714 * null if the value is not the desired type.
716 * @return a RcsResourceAttributes value
719 public RcsResourceAttributes asAttributes() {
724 * Returns the value as a boolean array, null if the value is not the
727 * @return a boolean array
730 public boolean[] asBooleanArray() {
735 * Returns the value as a two-dimensional boolean array, null if the value
736 * is not the desired type.
738 * @return a two-dimensional boolean array
741 public boolean[][] asBoolean2DArray() {
746 * Returns the value as a three-dimensional boolean array, null if the value
747 * is not the desired type.
749 * @return a three-dimensional boolean array
752 public boolean[][][] asBoolean3DArray() {
757 * Returns the value as an int array, null if the value is not the
760 * @return an int array
763 public int[] asIntArray() {
768 * Returns the value as a two-dimensional int array, null if the value
769 * is not the desired type.
771 * @return a two-dimensional int array
774 public int[][] asInt2DArray() {
779 * Returns the value as a three-dimensional int array, null if the value
780 * is not the desired type.
782 * @return a three-dimensional int array
785 public int[][][] asInt3DArray() {
790 * Returns the value as a double array, null if the value is not the
793 * @return a double array
796 public double[] asDoubleArray() {
801 * Returns the value as a two-dimensional double array, null if the value
802 * is not the desired type.
804 * @return a two-dimensional double array
807 public double[][] asDouble2DArray() {
812 * Returns the value as a three-dimensional double array, null if the value
813 * is not the desired type.
815 * @return a three-dimensional double array
818 public double[][][] asDouble3DArray() {
823 * Returns the value as a string array, null if the value is not the
826 * @return a string array
829 public String[] asStringArray() {
834 * Returns the value as a two-dimensional string array, null if the value
835 * is not the desired type.
837 * @return a two-dimensional string array
840 public String[][] asString2DArray() {
845 * Returns the value as a three-dimensional string array, null if the value
846 * is not the desired type.
848 * @return a three-dimensional string array
851 public String[][][] asString3DArray() {
856 * Returns the value as an RcsByteString array, null if the value is not the
859 * @return an RcsByteString array
861 public RcsByteString[] asByteStringArray() {
866 * Returns the value as a two-dimensional RcsByteString array, null if the
867 * value is not the desired type.
869 * @return a two-dimensional RcsByteString array
871 public RcsByteString[][] asByteString2DArray() {
876 * Returns the value as a three-dimensional RcsByteString array, null if the
877 * value is not the desired type.
879 * @return a three-dimensional RcsByteString array
881 public RcsByteString[][][] asByteString3DArray() {
886 * Returns the value as an attributes array, null if the value is not the
889 * @return an attributes array
892 public RcsResourceAttributes[] asAttributesArray() {
897 * Returns the value as a two-dimensional attributes array, null if the
898 * value is not the desired type.
900 * @return a two-dimensional attributes array
903 public RcsResourceAttributes[][] asAttributes2DArray() {
908 * Returns the value as a three-dimensional attributes array, null if the
909 * value is not the desired type.
911 * @return a three-dimensional attributes array
914 public RcsResourceAttributes[][][] asAttributes3DArray() {
919 public boolean equals(Object o) {
920 if (o == this) return true;
921 if (!(o instanceof RcsValue)) return false;
923 final RcsValue rhs = (RcsValue) o;
925 return mObject.equals(rhs.mObject);
929 public int hashCode() {
930 return mObject.hashCode();
934 public String toString() {
935 return mObject.toString();