tizen 2.4 release
[framework/web/wrt-plugins-common.git] / src / CommonsJavaScript / PrivateObject.h
1 /*
2  * Copyright (c) 2011 Samsung Electronics Co., Ltd All Rights Reserved
3  *
4  *    Licensed under the Apache License, Version 2.0 (the "License");
5  *    you may not use this file except in compliance with the License.
6  *    You may obtain a copy of the License at
7  *
8  *        http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *    Unless required by applicable law or agreed to in writing, software
11  *    distributed under the License is distributed on an "AS IS" BASIS,
12  *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *    See the License for the specific language governing permissions and
14  *    limitations under the License.
15  */
16 #ifndef WRTDEVICEAPIS_COMMONSJAVASCRIPT_PRIVATEOBJECT_H_
17 #define WRTDEVICEAPIS_COMMONSJAVASCRIPT_PRIVATEOBJECT_H_
18
19 #include <JavaScriptCore/JavaScript.h>
20 #include <dpl/noncopyable.h>
21 #include <dpl/assert.h>
22 #include <Commons/Exception.h>
23 #include <Commons/TypeTraits.h>
24 #include <CommonsJavaScript/JSLifeManager.h>
25
26 namespace WrtDeviceApis {
27 namespace CommonsJavaScript {
28 template<class T>
29 struct NoAcquire
30 {
31     void acquire(T*)
32     {}
33
34   protected:
35     ~NoAcquire()
36     {}
37 };
38
39 template<class T>
40 struct AcquireByProtect
41 {
42     void acquire(T* object)
43     {
44         Assert(object && "Object passed to protect can't be NULL.");
45         JSValueSafeProtect(object->getContext(), object->getObject());
46     }
47
48   protected:
49     ~AcquireByProtect()
50     {}
51 };
52
53 template<class T>
54 struct NoRelease
55 {
56     void release(T* object)
57     {
58         (void)object;
59     }
60
61   protected:
62     ~NoRelease()
63     {}
64 };
65
66 template<class T>
67 struct ReleaseByDelete
68 {
69     void release(T* object)
70     {
71         delete object->getObject();
72     }
73
74   protected:
75     ~ReleaseByDelete()
76     {}
77 };
78
79 template<class T>
80 struct ReleaseByUnprotect
81 {
82     void release(T* object)
83     {
84         Assert(object && "Object passed to unprotect can't be NULL.");
85         JSValueSafeUnprotect(object->getContext(), object->getObject());
86     }
87
88   protected:
89     ~ReleaseByUnprotect()
90     {}
91 };
92
93 template<class T>
94 struct NoOwnership : protected NoAcquire<T>,
95     protected NoRelease<T>
96 {
97   protected:
98     ~NoOwnership()
99     {}
100 };
101
102 template<class T>
103 struct OwnershipByAcquisition : protected NoAcquire<T>,
104     protected ReleaseByDelete<T>
105 {
106   protected:
107     ~OwnershipByAcquisition()
108     {}
109 };
110
111 template<class T>
112 struct OwnershipByProtection : protected AcquireByProtect<T>,
113     protected ReleaseByUnprotect<T>
114 {
115   protected:
116     ~OwnershipByProtection()
117     {}
118 };
119
120 template<class PrivateClass,
121          template <class> class OwnershipPolicy = OwnershipByAcquisition>
122 class PrivateObject : public DPL::Noncopyable,
123     protected OwnershipPolicy<PrivateObject<PrivateClass, OwnershipPolicy> >
124 {
125   public:
126     typedef PrivateClass ObjectType;
127
128   public:
129     /**
130      * Creates storage object for JS private data.
131      * @param context JS (root/global) context.
132      * @param object Object to store.
133      * @throw NullPointerException When object is pointer and is set to NULL.
134      */
135     PrivateObject(JSContextRef context,
136                   const PrivateClass& object) :
137         m_context(context),
138         m_object(object)
139     {
140         Assert(NULL != m_context && "Context is NULL.");
141         Assert(!Commons::IsNull<PrivateClass>::value(
142                    object) && "Object is NULL.");
143         this->acquire(this);
144     }
145
146     /**
147      * Destroys instance of the object.
148      */
149     virtual ~PrivateObject()
150     {
151         this->release(this);
152     }
153
154     /**
155      * Gets stored JS context.
156      * @return JavaScript context.
157      */
158     virtual JSContextRef getContext() const
159     {
160         return m_context;
161     }
162
163     /**
164      * Gets stored object.
165      * @return Stored object.
166      */
167     virtual PrivateClass getObject() const
168     {
169         return m_object;
170     }
171
172   protected:
173     JSContextRef m_context; ///< JS context.
174     PrivateClass m_object; ///< Stored object.
175 };
176
177 /**
178  * Specialization for type void.
179  */
180 template<>
181 class PrivateObject<void, NoOwnership> : private DPL::Noncopyable
182 {
183   public:
184     /**
185      * Creates storage object for JS private data.
186      * @param context JS (root/global) context.
187      * @remarks Takes ownership over stored object.
188      */
189     explicit PrivateObject(JSContextRef context) : m_context(context)
190     {
191         Assert(NULL != m_context && "Context is NULL.");
192     }
193
194     /**
195      * Destroys instance of the object.
196      */
197     virtual ~PrivateObject()
198     {}
199
200     /**
201      * Gets stored JS context.
202      * @return JavaScript context.
203      */
204     virtual JSContextRef getContext() const
205     {
206         return m_context;
207     }
208
209   protected:
210     JSContextRef m_context;
211 };
212
213 template<class C>
214 struct PrivateObjectT
215 {
216     typedef PrivateObject<C, NoOwnership> Type;
217 };
218
219 template<class C>
220 struct PrivateObjectT<C*>
221 {
222     typedef PrivateObject<C*, OwnershipByAcquisition> Type;
223 };
224
225 template<>
226 struct PrivateObjectT<JSObjectRef>
227 {
228     typedef PrivateObject<JSObjectRef, NoOwnership> Type;
229 };
230
231 template<>
232 struct PrivateObjectT<void>
233 {
234     typedef PrivateObject<void, NoOwnership> Type;
235 };
236 } // CommonsJavaScript
237 } // WrtDeviceApis
238
239 #endif /* PRIVATEOBJECT_H_ */