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.Js;
023 import js.Vars;
024 import jsx.Returnable;
025 import jsx.http.rpc.remote.Callback;
026 import jsx.http.rpc.remote.Objective;
027 import jsx.http.rpc.remote.Reflector;
028 import jsx.http.rpc.remote.Remote;
029 
030 /**
031  * <p>A client reflection to <tt>java.lang.Exception</tt> with the help of {@link Reflector}.</p>
032  * <p>Note that a object of this class is an {@link Objective} at client-side in that 
033  * when finalized it automatically tries to asynchronously dereference its server-side entity.</p>
034  * 
035  * @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>
036  */
037 public class CException extends CObject
038 {
039     /**
040      * <p>The typical constructor for a {@link CException} reflection.</p>
041      * @param reflector The {@link Reflector} object associated with the {@link CException} object 
042      * being constructed.
043      * @param remote The underlying {@link Remote} object associated with the {@link CException} 
044      * object being constructed.
045      * @since 1.0
046      */
047     protected CException(Reflector reflector, Remote remote) {
048         super(reflector, remote);
049     }
050 
051     /**
052      * <p>Synchronously creates a {@link CException} reflection from a {@link Remote} object 
053      * with a {@link Reflector}.</p>
054      * <p>This method synchronously increases server-side references to the {@link Remote} object.</p>
055      * @param reflector The {@link Reflector} object associated with the {@link CException} object 
056      * being constructed.
057      * @param remote The underlying {@link Remote} object associated with the {@link CException} 
058      * object being constructed.
059      * @return The created {@link CException} reflection.
060      * @since 1.0
061      */
062     public static CException create(Reflector reflector, Remote remote) {
063         reflector.increase(cat(remote));
064         return new CException(reflector, remote);
065     }
066 
067     /**
068      * <p>Asynchronously creates a {@link CException} reflection from a {@link Remote} object 
069      * with a {@link Reflector}.</p>
070      * <p>This method asynchronously increases server-side references to the {@link Remote} object.</p>
071      * @param reflector The {@link Reflector} object associated with the {@link CException} object 
072      * being constructed.
073      * @param remote The underlying {@link Remote} object associated with the {@link CException} 
074      * object being constructed.
075      * @param rt A {@link Returnable} to return the created {@link CException} reflection.
076      * @since 1.0
077      */
078     public static void create(final Reflector reflector, final Remote remote, final Returnable<CException> rt) {
079         reflector.increase(cat(remote), new Callback<Remote>() {
080             @Override
081             public void onCall(Remote ret) {
082                 rt.onReturn(new CException(reflector, remote));
083             }
084         });
085     }
086 
087     private CMethod getCause;
088 
089     /**
090      * <p>Synchronously gets cause from the server-side exception entity and returns the result.</p>
091      * @return The result of the remote invocation.
092      * @since 1.0
093      */
094     public final String getCause() {
095         if (Js.not(getCause)) {
096             getCause = getRemoteClass().getMethod("getCause");
097         }
098         return Remote.getString(getCause.invoke(
099                 new Vars<Remote>().add(remote).var()
100         ));
101     }
102 
103     /**
104      * <p>Asynchronously gets the {@link Exception#getCause()} method on the server-side entity.</p>
105      * @param rt A {@link Returnable} to return the result of the remote invocation.
106      * @since 1.0
107      */
108     public final void getGetCause(final Returnable<CMethod> rt) {
109         if (Js.not(getCause)) {
110             getRemoteClass(new Returnable<CClass>() {
111                 public void onReturn(CClass cc) {
112                     cc.getMethod(
113                             "getCause",
114                             new Returnable<CMethod>() {
115                                 public void onReturn(CMethod cm) {
116                                     getCause = cm;
117                                     rt.onReturn(getCause);
118                                 }
119                             }
120                     );
121                 }
122             });
123         } else {
124             rt.onReturn(getCause);
125         }
126     }
127 
128     /**
129      * <p>Asynchronously gets cause from the server-side exception entity and returns the result.</p>
130      * @param rt A {@link Returnable} to return the result of the remote invocation.
131      * @since 1.0
132      */
133     public final void getCause(final Returnable<String> rt) {
134         getGetCause(new Returnable<CMethod>() {
135             public void onReturn(CMethod cm) {
136                 cm.invoke(
137                         cat(),
138                         relay(rt)
139                 );
140             }
141         });
142     }
143 
144     private CMethod getMessage;
145 
146     /**
147      * <p>Synchronously gets detail message from the server-side exception entity and returns the result.</p>
148      * @return The result of the remote invocation.
149      * @since 1.0
150      */
151     public final String getMessage() {
152         if (Js.not(getMessage)) {
153             getMessage = getRemoteClass().getMethod("getMessage");
154         }
155         return Remote.getString(getMessage.invoke(
156                 new Vars<Remote>().add(remote).var()
157         ));
158     }
159 
160     /**
161      * <p>Asynchronously gets the {@link Exception#getMessage()} method on the server-side entity.</p>
162      * @param rt A {@link Returnable} to return the result of the remote invocation.
163      * @since 1.0
164      */
165     public final void getGetMessage(final Returnable<CMethod> rt) {
166         if (Js.not(getMessage)) {
167             getRemoteClass(new Returnable<CClass>() {
168                 public void onReturn(CClass cc) {
169                     cc.getMethod(
170                             "getMessage",
171                             new Returnable<CMethod>() {
172                                 public void onReturn(CMethod cm) {
173                                     getMessage = cm;
174                                     rt.onReturn(getMessage);
175                                 }
176                             }
177                     );
178                 }
179             });
180         } else {
181             rt.onReturn(getMessage);
182         }
183     }
184 
185     /**
186      * <p>Asynchronously gets detail message from the server-side exception entity and returns the result.</p>
187      * @param rt A {@link Returnable} to return the result of the remote invocation.
188      * @since 1.0
189      */
190     public final void getMessage(final Returnable<String> rt) {
191         getGetMessage(new Returnable<CMethod>() {
192             public void onReturn(CMethod cm) {
193                 cm.invoke(
194                         cat(),
195                         relay(rt)
196                 );
197             }
198         });
199     }
200 
201     /**
202      * <p>Relays a given {@link Returnable} for asynchronous service of {@link Reflector}.</p>
203      * @param ref The associated {@link Reflector} object.
204      * @param rt The given {@link Returnable} to be relayed.
205      * @return The relaying {@link Returnable}.
206      * @since 1.0
207      */
208     public static Returnable<Remote> relay(final Reflector ref, final Returnable<CException> rt) {
209         return new Returnable<Remote>() {
210             public void onReturn(Remote r) {
211                 create(ref, r, rt);
212             }
213         };
214     }
215 }