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.reflect.Method</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 class CMethod extends CObject
037 {
038     /**
039      * <p>The typical constructor for a {@link CMethod} reflection.</p>
040      * @param reflector The {@link Reflector} object associated with the {@link CMethod} object 
041      * being constructed.
042      * @param remote The underlying {@link Remote} object associated with the {@link CMethod} 
043      * object being constructed.
044      * @since 1.0
045      */
046     protected CMethod(Reflector reflector, Remote remote) {
047         super(reflector, remote);
048     }
049 
050     /**
051      * <p>Synchronously creates a {@link CMethod} 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 CMethod} object 
055      * being constructed.
056      * @param remote The underlying {@link Remote} object associated with the {@link CMethod} 
057      * object being constructed.
058      * @return The created {@link CMethod} reflection.
059      * @since 1.0
060      */
061     public static CMethod create(Reflector reflector, Remote remote) {
062         reflector.increase(cat(remote));
063         return new CMethod(reflector, remote);
064     }
065 
066     /**
067      * <p>Asynchronously creates a {@link CMethod} 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 CMethod} object 
071      * being constructed.
072      * @param remote The underlying {@link Remote} object associated with the {@link CMethod} 
073      * object being constructed.
074      * @param rt A {@link Returnable} to return the created {@link CMethod} reflection.
075      * @since 1.0
076      */
077     public static void create(final Reflector reflector, final Remote remote, final Returnable<CMethod> rt) {
078         reflector.increase(cat(remote), new Callback<Remote>() {
079             @Override
080             public void onCall(Remote ret) {
081                 rt.onReturn(new CMethod(reflector, remote));
082             }
083         });
084     }
085 
086     /**
087      * <p>Synchronously invokes the server-side static method entity with no arguments and 
088      * returns the result as a {@link Remote} value or object.</p>
089      * @return The result of the remote invocation.
090      * @since 1.0
091      */
092     public final Remote invoke() {
093         return reflector.invoke(remote);
094     }
095 
096     /**
097      * <p>Synchronously invokes the server-side static method entity with arguments and 
098      * returns the result as a {@link Remote} value or object.</p>
099      * @param args An array of arguments. The 1st argument in the array must be the base object
100      * for an instance method or <tt>null</tt> for a static one.
101      * @return The result of the remote invocation.
102      * @since 1.0
103      */
104     public final Remote invoke(ArrayLike<Remote> args) {
105         return reflector.invoke(remote, args);
106     }
107 
108     /**
109      * <p>Asynchronously invokes the server-side static method entity with no arguments and 
110      * returns the result as a {@link Remote} value or object.</p>
111      * @param rt A {@link Returnable} to return the result of the remote invocation.
112      * @since 1.0
113      */
114     public final void invoke(final Returnable<Remote> rt) {
115         reflector.increase(cat(), new Callback<Remote>() {
116             @Override
117             public void onCall(Remote ret) {
118                 reflector.invoke(remote, new Callback<Remote>() {
119                     @Override
120                     public void onCall(Remote ret) {
121                         rt.onReturn(ret);
122                         reflector.decrease(cat(), null);
123                     }
124                 });
125             }
126             
127         });
128     }
129 
130     /**
131      * <p>Asynchronously invokes the server-side static method entity with arguments and 
132      * returns the result as a {@link Remote} value or object.</p>
133      * @param args An array of arguments. The 1st argument in the array must be the base object
134      * for an instance method or <tt>null</tt> for a static one.
135      * @param rt A {@link Returnable} to return the result of the remote invocation.
136      * @since 1.0
137      */
138     public final void invoke(final ArrayLike<Remote> args, final Returnable<Remote> rt) {
139         reflector.increase(cat(args), new Callback<Remote>() {
140             @Override
141             public void onCall(Remote ret) {
142                 reflector.invoke(remote, args, new Callback<Remote>() {
143                     @Override
144                     public void onCall(Remote ret) {
145                         rt.onReturn(ret);
146                         reflector.decrease(cat(args), null);
147                     }
148                 });
149             }
150             
151         });
152     }
153 
154     /**
155      * <p>Relays a given {@link Returnable} for asynchronous service of {@link Reflector}.</p>
156      * @param ref The associated {@link Reflector} object.
157      * @param rt The given {@link Returnable} to be relayed.
158      * @return The relaying {@link Returnable}.
159      * @since 1.0
160      */
161     public static Returnable<Remote> relay(final Reflector ref, final Returnable<CMethod> rt) {
162         return new Returnable<Remote>() {
163             public void onReturn(Remote r) {
164                 create(ref, r, rt);
165             }
166         };
167     }
168 }