001 
002 /*
003  *  JScripter Standard 1.0 - To Script In Java
004  *  Copyright (C) 2008-2011  J.J.Liu<jianjunliu@126.com> <http://www.jscripter.org>
005  *  
006  *  This program is free software: you can redistribute it and/or modify
007  *  it under the terms of the GNU Affero General Public License as published by
008  *  the Free Software Foundation, either version 3 of the License, or
009  *  (at your option) any later version.
010  *  
011  *  This program is distributed in the hope that it will be useful,
012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014  *  GNU Affero General Public License for more details.
015  *  
016  *  You should have received a copy of the GNU Affero General Public License
017  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
018  */
019 
020 package jsx.http.rpc.remote;
021 
022 import js.Index;
023 import js.Initializer;
024 import js.Js;
025 import js.ObjectLike;
026 import jsx.http.rpc.XMLHttpRemote;
027 
028 /**
029  * <p>A base class for objects that support remote reflect services.</p>
030  * 
031  * @author <a href="mailto:jianjunliu@126.com">J.J.Liu (Jianjun Liu)</a> at <a href="http://www.jscripter.org" target="_blank">http://www.jscripter.org</a>
032  */
033 public class Remote extends XMLHttpRemote
034 {
035     /**
036      * <p>The type id for <tt>null</tt> in remote reflect service.</p>
037      * @since 1.0
038      */
039     public final static int TID_NULL      = 0;
040     /**
041      * <p>The type id for strings in remote reflect service.</p>
042      * @since 1.0
043      */
044     public final static int TID_STRING    = 1;
045     /**
046      * <p>The type id for numbers in remote reflect service.</p>
047      * @since 1.0
048      */
049     public final static int TID_NUMBER    = 2;
050     /**
051      * <p>The type id for general objects in remote reflect service.</p>
052      * @since 1.0
053      */
054     public final static int TID_OBJECT    = 3;
055     /**
056      * <p>The type id for fields in remote reflect service.</p>
057      * @since 1.0
058      */
059     public final static int TID_FIELD     = 4;
060     /**
061      * <p>The type id for methods in remote reflect service.</p>
062      * @since 1.0
063      */
064     public final static int TID_METHOD    = 5;
065     /**
066      * <p>The type id for classes in remote reflect service.</p>
067      * @since 1.0
068      */
069     public final static int TID_CLASS     = 6;
070     /**
071      * <p>The type id for arrays in remote reflect service.</p>
072      * @since 1.0
073      */
074     public final static int TID_ARRAY     = 7;
075     /**
076      * <p>The type id for exceptions in remote reflect service.</p>
077      * @since 1.0
078      */
079     public final static int TID_EXCEPTION = 8;
080     /**
081      * <p>The type id for reflectors in remote reflect service.</p>
082      * @since 1.0
083      */
084     public final static int TID_REFLECTOR = 9;
085 
086     /**
087      * <p>Returns a remote object for <tt>null</tt>.</p>
088      * @return A remote object of <tt>null</tt>.
089      * @since 1.0
090      */
091     public static final Remote nul() {
092         return new Remote(
093                 new Initializer().set(TID, TID_NULL).var()
094         );
095     }
096 
097     /**
098      * <p>Creates and returns a remote object for a given number.</p>
099      * @param v A number value.
100      * @return A remote object of the given number.
101      * @since 1.0
102      */
103     public static final Remote create(Number v) {
104         return new Remote(
105                 new Initializer().set(TID, TID_NUMBER)
106                                  .set(VID, Js.toString(v))
107                                  .var()
108         );
109     }
110 
111     /**
112      * <p>Creates and returns a remote object for a given string.</p>
113      * @param v A string value.
114      * @return A remote object of the given string.
115      * @since 1.0
116      */
117     public static final Remote create(String v) {
118         return new Remote(
119                 new Initializer().set(TID, TID_STRING)
120                                  .set(VID, v)
121                                  .var()
122         );
123     }
124 
125     /**
126      * <p>The {@link Index} of type id fields in remote objects.</p>
127      * @since 1.0
128      */
129     public final static Index<Number> TID = new Index<Number>(0);
130     /**
131      * <p>The {@link Index} of value id fields in remote objects.</p>
132      * @since 1.0
133      */
134     public final static Index<String> VID = new Index<String>(1);
135 
136     /**
137      * <p>A typical constructor for a {@link Remote} object.</p>
138      * @param o An initializer for configuration.
139      * @since 1.0
140      */
141     public Remote(ObjectLike o) {
142         super(o);
143     }
144 
145     /**
146      * <p>A typical constructor for an {@link Remote} object.</p>
147      * @param tid The type id for the remote object. The legal type ids are:
148      * <ul>
149      * <li>{@link #TID_ARRAY}</li>
150      * <li>{@link #TID_CLASS}</li>
151      * <li>{@link #TID_EXCEPTION}</li>
152      * <li>{@link #TID_FIELD}</li>
153      * <li>{@link #TID_METHOD}</li>
154      * <li>{@link #TID_NULL}</li>
155      * <li>{@link #TID_NUMBER}</li>
156      * <li>{@link #TID_OBJECT}</li>
157      * <li>{@link #TID_REFLECTOR}</li>
158      * <li>{@link #TID_STRING}</li>
159      * </ul>
160      * @param vid The value id for the remote object.
161      * @since 1.0
162      */
163     public Remote(int tid, String vid) {
164         this(new Initializer().set(TID, tid).set(VID, vid).var());
165     }
166 
167     /**
168      * <p>Gets a string field with an {@link Index} from a given {@link Remote} object.</p>
169      * @param v A given {@link Remote} object.
170      * @param id An {@link Index} for the field.
171      * @return A string value for the field.
172      * @since 1.0
173      */
174     public static final String getString(Remote v, Index<String> id) {
175         return string(v, id);
176     }
177 
178     /**
179      * <p>Gets description for a remote object type.</p>
180      * @param tid A type id for remote objects. The legal type ids are:
181      * <ul>
182      * <li>{@link #TID_ARRAY}</li>
183      * <li>{@link #TID_CLASS}</li>
184      * <li>{@link #TID_EXCEPTION}</li>
185      * <li>{@link #TID_FIELD}</li>
186      * <li>{@link #TID_METHOD}</li>
187      * <li>{@link #TID_NULL}</li>
188      * <li>{@link #TID_NUMBER}</li>
189      * <li>{@link #TID_OBJECT}</li>
190      * <li>{@link #TID_REFLECTOR}</li>
191      * <li>{@link #TID_STRING}</li>
192      * </ul>
193      * @return A short descriptive name for the type.
194      * @since 1.0
195      */
196     public static final String type(int tid) {
197         switch (tid) {
198             case TID_NULL:
199                 return "NULL";
200             case TID_STRING:
201                 return "STRING";
202             case TID_NUMBER:
203                 return "NUMBER";
204             case TID_OBJECT:
205                 return "OBJECT";
206             case TID_FIELD:
207                 return "FIELD";
208             case TID_METHOD:
209                 return "METHOD";
210             case TID_CLASS:
211                 return "CLASS";
212             case TID_ARRAY:
213                 return "ARRAY";
214             case TID_EXCEPTION:
215                 return "EXCEPTION";
216             case TID_REFLECTOR:
217                 return "REFLECTOR";
218             default:
219                 return "UNKNOWN";
220         }
221     }
222 
223     /**
224      * <p>Gets an integer value from a number field with an {@link Index} from a given 
225      * {@link Remote} object.</p>
226      * @param v A given {@link Remote} object.
227      * @param id An {@link Index} for the field.
228      * @return An integer value for the field.
229      * @since 1.0
230      */
231     public static final int get(Remote v, Index<Number> id) {
232         Number r = number(v, id);
233         if (Js.not(r)) {
234             return 0;
235         }
236         return r.intValue();
237     }
238 
239     /**
240      * <p>Asserts a {@link Remote} object is of a type.</p>
241      * @param v A given {@link Remote} object.
242      * @param t A type id.
243      * @throws This method throws a {@link ReflectException} if the types do not match.
244      * @since 1.0
245      */
246     public static final void assertType(Remote v, int t) {
247         if (Js.not(v)) {
248             throw new ReflectException();
249         }
250         if (get(v, TID) != t) {
251             throw new ReflectException();
252         }
253     }
254 
255     /**
256      * <p>Checks whether a {@link Remote} object is a remote object and not just a value.</p>
257      * @param v A given {@link Remote} object.
258      * @return <tt>true</tt> if the {@link Remote} object is a remote object; <tt>false</tt>
259      * if the {@link Remote} object is just a remote value.
260      * @since 1.0
261      */
262     public static final boolean isObject(Remote v) {
263         return Js.be(v) && get(v, TID) >= TID_OBJECT;
264     }
265 
266     /**
267      * <p>Asserts a {@link Remote} object is a remote object and not just a value.</p>
268      * @param v A given {@link Remote} object.
269      * @throws This method throws a {@link ReflectException} if the {@link Remote} 
270      * object is just a remote value and not a remote object.
271      * @since 1.0
272      */
273     public static final void assertObject(Remote v) {
274         if (!isObject(v)) {
275             throw new ReflectException();
276         }
277     }
278 
279     /**
280      * <p>Evaluates a given {@link Remote} object as a string value.</p>
281      * @param v A given {@link Remote} object.
282      * @return A string value of the given {@link Remote} object.
283      * @throws This method throws a {@link ReflectException} if the {@link Remote} 
284      * object is not a remote value of string.
285      * @since 1.0
286      */
287     public static final String getString(Remote v) {
288         assertType(v, TID_STRING);
289         return string(v, VID);
290     }
291 }