replace : iotivity -> iotivity-sec
[platform/upstream/iotivity.git] / service / resource-encapsulation / android / service / src / main / java / org / iotivity / service / RcsValue.java
1 /******************************************************************
2  *
3  * Copyright 2015 Samsung Electronics All Rights Reserved.
4  *
5  *
6  *
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
10  *
11  *      http://www.apache.org/licenses/LICENSE-2.0
12  *
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.
18  *
19  ******************************************************************/
20
21 package org.iotivity.service;
22
23 import java.util.Collections;
24 import java.util.HashMap;
25 import java.util.Map;
26
27 /**
28  * Value holds a value among various types at a time.
29  *
30  * Type helps identify type information of Value.
31  *
32  * @see RcsResourceAttributes
33  * @see Type
34  */
35 public final class RcsValue {
36
37     private static class NullType {
38         @Override
39         public String toString() {
40             return "";
41         }
42     }
43
44     /**
45      * Identifiers for types of Value.
46      *
47      * @see Type
48      */
49     public static enum TypeId {
50         NULL, BOOLEAN, INTEGER, DOUBLE, STRING, BYTESTRING, ATTRIBUTES, ARRAY;
51     }
52
53     /**
54      * A Helper class to identify types of Value.
55      *
56      * @see RcsResourceAttributes
57      * @see RcsValue
58      * @see TypeId
59      */
60     public static class Type {
61         private final TypeId mTypeId;
62
63         Type(TypeId typeId) {
64             mTypeId = typeId;
65         }
66
67         /**
68          * Returns type identifier.
69          *
70          * @return Identifier of type
71          *
72          * @see #getBaseTypeId(RcsValue.Type)
73          */
74         public final TypeId getId() {
75             return mTypeId;
76         }
77
78         protected TypeId getBaseTypeId() {
79             return mTypeId;
80         }
81
82         protected int getDepth() {
83             return 0;
84         }
85
86         /**
87          * Returns the type identifier of a base type of sequence.
88          *
89          * For non sequence types, it is equivalent to calling {@link #getId()}.
90          *
91          * @return identifier of type
92          *
93          * @see getDepth
94          * @see getId
95          */
96         public static TypeId getBaseTypeId(Type t) {
97             return t.getBaseTypeId();
98         }
99
100         /**
101          * Returns the depth of a type.
102          *
103          * The return will be zero for non sequence types.
104          *
105          * @see getBaseTypeId
106          */
107         public static int getDepth(Type t) {
108             return t.getDepth();
109         }
110
111         /**
112          * Factory method to create Type instance from an object.
113          * Note that object must be a supported type by RcsValue.
114          *
115          * @return An instance that has TypeId for obj.
116          *
117          * @throws NullPointerException
118          *             if obj is null.
119          * @throws IllegalArgumentException
120          *             if obj is not supported type.
121          *
122          */
123         public static Type typeOf(Object obj) {
124             if (obj == null) {
125                 throw new NullPointerException("object is null");
126             }
127
128             return typeOf(obj.getClass());
129         }
130
131         /**
132          * Factory method to create Type instance from a class.
133          * Note that class must be a supported type by RcsValue.
134          *
135          * @return An instance that has TypeId for class.
136          *
137          * @throws NullPointerException
138          *             if cls is null.
139          * @throws IllegalArgumentException
140          *             if cls is not supported type.
141          *
142          */
143         public static Type typeOf(Class<?> cls) {
144             if (cls == null) {
145                 throw new NullPointerException("class is null");
146             }
147
148             if (sTypes.containsKey(cls)) return sTypes.get(cls);
149
150             throw new IllegalArgumentException(
151                     cls.getSimpleName() + " is not supported type.");
152         }
153     }
154
155     private static class ArrayType extends Type {
156         private final TypeId mBaseTypeId;
157         private final int    mDimension;
158
159         ArrayType(TypeId baseTypeId, int dimension) {
160             super(TypeId.ARRAY);
161
162             mBaseTypeId = baseTypeId;
163             mDimension = dimension;
164         }
165
166         @Override
167         protected TypeId getBaseTypeId() {
168             return mBaseTypeId;
169         }
170
171         @Override
172         protected int getDepth() {
173             return mDimension;
174         }
175     }
176
177     private static final NullType sNullValue = new NullType();
178
179     private static Map<Class<?>, Type> sTypes;
180
181     private final Object mObject;
182     private Type         mType;
183
184     static {
185         final Map<Class<?>, Type> types = new HashMap<Class<?>, Type>();
186
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));
194
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));
202
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));
210
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));
218
219         sTypes = Collections.unmodifiableMap(types);
220
221     }
222
223     static boolean isSupportedType(Class<?> cls) {
224         return sTypes.containsKey(cls);
225     }
226
227     static void verifySupportedType(Class<?> cls) {
228         if (!isSupportedType(cls)) {
229             throw new IllegalArgumentException(
230                     cls.getSimpleName() + " is not supported type.");
231         }
232     }
233
234     /**
235      * Constructs a new value with an object.
236      *
237      * @param value
238      *            An object
239      *
240      * @throws NullPointerException
241      *             if value is null.
242      * @throws IllegalArgumentException
243      *             if value is not supported type.
244      */
245     public RcsValue(Object value) {
246         if (value == null) throw new NullPointerException("value is null!");
247
248         verifySupportedType(value.getClass());
249
250         mObject = value;
251     }
252
253     /**
254      * Constructs a new value that holds null value.
255      *
256      */
257     public RcsValue() {
258         this(sNullValue);
259     }
260
261     /**
262      * Constructs a new value that holds a boolean value.
263      *
264      * @param value
265      *            a boolean
266      */
267     public RcsValue(boolean value) {
268         this((Object) value);
269     }
270
271     /**
272      * Constructs a new value that holds an int value.
273      *
274      * @param value
275      *            an int
276      */
277     public RcsValue(int value) {
278         this((Object) value);
279     }
280
281     /**
282      * Constructs a new value that holds a double value.
283      *
284      * @param value
285      *            a double
286      */
287     public RcsValue(double value) {
288         this((Object) value);
289     }
290
291     /**
292      * Constructs a new value that holds a String value.
293      *
294      * @param value
295      *            a String
296      *
297      * @throws NullPointerException
298      *             if value is null.
299      */
300     public RcsValue(String value) {
301         this((Object) value);
302     }
303
304     /**
305      * Constructs a new value that holds a RcsResourceAttributes value.
306      *
307      * @param value
308      *            a RcsResourceAttributes
309      *
310      * @throws NullPointerException
311      *             if value is null.
312      */
313     public RcsValue(RcsResourceAttributes value) {
314         this((Object) value);
315     }
316
317     /**
318      * Constructs a new value that holds a boolean array.
319      *
320      * @param value
321      *            a boolean array
322      *
323      * @throws NullPointerException
324      *             if value is null.
325      */
326     public RcsValue(boolean[] value) {
327         this((Object) value);
328     }
329
330     /**
331      * Constructs a new value that holds a two-dimensional boolean array.
332      *
333      * @param value
334      *            a two-dimensional boolean array
335      *
336      * @throws NullPointerException
337      *             if value is null.
338      */
339     public RcsValue(boolean[][] value) {
340         this((Object) value);
341     }
342
343     /**
344      * Constructs a new value that holds a three-dimensional boolean array.
345      *
346      * @param value
347      *            a three-dimensional boolean array
348      *
349      * @throws NullPointerException
350      *             if value is null.
351      */
352     public RcsValue(boolean[][][] value) {
353         this((Object) value);
354     }
355
356     /**
357      * Constructs a new value that holds an int array.
358      *
359      * @param value
360      *            an int array
361      *
362      * @throws NullPointerException
363      *             if value is null.
364      */
365     public RcsValue(int[] value) {
366         this((Object) value);
367     }
368
369     /**
370      * Constructs a new value that holds a two-dimensional int array.
371      *
372      * @param value
373      *            a two-dimensional int array
374      *
375      * @throws NullPointerException
376      *             if value is null.
377      */
378     public RcsValue(int[][] value) {
379         this((Object) value);
380     }
381
382     /**
383      * Constructs a new value that holds a three-dimensional int array.
384      *
385      * @param value
386      *            a three-dimensional int array
387      *
388      * @throws NullPointerException
389      *             if value is null.
390      */
391     public RcsValue(int[][][] value) {
392         this((Object) value);
393     }
394
395     /**
396      * Constructs a new value that holds a double array.
397      *
398      * @param value
399      *            a double array
400      *
401      * @throws NullPointerException
402      *             if value is null.
403      */
404     public RcsValue(double[] value) {
405         this((Object) value);
406     }
407
408     /**
409      * Constructs a new value that holds a two-dimensional double array.
410      *
411      * @param value
412      *            a two-dimensional double array
413      *
414      * @throws NullPointerException
415      *             if value is null.
416      */
417     public RcsValue(double[][] value) {
418         this((Object) value);
419     }
420
421     /**
422      * Constructs a new value that holds a three-dimensional double array.
423      *
424      * @param value
425      *            a three-dimensional double array
426      *
427      * @throws NullPointerException
428      *             if value is null.
429      */
430     public RcsValue(double[][][] value) {
431         this((Object) value);
432     }
433
434     /**
435      * Constructs a new value that holds a String array.
436      *
437      * @param value
438      *            a String array
439      *
440      * @throws NullPointerException
441      *             if value is null.
442      */
443     public RcsValue(String[] value) {
444         this((Object) value);
445     }
446
447     /**
448      * Constructs a new value that holds a two-dimensional String array.
449      *
450      * @param value
451      *            a two-dimensional String array
452      *
453      * @throws NullPointerException
454      *             if value is null.
455      */
456     public RcsValue(String[][] value) {
457         this((Object) value);
458     }
459
460     /**
461      * Constructs a new value that holds a three-dimensional String array.
462      *
463      * @param value
464      *            a three-dimensional String array
465      *
466      * @throws NullPointerException
467      *             if value is null.
468      */
469     public RcsValue(String[][][] value) {
470         this((Object) value);
471     }
472
473     /**
474      * Constructs a new value that holds a RcsResourceAttributes array.
475      *
476      * @param value a RcsByteString array
477      * @throws NullPointerException if value is null.
478      */
479     public RcsValue(RcsByteString[] value) {
480         this((Object) value);
481     }
482
483     /**
484      * Constructs a new value that holds a two-dimensional RcsByteString array.
485      *
486      * @param value a two-dimensional RcsByteString array
487      * @throws NullPointerException if value is null.
488      */
489     public RcsValue(RcsByteString[][] value) {
490         this((Object) value);
491     }
492
493     /**
494      * Constructs a new value that holds a three-dimensional RcsByteString array.
495      *
496      * @param value a three-dimensional RcsByteString array
497      * @throws NullPointerException if value is null.
498      */
499     public RcsValue(RcsByteString[][][] value) {
500         this((Object) value);
501     }
502
503     /**
504      * Constructs a new value that holds a RcsResourceAttributes array.
505      *
506      * @throws NullPointerException
507      *             if value is null.
508      */
509     public RcsValue(RcsResourceAttributes[] value) {
510         this((Object) value);
511     }
512
513     /**
514      * Constructs a new value that holds a two-dimensional RcsResourceAttributes
515      * array.
516      *
517      * @param value
518      *            a two-dimensional RcsResourceAttributes array
519      *
520      * @throws NullPointerException
521      *             if value is null.
522      */
523     public RcsValue(RcsResourceAttributes[][] value) {
524         this((Object) value);
525     }
526
527     /**
528      * Constructs a new value that holds a three-dimensional
529      * RcsResourceAttributes array.
530      *
531      * @param value
532      *            a three-dimensional RcsResourceAttributes array
533      *
534      * @throws NullPointerException
535      *             if value is null.
536      */
537     public RcsValue(RcsResourceAttributes[][][] value) {
538         this((Object) value);
539     }
540
541     /**
542      * Returns whether the value is null.
543      *
544      * @return true if the value is null.
545      */
546     public boolean isNull() {
547         return isNullObject(mObject);
548     }
549
550     /**
551      * Returns whether the object represents null for RcsValue.
552      *
553      * @param o
554      *            an object to be tested
555      *
556      * @return true if the object represents null.
557      */
558     public static boolean isNullObject(Object o) {
559         return o == sNullValue;
560     }
561
562     /**
563      * Returns type information.
564      *
565      * @return type information for the value.
566      */
567     public Type getType() {
568         if (mType == null) mType = Type.typeOf(mObject);
569         return mType;
570     }
571
572     /**
573      * Returns the value as T.
574      *
575      * @return a value as T
576      *
577      * @throws ClassCastException
578      *             if the value is not of T.
579      */
580     @SuppressWarnings("unchecked")
581     public <T> T get() {
582         return (T) mObject;
583     }
584
585     @SuppressWarnings("unchecked")
586     private <T> T getOrNull() {
587         try {
588             return (T) mObject;
589         } catch (final ClassCastException e) {
590             return null;
591         }
592     }
593
594     /**
595      * Returns the value as an Object.
596      *
597      * @return an Object
598      */
599     public Object asObject() {
600         return mObject;
601     }
602
603     /**
604      * Returns the value as a boolean, false if the value is not the desired
605      * type.
606      *
607      * @return a boolean value
608      *
609      */
610     public boolean asBoolean() {
611         return asBoolean(false);
612     }
613
614     /**
615      * Returns the value as a boolean.
616      *
617      * @param defaultValue
618      *            value to return if the value is not boolean.
619      *
620      * @return a boolean value
621      *
622      */
623     public boolean asBoolean(boolean defaultValue) {
624         try {
625             return get();
626         } catch (final ClassCastException e) {
627             return defaultValue;
628         }
629     }
630
631     /**
632      * Returns the value as an int, 0 if the value is not the desired type.
633      *
634      * @return an int value
635      *
636      */
637     public int asInt() {
638         return asInt(0);
639     }
640
641     /**
642      * Returns the value as an int.
643      *
644      * @param defaultValue
645      *            value to return if the value is not int.
646      *
647      * @return an int value
648      *
649      */
650     public int asInt(int defaultValue) {
651         try {
652             return get();
653         } catch (final ClassCastException e) {
654             return defaultValue;
655         }
656     }
657
658     /**
659      * Returns the value as a double, 0 if the value is not the desired type.
660      *
661      * @return a double value
662      *
663      */
664     public double asDouble() {
665         return asDouble(0);
666     }
667
668     /**
669      * Returns the value as a double.
670      *
671      * @param defaultValue
672      *            value to return if the value is not double.
673      *
674      * @return a double value
675      *
676      */
677     public double asDouble(double defaultValue) {
678         try {
679             return get();
680         } catch (final ClassCastException e) {
681             return defaultValue;
682         }
683     }
684
685     /**
686      * Returns the value as a string, null if the value is not the desired type.
687      *
688      * @return a string value
689      *
690      */
691     public String asString() {
692         return asString(null);
693     }
694
695     /**
696      * Returns the value as a String.
697      *
698      * @param defaultValue
699      *            value to return if the value is not String.
700      *
701      * @return a String value
702      *
703      */
704     public String asString(String defaultValue) {
705         try {
706             return get();
707         } catch (final ClassCastException e) {
708             return defaultValue;
709         }
710     }
711
712     /**
713      * Returns the value as a RcsResourceAttributes,
714      * null if the value is not the desired type.
715      *
716      * @return a RcsResourceAttributes value
717      *
718      */
719     public RcsResourceAttributes asAttributes() {
720         return getOrNull();
721     }
722
723     /**
724      * Returns the value as a boolean array, null if the value is not the
725      * desired type.
726      *
727      * @return a boolean array
728      *
729      */
730     public boolean[] asBooleanArray() {
731         return getOrNull();
732     }
733
734     /**
735      * Returns the value as a two-dimensional boolean array, null if the value
736      * is not the desired type.
737      *
738      * @return a two-dimensional boolean array
739      *
740      */
741     public boolean[][] asBoolean2DArray() {
742         return getOrNull();
743     }
744
745     /**
746      * Returns the value as a three-dimensional boolean array, null if the value
747      * is not the desired type.
748      *
749      * @return a three-dimensional boolean array
750      *
751      */
752     public boolean[][][] asBoolean3DArray() {
753         return getOrNull();
754     }
755
756     /**
757      * Returns the value as an int array, null if the value is not the
758      * desired type.
759      *
760      * @return an int array
761      *
762      */
763     public int[] asIntArray() {
764         return getOrNull();
765     }
766
767     /**
768      * Returns the value as a two-dimensional int array, null if the value
769      * is not the desired type.
770      *
771      * @return a two-dimensional int array
772      *
773      */
774     public int[][] asInt2DArray() {
775         return getOrNull();
776     }
777
778     /**
779      * Returns the value as a three-dimensional int array, null if the value
780      * is not the desired type.
781      *
782      * @return a three-dimensional int array
783      *
784      */
785     public int[][][] asInt3DArray() {
786         return getOrNull();
787     }
788
789     /**
790      * Returns the value as a double array, null if the value is not the
791      * desired type.
792      *
793      * @return a double array
794      *
795      */
796     public double[] asDoubleArray() {
797         return getOrNull();
798     }
799
800     /**
801      * Returns the value as a two-dimensional double array, null if the value
802      * is not the desired type.
803      *
804      * @return a two-dimensional double array
805      *
806      */
807     public double[][] asDouble2DArray() {
808         return getOrNull();
809     }
810
811     /**
812      * Returns the value as a three-dimensional double array, null if the value
813      * is not the desired type.
814      *
815      * @return a three-dimensional double array
816      *
817      */
818     public double[][][] asDouble3DArray() {
819         return getOrNull();
820     }
821
822     /**
823      * Returns the value as a string array, null if the value is not the
824      * desired type.
825      *
826      * @return a string array
827      *
828      */
829     public String[] asStringArray() {
830         return getOrNull();
831     }
832
833     /**
834      * Returns the value as a two-dimensional string array, null if the value
835      * is not the desired type.
836      *
837      * @return a two-dimensional string array
838      *
839      */
840     public String[][] asString2DArray() {
841         return getOrNull();
842     }
843
844     /**
845      * Returns the value as a three-dimensional string array, null if the value
846      * is not the desired type.
847      *
848      * @return a three-dimensional string array
849      *
850      */
851     public String[][][] asString3DArray() {
852         return getOrNull();
853     }
854
855     /**
856      * Returns the value as an RcsByteString array, null if the value is not the
857      * desired type.
858      *
859      * @return an RcsByteString array
860      */
861     public RcsByteString[] asByteStringArray() {
862         return getOrNull();
863     }
864
865     /**
866      * Returns the value as a two-dimensional RcsByteString array, null if the
867      * value is not the desired type.
868      *
869      * @return a two-dimensional RcsByteString array
870      */
871     public RcsByteString[][] asByteString2DArray() {
872         return getOrNull();
873     }
874
875     /**
876      * Returns the value as a three-dimensional RcsByteString array, null if the
877      * value is not the desired type.
878      *
879      * @return a three-dimensional RcsByteString array
880      */
881     public RcsByteString[][][] asByteString3DArray() {
882         return getOrNull();
883     }
884
885     /**
886      * Returns the value as an attributes array, null if the value is not the
887      * desired type.
888      *
889      * @return an attributes array
890      *
891      */
892     public RcsResourceAttributes[] asAttributesArray() {
893         return getOrNull();
894     }
895
896     /**
897      * Returns the value as a two-dimensional attributes array, null if the
898      * value is not the desired type.
899      *
900      * @return a two-dimensional attributes array
901      *
902      */
903     public RcsResourceAttributes[][] asAttributes2DArray() {
904         return getOrNull();
905     }
906
907     /**
908      * Returns the value as a three-dimensional attributes array, null if the
909      * value is not the desired type.
910      *
911      * @return a three-dimensional attributes array
912      *
913      */
914     public RcsResourceAttributes[][][] asAttributes3DArray() {
915         return getOrNull();
916     }
917
918     @Override
919     public boolean equals(Object o) {
920         if (o == this) return true;
921         if (!(o instanceof RcsValue)) return false;
922
923         final RcsValue rhs = (RcsValue) o;
924
925         return mObject.equals(rhs.mObject);
926     }
927
928     @Override
929     public int hashCode() {
930         return mObject.hashCode();
931     }
932
933     @Override
934     public String toString() {
935         return mObject.toString();
936     }
937
938 }