Initial extension to support Android resource bundles
authorMarkus Jung <markus.jung@samsung.com>
Wed, 4 Nov 2015 10:58:14 +0000 (19:58 +0900)
committerUze Choi <uzchoi@samsung.com>
Wed, 11 Nov 2015 08:40:05 +0000 (08:40 +0000)
Change-Id: I83faf40e7219f08b9737c1d5625b838728c0dc99
Signed-off-by: Markus Jung <markus.jung@samsung.com>
Reviewed-on: https://gerrit.iotivity.org/gerrit/4081
Reviewed-by: Hun-je Yeon <hunje.yeon@samsung.com>
Reviewed-by: Uze Choi <uzchoi@samsung.com>
Tested-by: Uze Choi <uzchoi@samsung.com>
114 files changed:
service/SConscript
service/resource-container/android/SConscript
service/resource-container/android/resource-container/build.gradle
service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/AndroidBundleActivator.java [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/AndroidBundleResource.java [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsDestroyedObjectException.java [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsException.java [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsIllegalStateException.java [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsObject.java [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsPlatformException.java [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsResourceAttributes.java [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsResourceContainer.java
service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsResourceContainerBundleAPI.java [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsValue.java [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/ResourceConfig.java [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/server/RcsGetResponse.java [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/server/RcsLockedAttributes.java [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/server/RcsRequest.java [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/server/RcsResourceObject.java [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/server/RcsResponse.java [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/server/RcsSetResponse.java [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/server/RcsUnlockedException.java [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/jni/Android.mk
service/resource-container/android/resource-container/src/main/jni/AndroidResource.cpp [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/jni/AndroidResource.h [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/jni/JniMain.cpp
service/resource-container/android/resource-container/src/main/jni/JniRcsObject.cpp [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/jni/JniRcsObject.h [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/jni/JniRcsResourceAttributes.cpp [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/jni/JniRcsResourceAttributes.h [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/jni/JniRcsResourceContainer.cpp
service/resource-container/android/resource-container/src/main/jni/JniRcsResourceContainer.h
service/resource-container/android/resource-container/src/main/jni/JniRcsValue.cpp [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/jni/JniRcsValue.h [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/jni/util/JavaClasses.cpp
service/resource-container/android/resource-container/src/main/jni/util/JavaClasses.h
service/resource-container/android/resource-container/src/main/jni/util/JavaExceptions.cpp [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/jni/util/JavaExceptions.h [new file with mode: 0644]
service/resource-container/android/resource-container/src/main/jni/util/ScopedEnv.h [new file with mode: 0644]
service/resource-container/examples/ContainerSampleClient.cpp
service/resource-container/examples/android/AndroidBundle/AndroidBundle.iml [moved from service/resource-container/examples/android/RCSampleClientApp/RCSampleClientApp.iml with 54% similarity, mode: 0755]
service/resource-container/examples/android/AndroidBundle/app/app.iml [moved from service/resource-container/examples/android/RCSampleClientApp/app/app.iml with 78% similarity, mode: 0755]
service/resource-container/examples/android/AndroidBundle/app/build.gradle [moved from service/resource-container/examples/android/RCSampleClientApp/app/build.gradle with 53% similarity, mode: 0755]
service/resource-container/examples/android/AndroidBundle/app/src/androidTest/java/org/iotivity/service/sample/androidbundle/ApplicationTest.java [new file with mode: 0755]
service/resource-container/examples/android/AndroidBundle/app/src/main/AndroidManifest.xml [new file with mode: 0755]
service/resource-container/examples/android/AndroidBundle/app/src/main/java/org/iotivity/service/sample/androidbundle/AndroidLightResource.java [new file with mode: 0755]
service/resource-container/examples/android/AndroidBundle/app/src/main/java/org/iotivity/service/sample/androidbundle/AndroidLocationResource.java [new file with mode: 0755]
service/resource-container/examples/android/AndroidBundle/app/src/main/java/org/iotivity/service/sample/androidbundle/AndroidSampleActivator.java [new file with mode: 0755]
service/resource-container/examples/android/AndroidBundle/app/src/main/java/org/iotivity/service/sample/androidbundle/MainActivity.java [new file with mode: 0755]
service/resource-container/examples/android/AndroidBundle/app/src/main/res/layout/activity_main.xml [new file with mode: 0755]
service/resource-container/examples/android/AndroidBundle/app/src/main/res/menu/menu_main.xml [new file with mode: 0755]
service/resource-container/examples/android/AndroidBundle/app/src/main/res/mipmap-hdpi/ic_launcher.png [moved from service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/mipmap-hdpi/ic_launcher.png with 100% similarity, mode: 0755]
service/resource-container/examples/android/AndroidBundle/app/src/main/res/mipmap-mdpi/ic_launcher.png [moved from service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/mipmap-mdpi/ic_launcher.png with 100% similarity, mode: 0755]
service/resource-container/examples/android/AndroidBundle/app/src/main/res/mipmap-xhdpi/ic_launcher.png [moved from service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/mipmap-xhdpi/ic_launcher.png with 100% similarity, mode: 0755]
service/resource-container/examples/android/AndroidBundle/app/src/main/res/mipmap-xxhdpi/ic_launcher.png [moved from service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/mipmap-xxhdpi/ic_launcher.png with 100% similarity, mode: 0755]
service/resource-container/examples/android/AndroidBundle/app/src/main/res/values-v21/styles.xml [moved from service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/values-v21/styles.xml with 96% similarity, mode: 0755]
service/resource-container/examples/android/AndroidBundle/app/src/main/res/values-w820dp/dimens.xml [new file with mode: 0755]
service/resource-container/examples/android/AndroidBundle/app/src/main/res/values/dimens.xml [new file with mode: 0755]
service/resource-container/examples/android/AndroidBundle/app/src/main/res/values/strings.xml [new file with mode: 0755]
service/resource-container/examples/android/AndroidBundle/app/src/main/res/values/styles.xml [moved from service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/values/styles.xml with 96% similarity, mode: 0755]
service/resource-container/examples/android/AndroidBundle/build.gradle [moved from service/resource-container/examples/android/RCSampleServerApp/build.gradle with 69% similarity, mode: 0755]
service/resource-container/examples/android/AndroidBundle/gradle.properties [new file with mode: 0755]
service/resource-container/examples/android/AndroidBundle/gradle/wrapper/gradle-wrapper.jar [new file with mode: 0755]
service/resource-container/examples/android/AndroidBundle/gradle/wrapper/gradle-wrapper.properties [new file with mode: 0755]
service/resource-container/examples/android/AndroidBundle/gradlew [new file with mode: 0755]
service/resource-container/examples/android/AndroidBundle/gradlew.bat [new file with mode: 0755]
service/resource-container/examples/android/AndroidBundle/settings.gradle [moved from service/resource-container/examples/android/RCSampleClientApp/settings.gradle with 93% similarity, mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/ContainerSampleApp.iml [new file with mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/README [moved from service/resource-container/examples/android/RCSampleClientApp/README with 100% similarity, mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/RESampleServerApp.iml [moved from service/resource-container/examples/android/RCSampleServerApp/RCSampleServerApp.iml with 97% similarity, mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/app/app.iml [moved from service/resource-container/examples/android/RCSampleServerApp/app/app.iml with 77% similarity, mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/app/build.gradle [new file with mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/app/src/main/AndroidManifest.xml [moved from service/resource-container/examples/android/RCSampleServerApp/app/src/main/AndroidManifest.xml with 65% similarity, mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/app/src/main/assets/lib/ResourceContainerConfig.xml [moved from service/resource-container/examples/android/RCSampleServerApp/app/src/main/assets/lib/ResourceContainerConfig.xml with 78% similarity, mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/app/src/main/java/org/iotivity/service/sample/container/DroidLED.java [new file with mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/app/src/main/java/org/iotivity/service/sample/container/FlashLightResource.java [new file with mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/app/src/main/java/org/iotivity/service/sample/container/OicLightActivity.java [new file with mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/app/src/main/java/org/iotivity/service/sample/container/ResourceContainer.java [moved from service/resource-container/examples/android/RCSampleServerApp/app/src/main/java/org/iotivity/service/sample/container/ResourceContainer.java with 93% similarity, mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/app/src/main/java/org/iotivity/service/sample/container/ResourceContainerActivity.java [moved from service/resource-container/examples/android/RCSampleServerApp/app/src/main/java/org/iotivity/service/sample/container/ResourceContainerActivity.java with 97% similarity, mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/app/src/main/res/layout/group.xml [moved from service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/layout/group.xml with 100% similarity, mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/app/src/main/res/layout/list_item.xml [moved from service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/layout/list_item.xml with 100% similarity, mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/app/src/main/res/layout/resource_container.xml [moved from service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/layout/resource_container.xml with 100% similarity, mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/app/src/main/res/mipmap-hdpi/ic_launcher.png [moved from service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/mipmap-hdpi/ic_launcher.png with 100% similarity, mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/app/src/main/res/mipmap-mdpi/ic_launcher.png [moved from service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/mipmap-mdpi/ic_launcher.png with 100% similarity, mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/app/src/main/res/mipmap-xhdpi/ic_launcher.png [moved from service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/mipmap-xhdpi/ic_launcher.png with 100% similarity, mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/app/src/main/res/mipmap-xxhdpi/ic_launcher.png [moved from service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/mipmap-xxhdpi/ic_launcher.png with 100% similarity, mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/app/src/main/res/values-v21/styles.xml [moved from service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/values-v21/styles.xml with 100% similarity, mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/app/src/main/res/values/strings.xml [moved from service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/values/strings.xml with 100% similarity, mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/app/src/main/res/values/styles.xml [moved from service/resource-container/examples/android/RCSampleServerApp/app/src/main/res/values/styles.xml with 100% similarity, mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/build.gradle [moved from service/resource-container/examples/android/RCSampleClientApp/build.gradle with 66% similarity, mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/gradle.properties [new file with mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/gradlew [new file with mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/gradlew.bat [new file with mode: 0755]
service/resource-container/examples/android/ContainerSampleApp/settings.gradle [moved from service/resource-container/examples/android/RCSampleServerApp/settings.gradle with 100% similarity, mode: 0755]
service/resource-container/examples/android/RCSampleClientApp/.gitignore [deleted file]
service/resource-container/examples/android/RCSampleClientApp/app/.gitignore [deleted file]
service/resource-container/examples/android/RCSampleClientApp/app/src/main/AndroidManifest.xml [deleted file]
service/resource-container/examples/android/RCSampleClientApp/app/src/main/java/org/iotivity/service/sample/client/ContainerClientActivity.java [deleted file]
service/resource-container/examples/android/RCSampleClientApp/app/src/main/java/org/iotivity/service/sample/client/Utils.java [deleted file]
service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/layout/activity_container_client.xml [deleted file]
service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/values/strings.xml [deleted file]
service/resource-container/examples/android/RCSampleServerApp/.gitignore [deleted file]
service/resource-container/examples/android/RCSampleServerApp/README [deleted file]
service/resource-container/examples/android/RCSampleServerApp/app/.gitignore [deleted file]
service/resource-container/examples/android/RCSampleServerApp/app/build.gradle [deleted file]
service/resource-container/src/AndroidBundleResource.h [new file with mode: 0644]
service/resource-container/src/BaseActivator.cpp
service/resource-container/src/BundleInfoInternal.cpp
service/resource-container/src/BundleInfoInternal.h
service/resource-container/src/BundleResource.cpp
service/resource-container/src/JavaBundleResource.cpp
service/resource-container/src/ResourceContainerImpl.cpp
service/resource-container/src/ResourceContainerImpl.h
service/resource-encapsulation/src/serverBuilder/src/RCSResourceObject.cpp

index 3a35a4a..a457f73 100644 (file)
@@ -36,9 +36,8 @@ if target_os not in ['arduino','darwin']:
     # Build resource-encapsulation project
     SConscript('resource-encapsulation/SConscript')
 
-    # Build resource-container project
-    if target_os not in ['android']:
-        SConscript('resource-container/SConscript')
+    # Build resource-container project    
+    SConscript('resource-container/SConscript')
 
     # Build simulator module
     if target_os in ['linux'] and env.get('SIMULATOR', False):
index 0fa51a3..ee9f351 100644 (file)
@@ -41,8 +41,7 @@ if not os.path.exists(android_home + '/platforms/android-21') or not os.path.exi
 ...Opening Android SDK Manager now. Once you are finished, the build will continue.
 '''
     os.system(android_home + '/tools/android')
-
-
+    
 def ensure_libs(target, source, env):
     return target, [source, env.get('BUILD_DIR') + 'librcs_container.so']
 
index 50c7205..ee1273e 100644 (file)
@@ -97,7 +97,7 @@ task buildNative(type: Exec) {
         //for windows use 'ndk-build.cmd'
         //def ndkBuild = new File(System.env.ANDROID_NDK_HOME, 'ndk-build.cmd')
         def ndkBuild = new File(System.env.ANDROID_NDK_HOME, 'ndk-build')
-        commandLine ndkBuild, "APP_ABI=$TARGET_ARCH", "APP_OPTIM=$RELEASE", '-C', file('src/main').absolutePath
+        commandLine ndkBuild, "V=1", "APP_ABI=$TARGET_ARCH", "APP_OPTIM=$RELEASE", '-C', file('src/main').absolutePath
     } else {
         println '##################'
         println 'Skipping NDK build'
diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/AndroidBundleActivator.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/AndroidBundleActivator.java
new file mode 100644 (file)
index 0000000..9b212fb
--- /dev/null
@@ -0,0 +1,60 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics 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 org.iotivity.service.resourcecontainer;
+
+import android.content.Context;
+import java.util.List;
+
+public abstract class AndroidBundleActivator {
+    protected RcsResourceContainerBundleAPI bundleAPI;
+    protected Context appContext;
+    
+    public AndroidBundleActivator(RcsResourceContainerBundleAPI bundleAPI, Context appContext){
+        this.bundleAPI = bundleAPI;
+        this.appContext = appContext;
+    }
+    /**
+     * Activates the bundle and creates all resources.
+     */
+    public abstract void activateBundle();
+
+    /**
+     * Deactivates the bundle and destroys all resources.
+     */
+    public abstract void deactivateBundle();
+
+    /**
+     * Creates a resources
+     * @param resource Instance of a BundleResource
+     */
+    public abstract void createResource(ResourceConfig resource);
+
+    /**
+     * Destroys a resource
+     * @param resource Instance of a BundleResource
+     */
+    public abstract void destroyResource(AndroidBundleResource resource);
+
+    /**
+     * List the configuration of the bundle resources.
+     * @return List of configuration for each resource 
+     */
+    public abstract List<ResourceConfig> getConfiguredBundleResources();
+}
\ No newline at end of file
diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/AndroidBundleResource.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/AndroidBundleResource.java
new file mode 100644 (file)
index 0000000..4320004
--- /dev/null
@@ -0,0 +1,185 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics 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 org.iotivity.service.resourcecontainer;
+
+import java.util.HashMap;
+import java.util.Set;
+import android.content.Context;
+
+
+/**
+ * Basic BundleResource that should be used as a base class by a bundle
+ * resources. A concrete technology has to override the setAttribute and
+ * getAttribute method and map the according reads and writes to the technology
+ * specific messages.
+ */
+public abstract class AndroidBundleResource {
+       protected String m_name, m_uri, m_resourceType, m_address;
+
+       protected RcsResourceAttributes m_attributes = new RcsResourceAttributes();
+       
+       protected Context m_context;
+       
+       public AndroidBundleResource(){
+           initAttributes();
+       }
+       
+       public AndroidBundleResource(Context context){
+           this();
+           this.m_context = context;
+       }
+
+       /**
+        * Initialize the internal attribute structure.
+        */
+       protected abstract void initAttributes();
+
+       /**
+        * Set the attribute (map to a send command for the according protocol)
+        * 
+        * @param key
+        *            name of the attribute to be set
+        * @param value
+        *            new value of the attribute
+        */
+       protected final void setAttribute(String key, RcsValue value) {
+               m_attributes.put(key, value);
+       }
+
+       /**
+        * Set the attribute (map to a send command for the according protocol)
+        * 
+        * @param key
+        *            name of the attribute to be set
+        * @param value
+        *            new value of the attribute
+        */
+       public abstract void handleSetAttributesRequest(RcsResourceAttributes value);
+
+       /**
+        * Retrieve the attribute (only data)
+        * 
+        * @param key
+        *            name of the attribute to be read
+        * @return Value of the attribute
+        */
+       protected final RcsValue getAttribute(String key) {
+               return m_attributes.get(key);
+       }
+       
+       /**
+        * Retrieve the attribute (map to read command)
+        * 
+        * @param key
+        *            name of the attribute to be set
+        * @param value
+        *            new value of the attribute
+        */
+       public abstract RcsResourceAttributes handleGetAttributesRequest();
+
+       /**
+        * Attribute keys provided through by the bundle resource.
+        * 
+        * @return Name of attribute keys as string array
+        */
+       public String[] getAttributeKeys() {
+               Set<String> keys = m_attributes.keySet();
+               return keys.toArray(new String[keys.size()]);
+       }
+
+       /**
+        * Setter for the uri property
+        * 
+        * @param uri
+        *            URI of the resource
+        */
+       public void setURI(String uri) {
+               this.m_uri = uri;
+       }
+
+       /**
+        * Returns the URI of the resource
+        * 
+        * @return Resource URI
+        */
+       public String getURI() {
+               return m_uri;
+       }
+
+       /**
+        * Sets the resource type property
+        * 
+        * @param resourceType
+        *            OIC resource type
+        */
+       public void setResourceType(String resourceType) {
+               this.m_resourceType = resourceType;
+       }
+
+       /**
+        * Getter for the resource type
+        * 
+        * @return OIC resource type
+        */
+       public String getResourceType() {
+               return m_resourceType;
+       }
+
+       /**
+        * Sets the technology specific address information (e.g., ZigBee short or
+        * long identifier)
+        * 
+        * @param address
+        *            Resource address
+        */
+       public void setAddress(String address) {
+               this.m_address = address;
+       }
+
+       /**
+        * Returns the technology specific address information
+        * 
+        * @return Resource address
+        */
+       public String getAddress() {
+               return m_address;
+       }
+
+       /**
+        * Sets the name property of the resource
+        * 
+        * @param name
+        *            Resource name
+        */
+       public void setName(String name) {
+               this.m_name = name;
+       }
+
+       /**
+        * Returns the name property of the resource
+        * 
+        * @return Resource name
+        */
+       public String getName() {
+               return m_name;
+       }
+
+}
diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsDestroyedObjectException.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsDestroyedObjectException.java
new file mode 100644 (file)
index 0000000..10eb838
--- /dev/null
@@ -0,0 +1,15 @@
+package org.iotivity.service.resourcecontainer;
+
+/**
+ * Thrown when trying to access a destroyed resource object.
+ *
+ */
+public class RcsDestroyedObjectException extends RcsException {
+
+    private static final long serialVersionUID = -4107062696447237658L;
+
+    public RcsDestroyedObjectException(String message) {
+        super(message);
+    }
+
+}
diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsException.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsException.java
new file mode 100644 (file)
index 0000000..d06caa1
--- /dev/null
@@ -0,0 +1,33 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics 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 org.iotivity.service.resourcecontainer;
+
+/**
+ * An exception that indicates there was an error with execution of Rcs APIs.
+ */
+public class RcsException extends Exception {
+
+    private static final long serialVersionUID = 7044421943523001940L;
+
+    public RcsException(String message) {
+        super(message);
+    }
+}
diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsIllegalStateException.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsIllegalStateException.java
new file mode 100644 (file)
index 0000000..b015452
--- /dev/null
@@ -0,0 +1,35 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics 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 org.iotivity.service.resourcecontainer;
+
+/**
+ * Thrown when an action is attempted at a time when not in the correct state.
+ *
+ */
+public class RcsIllegalStateException extends RcsException {
+
+    private static final long serialVersionUID = 6142669404885957616L;
+
+    public RcsIllegalStateException(String message) {
+        super(message);
+    }
+
+}
diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsObject.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsObject.java
new file mode 100644 (file)
index 0000000..a34e9f3
--- /dev/null
@@ -0,0 +1,57 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics 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 org.iotivity.service.resourcecontainer;
+
+public class RcsObject {
+    /*static {
+        System.loadLibrary("gnustl_shared");
+        System.loadLibrary("oc_logger");
+        System.loadLibrary("connectivity_abstraction");
+        System.loadLibrary("ca-interface");
+        System.loadLibrary("octbstack");
+        System.loadLibrary("oc");
+        System.loadLibrary("rcs_client");
+        System.loadLibrary("rcs_server");
+        System.loadLibrary("rcs_common");
+        System.loadLibrary("rcs_jni");
+    }*/
+
+    private long mNativeHandle;
+
+    private native void nativeDispose();
+
+    protected RcsObject() {
+    }
+
+    @Override
+    protected void finalize() throws Throwable {
+        super.finalize();
+
+        dispose();
+    }
+
+    protected void dispose() {
+        if (mNativeHandle != 0L) nativeDispose();
+    }
+
+    protected boolean hasHandle() {
+        return mNativeHandle != 0L;
+    }
+}
diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsPlatformException.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsPlatformException.java
new file mode 100644 (file)
index 0000000..b344722
--- /dev/null
@@ -0,0 +1,22 @@
+package org.iotivity.service.resourcecontainer;
+
+/**
+ * Thrown when an operation that has base-layer dependency is failed.
+ *
+ */
+public class RcsPlatformException extends RcsException {
+
+    private static final long serialVersionUID = -6093438347973754721L;
+
+    private final int mReasonCode;
+
+    public RcsPlatformException(String message, int reasonCode) {
+        super(message);
+
+        mReasonCode = reasonCode;
+    }
+
+    public int getReasonCode() {
+        return mReasonCode;
+    }
+}
diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsResourceAttributes.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsResourceAttributes.java
new file mode 100644 (file)
index 0000000..f3611b1
--- /dev/null
@@ -0,0 +1,236 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics 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 org.iotivity.service.resourcecontainer;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.iotivity.service.resourcecontainer.server.RcsLockedAttributes;
+
+/**
+ *
+ * This class represents the attributes for a resource.
+ *
+ * @see RcsValue
+ */
+public final class RcsResourceAttributes extends RcsObject {
+
+    private native boolean nativeIsEmpty();
+
+    private native int nativeSize();
+
+    private native boolean nativeRemove(String key);
+
+    private native void nativeClear();
+
+    private native boolean nativeContains(String key);
+
+    private native void nativeAddKeys(Set<String> set);
+
+    private native RcsValue nativeExtract(String key);
+
+    private native void nativeExtractAll(Map<String, RcsValue> map);
+
+    private final Map<String, RcsValue> mCache = new HashMap<>();
+
+    public RcsResourceAttributes() {
+    }
+
+    public RcsResourceAttributes(RcsLockedAttributes lockedAttrs)
+            throws RcsException {
+        for (final String key : lockedAttrs.keySet()) {
+            mCache.put(key, lockedAttrs.get(key));
+        }
+    }
+
+    /**
+     * Returns a unmodifiable Set view of the keys contained in this attributes.
+     *
+     * @return an unmodifiable set view of the keys in this attributes
+     */
+    public Set<String> keySet() {
+        if (hasHandle()) {
+            final Set<String> keySet = new HashSet<>(mCache.keySet());
+
+            nativeAddKeys(keySet);
+
+            return Collections.unmodifiableSet(keySet);
+        }
+
+        return Collections.unmodifiableSet(mCache.keySet());
+    }
+
+    /**
+     * Returns the value to which the specified key is mapped, or null if this
+     * contains no mapping for the key.
+     *
+     * @param key
+     *            the key whose associated value is to be returned
+     *
+     * @return the value to which the specified key is mapped, or null if this
+     *         contains no mapping for the key
+     *
+     * @throws NullPointerException
+     *             if key is null
+     */
+    public RcsValue get(String key) {
+        if (key == null) throw new NullPointerException("key is null");
+
+        if (!mCache.containsKey(key) && hasHandle() && nativeContains(key)) {
+            mCache.put(key, nativeExtract(key));
+        }
+        return mCache.get(key);
+    }
+
+    /**
+     * Sets the specified value with the specified key.
+     * If the object previously contained a mapping for the key, the old value
+     * is replaced by the specified value.
+     *
+     * @param key
+     *            key with which the specified value is to be associated
+     *
+     * @param value
+     *            value to be associated with the specified key
+     *
+     * @throws NullPointerException
+     *             if key or value is null
+     *
+     */
+    public void put(String key, RcsValue value) {
+        if (key == null) throw new NullPointerException("key is null");
+        if (value == null) throw new NullPointerException("value is null");
+
+        mCache.put(key, value);
+        if (hasHandle()) nativeRemove(key);
+    }
+
+    /**
+     * Sets the specified value with the specified key.
+     * If the object previously contained a mapping for the key, the old value
+     * is replaced by the specified value.
+     *
+     * @param key
+     *            key with which the specified value is to be associated
+     *
+     * @param value
+     *            value to be associated with the specified key
+     *
+     * @throws NullPointerException
+     *             if key or value is null
+     * @throws IllegalArgumentException
+     *             if object is not supported type by {@link RcsValue}
+     */
+    public void put(String key, Object object) {
+        if (key == null) throw new NullPointerException("key is null");
+
+        put(key, new RcsValue(object));
+    }
+
+    /**
+     * Returns true if this contains no key-value mappings.
+     *
+     * @return true if this contains no key-value mappings
+     */
+    public boolean isEmpty() {
+        return mCache.isEmpty() && (!hasHandle() || nativeIsEmpty());
+    }
+
+    /**
+     * Returns the number of key-value mappings.
+     *
+     * @return the number of key-value mappings
+     */
+    public int size() {
+        if (hasHandle()) return mCache.size() + nativeSize();
+        return mCache.size();
+    }
+
+    /**
+     * Removes the mapping for a key from this attributes if it is present.
+     *
+     * @param key
+     *            key whose mapping is to be removed
+     *
+     * @return true if the key is present and the the value mapped is removed.
+     */
+    public boolean remove(String key) {
+        if (key == null) throw new NullPointerException("key is null");
+
+        // XXX make sure both cache and native values to be removed.
+        final boolean cacheRemove = mCache.remove(key) != null;
+        final boolean nativeRemove = hasHandle() && nativeRemove(key);
+
+        return cacheRemove || nativeRemove;
+    }
+
+    /**
+     * Removes all of the mappings.
+     */
+    public void clear() {
+        mCache.clear();
+        nativeClear();
+    }
+
+    /**
+     * Returns true if this contains a mapping for the specified key.
+     *
+     * @param key
+     *            key whose presence is to be tested
+     *
+     * @return true if this contains a mapping for the specified key.
+     *
+     * @throws NullPointerException
+     *             if key is null
+     */
+    public boolean contains(String key) {
+        if (key == null) throw new NullPointerException("key is null");
+
+        return mCache.containsKey(key) || nativeContains(key);
+    }
+
+    private void esnureAllExtracted() {
+        if (hasHandle()) nativeExtractAll(mCache);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) return true;
+        if (!(o instanceof RcsResourceAttributes)) return false;
+
+        final RcsResourceAttributes rhs = (RcsResourceAttributes) o;
+
+        esnureAllExtracted();
+        rhs.esnureAllExtracted();
+
+        return mCache.equals(rhs.mCache);
+    }
+
+    @Override
+    public int hashCode() {
+        esnureAllExtracted();
+        return mCache.hashCode();
+    }
+
+}
index bb19810..39c1b94 100644 (file)
@@ -26,14 +26,22 @@ package org.iotivity.service.resourcecontainer;
 
 import java.util.List;
 import java.util.Map;
+import java.util.Enumeration;
+import android.util.Log;
+import android.content.Context;
+
+import dalvik.system.DexFile;
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 
 // TODO null check for parameters
 /**
  * This class provides APIs for managing the container and bundles in the
  * container.
  */
-public class RcsResourceContainer {
+public class RcsResourceContainer implements RcsResourceContainerBundleAPI {
 
+    private static final String TAG = RcsResourceContainer.class.getSimpleName();
     static {
         System.loadLibrary("gnustl_shared");
         System.loadLibrary("oc_logger");
@@ -47,8 +55,8 @@ public class RcsResourceContainer {
         System.loadLibrary("rcs_container");
         System.loadLibrary("resource_container_jni");
     }
-
-    private static RcsResourceContainer sInstance = new RcsResourceContainer();
+    
+    private Context appContext;
 
     private native void nativeStartContainer(String configFile);
 
@@ -72,13 +80,21 @@ public class RcsResourceContainer {
             String resourceUri);
 
     private native List<String> nativeListBundleResources(String bundleId);
-
-    /**
-     * API for getting the Instance of ResourceContainer class
-     *
-     */
-    public static RcsResourceContainer getInstance() {
-        return sInstance;
+    
+    private native void nativeRegisterAndroidResource(AndroidBundleResource resource,
+        String[] attributes, String bundleId, String uri,
+        String resourceType, String name);
+    
+    private native void nativeUnregisterAndroidResource(AndroidBundleResource resource,
+        String uri);
+    
+    private native int nativeGetNumberOfConfiguredResources(String bundleId);
+        
+    private native String[] nativeGetConfiguredResourceParams(String bundleId,
+        int resId);  
+    
+    public RcsResourceContainer(Context appContext){
+        this.appContext = appContext;
     }
 
     /**
@@ -92,8 +108,43 @@ public class RcsResourceContainer {
      *            information.
      *
      */
-    public void startContainer(String configFile) {
+    public void startContainer(String configFile) {        
         nativeStartContainer(configFile);
+        Log.d(TAG, "startContainer");
+        List<RcsBundleInfo> bundles = listBundles();
+        for(RcsBundleInfo bundleInfo : bundles){
+            Log.d(TAG, "bundle-id: " + bundleInfo.getID() + ", " + bundleInfo.getPath());
+            if(bundleInfo.getPath().endsWith(".apk")){
+                String packageName = bundleInfo.getPath().replace(".apk", "");
+                try{
+                    PackageManager packageManager = appContext.getPackageManager();
+                    ApplicationInfo appInfo = packageManager.getApplicationInfo(packageName, 0);
+                    DexFile df = new DexFile(appInfo.sourceDir);
+                    ClassLoader cl = appContext.getClassLoader();
+                    for (Enumeration<String> iter = df.entries(); iter.hasMoreElements(); ) {
+                        String classN = iter.nextElement();
+                        if (classN.contains(packageName)) {
+                            Log.d(TAG,"Class: " + classN);
+                            df.loadClass(classN, cl);
+                        }
+                    }
+                    
+                    String className = bundleInfo.getActivatorName();
+                    Log.d(TAG, "Loading activator: " + className);
+                    Class activatorClass = df.loadClass(className, cl);
+                    if(activatorClass!= null){
+                        AndroidBundleActivator activator = (AndroidBundleActivator) activatorClass.getConstructor(RcsResourceContainerBundleAPI.class, Context.class).newInstance(this, appContext);
+                        activator.activateBundle();
+                    }else{
+                        Log.e(TAG, "Activator is null.");
+                    }
+                }
+                catch(Exception e){
+                    Log.e(TAG, e.getMessage());
+                }
+                Log.d(TAG, "Have to register android bundle");
+            }
+        }
     }
 
     /**
@@ -157,7 +208,18 @@ public class RcsResourceContainer {
      *
      */
     public void startBundle(String bundleId) {
-        nativeStartBundle(bundleId);
+        Log.d(TAG, "startBundle");
+        List<RcsBundleInfo> bundles = listBundles();
+        boolean androidBundle =false;
+        for(RcsBundleInfo bundleInfo : bundles){
+            if(bundleInfo.getID().equals(bundleId) && bundleInfo.getLibraryPath().endsWith(".apk")){
+                androidBundle = true;
+                Log.d(TAG, "Have to start android bundle");
+            }
+        }
+        if(!androidBundle){
+            nativeStartBundle(bundleId);
+        }
     }
 
     /**
@@ -211,4 +273,24 @@ public class RcsResourceContainer {
     public List<String> listBundleResources(String bundleId) {
         return nativeListBundleResources(bundleId);
     }
+
+    public void registerResource(String bundleId, AndroidBundleResource resource){
+        // bundleResources.add(resource);
+        nativeRegisterAndroidResource(resource, resource.getAttributeKeys(), bundleId,
+                        resource.getURI(), resource.getResourceType(),
+                        resource.getName());
+    }
+
+    
+    public void unregisterResource(AndroidBundleResource resource){
+        nativeUnregisterAndroidResource(resource, resource.getURI());
+    }
+
+    public int getNumberOfConfiguredResources(String bundleId){
+        return nativeGetNumberOfConfiguredResources(bundleId);
+    }
+
+    public String[] getConfiguredResourceParams(String bundleId, int resId){
+        return nativeGetConfiguredResourceParams(bundleId, resId);
+    }
 }
diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsResourceContainerBundleAPI.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsResourceContainerBundleAPI.java
new file mode 100644 (file)
index 0000000..e95ffae
--- /dev/null
@@ -0,0 +1,45 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics 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.
+ *
+ ******************************************************************/
+
+/**
+ * @file
+ * This file contains the Resource Container APIs
+ */
+package org.iotivity.service.resourcecontainer;
+
+import java.util.List;
+import java.util.Map;
+
+// TODO null check for parameters
+/**
+ * This class provides APIs for managing the container and bundles in the
+ * container.
+ */
+public interface RcsResourceContainerBundleAPI{
+    
+    public void registerResource(String bundleId, AndroidBundleResource resource);
+        
+    public void unregisterResource(AndroidBundleResource resource);
+            
+    public int getNumberOfConfiguredResources(String bundleId);
+   
+    public String[] getConfiguredResourceParams(String bundleId,
+        int resId);
+}
diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsValue.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/RcsValue.java
new file mode 100644 (file)
index 0000000..56bf9dc
--- /dev/null
@@ -0,0 +1,877 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics 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 org.iotivity.service.resourcecontainer;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Value holds a value among various types at a time.
+ *
+ * Type helps identify type information of Value.
+ *
+ * @see RcsResourceAttributes
+ * @see Type
+ */
+public final class RcsValue {
+
+    private static class NullType {
+        @Override
+        public String toString() {
+            return "";
+        }
+    }
+
+    /**
+     * Identifiers for types of Value.
+     *
+     * @see Type
+     */
+    public static enum TypeId {
+        NULL, BOOLEAN, INTEGER, DOUBLE, STRING, ATTRIBUTES, ARRAY;
+    }
+
+    /**
+     * A Helper class to identify types of Value.
+     *
+     * @see RcsResourceAttributes
+     * @see RcsValue
+     * @see TypeId
+     */
+    public static class Type {
+        private final TypeId mTypeId;
+
+        Type(TypeId typeId) {
+            mTypeId = typeId;
+        }
+
+        /**
+         * Returns type identifier.
+         *
+         * @return Identifier of type
+         *
+         * @see #getBaseTypeId(RcsValue.Type)
+         */
+        public final TypeId getId() {
+            return mTypeId;
+        }
+
+        protected TypeId getBaseTypeId() {
+            return mTypeId;
+        }
+
+        protected int getDepth() {
+            return 0;
+        }
+
+        /**
+         * Returns the type identifier of a base type of sequence.
+         *
+         * For non sequence types, it is equivalent to calling {@link #getId()}.
+         *
+         * @return identifier of type
+         *
+         * @see getDepth
+         * @see getId
+         */
+        public static TypeId getBaseTypeId(Type t) {
+            return t.getBaseTypeId();
+        }
+
+        /**
+         * Returns the depth of a type.
+         *
+         * The return will be zero for non sequence types.
+         *
+         * @see getBaseTypeId
+         */
+        public static int getDepth(Type t) {
+            return t.getDepth();
+        }
+
+        /**
+         * Factory method to create Type instance from an object.
+         * Note that object must be a supported type by RcsValue.
+         *
+         * @return An instance that has TypeId for obj.
+         *
+         * @throws NullPointerException
+         *             if obj is null.
+         * @throws IllegalArgumentException
+         *             if obj is not supported type.
+         *
+         */
+        public static Type typeOf(Object obj) {
+            if (obj == null) {
+                throw new NullPointerException("object is null");
+            }
+
+            return typeOf(obj.getClass());
+        }
+
+        /**
+         * Factory method to create Type instance from a class.
+         * Note that class must be a supported type by RcsValue.
+         *
+         * @return An instance that has TypeId for class.
+         *
+         * @throws NullPointerException
+         *             if cls is null.
+         * @throws IllegalArgumentException
+         *             if cls is not supported type.
+         *
+         */
+        public static Type typeOf(Class<?> cls) {
+            if (cls == null) {
+                throw new NullPointerException("class is null");
+            }
+
+            if (sTypes.containsKey(cls)) return sTypes.get(cls);
+
+            throw new IllegalArgumentException(
+                    cls.getSimpleName() + " is not supported type.");
+        }
+    }
+
+    private static class ArrayType extends Type {
+        private final TypeId mBaseTypeId;
+        private final int    mDimension;
+
+        ArrayType(TypeId baseTypeId, int dimension) {
+            super(TypeId.ARRAY);
+
+            mBaseTypeId = baseTypeId;
+            mDimension = dimension;
+        }
+
+        @Override
+        protected TypeId getBaseTypeId() {
+            return mBaseTypeId;
+        }
+
+        @Override
+        protected int getDepth() {
+            return mDimension;
+        }
+    }
+
+    private static final NullType sNullValue = new NullType();
+
+    private static Map<Class<?>, Type> sTypes;
+
+    private final Object mObject;
+    private Type         mType;
+
+    static {
+        final Map<Class<?>, Type> types = new HashMap<Class<?>, Type>();
+
+        types.put(NullType.class, new Type(TypeId.NULL));
+        types.put(Boolean.class, new Type(TypeId.BOOLEAN));
+        types.put(Integer.class, new Type(TypeId.INTEGER));
+        types.put(Double.class, new Type(TypeId.DOUBLE));
+        types.put(String.class, new Type(TypeId.STRING));
+        types.put(RcsResourceAttributes.class, new Type(TypeId.ATTRIBUTES));
+
+        types.put(boolean[].class, new ArrayType(TypeId.BOOLEAN, 1));
+        types.put(int[].class, new ArrayType(TypeId.INTEGER, 1));
+        types.put(double[].class, new ArrayType(TypeId.DOUBLE, 1));
+        types.put(String[].class, new ArrayType(TypeId.STRING, 1));
+        types.put(RcsResourceAttributes[].class,
+                new ArrayType(TypeId.ATTRIBUTES, 1));
+
+        types.put(boolean[][].class, new ArrayType(TypeId.BOOLEAN, 2));
+        types.put(int[][].class, new ArrayType(TypeId.INTEGER, 2));
+        types.put(double[][].class, new ArrayType(TypeId.DOUBLE, 2));
+        types.put(String[][].class, new ArrayType(TypeId.STRING, 2));
+        types.put(RcsResourceAttributes[][].class,
+                new ArrayType(TypeId.ATTRIBUTES, 2));
+
+        types.put(boolean[][][].class, new ArrayType(TypeId.BOOLEAN, 3));
+        types.put(int[][][].class, new ArrayType(TypeId.INTEGER, 3));
+        types.put(double[][][].class, new ArrayType(TypeId.DOUBLE, 3));
+        types.put(String[][][].class, new ArrayType(TypeId.STRING, 3));
+        types.put(RcsResourceAttributes[][][].class,
+                new ArrayType(TypeId.ATTRIBUTES, 3));
+
+        sTypes = Collections.unmodifiableMap(types);
+
+    }
+
+    static boolean isSupportedType(Class<?> cls) {
+        return sTypes.containsKey(cls);
+    }
+
+    static void verifySupportedType(Class<?> cls) {
+        if (!isSupportedType(cls)) {
+            throw new IllegalArgumentException(
+                    cls.getSimpleName() + " is not supported type.");
+        }
+    }
+
+    /**
+     * Constructs a new value with an object.
+     *
+     * @param value
+     *            An object
+     *
+     * @throws NullPointerException
+     *             if value is null.
+     * @throws IllegalArgumentException
+     *             if value is not supported type.
+     */
+    public RcsValue(Object value) {
+        if (value == null) throw new NullPointerException("value is null!");
+
+        verifySupportedType(value.getClass());
+
+        mObject = value;
+    }
+
+    /**
+     * Constructs a new value that holds null value.
+     *
+     */
+    public RcsValue() {
+        this(sNullValue);
+    }
+
+    /**
+     * Constructs a new value that holds a boolean value.
+     *
+     * @param value
+     *            a boolean
+     */
+    public RcsValue(boolean value) {
+        this((Object) value);
+    }
+
+    /**
+     * Constructs a new value that holds an int value.
+     *
+     * @param value
+     *            an int
+     */
+    public RcsValue(int value) {
+        this((Object) value);
+    }
+
+    /**
+     * Constructs a new value that holds a double value.
+     *
+     * @param value
+     *            a double
+     */
+    public RcsValue(double value) {
+        this((Object) value);
+    }
+
+    /**
+     * Constructs a new value that holds a String value.
+     *
+     * @param value
+     *            a String
+     *
+     * @throws NullPointerException
+     *             if value is null.
+     */
+    public RcsValue(String value) {
+        this((Object) value);
+    }
+
+    /**
+     * Constructs a new value that holds a RcsResourceAttributes value.
+     *
+     * @param value
+     *            a RcsResourceAttributes
+     *
+     * @throws NullPointerException
+     *             if value is null.
+     */
+    public RcsValue(RcsResourceAttributes value) {
+        this((Object) value);
+    }
+
+    /**
+     * Constructs a new value that holds a boolean array.
+     *
+     * @param value
+     *            a boolean array
+     *
+     * @throws NullPointerException
+     *             if value is null.
+     */
+    public RcsValue(boolean[] value) {
+        this((Object) value);
+    }
+
+    /**
+     * Constructs a new value that holds a two-dimensional boolean array.
+     *
+     * @param value
+     *            a two-dimensional boolean array
+     *
+     * @throws NullPointerException
+     *             if value is null.
+     */
+    public RcsValue(boolean[][] value) {
+        this((Object) value);
+    }
+
+    /**
+     * Constructs a new value that holds a three-dimensional boolean array.
+     *
+     * @param value
+     *            a three-dimensional boolean array
+     *
+     * @throws NullPointerException
+     *             if value is null.
+     */
+    public RcsValue(boolean[][][] value) {
+        this((Object) value);
+    }
+
+    /**
+     * Constructs a new value that holds an int array.
+     *
+     * @param value
+     *            an int array
+     *
+     * @throws NullPointerException
+     *             if value is null.
+     */
+    public RcsValue(int[] value) {
+        this((Object) value);
+    }
+
+    /**
+     * Constructs a new value that holds a two-dimensional int array.
+     *
+     * @param value
+     *            a two-dimensional int array
+     *
+     * @throws NullPointerException
+     *             if value is null.
+     */
+    public RcsValue(int[][] value) {
+        this((Object) value);
+    }
+
+    /**
+     * Constructs a new value that holds a three-dimensional int array.
+     *
+     * @param value
+     *            a three-dimensional int array
+     *
+     * @throws NullPointerException
+     *             if value is null.
+     */
+    public RcsValue(int[][][] value) {
+        this((Object) value);
+    }
+
+    /**
+     * Constructs a new value that holds a double array.
+     *
+     * @param value
+     *            a double array
+     *
+     * @throws NullPointerException
+     *             if value is null.
+     */
+    public RcsValue(double[] value) {
+        this((Object) value);
+    }
+
+    /**
+     * Constructs a new value that holds a two-dimensional double array.
+     *
+     * @param value
+     *            a two-dimensional double array
+     *
+     * @throws NullPointerException
+     *             if value is null.
+     */
+    public RcsValue(double[][] value) {
+        this((Object) value);
+    }
+
+    /**
+     * Constructs a new value that holds a three-dimensional double array.
+     *
+     * @param value
+     *            a three-dimensional double array
+     *
+     * @throws NullPointerException
+     *             if value is null.
+     */
+    public RcsValue(double[][][] value) {
+        this((Object) value);
+    }
+
+    /**
+     * Constructs a new value that holds a String array.
+     *
+     * @param value
+     *            a String array
+     *
+     * @throws NullPointerException
+     *             if value is null.
+     */
+    public RcsValue(String[] value) {
+        this((Object) value);
+    }
+
+    /**
+     * Constructs a new value that holds a two-dimensional String array.
+     *
+     * @param value
+     *            a two-dimensional String array
+     *
+     * @throws NullPointerException
+     *             if value is null.
+     */
+    public RcsValue(String[][] value) {
+        this((Object) value);
+    }
+
+    /**
+     * Constructs a new value that holds a three-dimensional String array.
+     *
+     * @param value
+     *            a three-dimensional String array
+     *
+     * @throws NullPointerException
+     *             if value is null.
+     */
+    public RcsValue(String[][][] value) {
+        this((Object) value);
+    }
+
+    /**
+     * Constructs a new value that holds a RcsResourceAttributes array.
+     *
+     * @param value
+     *            a RcsResourceAttributes array
+     *
+     * @throws NullPointerException
+     *             if value is null.
+     */
+    public RcsValue(RcsResourceAttributes[] value) {
+        this((Object) value);
+    }
+
+    /**
+     * Constructs a new value that holds a two-dimensional RcsResourceAttributes
+     * array.
+     *
+     * @param value
+     *            a two-dimensional RcsResourceAttributes array
+     *
+     * @throws NullPointerException
+     *             if value is null.
+     */
+    public RcsValue(RcsResourceAttributes[][] value) {
+        this((Object) value);
+    }
+
+    /**
+     * Constructs a new value that holds a three-dimensional
+     * RcsResourceAttributes array.
+     *
+     * @param value
+     *            a three-dimensional RcsResourceAttributes array
+     *
+     * @throws NullPointerException
+     *             if value is null.
+     */
+    public RcsValue(RcsResourceAttributes[][][] value) {
+        this((Object) value);
+    }
+
+    /**
+     * Returns whether the value is null.
+     *
+     * @return true if the value is null.
+     */
+    public boolean isNull() {
+        return isNullObject(mObject);
+    }
+
+    /**
+     * Returns whether the object represents null for RcsValue.
+     *
+     * @param o
+     *            an object to be tested
+     *
+     * @return true if the object represents null.
+     */
+    public static boolean isNullObject(Object o) {
+        return o == sNullValue;
+    }
+
+    /**
+     * Returns type information.
+     *
+     * @return type information for the value.
+     */
+    public Type getType() {
+        if (mType == null) mType = Type.typeOf(mObject);
+        return mType;
+    }
+
+    /**
+     * Returns the value as T.
+     *
+     * @return a value as T
+     *
+     * @throws ClassCastException
+     *             if the value is not of T.
+     */
+    @SuppressWarnings("unchecked")
+    public <T> T get() {
+        return (T) mObject;
+    }
+
+    @SuppressWarnings("unchecked")
+    private <T> T getOrNull() {
+        try {
+            return (T) mObject;
+        } catch (final ClassCastException e) {
+            return null;
+        }
+    }
+
+    /**
+     * Returns the value as an Object.
+     *
+     * @return an Object
+     */
+    public Object asObject() {
+        return mObject;
+    }
+
+    /**
+     * Returns the value as a boolean, false if the value is not the desired
+     * type.
+     *
+     * @return a boolean value
+     *
+     */
+    public boolean asBoolean() {
+        return asBoolean(false);
+    }
+
+    /**
+     * Returns the value as a boolean.
+     *
+     * @param defaultValue
+     *            value to return if the value is not boolean.
+     *
+     * @return a boolean value
+     *
+     */
+    public boolean asBoolean(boolean defaultValue) {
+        try {
+            return get();
+        } catch (final ClassCastException e) {
+            return defaultValue;
+        }
+    }
+
+    /**
+     * Returns the value as an int, 0 if the value is not the desired type.
+     *
+     * @return an int value
+     *
+     */
+    public int asInt() {
+        return asInt(0);
+    }
+
+    /**
+     * Returns the value as an int.
+     *
+     * @param defaultValue
+     *            value to return if the value is not int.
+     *
+     * @return an int value
+     *
+     */
+    public int asInt(int defaultValue) {
+        try {
+            return get();
+        } catch (final ClassCastException e) {
+            return defaultValue;
+        }
+    }
+
+    /**
+     * Returns the value as a double, 0 if the value is not the desired type.
+     *
+     * @return a double value
+     *
+     */
+    public double asDouble() {
+        return asDouble(0);
+    }
+
+    /**
+     * Returns the value as a double.
+     *
+     * @param defaultValue
+     *            value to return if the value is not double.
+     *
+     * @return a double value
+     *
+     */
+    public double asDouble(double defaultValue) {
+        try {
+            return get();
+        } catch (final ClassCastException e) {
+            return defaultValue;
+        }
+    }
+
+    /**
+     * Returns the value as a string, null if the value is not the desired type.
+     *
+     * @return a string value
+     *
+     */
+    public String asString() {
+        return asString(null);
+    }
+
+    /**
+     * Returns the value as a String.
+     *
+     * @param defaultValue
+     *            value to return if the value is not String.
+     *
+     * @return a String value
+     *
+     */
+    public String asString(String defaultValue) {
+        try {
+            return get();
+        } catch (final ClassCastException e) {
+            return defaultValue;
+        }
+    }
+
+    /**
+     * Returns the value as a RcsResourceAttributes,
+     * null if the value is not the desired type.
+     *
+     * @return a RcsResourceAttributes value
+     *
+     */
+    public RcsResourceAttributes asAttributes() {
+        return getOrNull();
+    }
+
+    /**
+     * Returns the value as a boolean array, null if the value is not the
+     * desired type.
+     *
+     * @return a boolean array
+     *
+     */
+    public boolean[] asBooleanArray() {
+        return getOrNull();
+    }
+
+    /**
+     * Returns the value as a two-dimensional boolean array, null if the value
+     * is not the desired type.
+     *
+     * @return a two-dimensional boolean array
+     *
+     */
+    public boolean[][] asBoolean2DArray() {
+        return getOrNull();
+    }
+
+    /**
+     * Returns the value as a three-dimensional boolean array, null if the value
+     * is not the desired type.
+     *
+     * @return a three-dimensional boolean array
+     *
+     */
+    public boolean[][][] asBoolean3DArray() {
+        return getOrNull();
+    }
+
+    /**
+     * Returns the value as an int array, null if the value is not the
+     * desired type.
+     *
+     * @return an int array
+     *
+     */
+    public int[] asIntArray() {
+        return getOrNull();
+    }
+
+    /**
+     * Returns the value as a two-dimensional int array, null if the value
+     * is not the desired type.
+     *
+     * @return a two-dimensional int array
+     *
+     */
+    public int[][] asInt2DArray() {
+        return getOrNull();
+    }
+
+    /**
+     * Returns the value as a three-dimensional int array, null if the value
+     * is not the desired type.
+     *
+     * @return a three-dimensional int array
+     *
+     */
+    public int[][][] asInt3DArray() {
+        return getOrNull();
+    }
+
+    /**
+     * Returns the value as a double array, null if the value is not the
+     * desired type.
+     *
+     * @return a double array
+     *
+     */
+    public double[] asDoubleArray() {
+        return getOrNull();
+    }
+
+    /**
+     * Returns the value as a two-dimensional double array, null if the value
+     * is not the desired type.
+     *
+     * @return a two-dimensional double array
+     *
+     */
+    public double[][] asDouble2DArray() {
+        return getOrNull();
+    }
+
+    /**
+     * Returns the value as a three-dimensional double array, null if the value
+     * is not the desired type.
+     *
+     * @return a three-dimensional double array
+     *
+     */
+    public double[][][] asDouble3DArray() {
+        return getOrNull();
+    }
+
+    /**
+     * Returns the value as a string array, null if the value is not the
+     * desired type.
+     *
+     * @return a string array
+     *
+     */
+    public String[] asStringArray() {
+        return getOrNull();
+    }
+
+    /**
+     * Returns the value as a two-dimensional string array, null if the value
+     * is not the desired type.
+     *
+     * @return a two-dimensional string array
+     *
+     */
+    public String[][] asString2DArray() {
+        return getOrNull();
+    }
+
+    /**
+     * Returns the value as a three-dimensional string array, null if the value
+     * is not the desired type.
+     *
+     * @return a three-dimensional string array
+     *
+     */
+    public String[][][] asString3DArray() {
+        return getOrNull();
+    }
+
+    /**
+     * Returns the value as an attributes array, null if the value is not the
+     * desired type.
+     *
+     * @return an attributes array
+     *
+     */
+    public RcsResourceAttributes[] asAttributesArray() {
+        return getOrNull();
+    }
+
+    /**
+     * Returns the value as a two-dimensional attributes array, null if the
+     * value is not the desired type.
+     *
+     * @return a two-dimensional attributes array
+     *
+     */
+    public RcsResourceAttributes[][] asAttributes2DArray() {
+        return getOrNull();
+    }
+
+    /**
+     * Returns the value as a three-dimensional attributes array, null if the
+     * value is not the desired type.
+     *
+     * @return a three-dimensional attributes array
+     *
+     */
+    public RcsResourceAttributes[][][] asAttributes3DArray() {
+        return getOrNull();
+    }
+
+    @Override
+    public boolean equals(Object o) {
+        if (o == this) return true;
+        if (!(o instanceof RcsValue)) return false;
+
+        final RcsValue rhs = (RcsValue) o;
+
+        return mObject.equals(rhs.mObject);
+    }
+
+    @Override
+    public int hashCode() {
+        return mObject.hashCode();
+    }
+
+    @Override
+    public String toString() {
+        return mObject.toString();
+    }
+
+}
diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/ResourceConfig.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/ResourceConfig.java
new file mode 100644 (file)
index 0000000..dd308f1
--- /dev/null
@@ -0,0 +1,119 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics 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 org.iotivity.service.resourcecontainer;
+
+/**
+ * This class holds the configuration parameters for a single resource instance provided
+ * by the resource bundle.
+ */
+public class ResourceConfig {
+    private String m_name, m_uri, m_resourceType, m_address;
+
+    /**
+     * Empty constructor for resoure config.
+     */
+    public ResourceConfig() {
+
+    }
+
+    /**
+     * Creates a new resource config instance.
+     * @param params Resource parameters as array. 1. Name, 2. URI, 3. Resource Type, 4. Address 
+     */
+    public ResourceConfig(String[] params) {
+        m_name = params[0];
+        m_uri = params[1];
+        m_resourceType = params[2];
+        m_address = params[3];
+    }
+
+    /**
+     * Returns the configured name
+     * @return name property
+     */
+    public String getName() {
+        return m_name;
+    }
+
+    /**
+     * Sets the name
+     * @param m_name Resource name
+     */
+    public void setName(String m_name) {
+        this.m_name = m_name;
+    }
+
+    /**
+     * Returns the configured URI
+     * @return Configured URI
+     */
+    public String getURI() {
+        return m_uri;
+    }
+
+    /**
+     * Sets the configured URI
+     * @param m_uri Configuration URI
+     */
+    public void setURI(String m_uri) {
+        this.m_uri = m_uri;
+    }
+
+    /**
+     * Returns the configured resource type
+     * @return configured resource type
+     */
+    public String getResourceType() {
+        return m_resourceType;
+    }
+
+    /**
+     * Sets the configured resource type
+     * @param m_resourceType updates the configured resource type
+     */
+    public void setResourceType(String m_resourceType) {
+        this.m_resourceType = m_resourceType;
+    }
+
+    /**
+     * Returns the configured address
+     * @return Configured address
+     */
+    public String getAddress() {
+        return m_address;
+    }
+
+    /**
+     * Sets the configured address
+     * @param m_address Configured address
+     */
+    public void setAddress(String m_address) {
+        this.m_address = m_address;
+    }
+
+    @Override
+    public String toString() {
+        return "ResourceConfig [m_name=" + m_name + ", m_uri=" + m_uri
+                + ", m_resourceType=" + m_resourceType + ", m_address="
+                + m_address + "]";
+    }
+
+}
diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/server/RcsGetResponse.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/server/RcsGetResponse.java
new file mode 100644 (file)
index 0000000..c09a1c4
--- /dev/null
@@ -0,0 +1,102 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics 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 org.iotivity.service.resourcecontainer.server;
+
+import org.iotivity.service.resourcecontainer.RcsResourceAttributes;
+
+/**
+ * This class provides methods to create the response for a get request.
+ *
+ * @see RcsResourceObject
+ * @see RcsSetResponse
+ */
+public class RcsGetResponse extends RcsResponse {
+
+    /**
+     * Creates a default RCcsGetResponse. The response will have
+     * {@link #DEFAULT_ERROR_CODE} for the errorCode. The attributes of
+     * {@link RcsResourceObject} will be set as the result attributes.
+     *
+     */
+    public static RcsGetResponse defaultAction() {
+        return new RcsGetResponse();
+    }
+
+    /**
+     * Creates a RcsGetResponse with error code passed. The
+     * attributes of the {@link RcsResourceObject} will be set as the result
+     * attributes.
+     *
+     * @param errorCode
+     *            error code to be set in response
+     *
+     */
+    public static RcsGetResponse create(int errorCode) {
+        return new RcsGetResponse(errorCode);
+
+    }
+
+    /**
+     * Creates a RcsGetResponse with custom attributes and
+     * {@link #DEFAULT_ERROR_CODE} for the errorCode. This sends the passed
+     * attributes as the result attributes instead of the one the
+     * {@link RcsResourceObject} holds.
+     *
+     * @param attributes
+     *            attributes to be sent as the result
+     *
+     */
+    public static RcsGetResponse create(RcsResourceAttributes attributes) {
+        return new RcsGetResponse(attributes);
+    }
+
+    /**
+     * Creates a RcsGetResponse with error code passed. This sends
+     * the passed attributes as the result attributes instead of one the
+     * {@link RcsResourceObject} holds.
+     *
+     * @param attributes
+     *            attributes to be sent as the result
+     * @param errorCode
+     *            error code for response
+     *
+     */
+    public static RcsGetResponse create(RcsResourceAttributes attributes,
+            int errorCode) {
+        return new RcsGetResponse(attributes, errorCode);
+    }
+
+    private RcsGetResponse() {
+        super();
+    }
+
+    private RcsGetResponse(int errorCode) {
+        super(errorCode);
+    }
+
+    private RcsGetResponse(RcsResourceAttributes attrs) {
+        super(attrs);
+    }
+
+    private RcsGetResponse(RcsResourceAttributes attrs, int errorCode) {
+        super(attrs, errorCode);
+    }
+}
diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/server/RcsLockedAttributes.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/server/RcsLockedAttributes.java
new file mode 100644 (file)
index 0000000..dd05826
--- /dev/null
@@ -0,0 +1,303 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics 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 org.iotivity.service.resourcecontainer.server;
+
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+import org.iotivity.service.resourcecontainer.RcsException;
+import org.iotivity.service.resourcecontainer.RcsObject;
+import org.iotivity.service.resourcecontainer.RcsResourceAttributes;
+import org.iotivity.service.resourcecontainer.RcsValue;
+
+public final class RcsLockedAttributes extends RcsObject {
+
+    private static native boolean nativeIsEmpty(RcsResourceObject resourceObj);
+
+    private static native int nativeSize(RcsResourceObject resourceObj);
+
+    private static native boolean nativeRemove(RcsResourceObject resourceObj,
+            String key);
+
+    private static native boolean nativeClear(RcsResourceObject resourceObj);
+
+    private static native boolean nativeContains(RcsResourceObject resourceObj,
+            String key);
+
+    private static native void nativeAddKeys(RcsResourceObject resourceObj,
+            Set<String> set);
+
+    private static native RcsValue nativeAsJavaObject(
+            RcsResourceObject resourceObj, String key);
+
+    private static native void nativeApply(RcsResourceObject resourceObj,
+            Map<String, RcsValue> cache);
+
+    private native void nativeLock(RcsResourceObject resourceObj);
+
+    private native void nativeUnlock();
+
+    private final RcsResourceObject mResourceObject;
+
+    private boolean mIsUnlocked;
+
+    private Map<String, RcsValue> mCache = new HashMap<>();
+
+    RcsLockedAttributes(RcsResourceObject resourceObject) throws RcsException {
+        if (resourceObject == null) {
+            throw new RcsException("Illegal opertaion!");
+        }
+
+        mResourceObject = resourceObject;
+
+        nativeLock(resourceObject);
+    }
+
+    void setUnlockState() {
+        mIsUnlocked = true;
+        mCache = null;
+
+        nativeUnlock();
+    }
+
+    void apply() {
+        nativeApply(mResourceObject, mCache);
+        mCache.clear();
+    }
+
+    private void ensureLocked() throws RcsException {
+        if (mIsUnlocked) {
+            throw new RcsUnlockedException("This attributes is unlocked!");
+        }
+    }
+
+    /**
+     * Returns a unmodifiable Set view of the keys contained in this attributes.
+     *
+     * @return an unmodifiable set view of the keys in this attributes
+     *
+     * @throws RcsUnlockedException
+     *             if the {@link RcsResourceObject.AttributesLock} for this
+     *             object is unlocked
+     */
+    public Set<String> keySet() throws RcsException {
+        ensureLocked();
+
+        final Set<String> keySet = new HashSet<>(mCache.keySet());
+
+        nativeAddKeys(mResourceObject, keySet);
+
+        return Collections.unmodifiableSet(keySet);
+    }
+
+    /**
+     * Returns the value to which the specified key is mapped, or null if this
+     * contains no mapping for the key.
+     *
+     * @param key
+     *            the key whose associated value is to be returned
+     *
+     * @return the value to which the specified key is mapped, or null if this
+     *         contains no mapping for the key
+     *
+     * @throws NullPointerException
+     *             if key is null
+     * @throws RcsUnlockedException
+     *             if the {@link RcsResourceObject.AttributesLock} for this
+     *             object is unlocked
+     */
+    public RcsValue get(String key) throws RcsException {
+        ensureLocked();
+
+        if (key == null) throw new NullPointerException("key is null");
+
+        if (!mCache.containsKey(key) && nativeContains(mResourceObject, key)) {
+            mCache.put(key, nativeAsJavaObject(mResourceObject, key));
+        }
+        return mCache.get(key);
+    }
+
+    /**
+     * Copies all of the mappings from the specified to this
+     *
+     * @param attributes
+     *            attributes to be copied
+     *
+     * @throws RcsUnlockedException
+     *             if the {@link RcsResourceObject.AttributesLock} for this
+     *             object is unlocked
+     *
+     */
+    public RcsLockedAttributes putAll(RcsResourceAttributes attributes)
+            throws RcsException {
+        ensureLocked();
+
+        final Set<String> keys = attributes.keySet();
+
+        for (final String k : keys) {
+            mCache.put(k, attributes.get(k));
+        }
+        return this;
+    }
+
+    /**
+     * Sets the specified value with the specified key.
+     * If the object previously contained a mapping for the key, the old value
+     * is replaced by the specified value.
+     *
+     * @param key
+     *            key with which the specified value is to be associated
+     *
+     * @param value
+     *            value to be associated with the specified key
+     *
+     * @throws NullPointerException
+     *             if key or value is null
+     * @throws RcsUnlockedException
+     *             if the {@link RcsResourceObject.AttributesLock} for this
+     *             object is unlocked
+     *
+     */
+    public RcsLockedAttributes put(String key, RcsValue value)
+            throws RcsException {
+        ensureLocked();
+
+        if (key == null) throw new NullPointerException("key is null");
+        if (value == null) throw new NullPointerException("value is null");
+
+        mCache.put(key, value);
+
+        return this;
+    }
+
+    /**
+     * Sets the specified value with the specified key.
+     * If the object previously contained a mapping for the key, the old value
+     * is replaced by the specified value.
+     *
+     * @param key
+     *            key with which the specified value is to be associated
+     *
+     * @param value
+     *            value to be associated with the specified key
+     *
+     * @throws NullPointerException
+     *             if key or value is null
+     * @throws IllegalArgumentException
+     *             if object is not supported type by {@link RcsValue}
+     * @throws RcsUnlockedException
+     *             if the {@link RcsResourceObject.AttributesLock} for this
+     *             object is unlocked
+     */
+    public void put(String key, Object value) throws RcsException {
+        if (key == null) throw new NullPointerException("key is null");
+
+        put(key, new RcsValue(value));
+    }
+
+    /**
+     * Returns whether attribute is empty.
+     *
+     * @throws RcsUnlockedException
+     *             if the {@link RcsResourceObject.AttributesLock} for this
+     *             object is unlocked
+     */
+    public boolean isEmpty() throws RcsException {
+        ensureLocked();
+
+        return mCache.isEmpty() && nativeIsEmpty(mResourceObject);
+    }
+
+    /**
+     * Returns the number of key-value mappings.
+     *
+     * @throws RcsUnlockedException
+     *             if the {@link RcsResourceObject.AttributesLock} for this
+     *             object is unlocked
+     */
+    public int size() throws RcsException {
+        ensureLocked();
+
+        return mCache.size() + nativeSize(mResourceObject);
+    }
+
+    /**
+     * Removes the mapping for a key from this attributes if it is present.
+     *
+     * @param key
+     *            key whose mapping is to be removed
+     *
+     * @return true if the key is present and the the value mapped is removed.
+     *
+     * @throws RcsUnlockedException
+     *             if the {@link RcsResourceObject.AttributesLock} for this
+     *             object is unlocked
+     */
+    public boolean remove(String key) throws RcsException {
+        ensureLocked();
+
+        if (key == null) throw new NullPointerException("key is null");
+
+        // XXX make sure both cache and native values to be removed.
+        final boolean cacheRemove = mCache.remove(key) != null;
+        final boolean nativeRemove = nativeRemove(mResourceObject, key);
+
+        return cacheRemove || nativeRemove;
+    }
+
+    /**
+     * Removes all elements.
+     *
+     * @throws RcsUnlockedException
+     *             if the {@link RcsResourceObject.AttributesLock} for this
+     *             object is unlocked
+     */
+    public void clear() throws RcsException {
+        ensureLocked();
+
+        nativeClear(mResourceObject);
+    }
+
+    /**
+     * Returns true if this contains a mapping for the specified key.
+     *
+     * @param key
+     *            key whose presence is to be tested
+     *
+     * @return true if this contains a mapping for the specified key.
+     *
+     * @throws NullPointerException
+     *             if key is null
+     * @throws RcsUnlockedException
+     *             if the {@link RcsResourceObject.AttributesLock} for this
+     *             object is unlocked
+     */
+    public boolean contains(String key) throws RcsException {
+        ensureLocked();
+
+        if (key == null) throw new NullPointerException("key is null");
+
+        return mCache.containsKey(key) || nativeContains(mResourceObject, key);
+    }
+}
diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/server/RcsRequest.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/server/RcsRequest.java
new file mode 100644 (file)
index 0000000..c3d2d88
--- /dev/null
@@ -0,0 +1,42 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics 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 org.iotivity.service.resourcecontainer.server;
+
+/**
+ * This class describes the request.
+ */
+public class RcsRequest {
+
+    private final String mUri;
+
+    private RcsRequest(String resourceUri) {
+        mUri = resourceUri;
+    }
+
+    /**
+     * Returns the URI of the request.
+     *
+     * @return Uri of the request in string form
+     */
+    public String getResourceUri() {
+        return mUri;
+    }
+}
diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/server/RcsResourceObject.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/server/RcsResourceObject.java
new file mode 100644 (file)
index 0000000..4ad8b6f
--- /dev/null
@@ -0,0 +1,708 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics 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.
+ *
+ ******************************************************************/
+/**
+ * @file   RCSResourceObject.java
+ *
+ *  This file contains the resource object APIs provided to the developers.
+ *        RCSResourceObject is a part of the server builder module.
+ *
+ */
+
+package org.iotivity.service.resourcecontainer.server;
+
+import java.lang.ref.WeakReference;
+
+import org.iotivity.service.resourcecontainer.RcsDestroyedObjectException;
+import org.iotivity.service.resourcecontainer.RcsException;
+import org.iotivity.service.resourcecontainer.RcsIllegalStateException;
+import org.iotivity.service.resourcecontainer.RcsObject;
+import org.iotivity.service.resourcecontainer.RcsPlatformException;
+import org.iotivity.service.resourcecontainer.RcsResourceAttributes;
+import org.iotivity.service.resourcecontainer.RcsValue;
+
+/**
+ * RCSResourceObject represents a resource. It handles any requests from clients
+ * automatically with attributes.
+ * <p>
+ * It also provides an auto notification mechanism that notifies to the
+ * observers. Requests are handled automatically by defaultAction of
+ * {@link RcsGetResponse} and {@link RcsSetResponse}. You can override them and
+ * send your own response with {@link GetRequestHandler} and
+ * {@link SetRequestHandler}.
+ * <p>
+ * For simple resources, they are simply required to notify whenever attributes
+ * are changed by a set request. In this case, add an
+ * {@link OnAttributeUpdatedListener} with a key interested in instead of
+ * overriding {@link SetRequestHandler}.
+ *
+ * @see Builder
+ */
+public final class RcsResourceObject extends RcsObject {
+    /**
+     * This is a builder to create resource with properties and attributes.
+     *
+     * The resource will be observable and discoverable by default, to make them
+     * disable
+     * set these properties explicitly with setDiscoverable and setObservable.
+     *
+     */
+    public static class Builder {
+        private final String          mUri;
+        private final String          mType;
+        private final String          mInterface;
+        private boolean               mIsObservable    = true;
+        private boolean               mIsDiscovervable = true;
+        private RcsResourceAttributes mAttributes;
+
+        /**
+         * Constructs a Builder.
+         *
+         * @param uri
+         *            resource uri
+         * @param resourceType
+         *            resource type
+         * @param resourceInterface
+         *            resource interface
+         *
+         * @throws NullPointerException
+         *             if any parameter is null
+         */
+        public Builder(String uri, String resourceType,
+                String resourceInterface) {
+            if (uri == null) {
+                throw new NullPointerException("uri is null.");
+            }
+            if (resourceType == null) {
+                throw new NullPointerException("resourceType is null.");
+            }
+            if (resourceInterface == null) {
+                throw new NullPointerException("resourceInterface is null.");
+            }
+
+            mUri = uri;
+            mType = resourceType;
+            mInterface = resourceInterface;
+        }
+
+        /**
+         * Sets whether the resource is discoverable.
+         *
+         * @param isDiscoverable
+         *            whether to be discoverable or not
+         *
+         */
+        public Builder setDiscoverable(boolean isDiscoverable) {
+            mIsDiscovervable = isDiscoverable;
+            return this;
+        }
+
+        /**
+         * Sets the observable(OC_OBSERVABLE) property of the resource.
+         *
+         * @param isObservable
+         *            whether to be observable or not
+         *
+         */
+        public Builder setObservable(boolean isObservable) {
+            mIsObservable = isObservable;
+            return this;
+        }
+
+        /**
+         * Sets attributes foe the resource.
+         *
+         */
+        public Builder setAttributes(RcsResourceAttributes attributes) {
+            mAttributes = attributes;
+            return this;
+        }
+
+        /**
+         * Register a resource and returns a RCSResourceObject.
+         *
+         * @throws RcsPlatformException
+         *             If registering a resource is failed.
+         *
+         */
+        public RcsResourceObject build() {
+            return nativeBuild(mUri, mType, mInterface, mIsObservable,
+                    mIsDiscovervable, mAttributes);
+        }
+    }
+
+    /**
+     * This provides the way to get the attributes of RcsResourceObject with
+     * lock.
+     * When a thread holds the lock, the other threads will be pending until the
+     * lock is released by unlock.
+     *
+     * Here is the standard idiom for AttributesLock:
+     *
+     * <pre>
+     * {@code
+     * AttributesLock lock = rcsResourceObject.getAttributesLock();
+     *
+     * try {
+     *     lock.lock();
+     *
+     *     ....
+     *
+     *     lock.apply();
+     * } finally {
+     *     lock.unlock();
+     * }
+     * }
+     * </pre>
+     */
+    public static class AttributesLock {
+
+        private final WeakReference<RcsResourceObject> mResourceObjectRef;
+
+        private RcsLockedAttributes mCurrentAttributes;
+
+        private AttributesLock(RcsResourceObject resourceObj) {
+            mResourceObjectRef = new WeakReference<RcsResourceObject>(
+                    resourceObj);
+        }
+
+        private RcsResourceObject ensureResourceObject() throws RcsException {
+            final RcsResourceObject object = mResourceObjectRef.get();
+
+            if (object == null || object.isDestroyed()) {
+                throw new RcsDestroyedObjectException(
+                        "The object is already destroyed!");
+            }
+
+            return object;
+        }
+
+        /**
+         * Locks the attributes of the RcsResourceObject and returns locked
+         * attributes that can be modified until unlocked.
+         *
+         * @return Locked attributes.
+         *
+         * @throws RcsException
+         *             if the RcsResourceObject is destroyed
+         */
+        public RcsLockedAttributes lock() throws RcsException {
+            return mCurrentAttributes = new RcsLockedAttributes(
+                    ensureResourceObject());
+        }
+
+        /**
+         * Changes the state to unlock of the attributes of the
+         * RcsResourceObject.
+         *
+         */
+        public void unlock() {
+            if (mCurrentAttributes == null) return;
+
+            mCurrentAttributes.setUnlockState();
+            mCurrentAttributes = null;
+        }
+
+        /**
+         * Applies the modified attributes to the RcsResourceObject.
+         *
+         * @throws RcsIllegalStateException
+         *             if not in locked state
+         */
+        public void apply() throws RcsIllegalStateException {
+            if (mCurrentAttributes == null) {
+                throw new RcsIllegalStateException("it is not locked state.");
+            }
+            mCurrentAttributes.apply();
+        }
+    }
+
+    private static native RcsResourceObject nativeBuild(String uri,
+            String resourceType, String resourceInterface, boolean isObservable,
+            boolean isDiscoverable, RcsResourceAttributes attributes);
+
+    private native void nativeSetAttribute(String key, RcsValue value);
+
+    private native RcsValue nativeGetAttributeValue(String key);
+
+    private native boolean nativeRemoveAttribute(String key);
+
+    private native boolean nativeContainsAttribute(String key);
+
+    private native RcsResourceAttributes nativeGetAttributes();
+
+    private native boolean nativeIsObservable();
+
+    private native boolean nativeIsDiscoverable();
+
+    private native void nativeNotify();
+
+    private native void nativeSetAutoNotifyPolicy(AutoNotifyPolicy policy);
+
+    private native AutoNotifyPolicy nativeGetAutoNotifyPolicy();
+
+    private native void nativeSetSetRequestHandlerPolicy(
+            SetRequestHandlerPolicy policy);
+
+    private native SetRequestHandlerPolicy nativeGetSetRequestHandlerPolicy();
+
+    private native void nativeSetGetRequestHandler(GetRequestHandler handler);
+
+    private native void nativeSetSetRequestHandler(SetRequestHandler handler);
+
+    private native void nativeAddAttributeUpdatedListener(String key,
+            OnAttributeUpdatedListener listener);
+
+    private native boolean nativeRemoveAttributeUpdatedListener(String key);
+
+    private RcsResourceObject() {
+    }
+
+    /**
+     * Represents the policy of AutoNotify function of RCSResourceObject class
+     * In accord with this, observers are notified of attributes that are
+     * changed or updated.
+     *
+     * <p>
+     * Attributes are changed or updated according to execution of some
+     * functions which modify attributes or receipt of set requests.
+     *
+     * @see setAttribute
+     * @see removeAttribute
+     * @see getAttributesLock
+     *
+     */
+    public enum AutoNotifyPolicy {
+        /** Never */
+        NEVER,
+
+        /** Always */
+        ALWAYS,
+
+        /** When attributes are changed */
+        UPDATED
+    }
+
+    /**
+     * Represents the policy of set-request handler.
+     * In accord with this, the RCSResourceObject decides whether a set-request
+     * is
+     * acceptable or not.
+     */
+    public enum SetRequestHandlerPolicy {
+        /**
+         * Requests will be ignored if attributes of the request contain
+         * a new key or a value that has different type from the current
+         * value of the key.
+         */
+        NEVER,
+
+        /**
+         * The attributes of the request will be applied unconditionally
+         * even if there are new name or type conflicts.
+         */
+        ACCEPT
+    }
+
+    /**
+     * Interface definition for a handler to be invoked when a get request is
+     * received.
+     * <p>
+     * The handler will be called first when a get request is received, before
+     * the RCSResourceObject handles.
+     *
+     * @see setGetRequestHandler
+     */
+    public interface GetRequestHandler {
+
+        /**
+         * Called when received a get request from the client.
+         *
+         * @param request
+         *            Request information.
+         * @param attributes
+         *            The attributes of the request.
+         *
+         * @return A response to be sent.
+         *
+         * @see RcsGetResponse
+         */
+        RcsGetResponse onGetRequested(RcsRequest request,
+                RcsResourceAttributes attributes);
+
+    }
+
+    /**
+     * Interface definition for a handler to be invoked when a set request is
+     * received.
+     * <p>
+     * The handler will be called first when a get request is received, before
+     * the RCSResourceObject handles. If the attributes are modified in the
+     * callback, the modified attributes will be set in the RCSResourceObject if
+     * the request is not ignored.
+     *
+     * @see setGetRequestHandler
+     */
+    public interface SetRequestHandler {
+
+        /**
+         * Called when received a set request from the client.
+         *
+         * @param request
+         *            request information
+         * @param attributes
+         *            the attributes of the request.
+         *            it will be applied to the RcsResourceObject
+         *
+         * @return A response indicating how to handle this request.
+         *
+         * @see RcsSetResponse
+         */
+        RcsSetResponse onSetRequested(RcsRequest request,
+                RcsResourceAttributes attributes);
+
+    }
+
+    /**
+     * Interface definition for a callback to be invoked when an attribute is
+     * updated.
+     */
+    public interface OnAttributeUpdatedListener {
+
+        /**
+         * Called when an attribute value is updated.
+         *
+         * @param oldValue
+         *            the attribute value before updated
+         * @param newValue
+         *            the current resource attribute value
+         */
+        void onAttributeUpdated(RcsValue oldValue, RcsValue newValue);
+    }
+
+    private void assertAlive() throws RcsException {
+        if (!hasHandle()) {
+            throw new RcsDestroyedObjectException(
+                    "The object is already destroyed!");
+        }
+    }
+
+    /**
+     * Sets a particular attribute value.
+     *
+     * @param key
+     *            key with which the specified value is to be associated
+     * @param value
+     *            value to be associated with the specified key
+     *
+     * @throws RcsDestroyedObjectException
+     *             if the object is destroyed
+     * @throws NullPointerException
+     *             if key or value is null
+     *
+     */
+    public void setAttribute(String key, RcsValue value) throws RcsException {
+        assertAlive();
+
+        if (key == null) throw new NullPointerException("key is null");
+        if (value == null) throw new NullPointerException("value is null");
+
+        nativeSetAttribute(key, value);
+    }
+
+    /**
+     * Returns a copied attribute value associated with the supplied key.
+     *
+     * @param key
+     *            the key whose associated value is to be returned
+     *
+     * @return the value to which the specified key is mapped, or null if no
+     *         attribute for the key
+     *
+     * @throws RcsDestroyedObjectException
+     *             if the object is destroyed
+     * @throws NullPointerException
+     *             if key is null
+     */
+    public RcsValue getAttributeValue(String key) throws RcsException {
+        assertAlive();
+
+        if (key == null) throw new NullPointerException("key is null");
+        return nativeGetAttributeValue(key);
+    }
+
+    /**
+     * Removes the mapping for a key from the attributes if it is present.
+     *
+     * @param key
+     *            key whose mapping is to be removed
+     *
+     * @return true if the key is present and the the value mapped is removed.
+     *
+     * @throws RcsDestroyedObjectException
+     *             if the object is destroyed
+     * @throws NullPointerException
+     *             if key is null
+     */
+    public boolean removeAttribute(String key) throws RcsException {
+        assertAlive();
+
+        if (key == null) throw new NullPointerException("key is null");
+        return nativeRemoveAttribute(key);
+    }
+
+    /**
+     * Returns true if the attributes contains a mapping for the specified key.
+     *
+     * @param key
+     *            key whose presence is to be tested
+     *
+     * @return true if the attributes contains a mapping for the specified key.
+     *
+     * @throws RcsDestroyedObjectException
+     *             if the object is destroyed
+     * @throws NullPointerException
+     *             if key is null
+     */
+    public boolean containsAttribute(String key) throws RcsException {
+        assertAlive();
+
+        if (key == null) throw new NullPointerException("key is null");
+        return nativeContainsAttribute(key);
+    }
+
+    /**
+     * Returns a copied attributes of the RCSResourceObject.
+     * To modify the attributes, use {@link AttributesLock}.
+     *
+     * @throws RcsDestroyedObjectException
+     *             if the object is destroyed
+     *
+     * @see getAttributesLock
+     */
+    public RcsResourceAttributes getAttributes() throws RcsException {
+        assertAlive();
+
+        return nativeGetAttributes();
+    }
+
+    /**
+     * Returns an AttributesLock for this RcsResourceObject.
+     *
+     * @throws RcsDestroyedObjectException
+     *             if the object is destroyed
+     */
+    public AttributesLock getAttributesLock() throws RcsException {
+        assertAlive();
+
+        return new AttributesLock(this);
+    }
+
+    /**
+     * Checks whether the resource is observable or not.
+     *
+     * @throws RcsDestroyedObjectException
+     *             if the object is destroyed
+     */
+    public boolean isObservable() throws RcsException {
+        assertAlive();
+
+        return nativeIsObservable();
+    }
+
+    /**
+     * Checks whether the resource is discoverable or not.
+     *
+     * @throws RcsDestroyedObjectException
+     *             if the object is destroyed
+     */
+    public boolean isDiscoverable() throws RcsException {
+        assertAlive();
+
+        return nativeIsDiscoverable();
+    }
+
+    /**
+     * Sets the get request handler. To remove handler, pass null.
+     *
+     * Default behavior is {@link RcsGetResponse#defaultAction()}.
+     *
+     * @throws RcsDestroyedObjectException
+     *             if the object is destroyed
+     */
+    public void setGetRequestHandler(GetRequestHandler handler)
+            throws RcsException {
+        assertAlive();
+
+        nativeSetGetRequestHandler(handler);
+    }
+
+    /**
+     * Sets the set request handler. To remove handler, pass null.
+     *
+     * Default behavior is {@link RcsSetResponse#defaultAction()}.
+     *
+     * @throws RcsDestroyedObjectException
+     *             if the object is destroyed
+     *
+     */
+    public void setSetRequestHandler(SetRequestHandler handler)
+            throws RcsException {
+        assertAlive();
+
+        nativeSetSetRequestHandler(handler);
+    }
+
+    /**
+     * Adds a listener for a particular attribute updated.
+     *
+     * @param key
+     *            the interested attribute's key
+     * @param listener
+     *            listener to be invoked
+     *
+     * @throws NullPointerException
+     *             if key or listener is null
+     * @throws RcsDestroyedObjectException
+     *             if the object is destroyed
+     */
+    public void addAttributeUpdatedListener(String key,
+            OnAttributeUpdatedListener listener) throws RcsException {
+        assertAlive();
+
+        if (key == null) {
+            throw new NullPointerException("key is null.");
+        }
+        if (listener == null) {
+            throw new NullPointerException("listener is null.");
+        }
+
+        nativeAddAttributeUpdatedListener(key, listener);
+    }
+
+    /**
+     * Removes a listener for a particular attribute updated.
+     *
+     * @param key
+     *            key the key associated with the listener to be removed
+     *
+     * @return true if the listener added with same key exists and is removed.
+     *
+     * @throws RcsDestroyedObjectException
+     *             if the object is destroyed
+     * @throws NullPointerException
+     *             if key is null
+     */
+    public boolean removeAttributeUpdatedListener(String key)
+            throws RcsException {
+        assertAlive();
+
+        if (key == null) throw new NullPointerException("key is null");
+        return nativeRemoveAttributeUpdatedListener(key);
+    }
+
+    /**
+     * Notifies all observers of the current attributes.
+     *
+     * @throws RcsDestroyedObjectException
+     *             if the object is destroyed
+     * @throws RcsPlatformException
+     *             if the operation failed
+     */
+    public void notifyObservers() throws RcsException {
+        assertAlive();
+
+        nativeNotify();
+    }
+
+    /**
+     * Sets auto notify policy
+     *
+     * @param policy
+     *            policy to be set
+     *
+     * @throws RcsDestroyedObjectException
+     *             if the object is destroyed
+     *
+     */
+    public void setAutoNotifyPolicy(AutoNotifyPolicy policy)
+            throws RcsException {
+        assertAlive();
+
+        if (policy == null) throw new NullPointerException("policy is null");
+        nativeSetAutoNotifyPolicy(policy);
+    }
+
+    /**
+     * Returns the current policy
+     *
+     * @throws RcsDestroyedObjectException
+     *             if the object is destroyed
+     *
+     */
+    public AutoNotifyPolicy getAutoNotifyPolicy() throws RcsException {
+        assertAlive();
+
+        return nativeGetAutoNotifyPolicy();
+    }
+
+    /**
+     * Sets the policy for handling a set request.
+     *
+     * @param policy
+     *            policy to be set
+     *
+     * @throws RcsDestroyedObjectException
+     *             if the object is destroyed
+     *
+     */
+    public void setSetRequestHandlerPolicy(SetRequestHandlerPolicy policy)
+            throws RcsException {
+        assertAlive();
+
+        if (policy == null) throw new NullPointerException("policy is null");
+        nativeSetSetRequestHandlerPolicy(policy);
+    }
+
+    /**
+     * Returns the current policy.
+     *
+     * @throws RcsDestroyedObjectException
+     *             if the object is destroyed
+     */
+    public SetRequestHandlerPolicy getSetRequestHandlerPolicy()
+            throws RcsException {
+        assertAlive();
+
+        return nativeGetSetRequestHandlerPolicy();
+    }
+
+    private boolean isDestroyed() {
+        return !hasHandle();
+    }
+
+    /**
+     * Unregister the resource and reclaims all resources used by this object.
+     * This must be called if the resource is not used any longer.
+     *
+     */
+    public void destroy() {
+        super.dispose();
+    }
+}
diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/server/RcsResponse.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/server/RcsResponse.java
new file mode 100644 (file)
index 0000000..d69759a
--- /dev/null
@@ -0,0 +1,53 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics 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 org.iotivity.service.resourcecontainer.server;
+
+import org.iotivity.service.resourcecontainer.RcsResourceAttributes;
+
+class RcsResponse {
+    private native static int nativeGetDefaultErrorCode();
+
+    public static final int DEFAULT_ERROR_CODE;
+
+    static {
+        DEFAULT_ERROR_CODE = nativeGetDefaultErrorCode();
+    }
+
+    private final int                   mErrorCode;
+    private final RcsResourceAttributes mAttrs;
+
+    RcsResponse() {
+        this(DEFAULT_ERROR_CODE);
+    }
+
+    RcsResponse(RcsResourceAttributes attrs) {
+        this(attrs, DEFAULT_ERROR_CODE);
+    }
+
+    RcsResponse(int errorCode) {
+        this(null, errorCode);
+    }
+
+    RcsResponse(RcsResourceAttributes attrs, int errorCode) {
+        mErrorCode = errorCode;
+        mAttrs = attrs;
+    }
+}
diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/server/RcsSetResponse.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/server/RcsSetResponse.java
new file mode 100644 (file)
index 0000000..f763b0f
--- /dev/null
@@ -0,0 +1,203 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics 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 org.iotivity.service.resourcecontainer.server;
+
+import org.iotivity.service.resourcecontainer.RcsResourceAttributes;
+
+/**
+ * This class provides methods to create the response for a received set
+ * request.
+ *
+ * @see RcsResourceObject
+ * @see RcsSetResponse
+ */
+public final class RcsSetResponse extends RcsResponse {
+    /**
+     * Options for handling a set request.
+     *
+     * This overrides {@link RcsResourceObject.SetRequestHandlerPolicy}.
+     *
+     */
+    public enum AcceptanceMethod {
+        /**
+         * Follow {@link RcsResourceObject.SetRequestHandlerPolicy}.
+         */
+        DEFAULT,
+
+        /**
+         * Accept the request attributes even if there is an unknown key or
+         * mismatched type.
+         */
+        ACCEPT,
+
+        /**
+         * Ignore the request attributes.
+         */
+        IGNORE
+    };
+
+    private AcceptanceMethod mAcceptanceMethod = AcceptanceMethod.DEFAULT;
+
+    /**
+     * Creates a default RcsSetResponse with {@link AcceptanceMethod#DEFAULT}.
+     * The response will have {@link #DEFAULT_ERROR_CODE} for the errorCode. The
+     * attributes of {@link RcsResourceObject} will be set as the result
+     * attributes.
+     *
+     */
+    public static RcsSetResponse defaultAction() {
+        return new RcsSetResponse();
+    }
+
+    /**
+     * Creates a default RcsSetResponse with {@link AcceptanceMethod#ACCEPT}
+     * The response will have {@link #DEFAULT_ERROR_CODE} for the errorCode. The
+     * attributes of {@link RcsResourceObject} will be set as the result
+     * attributes.
+     *
+     */
+    public static RcsSetResponse accept() {
+        return new RcsSetResponse()
+                .setAcceptanceMethod(AcceptanceMethod.ACCEPT);
+    }
+
+    /**
+     * Creates a RcsSetResponse with {@link AcceptanceMethod#ACCEPT} and error
+     * code passed.
+     * The attributes of the {@link RcsResourceObject} will be set as the result
+     * attributes.
+     *
+     * @param errorCode
+     *            error code to be set in response
+     *
+     */
+    public static RcsSetResponse accept(int errorCode) {
+        return new RcsSetResponse(errorCode)
+                .setAcceptanceMethod(AcceptanceMethod.ACCEPT);
+    }
+
+    /**
+     * Creates a default RcsSetResponse with {@link AcceptanceMethod#IGNORE}.
+     * The response will have {@link #DEFAULT_ERROR_CODE} for the errorCode. The
+     * attributes of {@link RcsResourceObject} will be set as the result
+     * attributes.
+     *
+     */
+    public static RcsSetResponse ignore() {
+        return new RcsSetResponse()
+                .setAcceptanceMethod(AcceptanceMethod.IGNORE);
+    }
+
+    /**
+     * Creates a RcsSetResponse with {@link AcceptanceMethod#IGNORE} and error
+     * code passed. The attributes of the {@link RcsResourceObject} will be set
+     * as the result attributes.
+     *
+     * @param errorCode
+     *            error code to be set in response
+     *
+     */
+    public static RcsSetResponse ignore(int errorCode) {
+        return new RcsSetResponse(errorCode)
+                .setAcceptanceMethod(AcceptanceMethod.IGNORE);
+    }
+
+    /**
+     * Creates a RcsSetResponse with error code passed and
+     * {@link AcceptanceMethod#DEFAULT}. The attributes of the
+     * {@link RcsResourceObject} will be set as the result attributes.
+     *
+     * @param errorCode
+     *            error code to be set in response
+     *
+     */
+    public static RcsSetResponse create(int errorCode) {
+        return new RcsSetResponse(errorCode);
+    }
+
+    /**
+     * Creates a RcsSetResponse with custom attributes and
+     * {@link AcceptanceMethod#DEFAULT}. This sends the passed attributes as the
+     * result attributes instead of one the {@link RcsResourceObject} holds.
+     *
+     * @param attributes
+     *            attributes to be sent as the result
+     *
+     */
+    public static RcsSetResponse create(RcsResourceAttributes attributes) {
+        return new RcsSetResponse(attributes);
+    }
+
+    /**
+     * Creates a RcsSetResponse with error code passed and
+     * {@link AcceptanceMethod#DEFAULT}. This sends the passed attributes as the
+     * result attributes instead of one the {@link RcsResourceObject} holds.
+     *
+     * @param attributes
+     *            attributes to be sent as the result
+     * @param errorCode
+     *            error code for response
+     *
+     */
+    public static RcsSetResponse create(RcsResourceAttributes attributes,
+            int errorCode) {
+        return new RcsSetResponse(attributes, errorCode);
+    }
+
+    /**
+     * Returns the acceptance method.
+     *
+     */
+    public AcceptanceMethod getAcceptanceMethod() {
+        return mAcceptanceMethod;
+    }
+
+    /**
+     * Sets the acceptance method.
+     *
+     * @param method
+     *            method to be set
+     *
+     * @return The reference to this RcsSetResponse
+     *
+     */
+    public RcsSetResponse setAcceptanceMethod(AcceptanceMethod method) {
+        mAcceptanceMethod = method;
+        return this;
+    }
+
+    private RcsSetResponse() {
+        super();
+    }
+
+    private RcsSetResponse(int errorCode) {
+        super(errorCode);
+    }
+
+    private RcsSetResponse(RcsResourceAttributes attrs) {
+        super(attrs);
+    }
+
+    private RcsSetResponse(RcsResourceAttributes attrs, int errorCode) {
+        super(attrs, errorCode);
+    }
+
+}
diff --git a/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/server/RcsUnlockedException.java b/service/resource-container/android/resource-container/src/main/java/org/iotivity/service/resourcecontainer/server/RcsUnlockedException.java
new file mode 100644 (file)
index 0000000..2788c42
--- /dev/null
@@ -0,0 +1,17 @@
+package org.iotivity.service.resourcecontainer.server;
+
+import org.iotivity.service.resourcecontainer.RcsException;
+
+/**
+ * Thrown when trying to access a unlocked {@link RcsLockedAttributes}.
+ *
+ */
+public class RcsUnlockedException extends RcsException {
+
+    private static final long serialVersionUID = 4292243643497860992L;
+
+    public RcsUnlockedException(String message) {
+        super(message);
+    }
+
+}
index 09a2288..915ada5 100644 (file)
@@ -9,20 +9,44 @@ LOCAL_SRC_FILES := $(IOTIVITY_LIB_PATH)/librcs_container.so
 include $(PREBUILT_SHARED_LIBRARY)
 
 include $(CLEAR_VARS)
+LOCAL_MODULE := rcs_common
+LOCAL_SRC_FILES := $(IOTIVITY_LIB_PATH)/librcs_common.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := rcs_client
+LOCAL_SRC_FILES := $(IOTIVITY_LIB_PATH)/librcs_client.so
+include $(PREBUILT_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_MODULE := rcs_server
+LOCAL_SRC_FILES := $(IOTIVITY_LIB_PATH)/librcs_server.so
+include $(PREBUILT_SHARED_LIBRARY)
+include $(CLEAR_VARS)
 OIC_SRC_DIR := ../../../../../..
 LOCAL_MODULE := resource_container_jni
 
 LOCAL_C_INCLUDES := $(LOCAL_PATH)/util
 LOCAL_C_INCLUDES += $(OIC_SRC_DIR)/extlibs/boost/boost_1_58_0
 LOCAL_C_INCLUDES += $(OIC_SRC_DIR)/service/resource-container/include
+LOCAL_C_INCLUDES += $(OIC_SRC_DIR)/service/resource-container/bundle-api/include
+LOCAL_C_INCLUDES += $(OIC_SRC_DIR)/service/resource-container/src
+LOCAL_C_INCLUDES += $(OIC_SRC_DIR)/service/resource-encapsulation/include
+LOCAL_C_INCLUDES += $(OIC_SRC_DIR)/service/resource-encapsulation/src/serverBuilder/include
+LOCAL_C_INCLUDES += $(OIC_SRC_DIR)/resource/csdk/stack/include
+LOCAL_C_INCLUDES += $(OIC_SRC_DIR)/resource/c_common
+
+LOCAL_C_INCLUDES += $(OIC_SRC_DIR)/extlibs/
 
 LOCAL_SRC_FILES += $(patsubst $(LOCAL_PATH)/%, %, $(wildcard $(LOCAL_PATH)/util/*.cpp))
 LOCAL_SRC_FILES += $(patsubst $(LOCAL_PATH)/%, %, $(wildcard $(LOCAL_PATH)/*.cpp))
 
 LOCAL_CPPFLAGS := -std=c++0x -frtti -fexceptions
 
-LOCAL_LDLIBS := -llog
 
-LOCAL_SHARED_LIBRARIES += rcs_container
+
+LOCAL_LDLIBS := -llog 
+
+LOCAL_SHARED_LIBRARIES += rcs_container rcs_common rcs_client rcs_server rcs_jni
 
 include $(BUILD_SHARED_LIBRARY)
diff --git a/service/resource-container/android/resource-container/src/main/jni/AndroidResource.cpp b/service/resource-container/android/resource-container/src/main/jni/AndroidResource.cpp
new file mode 100644 (file)
index 0000000..8486633
--- /dev/null
@@ -0,0 +1,182 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+
+#include "AndroidResource.h"
+#include "JniRcsResourceAttributes.h"
+
+#include <jni.h>
+#include <string.h>
+#include <iostream>
+#include "Log.h"
+
+#define LOG_TAG "JNI-AndroidResource"
+
+using namespace OIC::Service;
+using namespace std;
+
+
+AndroidResource::AndroidResource()
+{
+
+}
+
+void AndroidResource::initAttributes()
+{
+
+}
+
+AndroidResource::AndroidResource(JNIEnv *env, jobject obj, jobject bundleResource,
+                                       string bundleId, jobjectArray attributes)
+{
+    LOGD("Creating android resource");
+    (void) obj;
+    m_env = env;
+    int stringCount = m_env->GetArrayLength(attributes);
+    LOGD("string count is %d", stringCount);
+
+    for (int i = 0; i < stringCount; i++)
+    {
+        jstring str = (jstring) m_env->GetObjectArrayElement(attributes, i);
+        const char *rawString = m_env->GetStringUTFChars(str, 0);
+        string s(rawString, strlen(rawString));
+        BundleResource::setAttribute(s, "");
+    }
+
+    m_bundleId = bundleId;
+
+    this->m_bundleResource = m_env->NewGlobalRef(bundleResource);
+
+    m_bundleResourceClass = m_env->GetObjectClass(bundleResource);
+    LOGD("Looking for setter.");
+    m_attributeSetRequestHandler = m_env->GetMethodID(m_bundleResourceClass,
+            "handleSetAttributesRequest", "(Lorg/iotivity/service/resourcecontainer/RcsResourceAttributes;)V");
+    LOGD("Looking for getter.");
+    m_attributeGetRequestHandler = m_env->GetMethodID(m_bundleResourceClass,
+            "handleGetAttributesRequest", "()Lorg/iotivity/service/resourcecontainer/RcsResourceAttributes;");
+    LOGD("Get java vm.");
+    int jvmAccess = m_env->GetJavaVM(&m_jvm);
+    LOGD("JVM: %s", (jvmAccess ? "false" : "true") );
+
+
+}
+
+AndroidResource::~AndroidResource()
+{
+
+}
+
+RCSResourceAttributes::Value AndroidResource::handleGetAttributeRequest(
+        const std::string &attributeName)
+{
+    LOGD("handleGetAttributeRequest called2");
+    LOGD("Attaching thread now");
+    int attached = m_jvm->AttachCurrentThread(&m_env, NULL);
+    if(attached>0)
+    {
+        LOGE("Failed to attach thread to JavaVM");
+    }
+    else{
+        jstring attrName = m_env->NewStringUTF(attributeName.c_str());
+        auto responseObj =  m_env->CallObjectMethod(m_bundleResource,
+                m_attributeGetRequestHandler, attrName);
+
+        if (responseObj)
+        {
+            LOGD("parsing attributes");
+            RCSResourceAttributes attrs = toNativeAttributes(m_env, responseObj);
+            LOGD("Received attributes %d", attrs.size());
+        }
+        /*const char *js = m_env->GetStringUTFChars(returnString, NULL);
+        std::string val(js);
+        RCSResourceAttributes::Value newVal = val;
+        m_env->ReleaseStringUTFChars(returnString, js);
+        m_jvm->DetachCurrentThread();*/
+        //BundleResource::setAttribute(attributeName, newVal.toString());
+    }
+    return BundleResource::getAttribute(attributeName);
+}
+
+void AndroidResource::handleSetAttributeRequest(const std::string &attributeName,
+                                      RCSResourceAttributes::Value &&value)
+{
+    jstring attrName = m_env->NewStringUTF(attributeName.c_str());
+    jstring val = m_env->NewStringUTF(value.toString().c_str());
+
+    //LOGD("handleSetAttributeRequest calling object method %d", &m_attributeSetRequestHandler);
+    m_env->CallObjectMethod(m_bundleResource, m_attributeSetRequestHandler, attrName, val);
+    BundleResource::setAttribute(attributeName, std::move(value));
+}
+
+
+void AndroidResource::handleSetAttributesRequest(RCSResourceAttributes &attrs){
+    LOGD("handleSetAttributesRequest called %d", attrs.size());
+
+    //m_env->CallObjectMethod(m_bundleResource, m_attributeSetRequestHandler, attrName, val);
+    //BundleResource::setAttribute(attributeName, std::move(value));
+
+    int attached = m_jvm->AttachCurrentThread(&m_env, NULL);
+    if(attached>0)
+    {
+        LOGE("Failed to attach thread to JavaVM");
+    }
+    else{
+        LOGD("Creating resource attributes for JNI.");
+        auto jniRcsAttributes = newAttributesObject(m_env, attrs);
+        LOGD("jobject created. calling");
+        m_env->CallVoidMethod(m_bundleResource,
+                m_attributeSetRequestHandler, jniRcsAttributes);
+        BundleResource::setAttributes(attrs);
+        m_jvm->DetachCurrentThread();
+    }
+}
+
+RCSResourceAttributes & AndroidResource::handleGetAttributesRequest()
+{
+    LOGD("handleGetAttributesRequest");
+    /*std::list<string> attrsNames = getAttributeNames();
+    for(std::list<string>::iterator iterator = attrsNames.begin();
+            iterator != attrsNames.end(); ++iterator )
+    {
+        handleGetAttributeRequest(*iterator);
+    }*/
+    int attached = m_jvm->AttachCurrentThread(&m_env, NULL);
+    if(attached>0)
+    {
+        LOGE("Failed to attach thread to JavaVM");
+    }
+    else{
+        auto responseObj =  m_env->CallObjectMethod(m_bundleResource,
+                m_attributeGetRequestHandler);
+
+        if (responseObj)
+        {
+            LOGD("parsing attributes");
+
+            RCSResourceAttributes attrs = toNativeAttributes(m_env, responseObj);
+            LOGD("Received attributes %d", attrs.size());
+            BundleResource::setAttributes(attrs);
+        }
+
+        m_jvm->DetachCurrentThread();
+    }
+    LOGD("BundleResource::getAttributes().size() %d", BundleResource::getAttributes().size());
+    return BundleResource::getAttributes();
+}
diff --git a/service/resource-container/android/resource-container/src/main/jni/AndroidResource.h b/service/resource-container/android/resource-container/src/main/jni/AndroidResource.h
new file mode 100644 (file)
index 0000000..279f190
--- /dev/null
@@ -0,0 +1,69 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef ANDROIDRESOURCE_H_
+#define ANDROIDRESOURCE_H_
+
+#include <map>
+#include <vector>
+#include <string>
+#include <jni.h>
+#include "BundleResource.h"
+#include "ResourceContainerImpl.h"
+
+using namespace std;
+
+namespace OIC
+{
+    namespace Service
+    {
+        class AndroidResource: public BundleResource
+        {
+        public:
+            AndroidResource();
+            AndroidResource(JNIEnv *env, jobject obj, jobject bundleResource, string bundleId,
+                    jobjectArray attributes);
+            virtual ~AndroidResource();
+
+            void handleSetAttributeRequest(const std::string& key,
+                    RCSResourceAttributes::Value&&);
+
+            RCSResourceAttributes::Value handleGetAttributeRequest(const std::string& key);
+
+            virtual void handleSetAttributesRequest(RCSResourceAttributes &attrs);
+
+            virtual RCSResourceAttributes& handleGetAttributesRequest();
+
+            virtual void initAttributes();
+        private:
+            // needs to be a GlobalRef
+            jobject m_bundleResource;
+            jobjectArray m_attributes;
+            jclass m_bundleResourceClass;
+            jmethodID m_attributeSetRequestHandler;
+            jmethodID m_attributeGetRequestHandler;
+            string m_bundleId;
+            JNIEnv *m_env;
+            JavaVM *m_jvm;
+        };
+    }
+}
+
+#endif
index 999a171..bd223f9 100644 (file)
  ******************************************************************/
 
 #include "JniRcsResourceContainer.h"
+#include "JniRcsResourceAttributes.h"
 #include "JavaClasses.h"
 #include "JNIEnvWrapper.h"
 #include "Log.h"
+#include "JniRcsObject.h"
+#include "JniRcsValue.h"
+#include "JavaExceptions.h"
+#include "JniRcsValue.h"
 
 #define LOG_TAG "JNI-Main"
 
@@ -46,7 +51,11 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved)
     try
     {
         initJavaClasses(&envWrapper);
+        initJavaExceptions(&envWrapper);
+        initRCSValue(&envWrapper);
         initRCSResourceContainer(&envWrapper);
+        initRCSResourceAttributes(&envWrapper);
+        initRCSObject(&envWrapper);
     }
     catch (const JavaException &)
     {
diff --git a/service/resource-container/android/resource-container/src/main/jni/JniRcsObject.cpp b/service/resource-container/android/resource-container/src/main/jni/JniRcsObject.cpp
new file mode 100644 (file)
index 0000000..7e60bf1
--- /dev/null
@@ -0,0 +1,48 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics 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.
+ *
+ ******************************************************************/
+
+#include "JniRcsObject.h"
+
+#include "JavaClasses.h"
+#include "JNIEnvWrapper.h"
+#include "Log.h"
+#include "Verify.h"
+
+#define LOG_TAG "JNI-RCSObject"
+
+jfieldID g_field_mNativeHandle;
+
+void initRCSObject(JNIEnvWrapper* env)
+{
+    auto clsRCSObject = env->FindClass(PACKAGE_NAME "/RcsObject");
+
+    g_field_mNativeHandle = env->GetFieldID(clsRCSObject, "mNativeHandle", "J");
+}
+
+void clearRCSObject(JNIEnvWrapper* env)
+{
+}
+
+JNIEXPORT void JNICALL
+Java_org_iotivity_service_RcsObject_nativeDispose(JNIEnv* env, jobject obj)
+{
+    LOGD("release nativeHandle!");
+    releaseNativeHandle(env, obj);
+}
diff --git a/service/resource-container/android/resource-container/src/main/jni/JniRcsObject.h b/service/resource-container/android/resource-container/src/main/jni/JniRcsObject.h
new file mode 100644 (file)
index 0000000..46b5671
--- /dev/null
@@ -0,0 +1,125 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics 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.
+ *
+ ******************************************************************/
+
+#ifndef JNI_RCS_OBJECT_H_
+#define JNI_RCS_OBJECT_H_
+
+#include <jni.h>
+
+#include <memory>
+
+#include "JavaClasses.h"
+#include "JNIEnvWrapper.h"
+
+extern jfieldID g_field_mNativeHandle;
+
+void initRCSObject(JNIEnvWrapper*);
+void clearRCSObject(JNIEnvWrapper*);
+
+namespace Detail
+{
+    struct BaseHandleHolder
+    {
+        virtual ~BaseHandleHolder() {}
+    };
+
+    template< typename T >
+    struct HandleHolder: public BaseHandleHolder
+    {
+        HandleHolder(T* ptr) : m_ptr { ptr } {}
+
+        virtual ~HandleHolder() { delete m_ptr; }
+
+        T* m_ptr;
+    };
+
+    template< typename ENV >
+    void* getNativeHandle(ENV* env, jobject obj)
+    {
+        return reinterpret_cast< void* >(env->GetLongField(obj, g_field_mNativeHandle));
+    }
+}
+
+template< typename ENV >
+bool hasNativeHandle(ENV* env, jobject obj)
+{
+    return Detail::getNativeHandle(env, obj) != nullptr;
+}
+
+template< typename T, typename ENV, typename ...PARAMS >
+inline void setSafeNativeHandle(ENV* env, jobject obj, PARAMS&&... params)
+{
+    static_assert(!std::is_array< T >::value, "Array is not supported!");
+
+    std::unique_ptr< Detail::HandleHolder< T > > p(
+            new Detail::HandleHolder< T >{ new T{ std::forward< PARAMS >(params)... } });
+
+    env->SetLongField(obj, g_field_mNativeHandle, reinterpret_cast< jlong >(p.get()));
+
+    if (env->ExceptionCheck()) return;
+
+    p.release();
+}
+
+template< typename ENV >
+void releaseNativeHandle(ENV* env, jobject obj)
+{
+    auto handleHolder = reinterpret_cast< Detail::BaseHandleHolder* >(
+            env->GetLongField(obj, g_field_mNativeHandle));
+
+    delete handleHolder;
+
+    env->SetLongField(obj, g_field_mNativeHandle, 0);
+}
+
+
+template< typename T >
+inline T& getNativeHandleAs(JNIEnv* env, jobject obj)
+{
+    auto handleHolder = static_cast< Detail::HandleHolder< T >* >(Detail::getNativeHandle(env, obj));
+
+    if (!handleHolder)
+    {
+        env->ThrowNew(env->FindClass(EXC_NAME_ILLEGAL_STATE), "Internal handle is null!");
+    }
+
+   return *handleHolder->m_ptr;
+}
+
+template< typename T >
+inline T& getNativeHandleAs(JNIEnvWrapper* env, jobject obj)
+{
+    getNativeHandleAs< T >(env->get(), obj);
+    if (env->ExceptionCheck()) throw JavaException();
+}
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+JNIEXPORT void JNICALL
+Java_org_iotivity_service_RcsObject_nativeDispose(JNIEnv*, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif // JNI_RCS_OBJECT_H_
diff --git a/service/resource-container/android/resource-container/src/main/jni/JniRcsResourceAttributes.cpp b/service/resource-container/android/resource-container/src/main/jni/JniRcsResourceAttributes.cpp
new file mode 100644 (file)
index 0000000..163ac6a
--- /dev/null
@@ -0,0 +1,279 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics 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.
+ *
+ ******************************************************************/
+
+#include "JniRcsResourceAttributes.h"
+
+#include "JniRcsObject.h"
+#include "JavaLocalRef.h"
+#include "JniRcsValue.h"
+#include "Log.h"
+#include "Verify.h"
+
+using namespace OIC::Service;
+
+#define LOG_TAG "JNI-RCSResourceAttributes"
+
+namespace
+{
+    jclass g_cls_RCSResourceAttributes;
+
+    jmethodID g_ctor_RCSResourceAttributes;
+
+    jfieldID g_field_mCache;
+}
+
+void initRCSResourceAttributes(JNIEnvWrapper* env)
+{
+    g_cls_RCSResourceAttributes = env->FindClassAsGlobalRef(CLS_NAME_RESOURCEATTRIBUTES);
+    g_ctor_RCSResourceAttributes = env->GetConstructorID(g_cls_RCSResourceAttributes, "()V");
+
+    g_field_mCache = env->GetFieldID(g_cls_RCSResourceAttributes, "mCache", AS_SIG(CLS_NAME_MAP));
+}
+
+void clearRCSResourceAttributes(JNIEnvWrapper* env)
+{
+    env->DeleteGlobalRef(g_cls_RCSResourceAttributes);
+}
+
+jobject newAttributesObject(JNIEnv* env, const RCSResourceAttributes& attrs)
+{
+    jobject obj = env->NewObject(g_cls_RCSResourceAttributes, g_ctor_RCSResourceAttributes);
+    VERIFY_NO_EXC_RET_DEF(env);
+
+    setSafeNativeHandle< RCSResourceAttributes >(env, obj, attrs);
+
+    return obj;
+}
+
+jobject newAttributesObject(JNIEnvWrapper* env, const RCSResourceAttributes& attrs)
+{
+    jobject obj = env->NewObject(g_cls_RCSResourceAttributes, g_ctor_RCSResourceAttributes);
+
+    setSafeNativeHandle< RCSResourceAttributes >(env, obj, attrs);
+
+    return obj;
+}
+
+RCSResourceAttributes toNativeAttributes(JNIEnv* env, jobject attrsObj)
+{
+    EXPECT_RET(attrsObj, "attrsObj is null!", { });
+
+    JNIEnvWrapper envWrapper{ env };
+
+    try
+    {
+        return toNativeAttributes(&envWrapper, attrsObj);
+    }
+    catch (const JavaException&)
+    {
+        return {};
+    }
+}
+
+RCSResourceAttributes toNativeAttributes(JNIEnvWrapper* env, jobject attrsObj)
+{
+    EXPECT_RET(attrsObj, "attrsObj is null!", { });
+
+    RCSResourceAttributes attrs;
+
+    /*if (hasNativeHandle(env, attrsObj))
+    {
+        attrs = getNativeHandleAs< RCSResourceAttributes >(env, attrsObj);
+    }*/
+    LOGD("writeNativeAttributesFromMap");
+    writeNativeAttributesFromMap(env,
+            JavaLocalObject{ env, env->GetObjectField(attrsObj, g_field_mCache) }, attrs);
+
+    return attrs;
+}
+
+void writeNativeAttributesFromMap(JNIEnv* env, jobject mapObj, RCSResourceAttributes& targetAttrs)
+{
+    JNIEnvWrapper envWrapper{ env };
+
+    try
+    {
+        return writeNativeAttributesFromMap(&envWrapper, mapObj, targetAttrs);
+    }
+    catch (const JavaException&)
+    {
+    }
+}
+
+void writeNativeAttributesFromMap(JNIEnvWrapper* env, jobject mapObj,
+        RCSResourceAttributes& targetAttrs)
+{
+    LOGD("in write native attributes from map");
+    LOGD("invoke map entry set");
+    JavaLocalObject setObj{ env, invoke_Map_entrySet(env, mapObj) };
+    LOGD("invoke set iterator");
+    JavaLocalObject iterObj{ env, invoke_Set_iterator(env, setObj) };
+    LOGD("invoke has next");
+    while (invoke_Iterator_hasNext(env, iterObj))
+    {
+        LOGD("invoke entry obj next");
+        JavaLocalObject entryObj{ env, invoke_Iterator_next(env, iterObj) };
+        LOGD("invoke key obj next");
+        JavaLocalObject keyObj{ env, invoke_MapEntry_getKey(env, entryObj) };
+        LOGD("invoke value obj next");
+        JavaLocalObject valueObj{ env, invoke_MapEntry_getValue(env, entryObj) };
+        LOGD("invoke toStdString");
+        auto key = toStdString(env, static_cast< jstring >(keyObj.get()));
+        LOGD("invoke toNativeAttrsvalue");
+        targetAttrs[std::move(key)] = toNativeAttrsValue(env, valueObj);
+    }
+    LOGD("in write native attributes from map finished");
+}
+
+JNIEXPORT jboolean JNICALL Java_org_iotivity_service_resourcecontainer_RcsResourceAttributes_nativeIsEmpty
+(JNIEnv* env, jobject obj)
+{
+    LOGD("isEmpty");
+    EXPECT_RET(hasNativeHandle(env, obj), "no native handle.", true);
+
+    auto& attrs = getNativeHandleAs< RCSResourceAttributes >(env, obj);
+    VERIFY_NO_EXC_RET_DEF(env);
+
+    return attrs.empty();
+}
+
+JNIEXPORT jint JNICALL Java_org_iotivity_service_resourcecontainer_RcsResourceAttributes_nativeSize
+(JNIEnv* env, jobject obj)
+{
+    LOGD("size");
+    EXPECT_RET(hasNativeHandle(env, obj), "no native handle.", 0);
+
+    auto& attrs = getNativeHandleAs< RCSResourceAttributes >(env, obj);
+    VERIFY_NO_EXC_RET_DEF(env);
+
+    return attrs.size();
+}
+
+JNIEXPORT jboolean JNICALL Java_org_iotivity_service_resourcecontainer_RcsResourceAttributes_nativeRemove
+(JNIEnv* env, jobject obj, jstring keyObj)
+{
+    LOGD("remove");
+    EXPECT_RET_DEF(keyObj, "Key is null.");
+    EXPECT_RET_DEF(hasNativeHandle(env, obj), "no native handle.");
+
+    auto& attrs = getNativeHandleAs< RCSResourceAttributes >(env, obj);
+    VERIFY_NO_EXC_RET_DEF(env);
+    const auto& key = toStdString(env, keyObj);
+    VERIFY_NO_EXC_RET_DEF(env);
+
+    auto ret = attrs.erase(key);
+
+    if (attrs.empty()) releaseNativeHandle(env, obj);
+
+    return ret;
+}
+
+JNIEXPORT void JNICALL
+Java_org_iotivity_service_resourcecontainer_RcsResourceAttributes_nativeClear
+(JNIEnv* env, jobject obj)
+{
+    LOGD("clear");
+
+    releaseNativeHandle(env, obj);
+}
+
+JNIEXPORT jboolean JNICALL Java_org_iotivity_service_resourcecontainer_RcsResourceAttributes_nativeContains
+(JNIEnv *env, jobject obj, jstring keyObj)
+{
+    LOGD("contains");
+    EXPECT_RET(keyObj, "Key is null.", false);
+    EXPECT_RET(hasNativeHandle(env, obj), "no native handle.", false);
+
+    auto& attrs = getNativeHandleAs< RCSResourceAttributes >(env, obj);
+    VERIFY_NO_EXC_RET_DEF(env);
+    const auto& key = toStdString(env, keyObj);
+    VERIFY_NO_EXC_RET_DEF(env);
+    return attrs.contains(key);
+}
+
+JNIEXPORT void JNICALL Java_org_iotivity_service_resourcecontainer_RcsResourceAttributes_nativeAddKeys
+(JNIEnv *env, jobject obj, jstring setObj)
+{
+    LOGD("addKeys");
+    EXPECT(setObj, "set is null.");
+    EXPECT(hasNativeHandle(env, obj), "no native handle.");
+
+    auto& attrs = getNativeHandleAs< RCSResourceAttributes >(env, obj);
+    VERIFY_NO_EXC(env);
+
+    for (const auto& keyValue : attrs)
+    {
+        JavaLocalString localObj{ env, env->NewStringUTF(keyValue.key().c_str()) };
+        VERIFY_NO_EXC(env);
+
+        invoke_Collection_add(env, setObj, localObj);
+        VERIFY_NO_EXC(env);
+    }
+}
+
+JNIEXPORT jobject JNICALL Java_org_iotivity_service_resourcecontainer_RcsResourceAttributes_nativeExtract
+(JNIEnv* env, jobject obj, jstring keyObj)
+{
+    LOGD("extract");
+    EXPECT_RET_DEF(keyObj, "Key is null.");
+    EXPECT_RET_DEF(hasNativeHandle(env, obj), "no native handle.");
+
+    auto& attrs = getNativeHandleAs< RCSResourceAttributes >(env, obj);
+    VERIFY_NO_EXC_RET_DEF(env);
+
+    const auto& key = toStdString(env, keyObj);
+    VERIFY_NO_EXC_RET_DEF(env);
+
+    EXPECT_RET_DEF(attrs.contains(key), "no matched value");
+
+    jobject valueObj = newRCSValueObject(env, attrs[key]);
+    VERIFY_NO_EXC_RET_DEF(env);
+
+    attrs.erase(key);
+    if (attrs.empty()) releaseNativeHandle(env, obj);
+    return valueObj;
+}
+
+JNIEXPORT void JNICALL
+Java_org_iotivity_service_resourcecontainer_RcsResourceAttributes_nativeExtractAll
+(JNIEnv* env, jobject obj, jobject mapObj)
+{
+    LOGD("extractAll");
+    EXPECT(mapObj, "Map is null.");
+    EXPECT(hasNativeHandle(env, obj), "no native handle.");
+
+    auto& attrs = getNativeHandleAs< RCSResourceAttributes >(env, obj);
+    VERIFY_NO_EXC(env);
+
+    for (const auto& p : attrs) {
+        JavaLocalObject keyObj{ env, newStringObject(env, p.key()) };
+        VERIFY_NO_EXC(env);
+
+        JavaLocalObject valueObj{ env, newRCSValueObject(env, p.value()) };
+        VERIFY_NO_EXC(env);
+
+        invoke_Map_put(env, mapObj, keyObj, valueObj);
+        VERIFY_NO_EXC(env);
+    }
+
+    attrs.clear();
+    releaseNativeHandle(env, obj);
+}
+
diff --git a/service/resource-container/android/resource-container/src/main/jni/JniRcsResourceAttributes.h b/service/resource-container/android/resource-container/src/main/jni/JniRcsResourceAttributes.h
new file mode 100644 (file)
index 0000000..cd5b70b
--- /dev/null
@@ -0,0 +1,82 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics 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.
+ *
+ ******************************************************************/
+
+#ifndef JNI_RCS_RESOURCE_ATTRIBUTES_H_
+#define JNI_RCS_RESOURCE_ATTRIBUTES_H_
+
+#include <jni.h>
+
+namespace OIC
+{
+    namespace Service
+    {
+        class RCSResourceAttributes;
+    }
+}
+
+class JNIEnvWrapper;
+
+void initRCSResourceAttributes(JNIEnvWrapper*);
+void clearRCSResourceAttributes(JNIEnvWrapper*);
+
+jobject newAttributesObject(JNIEnv*, const OIC::Service::RCSResourceAttributes&);
+jobject newAttributesObject(JNIEnvWrapper*, const OIC::Service::RCSResourceAttributes&);
+
+OIC::Service::RCSResourceAttributes toNativeAttributes(JNIEnv*, jobject);
+OIC::Service::RCSResourceAttributes toNativeAttributes(JNIEnvWrapper*, jobject);
+
+void writeNativeAttributesFromMap(JNIEnv*, jobject mapObj,
+        OIC::Service::RCSResourceAttributes& targetAttrs);
+void writeNativeAttributesFromMap(JNIEnvWrapper*, jobject mapObj,
+        OIC::Service::RCSResourceAttributes& targetAttrs);
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+JNIEXPORT jboolean JNICALL
+Java_org_iotivity_service_resourcecontainer_RcsResourceAttributes_nativeIsEmpty(JNIEnv*, jobject);
+
+JNIEXPORT jint JNICALL
+Java_org_iotivity_service_resourcecontainer_RcsResourceAttributes_nativeSize(JNIEnv*, jobject);
+
+JNIEXPORT jboolean JNICALL
+Java_org_iotivity_service_resourcecontainer_RcsResourceAttributes_nativeRemove(JNIEnv*, jobject, jstring keyObj);
+
+JNIEXPORT void JNICALL
+Java_org_iotivity_service_resourcecontainer_RcsResourceAttributes_nativeClear(JNIEnv*, jobject);
+
+JNIEXPORT jboolean JNICALL
+Java_org_iotivity_service_resourcecontainer_RcsResourceAttributes_nativeContains(JNIEnv*, jobject, jstring keyObj);
+
+JNIEXPORT void JNICALL
+Java_org_iotivity_service_resourcecontainer_RcsResourceAttributes_nativeAddKeys(JNIEnv*, jobject, jstring setObj);
+
+JNIEXPORT jobject JNICALL
+Java_org_iotivity_service_resourcecontainer_RcsResourceAttributes_nativeExtract(JNIEnv*, jobject, jstring keyObj);
+
+JNIEXPORT void JNICALL
+Java_org_iotivity_service_resourcecontainer_RcsResourceAttributes_nativeExtractAll(JNIEnv*, jobject, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif  //JNI_RCS_RESOURCE_ATTRIBUTES_H_
index e23662a..4a9b183 100644 (file)
 #include "Log.h"
 #include "Verify.h"
 
+#include "ResourceContainerBundleAPI.h"
+#include "AndroidResource.h"
 #include "RCSResourceContainer.h"
 
+
+
 #define LOG_TAG "JNI-RCSResourceContainer"
 
 using namespace OIC::Service;
 
 #define CLS_NAME_BUNDLE_INFO "org/iotivity/service/resourcecontainer/RcsBundleInfo"
 
+std::map< string, BundleResource::Ptr > android_resources;
+
 namespace
 {
     jclass g_cls_RCSBundleInfo;
@@ -68,6 +74,8 @@ namespace
 
     jobject newBundleInfoObj(JNIEnvWrapper *env, const std::unique_ptr< RCSBundleInfo > &bundleInfo)
     {
+        LOGD("new bundle info");
+        __android_log_print(ANDROID_LOG_DEBUG, "CONTAINER", "newBundleInfoObj %s",bundleInfo->getActivatorName().c_str());
         JavaLocalString id{env, newStringObject(env, bundleInfo->getID()) };
         JavaLocalString path{env, newStringObject(env, bundleInfo->getPath()) };
         JavaLocalString activatorName{env, newStringObject(env, bundleInfo->getActivatorName()) };
@@ -195,7 +203,7 @@ JNIEXPORT void JNICALL
 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeStartBundle
 (JNIEnv *env, jobject, jstring idObj)
 {
-    LOGD("nativeStartBundle");
+    LOGD("nativeStartBundle2");
 
     EXPECT(idObj, "BundleId is null.");
 
@@ -292,3 +300,99 @@ Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeListBundl
     return nullptr;
 }
 
+
+JNIEXPORT void JNICALL
+Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeRegisterAndroidResource
+(JNIEnv *env, jobject obj, jobject bundleResource, jobjectArray attributes, jstring bundleId,
+ jstring uri, jstring resourceType, jstring res_name)
+{
+    LOGD("nativeRegisterAndroidResource");
+    const char *str_bundleId = env->GetStringUTFChars(bundleId, 0);
+    LOGD("retrieved bundle id.");
+    const char *str_uri = env->GetStringUTFChars(uri, 0);
+    LOGD("retrieved uri.");
+    const char *str_resourceType = env->GetStringUTFChars(resourceType, 0);
+    LOGD("retrieved resource type");
+    const char *str_res_name = env->GetStringUTFChars(res_name, 0);
+    LOGD("retrieved res name.");
+    AndroidResource res;
+
+    BundleResource::Ptr androidResource = std::make_shared< AndroidResource >
+            (env, obj, bundleResource, str_bundleId, attributes);
+    ResourceContainerImpl *container = ResourceContainerImpl::getImplInstance();
+
+    androidResource->m_uri = string(str_uri, strlen(str_uri));
+    androidResource->m_resourceType = string(str_resourceType, strlen(str_resourceType));
+    androidResource->m_name = string(str_res_name, strlen(str_res_name));
+    container->registerResource(androidResource);
+
+    android_resources[str_uri] = androidResource;
+}
+
+/*
+ * Class:     org_iotivity_resourcecontainer_bundle_api_BaseActivator
+ * Method:    unregisterJavaResource
+ * Signature: (Lorg/iotivity/resourcecontainer/bundle/api/BundleResource;)V
+ */
+JNIEXPORT void JNICALL
+Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeUnregisterAndroidResource
+(JNIEnv *env, jobject obj, jobject bundleResource, jstring uri)
+{
+    (void)obj;
+    (void)bundleResource;
+    const char *str_uri = env->GetStringUTFChars(uri, 0);
+
+    if (android_resources[str_uri] != NULL)
+    {
+        ResourceContainerImpl *container = ResourceContainerImpl::getImplInstance();
+        container->unregisterResource(android_resources[str_uri]);
+        android_resources.erase(str_uri);
+    }
+}
+
+/*
+ * Class:     org_iotivity_resourcecontainer_bundle_api_BaseActivator
+ * Method:    getNumberOfConfiguredResources
+ * Signature: (Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL
+Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeGetNumberOfConfiguredResources(
+    JNIEnv *env, jobject obj, jstring bundleId)
+{
+    (void)obj;
+    const char *str_bundleId = env->GetStringUTFChars(bundleId, 0);
+
+    ResourceContainerImpl *container = ResourceContainerImpl::getImplInstance();
+    vector< resourceInfo > resourceConfig;
+    container->getResourceConfiguration(str_bundleId, &resourceConfig);
+
+    return resourceConfig.size();
+}
+
+/*
+ * Class:     org_iotivity_resourcecontainer_bundle_api_BaseActivator
+ * Method:    getConfiguredResourceParams
+ * Signature: (Ljava/lang/String;I)[Ljava/lang/String;
+ */
+JNIEXPORT jobjectArray JNICALL
+Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeGetConfiguredResourceParams(
+    JNIEnv *env, jobject obj, jstring bundleId, jint resourceId)
+{
+    (void)obj;
+    jobjectArray ret;
+    const char *str_bundleId = env->GetStringUTFChars(bundleId, 0);
+
+    ResourceContainerImpl *container = ResourceContainerImpl::getImplInstance();
+    vector< resourceInfo > resourceConfig;
+    container->getResourceConfiguration(str_bundleId, &resourceConfig);
+    resourceInfo conf = resourceConfig[resourceId];
+    ret = (jobjectArray) env->NewObjectArray(4, env->FindClass("java/lang/String"),
+            env->NewStringUTF(""));
+
+    env->SetObjectArrayElement(ret, 0, env->NewStringUTF(conf.name.c_str()));
+    env->SetObjectArrayElement(ret, 1, env->NewStringUTF(conf.uri.c_str()));
+    env->SetObjectArrayElement(ret, 2, env->NewStringUTF(conf.resourceType.c_str()));
+    env->SetObjectArrayElement(ret, 3, env->NewStringUTF(conf.address.c_str()));
+    return ret;
+}
+
index 2474b7e..aac1fc5 100644 (file)
@@ -79,6 +79,20 @@ JNIEXPORT jobject JNICALL
 Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeListBundleResources
 (JNIEnv *, jobject, jstring bundleId);
 
+JNIEXPORT void JNICALL Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeRegisterAndroidResource
+  (JNIEnv *, jobject, jobject, jobjectArray, jstring, jstring, jstring, jstring);
+
+JNIEXPORT void JNICALL Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeUnregisterAndroidResource
+  (JNIEnv *, jobject, jstring, jobject, jstring);
+
+JNIEXPORT jint JNICALL Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeGetNumberOfConfiguredResources
+  (JNIEnv *, jobject,  jstring);
+
+JNIEXPORT jobjectArray JNICALL Java_org_iotivity_service_resourcecontainer_RcsResourceContainer_nativeBaseActivator_getConfiguredResourceParams
+  (JNIEnv *, jobject, jstring, jint);
+
+
+
 #ifdef __cplusplus
 }
 #endif
diff --git a/service/resource-container/android/resource-container/src/main/jni/JniRcsValue.cpp b/service/resource-container/android/resource-container/src/main/jni/JniRcsValue.cpp
new file mode 100644 (file)
index 0000000..77527c7
--- /dev/null
@@ -0,0 +1,572 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics 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.
+ *
+ ******************************************************************/
+
+#include "JniRcsValue.h"
+
+#include "JniRcsObject.h"
+#include "JniRcsResourceAttributes.h"
+#include "JavaClasses.h"
+#include "JavaExceptions.h"
+#include "JavaLocalRef.h"
+#include "Log.h"
+
+using namespace OIC::Service;
+
+#define LOG_TAG "JNI-RCSValue"
+
+#define CLS_NAME_VALUE_TYPE CLS_NAME_VALUE "$Type"
+#define CLS_NAME_VALUE_TYPEID CLS_NAME_VALUE "$TypeId"
+#define CLS_NAME_VALUE_NULL_TYPE CLS_NAME_VALUE "$NullType"
+
+namespace
+{
+    jclass g_cls_RCSValue;
+    jclass g_cls_Type;
+    jclass g_cls_TypeId;
+
+    jmethodID g_ctor_RCSValue;
+
+    jmethodID g_smethod_Type_getDepth;
+    jmethodID g_smethod_Type_getBaseTypeId;
+
+    jmethodID g_method_RCSValue_getType;
+
+    jfieldID g_field_RCSValue_mObject;
+    jfieldID g_field_RCSValue_sNullValue;
+
+    jobject g_obj_TypeId_Null;
+    jobject g_obj_TypeId_Boolean;
+    jobject g_obj_TypeId_Integer;
+    jobject g_obj_TypeId_Double;
+    jobject g_obj_TypeId_String;
+    jobject g_obj_TypeId_Attributes;
+    jobject g_obj_TypeId_Array;
+
+    template< int >
+    struct Int2Type{ };
+
+    template< int DEPTH, typename BASE_TYPE >
+    struct SeqType
+    {
+        typedef std::vector< typename SeqType< DEPTH - 1, BASE_TYPE >::type > type;
+    };
+
+    template< typename BASE_TYPE >
+    struct SeqType< 0, BASE_TYPE >
+    {
+        typedef BASE_TYPE type;
+    };
+
+    template< typename T >
+    struct BaseType
+    {
+      typedef T type;
+    };
+
+    template< typename T >
+    struct BaseType< std::vector< T > >
+    {
+      typedef typename BaseType< T >::type type;
+    };
+
+
+    template< int D >
+    struct ArrayPrefix
+    {
+        static constexpr char str[] = "";
+    };
+    template< int D >
+    constexpr char ArrayPrefix< D >::str[];
+
+    template<>
+    struct ArrayPrefix< 1 >
+    {
+        static constexpr char str[] = "[";
+    };
+    constexpr char ArrayPrefix< 1 >::str[];
+
+    template<>
+    struct ArrayPrefix< 2 >
+    {
+        static constexpr char str[] = "[[";
+    };
+    constexpr char ArrayPrefix< 2 >::str[];
+
+    struct PrimitiveType {
+        static constexpr bool isPrimitive = true;
+    };
+
+    struct ObjectType {
+        static constexpr bool isPrimitive = false;
+    };
+
+    template< typename T >
+    struct JniTypeTrait;
+
+    template<>
+    struct JniTypeTrait< int >: public PrimitiveType
+    {
+        static_assert(sizeof(int) == sizeof(jint), "int and jint have different size!");
+
+        static constexpr decltype(&JNIEnvWrapper::NewIntArray) newArrayFunc =
+                &JNIEnvWrapper::NewIntArray;
+        static constexpr decltype(&JNIEnvWrapper::SetIntArrayRegion) setArrayRegionFunc =
+                      &JNIEnvWrapper::SetIntArrayRegion;
+
+        static constexpr decltype(&invoke_Integer_intValue<JNIEnvWrapper>) converter =
+                      &invoke_Integer_intValue<JNIEnvWrapper>;
+
+        static constexpr decltype(&newIntegerObject<JNIEnvWrapper>) newObjectFunc =
+                &newIntegerObject<JNIEnvWrapper>;
+
+        static constexpr char className[] = "I";
+    };
+    constexpr char JniTypeTrait< int >::className[];
+
+    template<>
+    struct JniTypeTrait< bool >: public PrimitiveType
+    {
+        static_assert(sizeof(bool) == sizeof(jboolean), "bool and jboolean have different size!");
+
+        static constexpr decltype(&JNIEnvWrapper::NewBooleanArray) newArrayFunc =
+                &JNIEnvWrapper::NewBooleanArray;
+        static constexpr decltype(&JNIEnvWrapper::SetBooleanArrayRegion) setArrayRegionFunc =
+                      &JNIEnvWrapper::SetBooleanArrayRegion;
+
+        static constexpr decltype(&invoke_Boolean_booleanValue<JNIEnvWrapper>) converter =
+                      &invoke_Boolean_booleanValue<JNIEnvWrapper>;
+
+        static constexpr decltype(&newBooleanObject<JNIEnvWrapper>) newObjectFunc =
+                &newBooleanObject<JNIEnvWrapper>;
+
+        static constexpr char className[] = "Z";
+    };
+    constexpr char JniTypeTrait< bool >::className[];
+
+    template<>
+    struct JniTypeTrait< double > : public PrimitiveType
+    {
+        static_assert(sizeof(double) == sizeof(jdouble), "double and jdouble have different size!");
+
+        static constexpr decltype(&JNIEnvWrapper::NewDoubleArray) newArrayFunc =
+                &JNIEnvWrapper::NewDoubleArray;
+        static constexpr decltype(&JNIEnvWrapper::SetDoubleArrayRegion) setArrayRegionFunc =
+                      &JNIEnvWrapper::SetDoubleArrayRegion;
+
+        static constexpr decltype(&invoke_Double_doubleValue<JNIEnvWrapper>) converter =
+                      &invoke_Double_doubleValue<JNIEnvWrapper>;
+
+        static constexpr decltype(&newDoubleObject<JNIEnvWrapper>) newObjectFunc =
+                &newDoubleObject<JNIEnvWrapper>;
+
+        static constexpr char className[] = "D";
+    };
+    constexpr char JniTypeTrait< double >::className[];
+
+    template<>
+    struct JniTypeTrait< std::string >: public ObjectType
+    {
+        static constexpr decltype(&newStringObject<JNIEnvWrapper>) newObjectFunc =
+                &newStringObject<JNIEnvWrapper>;
+
+        static constexpr char className[] = "L" CLS_NAME_STRING ";";
+    };
+    constexpr char JniTypeTrait< std::string >::className[];
+
+    template<>
+    struct JniTypeTrait< RCSResourceAttributes >: public ObjectType
+    {
+        inline static jobject newObjectFunc(JNIEnvWrapper* env, const RCSResourceAttributes& value)
+        {
+            return newAttributesObject(env, value);
+        }
+
+        inline static RCSResourceAttributes converter(JNIEnvWrapper* env, jobject obj)
+        {
+            return toNativeAttributes(env, obj);
+        }
+
+        static constexpr char className[] = "L" CLS_NAME_RESOURCEATTRIBUTES ";";
+    };
+    constexpr char JniTypeTrait< RCSResourceAttributes >::className[];
+
+    inline void toNativeValue(JNIEnvWrapper* env, jobject obj, std::string& result, Int2Type< 0 >)
+    {
+        result = toStdString(env, static_cast< jstring >(obj));
+    }
+
+    template< typename T >
+    inline void toNativeValue(JNIEnvWrapper* env, jobject obj, T& result, Int2Type< 0 >)
+    {
+        result = JniTypeTrait< T >::converter(env, obj);
+    }
+
+    template< int DEPTH, typename RET >
+    inline void toNativeValue(JNIEnvWrapper* env, jobject obj, RET& result, Int2Type< DEPTH >)
+    {
+        const auto arrayObj = static_cast< jobjectArray >(obj);
+        result.resize(env->GetArrayLength(arrayObj));
+
+        for (typename RET::size_type i = 0; i < result.size(); ++i)
+        {
+            JavaLocalObject elementObj{ env, env->GetObjectArrayElement(arrayObj, i) };
+
+            toNativeValue(env, elementObj, result[i], Int2Type< DEPTH - 1 >{ });
+        }
+    }
+
+    template< typename T >
+    inline typename std::enable_if< JniTypeTrait< T >::isPrimitive >::type
+    toNativeValue(JNIEnvWrapper* env, jobject obj, std::vector< T >& result, Int2Type< 1 >)
+    {
+        const auto arrayObj = static_cast< jobjectArray >(obj);
+        const jsize arraySize = env->GetArrayLength(arrayObj);
+
+        T* raw = static_cast< T* >(env->GetPrimitiveArrayCritical(arrayObj, nullptr));
+
+        try
+        {
+            result = std::vector< T >(raw, raw + arraySize);
+        } catch (...)
+        {
+        }
+
+        env->ReleasePrimitiveArrayCritical(arrayObj, raw, JNI_ABORT);
+    }
+
+    template< typename T >
+    inline typename std::enable_if< !JniTypeTrait< T >::isPrimitive >::type
+    toNativeValue(JNIEnvWrapper* env, jobject obj, std::vector< T >& result, Int2Type< 1 >)
+    {
+        const auto arrayObj = static_cast< jobjectArray >(obj);
+        const jsize arraySize = env->GetArrayLength(arrayObj);
+
+        result.resize(arraySize);
+
+        for (typename std::vector< T >::size_type i = 0; i < result.size(); ++i)
+        {
+            JavaLocalObject elementObj{ env,  env->GetObjectArrayElement(arrayObj, i) };
+            toNativeValue(env, elementObj, result[i], Int2Type< 0 >{ });
+        }
+    }
+
+
+    template< typename T, int DEPTH, typename RET = typename SeqType< DEPTH, T >::type >
+    inline RET toNativeValue(JNIEnvWrapper* env, jobject obj)
+    {
+        static_assert(DEPTH >= 0, "DEPTH must be positive!");
+
+        typename SeqType< DEPTH, T >::type result;
+
+        toNativeValue(env, obj, result, Int2Type< DEPTH >{ });
+
+        return result;
+    }
+
+    template< typename T >
+    inline RCSResourceAttributes::Value toNativeValue(JNIEnvWrapper* env, jobject val, int depth)
+    {
+        switch (depth)
+        {
+            case 0: return toNativeValue< T, 0 >(env, val);
+            case 1: return toNativeValue< T, 1 >(env, val);
+            case 2: return toNativeValue< T, 2 >(env, val);
+            case 3: return toNativeValue< T, 3 >(env, val);
+        }
+
+        return {};
+    }
+
+    inline RCSResourceAttributes::Value toNativeValue(JNIEnvWrapper* env, jobject val, int depth,
+            RCSResourceAttributes::TypeId typeId)
+    {
+        LOGD("toNativeValue depth is %d", depth);
+        EXPECT_RET(depth >= 0 && depth <= 3, "Unsupported depth!", {});
+
+        switch (typeId)
+         {
+             case RCSResourceAttributes::TypeId::NULL_T: return { };
+
+             case RCSResourceAttributes::TypeId::BOOL:
+                 return toNativeValue< bool >(env, val, depth);
+
+             case RCSResourceAttributes::TypeId::INT:
+                 return toNativeValue< int >(env, val, depth);
+
+             case RCSResourceAttributes::TypeId::DOUBLE:
+                 return toNativeValue< double >(env, val, depth);
+
+             case RCSResourceAttributes::TypeId::STRING:
+                 return toNativeValue< std::string >(env, val, depth);
+
+             case RCSResourceAttributes::TypeId::ATTRIBUTES:
+                 return toNativeValue< RCSResourceAttributes >(env, val, depth);
+         }
+
+        throwRCSException(env, "Failed to convert RCSValue : unknown type id");
+        return {};
+    }
+
+    template< typename T, int DEPTH, typename BASE_TYPE = typename BaseType< T >::type >
+    inline jobject createJavaObject(JNIEnvWrapper* env, const T& value, Int2Type< DEPTH >)
+    {
+        const std::string elementClsName{ std::string{ ArrayPrefix< DEPTH - 1 >::str }
+            + JniTypeTrait< BASE_TYPE >::className };
+
+        LOGD("create array %dd, %s", DEPTH, elementClsName.c_str());
+
+        auto cls = env->FindClass(elementClsName.c_str());
+
+        const jsize len = value.size();
+
+        auto array = env->NewObjectArray(len, cls, nullptr);
+
+        for(jsize i = 0; i < len; ++i)
+        {
+            auto element = createJavaObject(env, value[i], Int2Type< DEPTH - 1>{ });
+            env->SetObjectArrayElement(array, i, element);
+        }
+
+        return array;
+    }
+
+    template< typename T, typename TRAIT = JniTypeTrait< T > >
+    inline typename std::enable_if< TRAIT::isPrimitive, jobject >::type
+    createJavaObject(JNIEnvWrapper* env, const std::vector< T >& value, Int2Type< 1 >)
+    {
+        LOGD("create array with newArray");
+        const jsize len = value.size();
+
+        auto array = (env->*TRAIT::newArrayFunc)(len);
+
+        if (!value.empty()) (env->*TRAIT::setArrayRegionFunc)(array, 0, len, &value[0]);
+
+        return array;
+    }
+
+    inline jobject createJavaObject(JNIEnvWrapper* env, const std::vector< bool >& value, Int2Type< 1 >)
+    {
+        const auto len = value.size();
+        LOGD("create bool array with newArray %d", len);
+
+        auto arrayObj = env->NewBooleanArray(len);
+
+        bool* raw = static_cast< bool* >(env->GetPrimitiveArrayCritical(arrayObj, 0));
+
+        std::copy(value.begin(), value.end(), raw);
+
+        env->ReleasePrimitiveArrayCritical(arrayObj, raw, 0);
+
+        return arrayObj;
+    }
+
+    template< typename T, typename TRAIT = JniTypeTrait< T > >
+    inline jobject createJavaObject(JNIEnvWrapper* env, const T& value, Int2Type< 0 >)
+    {
+        LOGD("createJavaObject 0-depth");
+        return TRAIT::newObjectFunc(env, value);
+    }
+
+    template< int DEPTH >
+    inline jobject createJavaObject(JNIEnvWrapper* env, const RCSResourceAttributes::Value& value)
+    {
+        const auto type = value.getType();
+        const auto baseType = RCSResourceAttributes::Type::getBaseTypeId(type);
+
+        LOGD("createJavaObject with DEPTH. type is %d", static_cast< int >(baseType));
+
+        switch (baseType)
+        {
+            case RCSResourceAttributes::TypeId::NULL_T:
+                return env->GetStaticObjectField(g_cls_RCSValue, g_field_RCSValue_sNullValue);
+
+            case RCSResourceAttributes::TypeId::BOOL:
+                return createJavaObject(env, value.get< typename SeqType< DEPTH, bool >::type >(),
+                        Int2Type< DEPTH >{ });
+
+            case RCSResourceAttributes::TypeId::INT:
+                return createJavaObject(env, value.get< typename SeqType< DEPTH, int >::type >(),
+                        Int2Type< DEPTH >{ });
+
+            case RCSResourceAttributes::TypeId::DOUBLE:
+                return createJavaObject(env, value.get< typename SeqType< DEPTH, double >::type >(),
+                        Int2Type< DEPTH >{ });
+
+            case RCSResourceAttributes::TypeId::STRING:
+                return createJavaObject(env,
+                        value.get< typename SeqType< DEPTH, std::string >::type >(),
+                        Int2Type< DEPTH >{ });
+
+            case RCSResourceAttributes::TypeId::ATTRIBUTES:
+                return createJavaObject(env,
+                        value.get< typename SeqType< DEPTH, RCSResourceAttributes >::type >(),
+                        Int2Type< DEPTH >{ });
+        }
+
+        LOGE("Unknown type!");
+
+        return nullptr;
+    }
+
+    inline jobject createJavaObject(JNIEnvWrapper* env, const RCSResourceAttributes::Value& value)
+    {
+        const auto type = value.getType();
+        const auto depth = RCSResourceAttributes::Type::getDepth(type);
+
+        EXPECT_RET(depth >= 0 && depth <= 3, "Unsupported depth!", {});
+
+        switch (depth)
+        {
+            case 0: return createJavaObject< 0 >(env, value);
+            case 1: return createJavaObject< 1 >(env, value);
+            case 2: return createJavaObject< 2 >(env, value);
+            case 3: return createJavaObject< 3 >(env, value);
+        }
+
+        return nullptr;
+    }
+
+    inline RCSResourceAttributes::TypeId toNativeTypeId(JNIEnvWrapper* env, jobject typeIdObj)
+    {
+        typedef RCSResourceAttributes::TypeId TypeId;
+
+        if (env->IsSameObject(g_obj_TypeId_Null, typeIdObj)) return TypeId::NULL_T;
+        if (env->IsSameObject(g_obj_TypeId_Boolean, typeIdObj)) return TypeId::BOOL;
+        if (env->IsSameObject(g_obj_TypeId_Integer, typeIdObj)) return TypeId::INT;
+        if (env->IsSameObject(g_obj_TypeId_Double, typeIdObj)) return TypeId::DOUBLE;
+        if (env->IsSameObject(g_obj_TypeId_String, typeIdObj)) return TypeId::STRING;
+        if (env->IsSameObject(g_obj_TypeId_Attributes, typeIdObj)) return TypeId::ATTRIBUTES;
+        if (env->IsSameObject(g_obj_TypeId_Array, typeIdObj)) return TypeId::VECTOR;
+
+        throwRCSException(env, "Failed to convert RCSValue : unknown type id");
+        return TypeId::NULL_T;
+    }
+
+    jobject getTypeIdObj(JNIEnvWrapper* env, const char* name)
+    {
+        return env->NewGlobalRef(
+                env->GetStaticObjectField(g_cls_TypeId, name, AS_SIG(CLS_NAME_VALUE_TYPEID)));
+    }
+}
+
+void initRCSValue(JNIEnvWrapper* env)
+{
+    g_cls_RCSValue = env->FindClassAsGlobalRef(CLS_NAME_VALUE);
+    g_ctor_RCSValue = env->GetConstructorID(g_cls_RCSValue, "(" AS_SIG(CLS_NAME_OBJECT) ")V");
+
+    g_method_RCSValue_getType = env->GetMethodID(g_cls_RCSValue, "getType",
+            "()" AS_SIG(CLS_NAME_VALUE_TYPE));
+
+    g_field_RCSValue_mObject = env->GetFieldID(g_cls_RCSValue, "mObject", AS_SIG(CLS_NAME_OBJECT));
+
+    g_field_RCSValue_sNullValue = env->GetStaticFieldID(g_cls_RCSValue, "sNullValue",
+            AS_SIG(CLS_NAME_VALUE_NULL_TYPE));
+
+    g_cls_Type = env->FindClassAsGlobalRef(CLS_NAME_VALUE_TYPE);
+
+    g_smethod_Type_getBaseTypeId = env->GetStaticMethodID(g_cls_Type, "getBaseTypeId",
+            "(" AS_SIG(CLS_NAME_VALUE_TYPE) ")" AS_SIG(CLS_NAME_VALUE_TYPEID));
+
+    g_smethod_Type_getDepth = env->GetStaticMethodID(g_cls_Type, "getDepth",
+                "(" AS_SIG(CLS_NAME_VALUE_TYPE) ")I");
+
+    g_cls_TypeId = env->FindClassAsGlobalRef(CLS_NAME_VALUE_TYPEID);
+
+    g_obj_TypeId_Null = getTypeIdObj(env, "NULL");
+    g_obj_TypeId_Boolean = getTypeIdObj(env, "BOOLEAN");
+    g_obj_TypeId_Integer = getTypeIdObj(env, "INTEGER");
+    g_obj_TypeId_Double = getTypeIdObj(env, "DOUBLE");
+    g_obj_TypeId_String = getTypeIdObj(env, "STRING");
+    g_obj_TypeId_Attributes = getTypeIdObj(env, "ATTRIBUTES");
+    g_obj_TypeId_Array = getTypeIdObj(env, "ARRAY");
+}
+
+void clearRCSValue(JNIEnvWrapper* env)
+{
+    env->DeleteGlobalRef(g_cls_RCSValue);
+    env->DeleteGlobalRef(g_cls_Type);
+    env->DeleteGlobalRef(g_cls_TypeId);
+
+    env->DeleteGlobalRef(g_obj_TypeId_Null);
+    env->DeleteGlobalRef(g_obj_TypeId_Boolean);
+    env->DeleteGlobalRef(g_obj_TypeId_Integer);
+    env->DeleteGlobalRef(g_obj_TypeId_Double);
+    env->DeleteGlobalRef(g_obj_TypeId_String);
+    env->DeleteGlobalRef(g_obj_TypeId_Attributes);
+    env->DeleteGlobalRef(g_obj_TypeId_Array);
+}
+
+RCSResourceAttributes::Value toNativeAttrsValue(JNIEnv* env, jobject valueObj)
+{
+    JNIEnvWrapper envWrapper(env);
+
+    try
+    {
+        return toNativeAttrsValue(&envWrapper, valueObj);
+    }
+    catch (const JavaException&)
+    {
+        return { };
+    }
+}
+
+RCSResourceAttributes::Value toNativeAttrsValue(JNIEnvWrapper* env, jobject valueObj)
+{
+    LOGD("Type object");
+    auto typeObj = env->CallObjectMethod(valueObj, g_method_RCSValue_getType);
+    LOGD("Type base type object");
+    auto typeIdObj = env->CallStaticObjectMethod(g_cls_Type, g_smethod_Type_getBaseTypeId, typeObj);
+    LOGD("Type getDepth");
+    auto depth = env->CallStaticIntMethod(g_cls_Type, g_smethod_Type_getDepth, typeObj);
+    LOGD("Type get object field");
+    auto memObj = env->GetObjectField(valueObj, g_field_RCSValue_mObject);
+
+    LOGD("Type to native value");
+    auto ret = toNativeValue(env, memObj, depth, toNativeTypeId(env, typeIdObj));
+
+    if (env->get()->ExceptionCheck()) throw JavaException();
+
+    return ret;
+}
+
+jobject newRCSValueObject(JNIEnv* env, const RCSResourceAttributes::Value& value)
+{
+    JNIEnvWrapper envWrapper(env);
+
+    try
+    {
+        return newRCSValueObject(&envWrapper, value);
+    }
+    catch (const JavaException&)
+    {
+        return {};
+    }
+}
+
+jobject newRCSValueObject(JNIEnvWrapper* env, const RCSResourceAttributes::Value& value)
+{
+    LOGD("newRCSValueObject");
+
+    JavaLocalObject valueObj{ env, createJavaObject(env, value) };
+
+    if (env->get()->ExceptionCheck()) throw JavaException();
+
+    return env->NewObject(g_cls_RCSValue, g_ctor_RCSValue, valueObj.get());
+}
diff --git a/service/resource-container/android/resource-container/src/main/jni/JniRcsValue.h b/service/resource-container/android/resource-container/src/main/jni/JniRcsValue.h
new file mode 100644 (file)
index 0000000..c27c23f
--- /dev/null
@@ -0,0 +1,39 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics 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.
+ *
+ ******************************************************************/
+
+#ifndef JNI_RCS_VALUE_H_
+#define JNI_RCS_VALUE_H_
+
+#include <jni.h>
+
+#include "RCSResourceAttributes.h"
+
+class JNIEnvWrapper;
+
+void initRCSValue(JNIEnvWrapper*);
+void clearRCSValue(JNIEnvWrapper*);
+
+OIC::Service::RCSResourceAttributes::Value toNativeAttrsValue(JNIEnv*, jobject);
+OIC::Service::RCSResourceAttributes::Value toNativeAttrsValue(JNIEnvWrapper*, jobject);
+
+jobject newRCSValueObject(JNIEnv*, const OIC::Service::RCSResourceAttributes::Value&);
+jobject newRCSValueObject(JNIEnvWrapper*, const OIC::Service::RCSResourceAttributes::Value&);
+
+#endif // JNI_RCS_VALUE_H_
index e9c88a8..1232d8c 100644 (file)
 
 #include "JNIEnvWrapper.h"
 
+jclass g_cls_String;
+jclass g_cls_Integer;
+jclass g_cls_Double;
+jclass g_cls_Boolean;
+
 jclass g_cls_ArrayList;
 jclass g_cls_Set;
 jclass g_cls_Map;
 jclass g_cls_MapEntry;
 jclass g_cls_Iterator;
 
+jmethodID g_method_Boolean_booleanValue;
+jmethodID g_method_Integer_intValue;
+jmethodID g_method_Double_doubleValue;
+
 jmethodID g_method_Collection_add;
 
 jmethodID g_method_Set_iterator;
@@ -41,13 +50,39 @@ jmethodID g_method_MapEntry_getValue;
 jmethodID g_method_Iterator_hasNext;
 jmethodID g_method_Iterator_next;
 
+jmethodID g_ctor_Boolean;
+jmethodID g_ctor_Integer;
+jmethodID g_ctor_Double;
+
 jmethodID g_ctor_ArrayList;
 
-void initJavaClasses(JNIEnvWrapper *env)
+namespace
 {
+    inline void initPrimitiveTypes(JNIEnvWrapper* env)
+    {
+        g_cls_Boolean = env->FindClassAsGlobalRef(CLS_NAME_BOOLEAN);
+        g_ctor_Boolean = env->GetConstructorID(g_cls_Boolean, "(Z)V");
+        g_method_Boolean_booleanValue = env->GetMethodID(g_cls_Boolean, "booleanValue", "()Z");
+
+        g_cls_Integer = env->FindClassAsGlobalRef(CLS_NAME_INTEGER);
+        g_ctor_Integer = env->GetConstructorID(g_cls_Integer, "(I)V");
+        g_method_Integer_intValue = env->GetMethodID(g_cls_Integer, "intValue", "()I");
+
+        g_cls_Double = env->FindClassAsGlobalRef(CLS_NAME_DOUBLE);
+        g_ctor_Double = env->GetConstructorID(g_cls_Double, "(D)V");
+        g_method_Double_doubleValue = env->GetMethodID(g_cls_Double, "doubleValue", "()D");
+
+        g_cls_String = env->FindClassAsGlobalRef(CLS_NAME_STRING);
+    }
+}
+
+void initJavaClasses(JNIEnvWrapper* env)
+{
+    initPrimitiveTypes(env);
+
     auto clsCollection = env->FindClass(CLS_NAME_COLLECTION);
     g_method_Collection_add = env->GetMethodID(clsCollection, "add",
-                              "(" AS_SIG(CLS_NAME_OBJECT) ")Z");
+            "(" AS_SIG(CLS_NAME_OBJECT) ")Z");
 
     g_cls_ArrayList = env->FindClassAsGlobalRef(CLS_NAME_ARRAY_LIST);
     g_ctor_ArrayList = env->GetConstructorID(g_cls_ArrayList, "()V");
@@ -58,21 +93,25 @@ void initJavaClasses(JNIEnvWrapper *env)
     g_cls_Map = env->FindClassAsGlobalRef(CLS_NAME_MAP);
     g_method_Map_entrySet = env->GetMethodID(g_cls_Map, "entrySet", "()" AS_SIG(CLS_NAME_SET));
     g_method_Map_put = env->GetMethodID(g_cls_Map, "put",
-                                        "(" AS_SIG(CLS_NAME_OBJECT) AS_SIG(CLS_NAME_OBJECT) ")" AS_SIG(CLS_NAME_OBJECT));
+            "(" AS_SIG(CLS_NAME_OBJECT) AS_SIG(CLS_NAME_OBJECT) ")" AS_SIG(CLS_NAME_OBJECT));
 
     g_cls_MapEntry = env->FindClassAsGlobalRef(CLS_NAME_MAP_ENTRY);
     g_method_MapEntry_getKey = env->GetMethodID(g_cls_MapEntry, "getKey",
-                               "()" AS_SIG(CLS_NAME_OBJECT));
+            "()" AS_SIG(CLS_NAME_OBJECT));
     g_method_MapEntry_getValue = env->GetMethodID(g_cls_MapEntry, "getValue",
-                                 "()" AS_SIG(CLS_NAME_OBJECT));
+            "()" AS_SIG(CLS_NAME_OBJECT));
 
     g_cls_Iterator = env->FindClassAsGlobalRef(CLS_NAME_ITERATOR);
     g_method_Iterator_hasNext = env->GetMethodID(g_cls_Iterator, "hasNext", "()Z");
     g_method_Iterator_next = env->GetMethodID(g_cls_Iterator, "next", "()" AS_SIG(CLS_NAME_OBJECT));
 }
 
-void clearJavaClasses(JNIEnvWrapper *env)
+void clearJavaClasses(JNIEnvWrapperenv)
 {
+    env->DeleteGlobalRef(g_cls_Boolean);
+    env->DeleteGlobalRef(g_cls_Integer);
+    env->DeleteGlobalRef(g_cls_Double);
+    env->DeleteGlobalRef(g_cls_String);
     env->DeleteGlobalRef(g_cls_Set);
     env->DeleteGlobalRef(g_cls_Map);
     env->DeleteGlobalRef(g_cls_MapEntry);
index b37211b..d51277c 100644 (file)
 
 #include <string>
 
+#define PACKAGE_NAME "org/iotivity/service/resourcecontainer"
+
+#define CLS_NAME_VALUE PACKAGE_NAME "/RcsValue"
+
+#define CLS_NAME_RESOURCEATTRIBUTES PACKAGE_NAME "/RcsResourceAttributes"
+#define CLS_NAME_REMOTERESOURCEOBJECT PACKAGE_NAME "/client/RcsRemoteResourceObject"
+
+#define EXC_NAME_RCS PACKAGE_NAME "/RcsException"
+#define EXC_NAME_PLATFORM PACKAGE_NAME "/RcsPlatformException"
+#define EXC_NAME_ILLEGAL_STATE PACKAGE_NAME "/RcsIllegalStateException"
+
 #define CLS_NAME_OBJECT "java/lang/Object"
 #define CLS_NAME_STRING "java/lang/String"
+#define CLS_NAME_INTEGER "java/lang/Integer"
+#define CLS_NAME_DOUBLE "java/lang/Double"
+#define CLS_NAME_BOOLEAN "java/lang/Boolean"
 
 #define CLS_NAME_COLLECTION "java/util/Collection"
 #define CLS_NAME_ARRAY_LIST "java/util/ArrayList"
 
 class JNIEnvWrapper;
 
+extern jclass g_cls_Integer;
+extern jclass g_cls_Double;
+extern jclass g_cls_Boolean;
+extern jclass g_cls_String;
+
 extern jclass g_cls_ArrayList;
 extern jclass g_cls_Set;
 extern jclass g_cls_Map;
 extern jclass g_cls_MapEntry;
 extern jclass g_cls_Iterator;
 
+extern jmethodID g_method_Boolean_booleanValue;
+extern jmethodID g_method_Integer_intValue;
+extern jmethodID g_method_Double_doubleValue;
+
 extern jmethodID g_method_Collection_add;
 
 extern jmethodID g_method_Set_iterator;
@@ -58,25 +81,46 @@ extern jmethodID g_method_MapEntry_getValue;
 extern jmethodID g_method_Iterator_hasNext;
 extern jmethodID g_method_Iterator_next;
 
-extern jmethodID g_ctor_ArrayList;
+extern jmethodID g_ctor_Boolean;
+extern jmethodID g_ctor_Integer;
+extern jmethodID g_ctor_Double;
 
+extern jmethodID g_ctor_ArrayList;
 void initJavaClasses(JNIEnvWrapper *);
 void clearJavaClasses(JNIEnvWrapper *);
 
 template< typename ENV >
-inline jstring newStringObject(ENV *env, const std::string &value)
+inline jobject newBooleanObject(ENV* env, bool value)
+{
+    return env->NewObject(g_cls_Boolean, g_ctor_Boolean, value);
+}
+
+template< typename ENV >
+inline jobject newIntegerObject(ENV* env, int value)
+{
+    return env->NewObject(g_cls_Integer, g_ctor_Integer, value);
+}
+
+template< typename ENV >
+inline jobject newDoubleObject(ENV* env, double value)
+{
+    return env->NewObject(g_cls_Double, g_ctor_Double, value);
+}
+
+template< typename ENV >
+inline jstring newStringObject(ENV* env, const std::string& value)
 {
     return env->NewStringUTF(value.c_str());
 }
 
 template< typename ENV >
-inline jstring newStringObjectCstr(ENV *env, const char *value)
+inline jstring newStringObjectCstr(ENV* env, const char* value)
 {
     return env->NewStringUTF(value);
 }
 
 template< typename ENV >
-inline std::string toStdString(ENV *env, jstring obj)
+inline std::string toStdString(ENVenv, jstring obj)
 {
     if (!obj) return "";
 
@@ -84,7 +128,7 @@ inline std::string toStdString(ENV *env, jstring obj)
 
     if (!cstr) return "";
 
-    std::string result { cstr };
+    std::string result{ cstr };
 
     env->ReleaseStringUTFChars(obj, cstr);
 
@@ -92,55 +136,73 @@ inline std::string toStdString(ENV *env, jstring obj)
 }
 
 template< typename ENV >
-inline jobject newArrayList(ENV *env)
+inline jobject newArrayList(ENVenv)
 {
     return env->NewObject(g_cls_ArrayList, g_ctor_ArrayList);
 }
 
 template< typename ENV >
-inline jboolean invoke_Collection_add(ENV *env, jobject collectionObj, jobject valueObj)
+inline bool invoke_Boolean_booleanValue(ENV* env, jobject obj)
+{
+    return env->CallBooleanMethod(obj, g_method_Boolean_booleanValue);
+}
+
+template< typename ENV >
+inline int invoke_Integer_intValue(ENV* env, jobject obj)
+{
+    return env->CallIntMethod(obj, g_method_Integer_intValue);
+}
+
+template< typename ENV >
+inline double invoke_Double_doubleValue(ENV* env, jobject obj)
+{
+    return env->CallDoubleMethod(obj, g_method_Double_doubleValue);
+}
+
+template< typename ENV >
+inline jboolean invoke_Collection_add(ENV* env, jobject collectionObj, jobject valueObj)
 {
     return env->CallBooleanMethod(collectionObj, g_method_Collection_add, valueObj);
 }
 
 template< typename ENV >
-inline jobject invoke_Map_entrySet(ENV *env, jobject mapObj)
+inline jobject invoke_Map_entrySet(ENVenv, jobject mapObj)
 {
     return env->CallObjectMethod(mapObj, g_method_Map_entrySet);
 }
 
 template< typename ENV >
-inline jobject invoke_Map_put(ENV *env, jobject mapObj, jobject keyObj, jobject valueObj)
+inline jobject invoke_Map_put(ENVenv, jobject mapObj, jobject keyObj, jobject valueObj)
 {
     return env->CallObjectMethod(mapObj, g_method_Map_put, keyObj, valueObj);
 }
 
 template< typename ENV >
-inline jobject invoke_MapEntry_getKey(ENV *env, jobject entryObj)
+inline jobject invoke_MapEntry_getKey(ENVenv, jobject entryObj)
 {
     return env->CallObjectMethod(entryObj, g_method_MapEntry_getKey);
 }
 
 template< typename ENV >
-inline jobject invoke_MapEntry_getValue(ENV *env, jobject entryObj)
+inline jobject invoke_MapEntry_getValue(ENVenv, jobject entryObj)
 {
     return env->CallObjectMethod(entryObj, g_method_MapEntry_getValue);
 }
 
 template< typename ENV >
-inline jobject invoke_Set_iterator(ENV *env, jobject setObj)
+inline jobject invoke_Set_iterator(ENVenv, jobject setObj)
 {
     return env->CallObjectMethod(setObj, g_method_Set_iterator);
 }
 
 template< typename ENV >
-inline bool invoke_Iterator_hasNext(ENV *env, jobject iterObj)
+inline bool invoke_Iterator_hasNext(ENVenv, jobject iterObj)
 {
     return env->CallBooleanMethod(iterObj, g_method_Iterator_hasNext);
 }
 
 template< typename ENV >
-inline jobject invoke_Iterator_next(ENV *env, jobject iterObj)
+inline jobject invoke_Iterator_next(ENVenv, jobject iterObj)
 {
     return env->CallObjectMethod(iterObj, g_method_Iterator_next);
 }
diff --git a/service/resource-container/android/resource-container/src/main/jni/util/JavaExceptions.cpp b/service/resource-container/android/resource-container/src/main/jni/util/JavaExceptions.cpp
new file mode 100644 (file)
index 0000000..74e6cfc
--- /dev/null
@@ -0,0 +1,57 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics 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.
+ *
+ ******************************************************************/
+
+#include "JavaExceptions.h"
+
+#include "JNIEnvWrapper.h"
+#include "Verify.h"
+
+#include "RCSException.h"
+
+namespace
+{
+    jclass g_cls_PlatformException;
+
+    jmethodID g_ctor_PlatformException;
+}
+
+void initJavaExceptions(JNIEnvWrapper* env)
+{
+    g_cls_PlatformException = env->FindClassAsGlobalRef(EXC_NAME_PLATFORM);
+    g_ctor_PlatformException = env->GetConstructorID(g_cls_PlatformException,
+            "(" AS_SIG(CLS_NAME_STRING) "I)V");
+}
+
+void clearJavaExceptions(JNIEnvWrapper* env)
+{
+    env->DeleteGlobalRef(g_cls_PlatformException);
+}
+
+void throwPlatformException(JNIEnv* env, const OIC::Service::RCSPlatformException& e)
+{
+    auto msg = newStringObject(env, e.getReason());
+    VERIFY_NO_EXC(env);
+
+    auto exObj = env->NewObject(g_cls_PlatformException, g_ctor_PlatformException,
+            msg, e.getReasonCode());
+    VERIFY_NO_EXC(env);
+
+    env->Throw(static_cast< jthrowable >(exObj));
+}
diff --git a/service/resource-container/android/resource-container/src/main/jni/util/JavaExceptions.h b/service/resource-container/android/resource-container/src/main/jni/util/JavaExceptions.h
new file mode 100644 (file)
index 0000000..eccbf0d
--- /dev/null
@@ -0,0 +1,50 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics 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.
+ *
+ ******************************************************************/
+
+#ifndef JAVA_EXCEPTIONS_H_
+#define JAVA_EXCEPTIONS_H_
+
+#include <jni.h>
+
+#include "JavaClasses.h"
+
+namespace OIC
+{
+    namespace Service
+    {
+        class RCSPlatformException;
+    }
+}
+
+class JNIEnvWrapper;
+
+void initJavaExceptions(JNIEnvWrapper*);
+void clearJavaExceptions(JNIEnvWrapper*);
+
+void throwPlatformException(JNIEnv*, const OIC::Service::RCSPlatformException&);
+
+template < typename ENV >
+void throwRCSException(ENV* env, const char* msg)
+{
+    env->ThrowNew(env->FindClass(EXC_NAME_RCS), msg);
+}
+
+
+#endif // JAVA_EXCEPTIONS_H_
diff --git a/service/resource-container/android/resource-container/src/main/jni/util/ScopedEnv.h b/service/resource-container/android/resource-container/src/main/jni/util/ScopedEnv.h
new file mode 100644 (file)
index 0000000..c1b9030
--- /dev/null
@@ -0,0 +1,162 @@
+/******************************************************************
+ *
+ * Copyright 2015 Samsung Electronics 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.
+ *
+ ******************************************************************/
+
+#ifndef RCS_JIN_SCOPEDENV_H_
+#define RCS_JIN_SCOPEDENV_H_
+
+#include <utility>
+
+#include <jni.h>
+
+#include "JNIEnvWrapper.h"
+#include "Log.h"
+
+extern JavaVM* g_jvm;
+
+namespace Detail
+{
+    inline std::pair<JNIEnv*, bool> getEnv()
+    {
+        JNIEnv* env{ };
+        bool needToDetach{ };
+
+        auto ret = g_jvm->GetEnv((void**) &env, JNI_VERSION_1_6);
+
+        switch (ret)
+        {
+            case JNI_OK:
+                break;
+
+            case JNI_EDETACHED:
+            {
+                auto attachRet = g_jvm->AttachCurrentThread(&env, NULL);
+
+                if (attachRet != JNI_OK)
+                {
+                    LOGT_E("JNI-ScopedEnv", "Failed to get the environment : %d", attachRet);
+                }
+                else
+                {
+                    needToDetach = true;
+                }
+                break;
+            }
+            case JNI_EVERSION:
+                LOGT_E("JNI-ScopedEnv", "JNI version not supported");
+                break;
+
+            default:
+                LOGT_E("JNI-ScopedEnv", "Failed to get the environment");
+                break;
+        }
+
+        return { env, needToDetach };
+    }
+}
+
+class ScopedEnv
+{
+public:
+    ScopedEnv() noexcept :
+        m_env { },
+        m_needToDetach{ false }
+    {
+        auto val = Detail::getEnv();
+
+        m_env = val.first;
+        m_needToDetach = val.second;
+    }
+
+    ~ScopedEnv()
+    {
+        if (m_env && m_needToDetach)
+        {
+            g_jvm->DetachCurrentThread();
+        }
+    }
+
+    ScopedEnv(const ScopedEnv&) = delete;
+    ScopedEnv& operator=(const ScopedEnv&) = delete;
+
+    operator bool() const noexcept
+    {
+        return m_env;
+    }
+
+    JNIEnv* operator->() noexcept
+    {
+        return m_env;
+    }
+
+    JNIEnv* get() noexcept
+    {
+        return m_env;
+    }
+
+private:
+    JNIEnv* m_env;
+    bool m_needToDetach;
+};
+
+class ScopedEnvWrapper
+{
+public:
+    ScopedEnvWrapper() noexcept :
+        m_env { },
+        m_needToDetach{ false }
+    {
+        auto val = Detail::getEnv();
+
+        m_env = val.first;
+        m_needToDetach = val.second;
+    }
+
+    ~ScopedEnvWrapper()
+    {
+        if (m_env && m_needToDetach)
+        {
+            g_jvm->DetachCurrentThread();
+        }
+    }
+
+    ScopedEnvWrapper(const ScopedEnvWrapper&) = delete;
+    ScopedEnvWrapper& operator=(const ScopedEnvWrapper&) = delete;
+
+    operator bool() const noexcept
+    {
+        return m_env;
+    }
+
+    JNIEnvWrapper* operator->() noexcept
+    {
+        return &m_env;
+    }
+
+    JNIEnvWrapper* get() noexcept
+    {
+        return &m_env;
+    }
+
+private:
+    JNIEnvWrapper m_env;
+    bool m_needToDetach;
+};
+
+#endif // RCS_JIN_SCOPEDENV_H_
index cc97d1d..17f1c34 100644 (file)
@@ -195,7 +195,7 @@ void onPost(const HeaderOptions &headerOptions, const OCRepresentation &rep, con
     }
 }
 
-// Local function to put a different state for this resource
+// Local function to put a different state for this re<< std::endlsource
 void postLightRepresentation(std::shared_ptr<OCResource> resource)
 {
     if (resource)
@@ -306,14 +306,11 @@ void onGet(const HeaderOptions &headerOptions, const OCRepresentation &rep, cons
             std::cout << "Resource URI: " << rep.getUri() << std::endl;
 
             std::cout << "Payload: " << rep.getPayload() << std::endl;
+            std::cout << "On-off: " << rep.getValueToString("on-off") << std::endl;
 
             rep.getValue("on-off", mylight.m_on_off);
-            rep.getValue("dim", mylight.m_dim);
-            rep.getValue("color", mylight.m_color);
 
             std::cout << "\ton-off: " << mylight.m_on_off << std::endl;
-            std::cout << "\tcolor: " << mylight.m_color << std::endl;
-            std::cout << "\tdim: " << mylight.m_dim << std::endl;
 
             putLightRepresentation(curResource);
         }
@@ -376,39 +373,7 @@ void foundResource(std::shared_ptr<OCResource> resource)
     std::string hostAddress;
     try
     {
-        {
-            std::lock_guard<std::mutex> lock(curResourceLock);
-            if (discoveredResources.find(resource->uniqueIdentifier()) == discoveredResources.end())
-            {
-                std::cout << "Found resource " << resource->uniqueIdentifier() <<
-                          " for the first time on server with ID: " << resource->sid() << std::endl;
-                discoveredResources[resource->uniqueIdentifier()] = resource;
-
-                if (resourceURI.find("/discomfortIndex") != std::string::npos)
-                {
-                    std::cout << "discomfortIndex found !!! " << std::endl;
-
-                    DISensorResource = resource;
-
-                    OCRepresentation rep;
 
-                    rep.setValue("humidity", std::string("30"));
-                    rep.setValue("temperature", std::string("27"));
-
-                    resource->put(rep, QueryParamsMap(), &onPutForDISensor);
-                }
-            }
-            else
-            {
-                std::cout << "Found resource " << resource->uniqueIdentifier() << " again!" << std::endl;
-            }
-
-            if (curResource)
-            {
-                std::cout << "Found another resource, ignoring" << std::endl;
-                return;
-            }
-        }
 
         // Do some operations with resource object.
         if (resource)
@@ -427,7 +392,6 @@ void foundResource(std::shared_ptr<OCResource> resource)
             for (auto &resourceTypes : resource->getResourceTypes())
             {
                 std::cout << "\t\t" << resourceTypes << std::endl;
-
                 if (resourceTypes == "oic.r.light")
                 {
                     curResource = resource;
@@ -1,15 +1,14 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4">
+<module external.linked.project.id="AndroidBundle" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
   <component name="FacetManager">
     <facet type="java-gradle" name="Java-Gradle">
       <configuration>
         <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
+        <option name="BUILDABLE" value="false" />
       </configuration>
     </facet>
   </component>
-  <component name="NewModuleRootManager" inherit-compiler-output="false">
-    <output url="file://$MODULE_DIR$/build/classes/main" />
-    <output-test url="file://$MODULE_DIR$/build/classes/test" />
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true">
     <exclude-output />
     <content url="file://$MODULE_DIR$">
       <excludeFolder url="file://$MODULE_DIR$/.gradle" />
@@ -17,5 +16,4 @@
     <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
   </component>
-</module>
-
+</module>
\ No newline at end of file
old mode 100644 (file)
new mode 100755 (executable)
similarity index 78%
rename from service/resource-container/examples/android/RCSampleClientApp/app/app.iml
rename to service/resource-container/examples/android/AndroidBundle/app/app.iml
index 8501ed3..98e7737
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
+<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="AndroidBundle" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
   <component name="FacetManager">
     <facet type="android-gradle" name="Android-Gradle">
       <configuration>
@@ -9,11 +9,15 @@
     <facet type="android" name="Android">
       <configuration>
         <option name="SELECTED_BUILD_VARIANT" value="debug" />
+        <option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
         <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
         <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
-        <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
-        <option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
-        <option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugTestSources" />
+        <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" />
+        <option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugAndroidTestSources" />
+        <afterSyncTasks>
+          <task>generateDebugAndroidTestSources</task>
+          <task>generateDebugSources</task>
+        </afterSyncTasks>
         <option name="ALLOW_USER_CONFIGURATION" value="false" />
         <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
         <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
@@ -22,8 +26,9 @@
       </configuration>
     </facet>
   </component>
-  <component name="NewModuleRootManager" inherit-compiler-output="false">
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false">
     <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
+    <output-test url="file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug" />
     <exclude-output />
     <content url="file://$MODULE_DIR$">
       <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
       <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
       <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
       <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/test/debug" isTestSource="true" generated="true" />
-      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/test/debug" isTestSource="true" generated="true" />
-      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/test/debug" isTestSource="true" generated="true" />
-      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/test/debug" isTestSource="true" generated="true" />
-      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/debug" type="java-test-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/test/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
       <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
       <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
       <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
@@ -66,6 +71,7 @@
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/iotivity-armeabi-v7a-resource-container-release/jars" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
       <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
       <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
     </content>
-    <orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
+    <orderEntry type="jdk" jdkName="Android API 23 Platform" jdkType="Android SDK" />
     <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" exported="" name="iotivity-service-release-" level="project" />
-    <orderEntry type="library" exported="" name="iotivity-base-release-" level="project" />
+    <orderEntry type="library" exported="" name="iotivity-armeabi-v7a-resource-container-release-" level="project" />
   </component>
-</module>
-
+</module>
\ No newline at end of file
@@ -1,26 +1,25 @@
-apply plugin: 'com.android.application'
-
-android {
-    compileSdkVersion 21
-    buildToolsVersion "21.1.2"
-
-    defaultConfig {
-        applicationId "org.iotivity.service.sample.client"
-        minSdkVersion 21
-        targetSdkVersion 21
-        versionCode 1
-        versionName "1.0"
-    }
-    buildTypes {
-        release {
-            minifyEnabled false
-            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
-        }
-    }
-}
-
-dependencies {
-    compile fileTree(include: ['*.jar'], dir: 'libs')
-    compile(name:'iotivity-service-release', ext:'aar')
-    compile(name:'iotivity-base-release', ext:'aar')
-}
+apply plugin: 'com.android.application'\r
+\r
+android {\r
+    compileSdkVersion 23\r
+    buildToolsVersion "22.0.1"\r
+\r
+    defaultConfig {\r
+        applicationId "org.iotivity.service.sample.androidbundle"\r
+        minSdkVersion 21\r
+        targetSdkVersion 23\r
+        versionCode 1\r
+        versionName "1.0"\r
+    }\r
+    buildTypes {\r
+        release {\r
+            minifyEnabled false\r
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'\r
+        }\r
+    }\r
+}\r
+\r
+dependencies {\r
+    compile fileTree(dir: 'libs', include: ['*.jar'])\r
+    compile(name:'iotivity-armeabi-v7a-resource-container-release', ext:'aar')\r
+}\r
diff --git a/service/resource-container/examples/android/AndroidBundle/app/src/androidTest/java/org/iotivity/service/sample/androidbundle/ApplicationTest.java b/service/resource-container/examples/android/AndroidBundle/app/src/androidTest/java/org/iotivity/service/sample/androidbundle/ApplicationTest.java
new file mode 100755 (executable)
index 0000000..e1b035e
--- /dev/null
@@ -0,0 +1,13 @@
+package org.iotivity.service.sample.androidbundle;\r
+\r
+import android.app.Application;\r
+import android.test.ApplicationTestCase;\r
+\r
+/**\r
+ * <a href="http://d.android.com/tools/testing/testing_android.html">Testing Fundamentals</a>\r
+ */\r
+public class ApplicationTest extends ApplicationTestCase<Application> {\r
+    public ApplicationTest() {\r
+        super(Application.class);\r
+    }\r
+}
\ No newline at end of file
diff --git a/service/resource-container/examples/android/AndroidBundle/app/src/main/AndroidManifest.xml b/service/resource-container/examples/android/AndroidBundle/app/src/main/AndroidManifest.xml
new file mode 100755 (executable)
index 0000000..4961797
--- /dev/null
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8"?>\r
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"\r
+    package="org.iotivity.service.sample.androidbundle" >\r
+\r
+    <application\r
+        android:allowBackup="true"\r
+        android:icon="@mipmap/ic_launcher"\r
+        android:label="@string/app_name"\r
+        android:theme="@style/AppTheme" >\r
+        <activity\r
+            android:name=".MainActivity"\r
+            android:label="@string/app_name" >\r
+            <intent-filter>\r
+                <action android:name="android.intent.action.MAIN" />\r
+\r
+                <category android:name="android.intent.category.LAUNCHER" />\r
+            </intent-filter>\r
+        </activity>\r
+    </application>\r
+\r
+</manifest>\r
diff --git a/service/resource-container/examples/android/AndroidBundle/app/src/main/java/org/iotivity/service/sample/androidbundle/AndroidLightResource.java b/service/resource-container/examples/android/AndroidBundle/app/src/main/java/org/iotivity/service/sample/androidbundle/AndroidLightResource.java
new file mode 100755 (executable)
index 0000000..0e07132
--- /dev/null
@@ -0,0 +1,35 @@
+package org.iotivity.service.sample.androidbundle;\r
+\r
+import android.content.Context;\r
+import android.util.Log;\r
+\r
+import org.iotivity.service.resourcecontainer.AndroidBundleResource;\r
+import org.iotivity.service.resourcecontainer.RcsResourceAttributes;\r
+\r
+/**\r
+ * Created by markus.jung on 11/8/2015.\r
+ */\r
+public class AndroidLightResource extends AndroidBundleResource {\r
+    private static final String LOG_TAG = AndroidBundleResource.class.getSimpleName();\r
+    public AndroidLightResource(Context context){\r
+        super(context);\r
+        this.setResourceType("oic.r.light");\r
+        this.setName("androidLightResource");\r
+    }\r
+    @Override\r
+    protected void initAttributes() {\r
+        this.m_attributes.put("on-off", true);\r
+    }\r
+\r
+    @Override\r
+    public void handleSetAttributesRequest(RcsResourceAttributes attrs) {\r
+        Log.i(LOG_TAG, "Set Attributes called with " + attrs);\r
+\r
+        Log.i(LOG_TAG, "On-off value: " + attrs.get("on-off"));\r
+    }\r
+\r
+    @Override\r
+    public RcsResourceAttributes handleGetAttributesRequest() {\r
+        return null;\r
+    }\r
+}\r
diff --git a/service/resource-container/examples/android/AndroidBundle/app/src/main/java/org/iotivity/service/sample/androidbundle/AndroidLocationResource.java b/service/resource-container/examples/android/AndroidBundle/app/src/main/java/org/iotivity/service/sample/androidbundle/AndroidLocationResource.java
new file mode 100755 (executable)
index 0000000..39bef3f
--- /dev/null
@@ -0,0 +1,24 @@
+package org.iotivity.service.sample.androidbundle;\r
+\r
+import org.iotivity.service.resourcecontainer.AndroidBundleResource;\r
+import org.iotivity.service.resourcecontainer.RcsResourceAttributes;\r
+\r
+/**\r
+ * Created by markus.jung on 11/8/2015.\r
+ */\r
+public class AndroidLocationResource extends AndroidBundleResource {\r
+    @Override\r
+    protected void initAttributes() {\r
+\r
+    }\r
+\r
+    @Override\r
+    public void handleSetAttributesRequest(RcsResourceAttributes rcsResourceAttributes) {\r
+\r
+    }\r
+\r
+    @Override\r
+    public RcsResourceAttributes handleGetAttributesRequest() {\r
+        return null;\r
+    }\r
+}\r
diff --git a/service/resource-container/examples/android/AndroidBundle/app/src/main/java/org/iotivity/service/sample/androidbundle/AndroidSampleActivator.java b/service/resource-container/examples/android/AndroidBundle/app/src/main/java/org/iotivity/service/sample/androidbundle/AndroidSampleActivator.java
new file mode 100755 (executable)
index 0000000..6e909ff
--- /dev/null
@@ -0,0 +1,52 @@
+package org.iotivity.service.sample.androidbundle;\r
+\r
+import android.content.Context;\r
+import android.util.Log;\r
+\r
+import org.iotivity.service.resourcecontainer.AndroidBundleActivator;\r
+import org.iotivity.service.resourcecontainer.AndroidBundleResource;\r
+import org.iotivity.service.resourcecontainer.RcsResourceContainerBundleAPI;\r
+import org.iotivity.service.resourcecontainer.ResourceConfig;\r
+\r
+import java.util.List;\r
+\r
+/**\r
+ * Created by markus.jung on 11/7/2015.\r
+ */\r
+public class AndroidSampleActivator extends AndroidBundleActivator {\r
+\r
+    public AndroidSampleActivator(RcsResourceContainerBundleAPI bundleAPI, Context appContext){\r
+        super(bundleAPI, appContext);\r
+        Log.d(AndroidSampleActivator.class.getName(), "Created activator instance");\r
+    }\r
+\r
+    @Override\r
+    public void activateBundle() {\r
+        Log.d(AndroidSampleActivator.class.getName(), "Activate bundle called");\r
+\r
+        // make a test resource\r
+        AndroidLightResource lightRes = new AndroidLightResource(this.appContext);\r
+        lightRes.setURI("/android/light/1");\r
+        bundleAPI.registerResource("oic.android.sample", lightRes);\r
+    }\r
+\r
+    @Override\r
+    public void deactivateBundle() {\r
+\r
+    }\r
+\r
+    @Override\r
+    public void createResource(ResourceConfig resourceConfig) {\r
+\r
+    }\r
+\r
+    @Override\r
+    public void destroyResource(AndroidBundleResource androidBundleResource) {\r
+\r
+    }\r
+\r
+    @Override\r
+    public List<ResourceConfig> getConfiguredBundleResources() {\r
+        return null;\r
+    }\r
+}\r
diff --git a/service/resource-container/examples/android/AndroidBundle/app/src/main/java/org/iotivity/service/sample/androidbundle/MainActivity.java b/service/resource-container/examples/android/AndroidBundle/app/src/main/java/org/iotivity/service/sample/androidbundle/MainActivity.java
new file mode 100755 (executable)
index 0000000..f4bbacd
--- /dev/null
@@ -0,0 +1,37 @@
+package org.iotivity.service.sample.androidbundle;\r
+\r
+import android.app.Activity;\r
+import android.os.Bundle;\r
+import android.view.Menu;\r
+import android.view.MenuItem;\r
+\r
+public class MainActivity extends Activity {\r
+\r
+    @Override\r
+    protected void onCreate(Bundle savedInstanceState) {\r
+        super.onCreate(savedInstanceState);\r
+        setContentView(R.layout.activity_main);\r
+    }\r
+\r
+    @Override\r
+    public boolean onCreateOptionsMenu(Menu menu) {\r
+        // Inflate the menu; this adds items to the action bar if it is present.\r
+        getMenuInflater().inflate(R.menu.menu_main, menu);\r
+        return true;\r
+    }\r
+\r
+    @Override\r
+    public boolean onOptionsItemSelected(MenuItem item) {\r
+        // Handle action bar item clicks here. The action bar will\r
+        // automatically handle clicks on the Home/Up button, so long\r
+        // as you specify a parent activity in AndroidManifest.xml.\r
+        int id = item.getItemId();\r
+\r
+        //noinspection SimplifiableIfStatement\r
+        if (id == R.id.action_settings) {\r
+            return true;\r
+        }\r
+\r
+        return super.onOptionsItemSelected(item);\r
+    }\r
+}\r
diff --git a/service/resource-container/examples/android/AndroidBundle/app/src/main/res/layout/activity_main.xml b/service/resource-container/examples/android/AndroidBundle/app/src/main/res/layout/activity_main.xml
new file mode 100755 (executable)
index 0000000..1f8ac75
--- /dev/null
@@ -0,0 +1,11 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"\r
+    xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"\r
+    android:layout_height="match_parent" android:paddingLeft="@dimen/activity_horizontal_margin"\r
+    android:paddingRight="@dimen/activity_horizontal_margin"\r
+    android:paddingTop="@dimen/activity_vertical_margin"\r
+    android:paddingBottom="@dimen/activity_vertical_margin" tools:context=".MainActivity">\r
+\r
+    <TextView android:text="@string/hello_world" android:layout_width="wrap_content"\r
+        android:layout_height="wrap_content" />\r
+\r
+</RelativeLayout>\r
diff --git a/service/resource-container/examples/android/AndroidBundle/app/src/main/res/menu/menu_main.xml b/service/resource-container/examples/android/AndroidBundle/app/src/main/res/menu/menu_main.xml
new file mode 100755 (executable)
index 0000000..32b5445
--- /dev/null
@@ -0,0 +1,5 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android"\r
+    xmlns:tools="http://schemas.android.com/tools" tools:context=".MainActivity">\r
+    <item android:id="@+id/action_settings" android:title="@string/action_settings"\r
+        android:orderInCategory="100" android:showAsAction="never" />\r
+</menu>\r
@@ -1,5 +1,5 @@
-<?xml version="1.0" encoding="utf-8"?>
-<resources>
-    <style name="AppTheme" parent="android:Theme.Material.Light">
-    </style>
-</resources>
+<?xml version="1.0" encoding="utf-8"?>\r
+<resources>\r
+    <style name="AppTheme" parent="android:Theme.Material.Light">\r
+    </style>\r
+</resources>\r
diff --git a/service/resource-container/examples/android/AndroidBundle/app/src/main/res/values-w820dp/dimens.xml b/service/resource-container/examples/android/AndroidBundle/app/src/main/res/values-w820dp/dimens.xml
new file mode 100755 (executable)
index 0000000..62df187
--- /dev/null
@@ -0,0 +1,6 @@
+<resources>\r
+    <!-- Example customization of dimensions originally defined in res/values/dimens.xml\r
+         (such as screen margins) for screens with more than 820dp of available width. This\r
+         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively). -->\r
+    <dimen name="activity_horizontal_margin">64dp</dimen>\r
+</resources>\r
diff --git a/service/resource-container/examples/android/AndroidBundle/app/src/main/res/values/dimens.xml b/service/resource-container/examples/android/AndroidBundle/app/src/main/res/values/dimens.xml
new file mode 100755 (executable)
index 0000000..295b5a9
--- /dev/null
@@ -0,0 +1,5 @@
+<resources>\r
+    <!-- Default screen margins, per the Android Design guidelines. -->\r
+    <dimen name="activity_horizontal_margin">16dp</dimen>\r
+    <dimen name="activity_vertical_margin">16dp</dimen>\r
+</resources>\r
diff --git a/service/resource-container/examples/android/AndroidBundle/app/src/main/res/values/strings.xml b/service/resource-container/examples/android/AndroidBundle/app/src/main/res/values/strings.xml
new file mode 100755 (executable)
index 0000000..e76f575
--- /dev/null
@@ -0,0 +1,6 @@
+<resources>\r
+    <string name="app_name">AndroidBundle</string>\r
+\r
+    <string name="hello_world">Hello world!</string>\r
+    <string name="action_settings">Settings</string>\r
+</resources>\r
@@ -1,8 +1,8 @@
-<resources>
-
-    <!-- Base application theme. -->
-    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">
-        <!-- Customize your theme here. -->
-    </style>
-
-</resources>
+<resources>\r
+\r
+    <!-- Base application theme. -->\r
+    <style name="AppTheme" parent="android:Theme.Holo.Light.DarkActionBar">\r
+        <!-- Customize your theme here. -->\r
+    </style>\r
+\r
+</resources>\r
old mode 100644 (file)
new mode 100755 (executable)
similarity index 69%
rename from service/resource-container/examples/android/RCSampleServerApp/build.gradle
rename to service/resource-container/examples/android/AndroidBundle/build.gradle
index 34a7ef9..d8b6a5d
@@ -1,23 +1,20 @@
-// Top-level build file where you can add configuration options common to all sub-projects/modules.
-
-buildscript {
-    repositories {
-        jcenter()
-    }
-    dependencies {
-        classpath 'com.android.tools.build:gradle:1.0.0'
-
-        // NOTE: Do not place your application dependencies here; they belong
-        // in the individual module build.gradle files
-    }
-}
-
-allprojects {
-    repositories {
-        jcenter()
-
-        flatDir {
-            dirs 'libs'
-        }
-    }
-}
+// Top-level build file where you can add configuration options common to all sub-projects/modules.\r
+\r
+buildscript {\r
+    repositories {\r
+        jcenter()\r
+    }\r
+    dependencies {\r
+        classpath 'com.android.tools.build:gradle:1.3.0'\r
+\r
+        // NOTE: Do not place your application dependencies here; they belong\r
+        // in the individual module build.gradle files\r
+    }\r
+}\r
+\r
+allprojects {\r
+    repositories {\r
+        maven { url 'http://jcenter.bintray.com/' }\r
+        flatDir { dirs 'libs' }\r
+    }\r
+}\r
diff --git a/service/resource-container/examples/android/AndroidBundle/gradle.properties b/service/resource-container/examples/android/AndroidBundle/gradle.properties
new file mode 100755 (executable)
index 0000000..0c9c39a
--- /dev/null
@@ -0,0 +1,17 @@
+## Project-wide Gradle settings.\r
+#\r
+# For more details on how to configure your build environment visit\r
+# http://www.gradle.org/docs/current/userguide/build_environment.html\r
+#\r
+# Specifies the JVM arguments used for the daemon process.\r
+# The setting is particularly useful for tweaking memory settings.\r
+# Default value: -Xmx10248m -XX:MaxPermSize=256m\r
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8\r
+#\r
+# When configured, Gradle will run in incubating parallel mode.\r
+# This option should only be used with decoupled projects. More details, visit\r
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\r
+# org.gradle.parallel=true\r
+#Sun Nov 08 19:01:43 KST 2015\r
+systemProp.http.proxyHost=168.219.61.252\r
+systemProp.http.proxyPort=8080\r
diff --git a/service/resource-container/examples/android/AndroidBundle/gradle/wrapper/gradle-wrapper.jar b/service/resource-container/examples/android/AndroidBundle/gradle/wrapper/gradle-wrapper.jar
new file mode 100755 (executable)
index 0000000..8c0fb64
Binary files /dev/null and b/service/resource-container/examples/android/AndroidBundle/gradle/wrapper/gradle-wrapper.jar differ
diff --git a/service/resource-container/examples/android/AndroidBundle/gradle/wrapper/gradle-wrapper.properties b/service/resource-container/examples/android/AndroidBundle/gradle/wrapper/gradle-wrapper.properties
new file mode 100755 (executable)
index 0000000..0a74de7
--- /dev/null
@@ -0,0 +1,6 @@
+#Sun Nov 08 19:01:42 KST 2015\r
+distributionBase=GRADLE_USER_HOME\r
+distributionPath=wrapper/dists\r
+zipStoreBase=GRADLE_USER_HOME\r
+zipStorePath=wrapper/dists\r
+distributionUrl=https\://services.gradle.org/distributions/gradle-2.4-all.zip\r
diff --git a/service/resource-container/examples/android/AndroidBundle/gradlew b/service/resource-container/examples/android/AndroidBundle/gradlew
new file mode 100755 (executable)
index 0000000..91a7e26
--- /dev/null
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/service/resource-container/examples/android/AndroidBundle/gradlew.bat b/service/resource-container/examples/android/AndroidBundle/gradlew.bat
new file mode 100755 (executable)
index 0000000..aec9973
--- /dev/null
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off\r
+@rem ##########################################################################\r
+@rem\r
+@rem  Gradle startup script for Windows\r
+@rem\r
+@rem ##########################################################################\r
+\r
+@rem Set local scope for the variables with windows NT shell\r
+if "%OS%"=="Windows_NT" setlocal\r
+\r
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r
+set DEFAULT_JVM_OPTS=\r
+\r
+set DIRNAME=%~dp0\r
+if "%DIRNAME%" == "" set DIRNAME=.\r
+set APP_BASE_NAME=%~n0\r
+set APP_HOME=%DIRNAME%\r
+\r
+@rem Find java.exe\r
+if defined JAVA_HOME goto findJavaFromJavaHome\r
+\r
+set JAVA_EXE=java.exe\r
+%JAVA_EXE% -version >NUL 2>&1\r
+if "%ERRORLEVEL%" == "0" goto init\r
+\r
+echo.\r
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r
+echo.\r
+echo Please set the JAVA_HOME variable in your environment to match the\r
+echo location of your Java installation.\r
+\r
+goto fail\r
+\r
+:findJavaFromJavaHome\r
+set JAVA_HOME=%JAVA_HOME:"=%\r
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe\r
+\r
+if exist "%JAVA_EXE%" goto init\r
+\r
+echo.\r
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r
+echo.\r
+echo Please set the JAVA_HOME variable in your environment to match the\r
+echo location of your Java installation.\r
+\r
+goto fail\r
+\r
+:init\r
+@rem Get command-line arguments, handling Windowz variants\r
+\r
+if not "%OS%" == "Windows_NT" goto win9xME_args\r
+if "%@eval[2+2]" == "4" goto 4NT_args\r
+\r
+:win9xME_args\r
+@rem Slurp the command line arguments.\r
+set CMD_LINE_ARGS=\r
+set _SKIP=2\r
+\r
+:win9xME_args_slurp\r
+if "x%~1" == "x" goto execute\r
+\r
+set CMD_LINE_ARGS=%*\r
+goto execute\r
+\r
+:4NT_args\r
+@rem Get arguments from the 4NT Shell from JP Software\r
+set CMD_LINE_ARGS=%$\r
+\r
+:execute\r
+@rem Setup the command line\r
+\r
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar\r
+\r
+@rem Execute Gradle\r
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r
+\r
+:end\r
+@rem End local scope for the variables with windows NT shell\r
+if "%ERRORLEVEL%"=="0" goto mainEnd\r
+\r
+:fail\r
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r
+rem the _cmd.exe /c_ return code!\r
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1\r
+exit /b 1\r
+\r
+:mainEnd\r
+if "%OS%"=="Windows_NT" endlocal\r
+\r
+:omega\r
diff --git a/service/resource-container/examples/android/ContainerSampleApp/ContainerSampleApp.iml b/service/resource-container/examples/android/ContainerSampleApp/ContainerSampleApp.iml
new file mode 100755 (executable)
index 0000000..ea7c6e5
--- /dev/null
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module external.linked.project.id="ContainerSampleApp" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" external.system.module.group="" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
+  <component name="FacetManager">
+    <facet type="java-gradle" name="Java-Gradle">
+      <configuration>
+        <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
+        <option name="BUILDABLE" value="false" />
+      </configuration>
+    </facet>
+  </component>
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <excludeFolder url="file://$MODULE_DIR$/.gradle" />
+    </content>
+    <orderEntry type="jdk" jdkName="1.8" jdkType="JavaSDK" />
+    <orderEntry type="sourceFolder" forTests="false" />
+  </component>
+</module>
\ No newline at end of file
@@ -1,21 +1,21 @@
-<?xml version="1.0" encoding="UTF-8"?>
-<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4">
-  <component name="FacetManager">
-    <facet type="java-gradle" name="Java-Gradle">
-      <configuration>
-        <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />
-      </configuration>
-    </facet>
-  </component>
-  <component name="NewModuleRootManager" inherit-compiler-output="false">
-    <output url="file://$MODULE_DIR$/build/classes/main" />
-    <output-test url="file://$MODULE_DIR$/build/classes/test" />
-    <exclude-output />
-    <content url="file://$MODULE_DIR$">
-      <excludeFolder url="file://$MODULE_DIR$/.gradle" />
-    </content>
-    <orderEntry type="inheritedJdk" />
-    <orderEntry type="sourceFolder" forTests="false" />
-  </component>
-</module>
-
+<?xml version="1.0" encoding="UTF-8"?>\r
+<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$" external.system.id="GRADLE" type="JAVA_MODULE" version="4">\r
+  <component name="FacetManager">\r
+    <facet type="java-gradle" name="Java-Gradle">\r
+      <configuration>\r
+        <option name="BUILD_FOLDER_PATH" value="$MODULE_DIR$/build" />\r
+      </configuration>\r
+    </facet>\r
+  </component>\r
+  <component name="NewModuleRootManager" inherit-compiler-output="false">\r
+    <output url="file://$MODULE_DIR$/build/classes/main" />\r
+    <output-test url="file://$MODULE_DIR$/build/classes/test" />\r
+    <exclude-output />\r
+    <content url="file://$MODULE_DIR$">\r
+      <excludeFolder url="file://$MODULE_DIR$/.gradle" />\r
+    </content>\r
+    <orderEntry type="inheritedJdk" />\r
+    <orderEntry type="sourceFolder" forTests="false" />\r
+  </component>\r
+</module>\r
+\r
@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<module external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" type="JAVA_MODULE" version="4">
+<module external.linked.project.id=":app" external.linked.project.path="$MODULE_DIR$" external.root.project.path="$MODULE_DIR$/.." external.system.id="GRADLE" external.system.module.group="ContainerSampleApp" external.system.module.version="unspecified" type="JAVA_MODULE" version="4">
   <component name="FacetManager">
     <facet type="android-gradle" name="Android-Gradle">
       <configuration>
@@ -9,11 +9,15 @@
     <facet type="android" name="Android">
       <configuration>
         <option name="SELECTED_BUILD_VARIANT" value="debug" />
+        <option name="SELECTED_TEST_ARTIFACT" value="_android_test_" />
         <option name="ASSEMBLE_TASK_NAME" value="assembleDebug" />
         <option name="COMPILE_JAVA_TASK_NAME" value="compileDebugSources" />
-        <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugTest" />
-        <option name="SOURCE_GEN_TASK_NAME" value="generateDebugSources" />
-        <option name="TEST_SOURCE_GEN_TASK_NAME" value="generateDebugTestSources" />
+        <option name="ASSEMBLE_TEST_TASK_NAME" value="assembleDebugAndroidTest" />
+        <option name="COMPILE_JAVA_TEST_TASK_NAME" value="compileDebugAndroidTestSources" />
+        <afterSyncTasks>
+          <task>generateDebugAndroidTestSources</task>
+          <task>generateDebugSources</task>
+        </afterSyncTasks>
         <option name="ALLOW_USER_CONFIGURATION" value="false" />
         <option name="MANIFEST_FILE_RELATIVE_PATH" value="/src/main/AndroidManifest.xml" />
         <option name="RES_FOLDER_RELATIVE_PATH" value="/src/main/res" />
@@ -22,8 +26,9 @@
       </configuration>
     </facet>
   </component>
-  <component name="NewModuleRootManager" inherit-compiler-output="false">
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_7" inherit-compiler-output="false">
     <output url="file://$MODULE_DIR$/build/intermediates/classes/debug" />
+    <output-test url="file://$MODULE_DIR$/build/intermediates/classes/androidTest/debug" />
     <exclude-output />
     <content url="file://$MODULE_DIR$">
       <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/debug" isTestSource="false" generated="true" />
       <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
       <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
       <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/debug" type="java-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/test/debug" isTestSource="true" generated="true" />
-      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/test/debug" isTestSource="true" generated="true" />
-      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/test/debug" isTestSource="true" generated="true" />
-      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/test/debug" isTestSource="true" generated="true" />
-      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/test/debug" type="java-test-resource" />
-      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/generated/test/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
+      <sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
       <sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
       <sourceFolder url="file://$MODULE_DIR$/src/debug/resources" type="java-resource" />
       <sourceFolder url="file://$MODULE_DIR$/src/debug/assets" type="java-resource" />
@@ -66,6 +71,8 @@
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex-cache" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/iotivity-armeabi-v7a-resource-container-release/jars" />
+      <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/iotivity-base-armeabi-v7a-release/jars" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jacoco" />
       <excludeFolder url="file://$MODULE_DIR$/build/intermediates/javaResources" />
@@ -83,9 +90,7 @@
     </content>
     <orderEntry type="jdk" jdkName="Android API 21 Platform" jdkType="Android SDK" />
     <orderEntry type="sourceFolder" forTests="false" />
-    <orderEntry type="library" exported="" name="iotivity-service-release-" level="project" />
-    <orderEntry type="library" exported="" name="iotivity-resource-container-release-" level="project" />
-    <orderEntry type="library" exported="" name="iotivity-base-release-" level="project" />
+    <orderEntry type="library" exported="" name="iotivity-armeabi-v7a-resource-container-release-" level="project" />
+    <orderEntry type="library" exported="" name="iotivity-base-armeabi-v7a-release-" level="project" />
   </component>
-</module>
-
+</module>
\ No newline at end of file
diff --git a/service/resource-container/examples/android/ContainerSampleApp/app/build.gradle b/service/resource-container/examples/android/ContainerSampleApp/app/build.gradle
new file mode 100755 (executable)
index 0000000..80970fa
--- /dev/null
@@ -0,0 +1,35 @@
+apply plugin: 'com.android.application'
+
+android {
+    compileSdkVersion 21
+    buildToolsVersion "21.1.2"
+
+    defaultConfig {
+        applicationId "org.iotivity.service.sample.resourcecontainer"
+        minSdkVersion 21
+        targetSdkVersion 21
+        versionCode 1
+        versionName "1.0"
+    }
+    buildTypes {
+        release {
+            minifyEnabled false
+            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
+        }
+    }
+
+    /*packagingOptions{
+        exclude 'lib/armeabi-v7a/librcs_client.so'
+        exclude 'lib/armeabi-v7a/librcs_common.so'
+        exclude 'lib/armeabi-v7a/librcs_server.so'
+    }*/
+
+}
+
+dependencies {
+    compile fileTree(include: ['*.jar'], dir: 'libs')
+    //provided(name:'iotivity-armeabi-v7a-service-release', ext:'aar')
+    compile(name:'iotivity-armeabi-v7a-resource-container-release', ext:'aar')
+   // compile(name:'iotivity-armeabi-v7a-resource-container-debug', ext:'aar')
+    compile(name:'iotivity-base-armeabi-v7a-release', ext:'aar')
+}
@@ -3,7 +3,17 @@
 
     <uses-permission android:name="android.permission.INTERNET" />
     <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE"/>
+
+    <uses-permission android:name="android.permission.CAMERA" />
+    <uses-permission android:name="android.permission.FLASHLIGHT"/>
+    <uses-feature android:name="android.hardware.camera" />
+    <uses-feature android:name="android.hardware.camera.autofocus" />
+    <uses-feature android:name="android.hardware.camera.flash" />
+
+    <uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE">
+    </uses-permission>
+    <uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE">
+    </uses-permission>
 
     <application android:allowBackup="true" android:label="@string/app_name"
         android:icon="@mipmap/ic_launcher" android:theme="@style/AppTheme">
@@ -1,8 +1,7 @@
-<?xml version="1.0" encoding="UTF-8" standalone="no"?>
 <container>
     <bundle>
         <id>oic.bundle.discomfortIndexSensor</id>
-        <path>data/data/org.iotivity.service.sample.server/files/libDISensorBundle.so</path>
+        <path>data/data/org.iotivity.service.sample.resourcecontainer/files/libDISensorBundle.so</path>
         <activator>disensor</activator>
         <version>1.0.0</version>
         <resources>
             </resourceInfo>
         </resources>
     </bundle>
+    <bundle>
+        <id>oic.bundle.android.light</id>
+        <path>org.iotivity.service.sample.androidbundle.apk</path>
+        <activator>org.iotivity.service.sample.androidbundle.AndroidSampleActivator</activator>
+        <version>1.0.0</version>
+    </bundle>
 </container>
\ No newline at end of file
diff --git a/service/resource-container/examples/android/ContainerSampleApp/app/src/main/java/org/iotivity/service/sample/container/DroidLED.java b/service/resource-container/examples/android/ContainerSampleApp/app/src/main/java/org/iotivity/service/sample/container/DroidLED.java
new file mode 100755 (executable)
index 0000000..1726012
--- /dev/null
@@ -0,0 +1,58 @@
+package org.iotivity.service.sample.container;\r
+\r
+import android.os.IBinder;\r
+import android.util.Log;\r
+\r
+import java.lang.reflect.Method;\r
+\r
+/**\r
+ * Created by markus.jung on 11/4/2015.\r
+ */\r
+public class DroidLED {\r
+    private Object svc = null;\r
+    private Method getFlashlightEnabled = null;\r
+    private Method setFlashlightEnabled = null;\r
+\r
+    @SuppressWarnings("unchecked")\r
+    public DroidLED() throws Exception {\r
+        try {\r
+            // call ServiceManager.getService("hardware") to get an IBinder for the service.\r
+            // this appears to be totally undocumented and not exposed in the SDK whatsoever.\r
+            Class sm = Class.forName("android.os.ServiceManager");\r
+            Object hwBinder = sm.getMethod("getService", String.class).invoke(null, "hardware");\r
+\r
+            // get the hardware service stub. this seems to just get us one step closer to the proxy\r
+            Class hwsstub = Class.forName("android.os.IHardwareService$Stub");\r
+            Method asInterface = hwsstub.getMethod("asInterface", android.os.IBinder.class);\r
+            svc = asInterface.invoke(null, (IBinder) hwBinder);\r
+\r
+            // grab the class (android.os.IHardwareService$Stub$Proxy) so we can reflect on its methods\r
+            Class proxy = svc.getClass();\r
+\r
+            // save methods\r
+            getFlashlightEnabled = proxy.getMethod("getFlashlightEnabled");\r
+            setFlashlightEnabled = proxy.getMethod("setFlashlightEnabled", boolean.class);\r
+        }\r
+        catch(Exception e) {\r
+            Log.e(DroidLED.class.getName(), "Cannot initialize LED", e);\r
+            throw new Exception("LED could not be initialized");\r
+        }\r
+    }\r
+\r
+    public boolean isEnabled() {\r
+        try {\r
+            return getFlashlightEnabled.invoke(svc).equals(true);\r
+        }\r
+        catch(Exception e) {\r
+            return false;\r
+        }\r
+    }\r
+\r
+    public void enable(boolean tf) {\r
+        try {\r
+            Log.i(DroidLED.class.getName(), "enabling light");\r
+            setFlashlightEnabled.invoke(svc, tf);\r
+        }\r
+        catch(Exception e) {}\r
+    }\r
+}\r
diff --git a/service/resource-container/examples/android/ContainerSampleApp/app/src/main/java/org/iotivity/service/sample/container/FlashLightResource.java b/service/resource-container/examples/android/ContainerSampleApp/app/src/main/java/org/iotivity/service/sample/container/FlashLightResource.java
new file mode 100755 (executable)
index 0000000..4df57fb
--- /dev/null
@@ -0,0 +1,48 @@
+package org.iotivity.service.sample.container;\r
+\r
+import android.content.Context;\r
+import android.util.Log;\r
+\r
+\r
+import org.iotivity.service.resourcecontainer.AndroidBundleResource;\r
+import org.iotivity.service.resourcecontainer.RcsResourceAttributes;\r
+\r
+/**\r
+ * Created by markus.jung on 11/2/2015.\r
+ */\r
+public class FlashLightResource extends AndroidBundleResource {\r
+    private static final String LOG_TAG = FlashLightResource.class.getSimpleName();\r
+\r
+    public FlashLightResource(Context context){\r
+        super(context);\r
+        this.setResourceType("oic.r.light");\r
+        this.setName("flashLightResource");\r
+    }\r
+\r
+    @Override\r
+    protected void initAttributes() {\r
+        this.m_attributes.put("on-off", true);\r
+    }\r
+\r
+    @Override\r
+    public void handleSetAttributesRequest(RcsResourceAttributes attrs) {\r
+        Log.i(LOG_TAG, "Set Attributes called with " + attrs);\r
+\r
+        Log.i(LOG_TAG, "New attributes value: " + attrs.get("on-off"));\r
+        /*super.setAttribute(attribute ,value);\r
+        if("on-off".equals(attribute)){\r
+            if("true".equals(value)){\r
+                Log.i(LOG_TAG, "Turn on");\r
+            }\r
+            else{\r
+                Log.i(LOG_TAG, "Turn off");\r
+            }\r
+        }*/\r
+\r
+    }\r
+\r
+    @Override\r
+    public RcsResourceAttributes handleGetAttributesRequest() {\r
+        return this.m_attributes;\r
+    }\r
+}\r
diff --git a/service/resource-container/examples/android/ContainerSampleApp/app/src/main/java/org/iotivity/service/sample/container/OicLightActivity.java b/service/resource-container/examples/android/ContainerSampleApp/app/src/main/java/org/iotivity/service/sample/container/OicLightActivity.java
new file mode 100755 (executable)
index 0000000..b0a8581
--- /dev/null
@@ -0,0 +1,169 @@
+package org.iotivity.service.sample.container;\r
+\r
+import android.app.Activity;\r
+import android.content.Context;\r
+import android.graphics.Color;\r
+import android.os.Bundle;\r
+import android.os.PowerManager;\r
+import android.os.PowerManager.WakeLock;\r
+import android.util.Log;\r
+import android.view.KeyEvent;\r
+import android.view.SurfaceHolder;\r
+import android.view.View;\r
+import android.view.WindowManager;\r
+\r
+/*\r
+ * Torch is an LED flashlight.\r
+ */\r
+public class OicLightActivity extends Activity implements SurfaceHolder.Callback {\r
+\r
+    private static final String TAG = OicLightActivity.class.getSimpleName();\r
+\r
+    private static final String WAKE_LOCK_TAG = "TORCH_WAKE_LOCK";\r
+\r
+    private View button;\r
+    private View lightText;\r
+\r
+    private WakeLock wakeLock;\r
+    private boolean lightOn = false;\r
+\r
+    private static OicLightActivity torch;\r
+\r
+    public OicLightActivity() {\r
+        super();\r
+        torch = this;\r
+    }\r
+\r
+    public static OicLightActivity getTorch() {\r
+        return torch;\r
+    }\r
+\r
+    /*\r
+     * Called by the view (see main.xml)\r
+     */\r
+    public void toggleLight(View view) {\r
+        toggleLight();\r
+    }\r
+\r
+    private void toggleLight() {\r
+        Log.i(OicLightActivity.class.getName(), "Toggle light");\r
+        if (lightOn) {\r
+            turnLightOff();\r
+        } else {\r
+            turnLightOn();\r
+        }\r
+    }\r
+\r
+    private void turnLightOn() {\r
+        lightOn = true;\r
+        Log.i(OicLightActivity.class.getName(), "Turn light on");\r
+        lightText.setBackgroundColor(Color.WHITE);\r
+    }\r
+\r
+    private void turnLightOff() {\r
+        lightOn = false;\r
+        Log.i(OicLightActivity.class.getName(), "Turn light off");\r
+        lightText.setBackgroundColor(Color.BLACK);\r
+    }\r
+\r
+    private void startWakeLock() {\r
+        if (wakeLock == null) {\r
+            Log.d(TAG, "wakeLock is null, getting a new WakeLock");\r
+            PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);\r
+            Log.d(TAG, "PowerManager acquired");\r
+            wakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, WAKE_LOCK_TAG);\r
+            Log.d(TAG, "WakeLock set");\r
+        }\r
+        wakeLock.acquire();\r
+        Log.d(TAG, "WakeLock acquired");\r
+    }\r
+\r
+    private void stopWakeLock() {\r
+        if (wakeLock != null) {\r
+            wakeLock.release();\r
+            Log.d(TAG, "WakeLock released");\r
+        }\r
+    }\r
+\r
+    /** Called when the activity is first created. */\r
+    @Override\r
+    public void onCreate(Bundle savedInstanceState) {\r
+        super.onCreate(savedInstanceState);\r
+        button.setOnClickListener(new View.OnClickListener() {\r
+            @Override\r
+            public void onClick(View view) {\r
+                toggleLight();\r
+            }\r
+        });\r
+        disablePhoneSleep();\r
+        Log.i(TAG, "onCreate");\r
+    }\r
+\r
+    private void disablePhoneSleep() {\r
+        getWindow().addFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);\r
+    }\r
+\r
+    @Override\r
+    public void onRestart() {\r
+        super.onRestart();\r
+        Log.i(TAG, "onRestart");\r
+    }\r
+\r
+    @Override\r
+    public void onStart() {\r
+        super.onStart();\r
+        Log.i(TAG, "onStart");\r
+    }\r
+\r
+    @Override\r
+    public void onResume() {\r
+        super.onResume();\r
+        turnLightOn();\r
+        Log.i(TAG, "onResume");\r
+    }\r
+\r
+    @Override\r
+    public void onPause() {\r
+        super.onPause();\r
+        turnLightOff();\r
+        Log.i(TAG, "onPause");\r
+    }\r
+\r
+    @Override\r
+    public void onStop() {\r
+        super.onStop();\r
+        torch = null;\r
+        Log.i(TAG, "onStop");\r
+    }\r
+\r
+    @Override\r
+    public void onDestroy() {\r
+        super.onDestroy();\r
+        Log.i(TAG, "onDestroy");\r
+    }\r
+\r
+    @Override\r
+    public boolean onKeyLongPress(int keyCode, KeyEvent event) {\r
+        // When the search button is long pressed, quit\r
+        if (keyCode == KeyEvent.KEYCODE_SEARCH) {\r
+            finish();\r
+            return true;\r
+        }\r
+        return false;\r
+    }\r
+\r
+    @Override\r
+    public void surfaceChanged(SurfaceHolder holder, int I, int J, int K) {\r
+        Log.d(TAG, "surfaceChanged");\r
+    }\r
+\r
+    @Override\r
+    public void surfaceCreated(SurfaceHolder holder) {\r
+        Log.d(TAG, "surfaceCreated");\r
+    }\r
+\r
+    @Override\r
+    public void surfaceDestroyed(SurfaceHolder holder) {\r
+        Log.d(TAG, "surfaceDestroyed");\r
+    }\r
+}
\ No newline at end of file
@@ -20,6 +20,8 @@
 
 package org.iotivity.service.sample.container;
 
+import android.content.pm.ApplicationInfo;
+import android.content.pm.PackageManager;
 import android.os.Message;
 
 import android.util.Log;
@@ -32,6 +34,8 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 
+import dalvik.system.DexFile;
+
 /**
  * For calling the Resource Container APIs as per user selection on UI and for
  * updating the UI
@@ -49,11 +53,16 @@ public class ResourceContainer {
     private static boolean                   isStarted     = false;
     public static boolean                    isInitialized = false;
 
+    private FlashLightResource testResource;
+
     // constructor
     public ResourceContainer() {
         resourceContainerActivityInstance = ResourceContainerActivity
                 .getResourceContainerActivityObj();
-        containerInstance = RcsResourceContainer.getInstance();
+        containerInstance = new RcsResourceContainer(resourceContainerActivityInstance.getApplicationContext());
+        testResource = new FlashLightResource(resourceContainerActivityInstance.getApplicationContext());
+        testResource.setURI("/light/1");
+        testResource.setName("light1");
     }
 
     // Start Container
@@ -63,26 +72,19 @@ public class ResourceContainer {
         Log.i("startContainer : config path : ", configFile);
 
         if (!isStarted) {
-            for (int i = 0; i < 2; i++) {
-                containerInstance.startContainer(configFile);
-                isStarted = true;
-            }
-        } else {
             containerInstance.startContainer(configFile);
-        }
-
-        logMessage = "Container Started ";
-        logMessage += "with one Bundle" + "\n";
-        logMessage += "ID : oic.bundle.discomfortIndexSensor";
+            isStarted = true;
+            logMessage = "Container Started ";
 
-        ResourceContainerActivity.setMessageLog(logMessage);
-        msg = Message.obtain();
-        msg.what = 1;
-        resourceContainerActivityInstance.getHandler().sendMessage(msg);
+            ResourceContainerActivity.setMessageLog(logMessage);
+            msg = Message.obtain();
+            msg.what = 1;
+            resourceContainerActivityInstance.getHandler().sendMessage(msg);
 
-        msg = Message.obtain();
-        msg.what = 0;
-        resourceContainerActivityInstance.getHandler().sendMessage(msg);
+            msg = Message.obtain();
+            msg.what = 0;
+            resourceContainerActivityInstance.getHandler().sendMessage(msg);
+        }
     }
 
     // Stop Container
@@ -153,7 +155,6 @@ public class ResourceContainer {
 
     // Add BMI Bundles
     public void addBMIBundle() {
-
         Map<String, String> bundleParams = null;
         List<RcsBundleInfo> bundleList = containerInstance.listBundles();
         if (1 < bundleList.size()) {
@@ -396,5 +397,13 @@ public class ResourceContainer {
         msg.what = 1;
         resourceContainerActivityInstance.getHandler().sendMessage(msg);
     }
-}
 
+    public void addAndroidResource(){
+        logMessage = "Add android resource " + "\n";
+        ResourceContainerActivity.setMessageLog(logMessage);
+        msg = Message.obtain();
+        msg.what = 1;
+        resourceContainerActivityInstance.getHandler().sendMessage(msg);
+        //containerInstance.registerAndroidResource("testBundle", testResource);
+    }
+}
@@ -64,8 +64,8 @@ public class ResourceContainerActivity extends Activity {
     // ResourceContainerActivity.class.getSimpleName();
 
     private final String                     LOG_TAG = "[ContainerSampleApp] "
-                                                             + this.getClass()
-                                                                     .getSimpleName();
+            + this.getClass()
+            .getSimpleName();
     private static ResourceContainerActivity resourceContainerActivityInstance;
     private ResourceContainer                resourceContainerInstance;
     private static String                    logMessage;
@@ -210,8 +210,8 @@ public class ResourceContainerActivity extends Activity {
 
                     @Override
                     public boolean onChildClick(ExpandableListView parent,
-                            View v, int groupPosition, int childPosition,
-                            long id) {
+                                                View v, int groupPosition, int childPosition,
+                                                long id) {
 
                         if (0 == groupPosition) {
                             if (childPosition == 0) {
@@ -305,7 +305,7 @@ public class ResourceContainerActivity extends Activity {
 
         // constructor
         public ExpandableList(Context context, List<String> dataHeader,
-                HashMap<String, List<String>> childData) {
+                              HashMap<String, List<String>> childData) {
             this.mContext = context;
             this.mListDataHeader = dataHeader;
             this.mListDataChild = childData;
@@ -327,7 +327,7 @@ public class ResourceContainerActivity extends Activity {
         // get Group View
         @Override
         public View getGroupView(int grpPosition, boolean isExpandable,
-                View changeView, ViewGroup head) {
+                                 View changeView, ViewGroup head) {
             String mainHeading = (String) getGroup(grpPosition);
             if (changeView == null) {
                 LayoutInflater flater;
@@ -373,7 +373,7 @@ public class ResourceContainerActivity extends Activity {
         // get Group View
         @Override
         public View getChildView(int grpPosition, final int childPosition,
-                boolean isLastItem, View changeView, ViewGroup head) {
+                                 boolean isLastItem, View changeView, ViewGroup head) {
 
             final String innerText = (String) getChild(grpPosition,
                     childPosition);
@@ -2,10 +2,12 @@
 
 buildscript {
     repositories {
-        jcenter()
+        maven{
+            url "http://jcenter.bintray.com/"
+        }
     }
     dependencies {
-        classpath 'com.android.tools.build:gradle:1.0.0'
+        classpath 'com.android.tools.build:gradle:1.3.0'
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
@@ -14,10 +16,14 @@ buildscript {
 
 allprojects {
     repositories {
-        jcenter()
+        maven{
+            url "http://jcenter.bintray.com/"
+        }
 
         flatDir {
             dirs 'libs'
         }
     }
 }
+
+
diff --git a/service/resource-container/examples/android/ContainerSampleApp/gradle.properties b/service/resource-container/examples/android/ContainerSampleApp/gradle.properties
new file mode 100755 (executable)
index 0000000..892973b
--- /dev/null
@@ -0,0 +1,17 @@
+## Project-wide Gradle settings.\r
+#\r
+# For more details on how to configure your build environment visit\r
+# http://www.gradle.org/docs/current/userguide/build_environment.html\r
+#\r
+# Specifies the JVM arguments used for the daemon process.\r
+# The setting is particularly useful for tweaking memory settings.\r
+# Default value: -Xmx10248m -XX:MaxPermSize=256m\r
+# org.gradle.jvmargs=-Xmx2048m -XX:MaxPermSize=512m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8\r
+#\r
+# When configured, Gradle will run in incubating parallel mode.\r
+# This option should only be used with decoupled projects. More details, visit\r
+# http://www.gradle.org/docs/current/userguide/multi_project_builds.html#sec:decoupled_projects\r
+# org.gradle.parallel=true\r
+#Sat Oct 03 13:27:12 KST 2015\r
+systemProp.http.proxyHost=168.219.61.252\r
+systemProp.http.proxyPort=8080\r
diff --git a/service/resource-container/examples/android/ContainerSampleApp/gradlew b/service/resource-container/examples/android/ContainerSampleApp/gradlew
new file mode 100755 (executable)
index 0000000..91a7e26
--- /dev/null
@@ -0,0 +1,164 @@
+#!/usr/bin/env bash
+
+##############################################################################
+##
+##  Gradle start up script for UN*X
+##
+##############################################################################
+
+# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
+DEFAULT_JVM_OPTS=""
+
+APP_NAME="Gradle"
+APP_BASE_NAME=`basename "$0"`
+
+# Use the maximum available, or set MAX_FD != -1 to use that value.
+MAX_FD="maximum"
+
+warn ( ) {
+    echo "$*"
+}
+
+die ( ) {
+    echo
+    echo "$*"
+    echo
+    exit 1
+}
+
+# OS specific support (must be 'true' or 'false').
+cygwin=false
+msys=false
+darwin=false
+case "`uname`" in
+  CYGWIN* )
+    cygwin=true
+    ;;
+  Darwin* )
+    darwin=true
+    ;;
+  MINGW* )
+    msys=true
+    ;;
+esac
+
+# For Cygwin, ensure paths are in UNIX format before anything is touched.
+if $cygwin ; then
+    [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
+fi
+
+# Attempt to set APP_HOME
+# Resolve links: $0 may be a link
+PRG="$0"
+# Need this for relative symlinks.
+while [ -h "$PRG" ] ; do
+    ls=`ls -ld "$PRG"`
+    link=`expr "$ls" : '.*-> \(.*\)$'`
+    if expr "$link" : '/.*' > /dev/null; then
+        PRG="$link"
+    else
+        PRG=`dirname "$PRG"`"/$link"
+    fi
+done
+SAVED="`pwd`"
+cd "`dirname \"$PRG\"`/" >&-
+APP_HOME="`pwd -P`"
+cd "$SAVED" >&-
+
+CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
+
+# Determine the Java command to use to start the JVM.
+if [ -n "$JAVA_HOME" ] ; then
+    if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
+        # IBM's JDK on AIX uses strange locations for the executables
+        JAVACMD="$JAVA_HOME/jre/sh/java"
+    else
+        JAVACMD="$JAVA_HOME/bin/java"
+    fi
+    if [ ! -x "$JAVACMD" ] ; then
+        die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+    fi
+else
+    JAVACMD="java"
+    which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
+
+Please set the JAVA_HOME variable in your environment to match the
+location of your Java installation."
+fi
+
+# Increase the maximum file descriptors if we can.
+if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then
+    MAX_FD_LIMIT=`ulimit -H -n`
+    if [ $? -eq 0 ] ; then
+        if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then
+            MAX_FD="$MAX_FD_LIMIT"
+        fi
+        ulimit -n $MAX_FD
+        if [ $? -ne 0 ] ; then
+            warn "Could not set maximum file descriptor limit: $MAX_FD"
+        fi
+    else
+        warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT"
+    fi
+fi
+
+# For Darwin, add options to specify how the application appears in the dock
+if $darwin; then
+    GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
+fi
+
+# For Cygwin, switch paths to Windows format before running java
+if $cygwin ; then
+    APP_HOME=`cygpath --path --mixed "$APP_HOME"`
+    CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
+
+    # We build the pattern for arguments to be converted via cygpath
+    ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null`
+    SEP=""
+    for dir in $ROOTDIRSRAW ; do
+        ROOTDIRS="$ROOTDIRS$SEP$dir"
+        SEP="|"
+    done
+    OURCYGPATTERN="(^($ROOTDIRS))"
+    # Add a user-defined pattern to the cygpath arguments
+    if [ "$GRADLE_CYGPATTERN" != "" ] ; then
+        OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)"
+    fi
+    # Now convert the arguments - kludge to limit ourselves to /bin/sh
+    i=0
+    for arg in "$@" ; do
+        CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -`
+        CHECK2=`echo "$arg"|egrep -c "^-"`                                 ### Determine if an option
+
+        if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then                    ### Added a condition
+            eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"`
+        else
+            eval `echo args$i`="\"$arg\""
+        fi
+        i=$((i+1))
+    done
+    case $i in
+        (0) set -- ;;
+        (1) set -- "$args0" ;;
+        (2) set -- "$args0" "$args1" ;;
+        (3) set -- "$args0" "$args1" "$args2" ;;
+        (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
+        (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
+        (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
+        (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
+        (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
+        (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
+    esac
+fi
+
+# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules
+function splitJvmOpts() {
+    JVM_OPTS=("$@")
+}
+eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS
+JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME"
+
+exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@"
diff --git a/service/resource-container/examples/android/ContainerSampleApp/gradlew.bat b/service/resource-container/examples/android/ContainerSampleApp/gradlew.bat
new file mode 100755 (executable)
index 0000000..aec9973
--- /dev/null
@@ -0,0 +1,90 @@
+@if "%DEBUG%" == "" @echo off\r
+@rem ##########################################################################\r
+@rem\r
+@rem  Gradle startup script for Windows\r
+@rem\r
+@rem ##########################################################################\r
+\r
+@rem Set local scope for the variables with windows NT shell\r
+if "%OS%"=="Windows_NT" setlocal\r
+\r
+@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.\r
+set DEFAULT_JVM_OPTS=\r
+\r
+set DIRNAME=%~dp0\r
+if "%DIRNAME%" == "" set DIRNAME=.\r
+set APP_BASE_NAME=%~n0\r
+set APP_HOME=%DIRNAME%\r
+\r
+@rem Find java.exe\r
+if defined JAVA_HOME goto findJavaFromJavaHome\r
+\r
+set JAVA_EXE=java.exe\r
+%JAVA_EXE% -version >NUL 2>&1\r
+if "%ERRORLEVEL%" == "0" goto init\r
+\r
+echo.\r
+echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.\r
+echo.\r
+echo Please set the JAVA_HOME variable in your environment to match the\r
+echo location of your Java installation.\r
+\r
+goto fail\r
+\r
+:findJavaFromJavaHome\r
+set JAVA_HOME=%JAVA_HOME:"=%\r
+set JAVA_EXE=%JAVA_HOME%/bin/java.exe\r
+\r
+if exist "%JAVA_EXE%" goto init\r
+\r
+echo.\r
+echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%\r
+echo.\r
+echo Please set the JAVA_HOME variable in your environment to match the\r
+echo location of your Java installation.\r
+\r
+goto fail\r
+\r
+:init\r
+@rem Get command-line arguments, handling Windowz variants\r
+\r
+if not "%OS%" == "Windows_NT" goto win9xME_args\r
+if "%@eval[2+2]" == "4" goto 4NT_args\r
+\r
+:win9xME_args\r
+@rem Slurp the command line arguments.\r
+set CMD_LINE_ARGS=\r
+set _SKIP=2\r
+\r
+:win9xME_args_slurp\r
+if "x%~1" == "x" goto execute\r
+\r
+set CMD_LINE_ARGS=%*\r
+goto execute\r
+\r
+:4NT_args\r
+@rem Get arguments from the 4NT Shell from JP Software\r
+set CMD_LINE_ARGS=%$\r
+\r
+:execute\r
+@rem Setup the command line\r
+\r
+set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar\r
+\r
+@rem Execute Gradle\r
+"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%\r
+\r
+:end\r
+@rem End local scope for the variables with windows NT shell\r
+if "%ERRORLEVEL%"=="0" goto mainEnd\r
+\r
+:fail\r
+rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of\r
+rem the _cmd.exe /c_ return code!\r
+if  not "" == "%GRADLE_EXIT_CONSOLE%" exit 1\r
+exit /b 1\r
+\r
+:mainEnd\r
+if "%OS%"=="Windows_NT" endlocal\r
+\r
+:omega\r
diff --git a/service/resource-container/examples/android/RCSampleClientApp/.gitignore b/service/resource-container/examples/android/RCSampleClientApp/.gitignore
deleted file mode 100644 (file)
index 8b41237..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-.gradle
-/local.properties
-/.idea
-.DS_Store
-/build
-/captures
-/gradle
diff --git a/service/resource-container/examples/android/RCSampleClientApp/app/.gitignore b/service/resource-container/examples/android/RCSampleClientApp/app/.gitignore
deleted file mode 100644 (file)
index 6a384b7..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/build
-/libs/*
diff --git a/service/resource-container/examples/android/RCSampleClientApp/app/src/main/AndroidManifest.xml b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/AndroidManifest.xml
deleted file mode 100644 (file)
index c42c1ca..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-<manifest xmlns:android="http://schemas.android.com/apk/res/android"
-    package="org.iotivity.service.sample.client">
-
-    <uses-permission android:name="android.permission.INTERNET" />
-    <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
-
-    <application android:allowBackup="true" android:label="@string/app_name"
-        android:icon="@mipmap/ic_launcher" android:theme="@style/AppTheme">
-        <activity
-            android:name=".ContainerClientActivity"
-            android:label="@string/app_name" >
-            <intent-filter>
-                <action android:name="android.intent.action.MAIN" />
-
-                <category android:name="android.intent.category.LAUNCHER" />
-            </intent-filter>
-        </activity>
-    <!--    <activity android:name=".ContainerClientActivity" /> -->
-    </application>
-
-</manifest>
diff --git a/service/resource-container/examples/android/RCSampleClientApp/app/src/main/java/org/iotivity/service/sample/client/ContainerClientActivity.java b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/java/org/iotivity/service/sample/client/ContainerClientActivity.java
deleted file mode 100644 (file)
index 319d5e1..0000000
+++ /dev/null
@@ -1,75 +0,0 @@
-/******************************************************************
- * Copyright 2015 Samsung Electronics All Rights Reserved.
- * <p>
- * <p>
- * <p>
- * 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
- * <p>
- * http://www.apache.org/licenses/LICENSE-2.0
- * <p>
- * 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 org.iotivity.service.sample.client;
-
-import android.app.Activity;
-import android.os.Bundle;
-import android.util.Log;
-import android.view.View;
-import android.widget.TextView;
-
-import org.iotivity.service.RcsException;
-import org.iotivity.service.client.RcsAddress;
-import org.iotivity.service.client.RcsDiscoveryManager;
-import org.iotivity.service.client.RcsRemoteResourceObject;
-
-/**
- * It contains the discover resource API for Discovering Container Resource
- */
-public class ContainerClientActivity extends Activity implements
-        RcsDiscoveryManager.OnResourceDiscoveredListener {
-    private final String LOG_TAG = "[SampleClient] "
-                                         + this.getClass().getSimpleName();
-
-    private TextView     mLogView;
-
-    @Override
-    protected void onCreate(Bundle savedInstanceState) {
-        super.onCreate(savedInstanceState);
-        setContentView(R.layout.activity_container_client);
-        mLogView = (TextView) findViewById(R.id.log);
-    }
-
-    public void onDiscoverResourceClick(View v) {
-        try {
-            RcsDiscoveryManager.getInstance().discoverResourceByType(
-                    RcsAddress.multicast(), "oic.r.sensor",
-                    ContainerClientActivity.this);
-            mLogView.setText("");
-        } catch (RcsException e) {
-            e.printStackTrace();
-        }
-    }
-
-    @Override
-    public void onResourceDiscovered(
-            final RcsRemoteResourceObject discoveredResource) {
-        Log.i(LOG_TAG, "onResourceDiscovered");
-
-        runOnUiThread(new Runnable() {
-            public void run() {
-                try {
-                    mLogView.setText(Utils.resourceInfo(discoveredResource));
-                } catch (RcsException e) {
-                    Utils.showError(ContainerClientActivity.this, LOG_TAG, e);
-                }
-            }
-        });
-    }
-}
diff --git a/service/resource-container/examples/android/RCSampleClientApp/app/src/main/java/org/iotivity/service/sample/client/Utils.java b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/java/org/iotivity/service/sample/client/Utils.java
deleted file mode 100644 (file)
index a39afd1..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-package org.iotivity.service.sample.client;
-
-import android.content.Context;
-import android.util.Log;
-import android.widget.Toast;
-
-import org.iotivity.service.RcsException;
-import org.iotivity.service.client.RcsRemoteResourceObject;
-
-public class Utils {
-    public static String resourceInfo(RcsRemoteResourceObject resourceObject)
-            throws RcsException {
-        StringBuilder sb = new StringBuilder();
-
-        sb.append("URI : " + resourceObject.getUri() + "\n");
-        sb.append("Host : " + resourceObject.getAddress() + "\n");
-        for (String type : resourceObject.getTypes()) {
-            sb.append("resourceType : " + type + "\n");
-        }
-
-        for (String itf : resourceObject.getInterfaces()) {
-            sb.append("resourceInterfaces : " + itf + "\n");
-        }
-
-        sb.append("isObservable : " + resourceObject.isObservable() + "\n");
-
-        return sb.toString();
-    }
-
-    public static void showError(Context ctx, String tag, String msg) {
-        Toast.makeText(ctx, msg, Toast.LENGTH_SHORT).show();
-        Log.e(tag, msg);
-    }
-
-    public static void showError(Context ctx, String tag, Exception e) {
-        Toast.makeText(ctx, e.getMessage(), Toast.LENGTH_SHORT).show();
-        Log.e(tag, e.getMessage(), e);
-    }
-}
diff --git a/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/layout/activity_container_client.xml b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/layout/activity_container_client.xml
deleted file mode 100644 (file)
index 09634a3..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
-    android:layout_width="match_parent"
-    android:layout_height="match_parent"
-    android:orientation="vertical"
-    android:id="@+id/main"
-    android:weightSum="1">
-
-    <Button
-        android:layout_width="match_parent"
-        android:layout_height="wrap_content"
-        android:onClick="onDiscoverResourceClick"
-        android:text="@string/discover_resource"
-        android:id="@+id/di" />
-
-    <TextView
-        android:id="@+id/log"
-        android:layout_width="fill_parent"
-        android:layout_height="250dp"
-        android:ems="10"
-        android:layout_weight="0.26"
-        android:layout_below="@+id/di"
-        android:layout_alignParentStart="true" />
-
-</RelativeLayout>
diff --git a/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/values/strings.xml b/service/resource-container/examples/android/RCSampleClientApp/app/src/main/res/values/strings.xml
deleted file mode 100644 (file)
index c5bd024..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-<resources>
-    <string name="app_name">RCSampleClientApp</string>
-    <string name="container_resource">Discover Container Resource</string>
-    <string name="discover_resource">Discover Resource</string>
-</resources>
diff --git a/service/resource-container/examples/android/RCSampleServerApp/.gitignore b/service/resource-container/examples/android/RCSampleServerApp/.gitignore
deleted file mode 100644 (file)
index 8b41237..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-.gradle
-/local.properties
-/.idea
-.DS_Store
-/build
-/captures
-/gradle
diff --git a/service/resource-container/examples/android/RCSampleServerApp/README b/service/resource-container/examples/android/RCSampleServerApp/README
deleted file mode 100644 (file)
index b64c046..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-To build the app
-
-1. build Iotivity with TARGET_OS=android
-
-2. Copy aar files into app/libs folder
-   - {Iotivity_root}/android/android_api/base/build/outputs/aar/iotivity-{TARGET_ARCH}-base-{MODE}.aar
-   - {Iotivity_root}/service/resource-encapsulation/android/service/build/outputs/aar/iotivity-{TARGET_ARCH}-service-{MODE}.aar
-   - {Iotivity_root}/service/resource-container/android/resource-container/build/outputs/aar/iotivity-{TARGET_ARCH}-resource-container-{MODE}.aar
-
-3. Configure dependencies for libs in app/build.gradle
-   - default TARGET_ARCH is armeabi
-   - default MODE is release
-
-   for example, if you build Iotivity as follows,
-
-   $scons TARGET_OS=android TARGET_ARCH=x86 RELEASE=0
-
-   then, dependencies should be modified like below
-
-   dependencies {
-      compile(name:'iotivity-x86-base-debug', ext:'aar')
-      compile(name:'iotivity-x86-service-debug', ext:'aar')
-      compile(name:'iotivity-x86-resource-container-debug', ext:'aar')
-   }
-
-4. In the app/src/main/assets/lib folder copy the following libs:
-   - libBMISensorBundle.so
-   - libDISensorBundle.so
-   From : {Iotivity_root}/out/android/{TARGET_ARCH}/{MODE}/
-   
diff --git a/service/resource-container/examples/android/RCSampleServerApp/app/.gitignore b/service/resource-container/examples/android/RCSampleServerApp/app/.gitignore
deleted file mode 100644 (file)
index 6a384b7..0000000
+++ /dev/null
@@ -1,2 +0,0 @@
-/build
-/libs/*
diff --git a/service/resource-container/examples/android/RCSampleServerApp/app/build.gradle b/service/resource-container/examples/android/RCSampleServerApp/app/build.gradle
deleted file mode 100644 (file)
index bcb90e5..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-apply plugin: 'com.android.application'
-
-android {
-    compileSdkVersion 21
-    buildToolsVersion "21.1.2"
-
-    defaultConfig {
-        applicationId "org.iotivity.service.sample.server"
-        minSdkVersion 21
-        targetSdkVersion 21
-        versionCode 1
-        versionName "1.0"
-    }
-    buildTypes {
-        release {
-            minifyEnabled false
-            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
-        }
-    }
-}
-
-dependencies {
-    compile fileTree(include: ['*.jar'], dir: 'libs')
-    compile(name:'iotivity-base-release', ext:'aar')
-    compile(name:'iotivity-service-release', ext:'aar')
-    compile(name:'iotivity-resource-container-release', ext:'aar')
-}
diff --git a/service/resource-container/src/AndroidBundleResource.h b/service/resource-container/src/AndroidBundleResource.h
new file mode 100644 (file)
index 0000000..c0b074e
--- /dev/null
@@ -0,0 +1,67 @@
+//******************************************************************
+//
+// Copyright 2015 Samsung Electronics 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.
+//
+//-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=
+
+#ifndef ANDROIDBUNDLERESOURCE_H_
+#define ANDROIDBUNDLERESOURCE_H_
+
+#include <map>
+#include <vector>
+#include <string>
+#include <jni.h>
+#include "BundleResource.h"
+#include "ResourceContainerImpl.h"
+
+using namespace std;
+
+namespace OIC
+{
+    namespace Service
+    {
+        class JavaBundleResource: public BundleResource
+        {
+        public:
+            JavaBundleResource();
+            JavaBundleResource(JNIEnv *env, jobject obj, jobject bundleResource, string bundleId,
+                    jobjectArray attributes);
+            virtual ~JavaBundleResource();
+
+            void handleSetAttributeRequest(const std::string& key,
+                    RCSResourceAttributes::Value&&);
+
+            RCSResourceAttributes::Value handleGetAttributeRequest(const std::string& key);
+
+            virtual void handleSetAttributesRequest(RCSResourceAttributes &attrs);
+
+            virtual RCSResourceAttributes& handleGetAttributesRequest();
+
+            virtual void initAttributes();
+        private:
+            // needs to be a GlobalRef
+            jobject m_bundleResource;
+            jobjectArray m_attributes;
+            jclass m_bundleResourceClass;
+            jmethodID m_attributeSetRequestHandler;
+            jmethodID m_attributeGetRequestHandler;
+            string m_bundleId;
+        };
+    }
+}
+
+#endif
index e5cf71c..30ed9aa 100644 (file)
@@ -120,4 +120,4 @@ Java_org_iotivity_resourcecontainer_bundle_api_BaseActivator_getConfiguredResour
     env->SetObjectArrayElement(ret, 3, env->NewStringUTF(conf.address.c_str()));
     return ret;
 }
-#endif
\ No newline at end of file
+#endif
index 6adef62..da45256 100644 (file)
@@ -157,6 +157,16 @@ namespace OIC
             return m_java_bundle;
         }
 
+        void BundleInfoInternal::setSoBundle(bool soBundle)
+        {
+            m_so_bundle = soBundle;
+        }
+
+        bool BundleInfoInternal::getSoBundle()
+        {
+            return m_so_bundle;
+        }
+
         void BundleInfoInternal::setActivatorName( const std::string &activatorName)
         {
             m_activator_name = activatorName;
@@ -220,6 +230,7 @@ namespace OIC
             m_java_bundle = source->getJavaBundle();
             m_activator = source->getBundleActivator();
             m_bundleHandle = source->getBundleHandle();
+            m_activator_name = source->getActivatorName();
         }
     }
 }
index 13337bf..a899983 100644 (file)
@@ -85,6 +85,9 @@ namespace OIC
                 void setJavaBundle(bool javaBundle);
                 bool getJavaBundle();
 
+                void setSoBundle(bool javaBundle);
+                bool getSoBundle();
+
 #if (JAVA_SUPPORT)
                 void setJavaBundleActivatorMethod(jmethodID activator);
                 jmethodID getJavaBundleActivatorMethod();
@@ -96,7 +99,7 @@ namespace OIC
 #endif
 
             private:
-                bool m_loaded, m_activated, m_java_bundle;
+                bool m_loaded, m_activated, m_java_bundle, m_so_bundle;
                 int m_id;
                 activator_t *m_activator;
                 deactivator_t *m_deactivator;
index 93c255f..4d82793 100644 (file)
@@ -64,7 +64,7 @@ namespace OIC
         {
             for (RCSResourceAttributes::iterator it = attrs.begin(); it != attrs.end(); ++it)
             {
-                OC_LOG_V(INFO, CONTAINER_TAG, "set attribute \(%s)'",
+                OC_LOG_V(INFO, "BUNDLE_RESOUCE", "set attribute \(%s)'",
                          std::string(it->key() + "\', with " + it->value().toString()).c_str());
 
                 m_resourceAttributes[it->key()] = it->value();
@@ -74,7 +74,7 @@ namespace OIC
         void BundleResource::setAttribute(const std::string &key,
                                           RCSResourceAttributes::Value &&value, bool notify)
         {
-            OC_LOG_V(INFO, CONTAINER_TAG, "set attribute \(%s)'", std::string(key + "\', with " +
+            OC_LOG_V(INFO, "BUNDLE_RESOUCE", "set attribute \(%s)'", std::string(key + "\', with " +
                      value.toString()).c_str());
 
             m_resourceAttributes[key] = value;
@@ -90,7 +90,7 @@ namespace OIC
 
         RCSResourceAttributes::Value BundleResource::getAttribute(const std::string &key)
         {
-            OC_LOG_V(INFO, CONTAINER_TAG, "get attribute \'(%s)" , std::string(key + "\'").c_str());
+            OC_LOG_V(INFO, "BUNDLE_RESOUCE", "get attribute \'(%s)" , std::string(key + "\'").c_str());
 
             return m_resourceAttributes.at(key);
         }
index 67e71b1..17a490a 100644 (file)
@@ -80,11 +80,11 @@ RCSResourceAttributes::Value JavaBundleResource::handleGetAttributeRequest(
     JavaVM *vm = ResourceContainerImpl::getImplInstance()->getJavaVM(m_bundleId);
 
     JNIEnv *env;
-    int envStat = vm->GetEnv((void **) &env, JNI_VERSION_1_4);
+    int envStat = vm->GetEnv(&env, JNI_VERSION_1_4);
 
     if (envStat == JNI_EDETACHED)
     {
-        if (vm->AttachCurrentThread((void **) &env, NULL) != 0)
+        if (vm->AttachCurrentThread(&env, NULL) != 0)
         {
             OC_LOG_V(ERROR, CONTAINER_TAG,
                     "[JavaBundleResource::handleGetAttributeRequest] Failed to attach ");
index aaff441..e9d02cc 100644 (file)
@@ -120,6 +120,7 @@ namespace OIC
                 // wait for bundles to be activated
             }
             activationLock.unlock();
+            OC_LOG(INFO, CONTAINER_TAG, "Resource container started.");
         }
 
         void ResourceContainerImpl::stopContainer()
@@ -209,14 +210,22 @@ namespace OIC
             {
 #if(JAVA_SUPPORT)
                 ((BundleInfoInternal *) bundleInfo)->setJavaBundle(true);
+                ((BundleInfoInternal *) bundleInfo)->setSoBundle(false);
                 registerJavaBundle(bundleInfo);
 #endif
             }
-            else
+            else if(has_suffix(bundleInfo->getPath(), ".so"))
             {
+                ((BundleInfoInternal *) bundleInfo)->setSoBundle(true);
                 ((BundleInfoInternal *) bundleInfo)->setJavaBundle(false);
                 registerSoBundle(bundleInfo);
             }
+            else{
+                ((BundleInfoInternal *) bundleInfo)->setSoBundle(false);
+                ((BundleInfoInternal *) bundleInfo)->setJavaBundle(false);
+                registerExtBundle(bundleInfo);
+            }
+            // other cases might be for example .apk for android, which are loaded in the wrapper
         }
 
         void ResourceContainerImpl::unregisterBundle(RCSBundleInfo *bundleInfo)
@@ -224,11 +233,11 @@ namespace OIC
             BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) bundleInfo;
             if (bundleInfoInternal->isLoaded() && !bundleInfoInternal->isActivated())
             {
-                if (!bundleInfoInternal->getJavaBundle())
+                if (bundleInfoInternal->getSoBundle())
                 {
                     unregisterBundleSo(bundleInfo->getID());
                 }
-                else
+                else if(bundleInfoInternal->getJavaBundle())
                 {
 #if(JAVA_SUPPORT)
                     unregisterBundleJava(bundleInfo->getID());
@@ -264,7 +273,7 @@ namespace OIC
             string strResourceType = resource->m_resourceType;
             RCSResourceObject::Ptr server = nullptr;
 
-            OC_LOG_V(INFO, CONTAINER_TAG, "Registration of resource (%s)" ,
+            OC_LOG_V(INFO, CONTAINER_TAG, "Registration of resource (%s)" ,
                      std::string(strUri + ", " + strResourceType).c_str());
 
             registrationLock.lock();
@@ -353,6 +362,7 @@ namespace OIC
         {
             RCSResourceAttributes attr;
             std::string strResourceUri = request.getResourceUri();
+            OC_LOG_V(INFO, CONTAINER_TAG, "Container get request for %s",strResourceUri.c_str());
 
             if (m_mapServers.find(strResourceUri) != m_mapServers.end()
                 && m_mapResources.find(strResourceUri) != m_mapResources.end())
@@ -368,6 +378,7 @@ namespace OIC
 
                 }
             }
+            OC_LOG_V(INFO, CONTAINER_TAG, "Container get request for %s finished, %d attributes",strResourceUri.c_str(), attr.size());
 
             return RCSGetResponse::create(std::move(attr), 200);
         }
@@ -379,6 +390,8 @@ namespace OIC
             std::list<std::string> lstAttributes;
             std::string strResourceUri = request.getResourceUri();
 
+            OC_LOG_V(INFO, CONTAINER_TAG, "Container set request for %s, %d attributes",strResourceUri.c_str(), attributes.size());
+
             if (m_mapServers.find(strResourceUri) != m_mapServers.end()
                 && m_mapResources.find(strResourceUri) != m_mapResources.end())
             {
@@ -398,6 +411,7 @@ namespace OIC
                             }
                         }
 
+                        OC_LOG_V(INFO, CONTAINER_TAG, "Calling handleSetAttributeRequest");
                         m_mapResources[strResourceUri]->handleSetAttributesRequest(attr);
                     };
                     boost::thread setThread(setFunction);
@@ -514,12 +528,14 @@ namespace OIC
             else
             {
                 OC_LOG_V(ERROR, CONTAINER_TAG, "Bundle with ID \'(%s)",
-                         std::string(bundleId + "\' is not registered.").c_str());
+                         std::string(bundleId + "\' is not ced.").c_str());
             }
         }
 
         std::list<std::unique_ptr<RCSBundleInfo>> ResourceContainerImpl::listBundles()
         {
+            OC_LOG_V(INFO, CONTAINER_TAG,
+                                 "list bundles (%d)", m_bundles.size());
             std::list<std::unique_ptr<RCSBundleInfo> > ret;
             for (std::map< std::string, BundleInfoInternal * >::iterator it = m_bundles.begin();
                  it != m_bundles.end(); ++it)
@@ -565,7 +581,7 @@ namespace OIC
         {
             if (m_bundles.find(bundleId) != m_bundles.end())
             {
-                if (!m_bundles[bundleId]->getJavaBundle())
+                if (m_bundles[bundleId]->getSoBundle())
                 {
                     removeSoBundleResource(bundleId, resourceUri);
                 }
@@ -592,6 +608,7 @@ namespace OIC
 
         void ResourceContainerImpl::registerSoBundle(RCSBundleInfo *bundleInfo)
         {
+            OC_LOG_V(DEBUG, CONTAINER_TAG, "Register SO bundle");
             const char *error;
 
             activator_t *bundleActivator = NULL;
@@ -601,30 +618,67 @@ namespace OIC
             BundleInfoInternal *bundleInfoInternal = (BundleInfoInternal *) bundleInfo;
             void *bundleHandle = NULL;
             bundleHandle = dlopen(bundleInfo->getPath().c_str(), RTLD_LAZY);
+            if ((error = dlerror()) != NULL)
+            {
+              OC_LOG_V(ERROR, CONTAINER_TAG, "Error while loading .so bundle: (%s)", error);
+            }
 
             if (bundleHandle != NULL)
             {
+                OC_LOG_V(DEBUG, CONTAINER_TAG, "Activator name %s", bundleInfoInternal->getActivatorName().c_str());
                 bundleActivator =
                     (activator_t *) dlsym(bundleHandle,
                                           ("" + bundleInfoInternal->getActivatorName()
                                            + "_externalActivateBundle").c_str());
+                if ((error = dlerror()) != NULL)
+                {
+                  OC_LOG_V(ERROR, CONTAINER_TAG, "Error while loading .so bundle: (%s)", error);
+                }
+                else{
+                  OC_LOG_V(DEBUG, CONTAINER_TAG, "Looked up %s", ("" + bundleInfoInternal->getActivatorName()
+                          + "_externalActivateBundle").c_str());
+                }
                 bundleDeactivator =
                     (deactivator_t *) dlsym(bundleHandle,
                                             ("" + bundleInfoInternal->getActivatorName()
                                              + "_externalDeactivateBundle").c_str());
+                if ((error = dlerror()) != NULL)
+                {
+                  OC_LOG_V(ERROR, CONTAINER_TAG, "Error while loading .so bundle: (%s)", error);
+                }
+                else{
+                  OC_LOG_V(DEBUG, CONTAINER_TAG, "Looked up %s", ("" + bundleInfoInternal->getActivatorName()
+                          + "_externalDeactivateBundle").c_str());
+                }
                 resourceCreator =
                     (resourceCreator_t *) dlsym(bundleHandle,
                                                 ("" + bundleInfoInternal->getActivatorName()
                                                  + "_externalCreateResource").c_str());
+                if ((error = dlerror()) != NULL)
+                {
+                  OC_LOG_V(ERROR, CONTAINER_TAG, "Error while loading .so bundle: (%s)", error);
+                }
+                else{
+                  OC_LOG_V(DEBUG, CONTAINER_TAG, "Looked up %s", ("" + bundleInfoInternal->getActivatorName()
+                          + "_externalCreateResource").c_str());
+                }
                 resourceDestroyer =
                     (resourceDestroyer_t *) dlsym(bundleHandle,
                                                   ("" + bundleInfoInternal->getActivatorName()
                                                    + "_externalDestroyResource").c_str());
+                if ((error = dlerror()) != NULL)
+                {
+                  OC_LOG_V(ERROR, CONTAINER_TAG, "Error while loading .so bundle: (%s)", error);
+                }
+                else{
+                  OC_LOG_V(DEBUG, CONTAINER_TAG, "Looked up %s", ("" + bundleInfoInternal->getActivatorName()
+                          + "_externalDestroyResource").c_str());
+                }
 
 
                 if ((error = dlerror()) != NULL)
                 {
-                    OC_LOG_V(ERROR, CONTAINER_TAG, "Error : (%s)", error);
+                    OC_LOG_V(ERROR, CONTAINER_TAG, "Error while loading .so bundle: (%s)", error);
                 }
                 else
                 {
@@ -642,9 +696,21 @@ namespace OIC
             {
                 if ((error = dlerror()) != NULL)
                 {
-                    OC_LOG_V(ERROR, CONTAINER_TAG, "Error : (%s)", error);
+                    OC_LOG_V(ERROR, CONTAINER_TAG, "Error while loading .so bundle: (%s)", error);
                 }
             }
+            OC_LOG_V(DEBUG, CONTAINER_TAG, "Register SO bundle finished");
+        }
+
+        void ResourceContainerImpl::registerExtBundle(RCSBundleInfo *bundleInfo){
+            OC_LOG_V(INFO, CONTAINER_TAG, "Registering ext bundle (%s)",
+                                 std::string(bundleInfo->getID()).c_str());
+            OC_LOG_V(INFO, CONTAINER_TAG, "Activator name (%s)",
+                                             std::string(bundleInfo->getActivatorName()).c_str());
+
+            m_bundles[bundleInfo->getID()] = ((BundleInfoInternal *)bundleInfo);
+
+            OC_LOG(INFO, CONTAINER_TAG, "Bundle registered");
         }
 
         void ResourceContainerImpl::activateSoBundle(const std::string &bundleId)
@@ -806,7 +872,7 @@ namespace OIC
                 activateJavaBundle(id);
 #endif
             }
-            else
+            else if(m_bundles[id]->getSoBundle())
             {
                 activateSoBundle (id);
             }
@@ -946,6 +1012,8 @@ namespace OIC
             OC_LOG(INFO, CONTAINER_TAG, "Bundle registered");
         }
 
+
+
         void ResourceContainerImpl::activateJavaBundle(string bundleId)
         {
             OC_LOG(INFO, CONTAINER_TAG, "Activating java bundle");
@@ -1005,7 +1073,7 @@ namespace OIC
             OC_LOG_V(INFO, CONTAINER_TAG, "Unregister Java bundle: (%s)", std::string(
                          m_bundles[id]->getID()).c_str());
 
-            OC_LOG(INFO, CONTAINER_TAG, "Destroying JVM");
+            OC_LOG_V(INFO, CONTAINER_TAG, "Destroying JVM");
 
             m_bundleVM[id]->DestroyJavaVM();
 
index e141fec..a68a01e 100644 (file)
@@ -135,6 +135,7 @@ namespace OIC
                 void removeSoBundleResource(const std::string &bundleId,
                                             const std::string &resourceUri);
                 void registerSoBundle(RCSBundleInfo *bundleInfo);
+                void registerExtBundle(RCSBundleInfo *bundleInfo);
                 void discoverInputResource(const std::string &outputResourceUri);
                 void undiscoverInputResource(const std::string &outputResourceUri);
                 void activateBundleThread(const std::string &bundleId);
index 575cb2b..49425a5 100644 (file)
@@ -480,7 +480,7 @@ namespace OIC
             assert(request != nullptr);
 
             auto attrs = getAttributesFromOCRequest(request);
-
+            OC_LOG(INFO, "RESOURCE_OBJECT", ("handleRequestGet " + request->getResourceUri()).c_str());
             return sendResponse(*this, request, invokeHandler(attrs, request, m_getRequestHandler));
         }