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;
021 
022 import js.Disposable;
023 import js.Js;
024 import js.Vars;
025 import js.core.JsFunction;
026 import jsx.core.ArrayLikes;
027 
028 /**
029  * <p>A utility class, with its static methods, providing facilities to create JavaScript
030  * code at runtime.</p>
031  * 
032  * @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>
033  */
034 public final class Code extends Disposable
035 {
036     private Code() {}
037 
038     /**
039      * <p>Statically creates code that joins three strings into one.</p>
040      * @param s1 The 1st string to join.
041      * @param s2 The 2nd string to join.
042      * @param s3 The 3rd string to join.
043      * @return The newly created JavaScript code.
044      * @since 1.0
045      */
046     public final static String join(Object s1, Object s2, Object s3) {
047         return ArrayLikes.join(
048                 new Vars<Object>().add(s1).add(s2).add(s3).var(),
049                 ""
050         );
051     }
052 
053     /**
054      * <p>Statically creates code that quotes a string.</p>
055      * @param s The string to quote.
056      * @return The newly created JavaScript code.
057      * @since 1.0
058      */
059     public static final String qt(String s) {
060         return join("'", s, "'");
061     }
062 
063     /**
064      * <p>Statically creates code that joins two strings with a symbol of slash.</p> 
065      * @param p The parent name.
066      * @param c The child name.
067      * @return The newly created JavaScript code.
068      * @since 1.0
069      */
070     public static final String sub(String p, String c) {
071         return join(p, "/", c);
072     }
073 
074     /**
075      * <p>Statically creates code that joins two strings with a symbol of dash.</p> 
076      * @param s The string preceding the hyphen.
077      * @param t The string succeeding the hyphen.
078      * @return The newly created JavaScript code.
079      * @since 1.0
080      */
081     public static final String hyphen(String s, String t) {
082         return join(s, "-", t);
083     }
084 
085     /**
086      * <p>Statically creates code that joins two strings with a symbol of underline.</p>
087      * @param s The string preceding the underline.
088      * @param t The string succeeding the underline.
089      * @return The newly created JavaScript code.
090      * @since 1.0
091      */
092     public static final String underline(String s, String t) {
093         return join(s, "_", t);
094     }
095 
096     /**
097      * <p>Statically creates code that joins two strings with a symbol of period.</p> 
098      * @param q The qualifier.
099      * @param r The reference.
100      * @return The newly created JavaScript code.
101      * @since 1.0
102      */
103     public static final String ref(String q, String r) {
104         return join(q, ".", r);
105     }
106 
107     /**
108      * <p>Statically creates code that joins two expressions with a symbol of comma.</p> 
109      * @param a The 1st expression.
110      * @param b The 2nd expression.
111      * @return The newly created JavaScript code.
112      * @since 1.0
113      */
114     public static final String comma(String a, String b) {
115         return join(a, ",", b);
116     }
117 
118     /**
119      * <p>Statically creates code that lists two strings with a blank separator.</p> 
120      * @param a The 1st expression.
121      * @param b The 2nd expression.
122      * @return The newly created JavaScript code.
123      * @since 1.0
124      */
125     public static final String list(String a, String b) {
126         return join(a, " ", b);
127     }
128 
129     /**
130      * <p>Statically creates code that creates an assignment expression with the two
131      * existing expressions.</p> 
132      * @param a The 1st expression.
133      * @param b The 2nd expression.
134      * @return The newly created JavaScript code.
135      * @since 1.0
136      */
137     public static final String asg(String a, String b) {
138         return join(a, "=", b);
139     }
140 
141     /**
142      * <p>Statically creates code that creates an assignment-adding expression with the two
143      * existing expressions.</p> 
144      * @param a The 1st expression.
145      * @param b The 2nd expression.
146      * @return The newly created JavaScript code.
147      * @since 1.0
148      */
149     public static final String aasg(String a, String b) {
150         return join(a, AASG, b);
151     }
152 
153     /**
154      * <p>Statically creates code that creates an add expression with the two
155      * existing expressions.</p> 
156      * @param a The 1st expression.
157      * @param b The 2nd expression.
158      * @return The newly created JavaScript code.
159      * @since 1.0
160      */
161     public static final String add(String a, String b) {
162         return join(a, "+", b);
163     }
164 
165     /**
166      * <p>Statically creates code that creates code that dynamically lists the two
167      * expressions with a blank separator.</p> 
168      * @param a The 1st expression.
169      * @param b The 2nd expression.
170      * @return The newly created JavaScript code.
171      * @since 1.0
172      */
173     public static final String qlist(String a, String b) {
174         return add(add(a, "' '"), b);
175     }
176 
177     /**
178      * <p>Statically creates code that creates a conditional expression.</p> 
179      * @param c The conditional expression.
180      * @param a The 1st expression.
181      * @param b The 2nd expression.
182      * @return The newly created JavaScript code.
183      * @since 1.0
184      */
185     public static final String cond(String c, String a, String b) {
186         return join(c, "?", join(a, ":", b));
187     }
188 
189     /**
190      * <p>Statically creates code that invokes a method with no arguments.</p> 
191      * @param met The method name.
192      * @return The newly created JavaScript code.
193      * @since 1.0
194      */
195     public static final String invoke(String met) {
196         return join(met, "(", ")");
197     }
198 
199     /**
200      * <p>Statically creates code that invokes a method with arguments.</p> 
201      * @param met The method name.
202      * @param arg The argument(s).
203      * @return The newly created JavaScript code.
204      * @since 1.0
205      */
206     public static final String invoke(String met, String arg) {
207         return Js.add(met, join("(", arg, ")"));
208     }
209 
210     /**
211      * <p>Statically creates code that calls a method at an object with no arguments.</p> 
212      * @param met The method name.
213      * @param obj The base object.
214      * @return The newly created JavaScript code.
215      * @since 1.0
216      */
217     public static final String call(String met, String obj) {
218         return invoke(ref(met, "call"), obj);
219     }
220 
221     /**
222      * <p>Statically creates code that calls a method at the base object with arguments.</p> 
223      * @param met The method name.
224      * @param obj The base object.
225      * @param arg The argument(s).
226      * @return The newly created JavaScript code.
227      * @since 1.0
228      */
229     public static final String call(String met, String obj, String arg) {
230         return invoke(ref(met, "call"), comma(obj, arg));
231     }
232 
233     /**
234      * <p>Statically creates code that dynamically creates a block with statements.</p> 
235      * @param stmts The statement(s).
236      * @return The newly created JavaScript code.
237      * @since 1.0
238      */
239     public static final String block(String stmts) {
240         return join("{", stmts, "}");
241     }
242 
243     /**
244      * <p>Statically creates code that dynamically defines a function with statements.</p> 
245      * @param stmts The statement(s).
246      * @return The newly created JavaScript code.
247      * @since 1.0
248      */
249     public static final String function(String stmts) {
250         return Js.add(invoke("function"), block(stmts));
251     }
252 
253     /**
254      * <p>Statically creates code that dynamically creates a NOT expression.</p> 
255      * @param e The expression to apply a NOT-operation for.
256      * @return The newly created JavaScript code.
257      * @since 1.0
258      */
259     public static final String not(String e) {
260         return Js.add("!", e);
261     }
262 
263     /**
264      * <p>Statically creates code that dynamically creates an IF-NOT expression.</p> 
265      * @param e The expression to apply a NOT-operation for.
266      * @param s The statement for the if-statement.
267      * @return The newly created JavaScript code.
268      * @since 1.0
269      */
270     public static final String ifnot(String e, String s) {
271         return Js.add(invoke("if", not(e)), s);
272     }
273 
274     /**
275      * <p>Statically creates code that dynamically creates a statement from the statement.</p> 
276      * @param e The expression for the expressive statement.
277      * @return The newly created JavaScript code.
278      * @since 1.0
279      */
280     public static final String stmt(String e) {
281         return Js.add(e, ";");
282     }
283 
284     /**
285      * <p>Statically creates code that dynamically returns the expression.</p> 
286      * @param e The expression to return.
287      * @return The newly created JavaScript code.
288      * @since 1.0
289      */
290     public static final String ret(String e) {
291         return stmt(list("return", e));
292     }
293 
294     /**
295      * <p>Statically creates code that dynamically creates an event handler with a
296      * single statement to return an expression.</p> 
297      * @param e The expression to return.
298      * @return The newly created JavaScript code.
299      * @since 1.0
300      */
301     public static final JsFunction<Boolean> handler(String e) {
302         return Js.function(
303                 Js.add(
304                         stmt(e),
305                         ret("true")
306                 )
307         );
308     }
309 
310     /**
311      * <p>Statically creates code that dynamically creates a regular expression.</p> 
312      * @param r The regular expression.
313      * @return The newly created JavaScript code.
314      * @since 1.0
315      */
316     public static final String re(String r) {
317         return join("/", r, "/");
318     }
319 
320     /**
321      * <p>Statically creates code that dynamically creates a regular expression with
322      * an ignore-case option.</p>
323      * @param r The regular expression.
324      * @return The newly created JavaScript code.
325      * @since 1.0
326      */
327     public static final String regi(String r) {
328         return join(re(r), "g", "i");
329     }
330 
331     /**
332      * <p>Statically creates code that dynamically tests the regular express against 
333      * the other string.</p> 
334      * @param r The regular expression to test.
335      * @param s The string to test against.
336      * @return The newly created JavaScript code.
337      * @since 1.0
338      */
339     public static final String test(String r, String s) {
340         return invoke(ref(r, "test"), s);
341     }
342 
343     /**
344      * <p>The assignment-add operator.</p> 
345      * @since 1.0
346      */
347     public final static String AASG = Js.add("+", "=");
348     /**
349      * <p>The ascii character specifier for regular expressions.</p> 
350      * @since 1.0
351      */
352     public final static String ASCII = join("\\", "w", "+");
353     /**
354      * <p>The non-white character specifier for regular expressions.</p> 
355      * @since 1.0
356      */
357     public final static String NONWS = join("\\", "S", "+");
358     /**
359      * <p>The code for an empty string.</p> 
360      * @since 1.0
361      */
362     public final static String EMPTY = "''";
363     /**
364      * <p>The code for the <tt>this.className</tt> objects.</p> 
365      * @since 1.0
366      */
367     public final static String THIS_CLASSNAME = ref("this", "className");
368     /**
369      * <p>The code for the <tt>this.className.replace</tt> function.</p> 
370      * @since 1.0
371      */
372     public final static String THIS_CLASSNAME_REPLACE = ref(
373             THIS_CLASSNAME,
374             "replace"
375     );
376 
377     /**
378      * <p>Statically creates code that dynamically performs replacements on the JavaScript
379      * <tt>this.className objects</tt>.</p> 
380      * @param r The regular expression to perform the replacement.
381      * @param s The replacement string.
382      * @return The newly created JavaScript code.
383      * @since 1.0
384      */
385     public static final String replaceThisClassName(String r, Object s) {
386         return asg(
387                 THIS_CLASSNAME,
388                 invoke(
389                         THIS_CLASSNAME_REPLACE,
390                         join(
391                                 regi(r),
392                                 ",",
393                                 s
394                         )
395                 )
396         );
397     }
398 }