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.client;
021 
022 import js.ArrayLike;
023 import jsx.Returnable;
024 import jsx.http.rpc.remote.Callback;
025 import jsx.http.rpc.remote.Objective;
026 import jsx.http.rpc.remote.Reflector;
027 import jsx.http.rpc.remote.Remote;
028 
029 /**
030  * <p>A client reflection to <tt>java.lang.Class</tt> with the help of {@link Reflector}.</p>
031  * <p>Note that a object of this class is an {@link Objective} at client-side in that 
032  * when finalized it automatically tries to asynchronously dereference its server-side entity.</p>
033  * 
034  * @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>
035  */
036 public final class CClass extends CObject
037 {
038     /**
039      * <p>The typical constructor for a {@link CClass} reflection.</p>
040      * @param reflector The {@link Reflector} object associated with the {@link CClass} object 
041      * being constructed.
042      * @param remote The underlying {@link Remote} object associated with the {@link CClass} 
043      * object being constructed.
044      * @since 1.0
045      */
046     protected CClass(Reflector reflector, Remote remote) {
047         super(reflector, remote);
048     }
049 
050     /**
051      * <p>Synchronously creates a {@link CClass} reflection from a {@link Remote} object 
052      * with a {@link Reflector}.</p>
053      * <p>This method synchronously increases server-side references to the {@link Remote} object.</p>
054      * @param reflector The {@link Reflector} object associated with the {@link CClass} object 
055      * being constructed.
056      * @param remote The underlying {@link Remote} object associated with the {@link CClass} 
057      * object being constructed.
058      * @return The created {@link CClass} reflection.
059      * @since 1.0
060      */
061     public static CClass create(Reflector reflector, Remote remote) {
062         reflector.increase(cat(remote));
063         return new CClass(reflector, remote);
064     }
065 
066     /**
067      * <p>Asynchronously creates a {@link CClass} reflection from a {@link Remote} object 
068      * with a {@link Reflector}.</p>
069      * <p>This method asynchronously increases server-side references to the {@link Remote} object.</p>
070      * @param reflector The {@link Reflector} object associated with the {@link CClass} object 
071      * being constructed.
072      * @param remote The underlying {@link Remote} object associated with the {@link CClass} 
073      * object being constructed.
074      * @param rt A {@link Returnable} to return the created {@link CClass} reflection.
075      * @since 1.0
076      */
077     public static void create(final Reflector reflector, final Remote remote, final Returnable<CClass> rt) {
078         reflector.increase(cat(remote), new Callback<Remote>() {
079             @Override
080             public void onCall(Remote ret) {
081                 rt.onReturn(new CClass(reflector, remote));
082             }
083         });
084     }
085 
086     /**
087      * <p>Synchronously asks server-side to load a named class and return it as a 
088      * {@link CClass} reflection.</p>
089      * @param name The name of the class to load.
090      * @param ref The {@link Reflector} object providing the service.
091      * @return The {@link CClass} reflection for the loaded class.
092      * @since 1.0
093      */
094     public static final CClass forName(String name, Reflector ref) {
095         return create(ref, ref.forName(name));
096     }
097 
098     /**
099      * <p>Asynchronously asks server-side to load a named class and return it as a 
100      * {@link CClass} reflection.</p>
101      * @param name The name of the class to load.
102      * @param ref The {@link Reflector} object providing the service.
103      * @param rt A {@link Returnable} to return the {@link CClass} reflection for the loaded class.
104      * @since 1.0
105      */
106     public static final void forName(String name, Reflector ref, Returnable<CClass> rt) {
107         ref.forName(name, Callback.create(relay(ref, rt)));
108     }
109 
110     /**
111      * <p>Gets the name of the server-side class of reflected by this {@link CClass} reflection.</p>
112      * @return The name of the server-side class.
113      * @since 1.0
114      */
115     public final String getName() {
116         Remote.assertType(remote, Remote.TID_CLASS);
117         return Remote.getString(remote, Remote.VID);
118     }
119 
120     /**
121      * <p>Synchronously asks server-side to create an instance of the reflected class and 
122      * return it as a {@link CObject} reflection.</p>
123      * @return The {@link CObject} reflection for the created server-side object.
124      * @since 1.0
125      */
126     public final CObject newInstance() {
127         return CObject.create(reflector, reflector.newInstance(remote));
128     }
129 
130     /**
131      * <p>Asynchronously asks server-side to create an instance of the reflected class and 
132      * return it as a {@link CObject} reflection.</p>
133      * @param rt A {@link Returnable} to return the {@link CObject} reflection for the created 
134      * server-side object.
135      * @since 1.0
136      */
137     public final void newInstance(Returnable<CObject> rt) {
138         reflector.newInstance(
139                 remote,
140                 Callback.create(CObject.relay(reflector, rt))
141         );
142     }
143 
144     /**
145      * <p>Synchronously asks server-side to get a named field of the reflected class and 
146      * return it as a {@link CField} reflection.</p>
147      * @param name The name for the field.
148      * @return The {@link CField} reflection for the server-side field.
149      * @since 1.0
150      */
151     public final CField getField(String name) {
152         return CField.create(reflector, reflector.getField(remote, name));
153     }
154 
155     /**
156      * <p>Asynchronously asks server-side to get a named field of the reflected class and 
157      * return it as a {@link CField} reflection.</p>
158      * @param name The name for the field.
159      * @param rt A {@link Returnable} to return the {@link CField} reflection for the 
160      * server-side field.
161      * @since 1.0
162      */
163     public final void getField(String name, Returnable<CField> rt) {
164         reflector.getField(
165                 remote,
166                 name,
167                 Callback.create(CField.relay(reflector, rt))
168         );
169     }
170 
171     /**
172      * <p>Synchronously asks server-side to get a named method of the reflected class and 
173      * return it as a {@link CMethod} reflection.</p>
174      * @param name The name for the method.
175      * @return The {@link CMethod} reflection for the server-side method.
176      * @since 1.0
177      */
178     public final CMethod getMethod(String name) {
179         return CMethod.create(reflector, reflector.getMethod(remote, name));
180     }
181 
182     /**
183      * <p>Asynchronously asks server-side to get a named method of the reflected class and 
184      * return it as a {@link CMethod} reflection.</p>
185      * @param name The name for the method.
186      * @param rt A {@link Returnable} to return the {@link CMethod} reflection for the 
187      * server-side method.
188      * @since 1.0
189      */
190     public final void getMethod(String name, Returnable<CMethod> rt) {
191         reflector.getMethod(
192                 remote,
193                 name,
194                 Callback.create(CMethod.relay(reflector, rt))
195         );
196     }
197 
198     /**
199      * <p>Synchronously asks server-side to get a named method with a given parameter types of 
200      * the reflected class and return it as a {@link CMethod} reflection.</p>
201      * @param name The name for the method.
202      * @param types An array of parameters for the method to get.
203      * @return The {@link CMethod} reflection for the server-side method.
204      * @since 1.0
205      */
206     public final CMethod getMethod(String name, ArrayLike<String> types) {
207         return CMethod.create(reflector, reflector.getMethod(remote, name, types));
208     }
209 
210     /**
211      * <p>Asynchronously asks server-side to get a named method with a given parameter types of 
212      * the reflected class and return it as a {@link CMethod} reflection.</p>
213      * @param name The name for the method.
214      * @param types An array of parameters for the method to get.
215      * @param rt A {@link Returnable} to return the {@link CMethod} reflection for the server-side method.
216      * @since 1.0
217      */
218     public final void getMethod(String name, ArrayLike<String> types, Returnable<CMethod> rt) {
219         reflector.getMethod(
220                 remote,
221                 name,
222                 types,
223                 Callback.create(CMethod.relay(reflector, rt))
224         );
225     }
226 
227     /**
228      * <p>Relays a given {@link Returnable} for asynchronous service of {@link Reflector}.</p>
229      * @param ref The associated {@link Reflector} object.
230      * @param rt The given {@link Returnable} to be relayed.
231      * @return The relaying {@link Returnable}.
232      * @since 1.0
233      */
234     public static Returnable<Remote> relay(final Reflector ref, final Returnable<CClass> rt) {
235         return new Returnable<Remote>() {
236             public void onReturn(Remote r) {
237                 create(ref, r, rt);
238             }
239         };
240     }
241 }