001 
002 /*
003  *  JScripter Simulation 1.0 - For Java To Script
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 org.jscripter.sim.server;
021 
022 import org.jscripter.sim.Simul;
023 
024 import js.*;
025 import js.core.*;
026 import js.user.*;
027 
028 /**
029  * <p>An <b>internal</b> class for JS Server-Side Simulation.</p>
030  * <p>This <b>internal</b> class is only used or extended internally in JS Simulation Library.</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  * @javascript Re-compilers must report error on resolving an <tt>internal</tt> class. 
035  */
036 public class ServerSide extends Simul
037 {
038     private static ServerSide singleton;
039 
040     /**
041      * <p>Internally determines whether a JS Server-Side Simulation is running.</p>
042      * @return <tt>true</tt> if there is a JS Core Simulation running; <tt>false</tt> otherwise.
043      * @since 1.0
044      * 
045      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> constructor. 
046      */
047     public final static synchronized boolean isRunning() {
048         return singleton != null;
049     }
050 
051     /**
052      * <p>Internally gets a JS Server-Side Simulation.</p>
053      * @return A Js Server-Side Simulation.
054      * @since 1.0
055      * 
056      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> constructor. 
057      */
058     public final static synchronized ServerSide get() {
059         if (singleton == null) {
060             singleton = new ServerSide();
061         }
062         return singleton;
063     }
064 
065     /**
066      * <p>Internally constructs a JS Server-Side Simulation.</p>
067      * @since 1.0
068      * 
069      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> constructor. 
070      */
071     protected ServerSide() {}
072 
073     /**
074      * <p>Internally checks if the simulation is limited to JavaScript core features only.</p>
075      * <p>This method always returns <tt>true</tt>.</p>
076      * @return <tt>true</tt> if this is a core simulation; <tt>false</tt>, otherwise;
077      * @since 1.0
078      * 
079      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
080      */
081     @Override
082     protected final boolean isCore() {
083         return true;
084     }
085 
086     /**
087      * <p>Internally creates function object from a function definition.</p>
088      * <p>This method simply throws an {@link UnsupportedOperationException} exception.</p>
089      * @param f A {@link Function} definition.
090      * @return The function object.
091      * @since 1.0
092      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
093      */
094     @Override
095     protected <T> JsFunction<T> var(Function<T> f) {
096         throw new UnsupportedOperationException("Server Side only!");
097     }
098 
099     /**
100      * <p>Returns the opaque global object with the client-side support.</p>
101      * <p>This method simply throws an {@link UnsupportedOperationException} exception.</p>
102      * @return The opaque global object with the client-side support.
103      * @see Js#win()
104      * @see jsx.client.Client
105      * @since 1.0
106      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
107      */
108     @Override
109     protected JsWin win() {
110         throw new UnsupportedOperationException("Server Side only!");
111     }
112 
113     /**
114      * <p>Returns the opaque global object with the core support only.</p>
115      * <p>This method simply throws an {@link UnsupportedOperationException} exception.</p>
116      * @return The opaque global object with the core support only.
117      * @see Js#core()
118      * @see jsx.client.Global
119      * @since 1.0
120      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
121      */
122     @Override
123     protected JsGlobal core() {
124         throw new UnsupportedOperationException("Server Side only!");
125     }
126 
127     /**
128      * <p>Internally down cast an object to array type.</p>
129      * <p>This method is internal and only called inside of opaque or internal classes 
130      * or class members.</p>
131      * @param o The object
132      * @since 1.0
133      * @return The array representation of an object
134      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
135      */
136     @Override
137     protected JsArray toJsArray(JsObject o) {
138         throw new UnsupportedOperationException("Server Side only!");
139     }
140 
141     /**
142      * <p>Internally down cast an object to boolean type.</p>
143      * <p>This method simply throws an {@link UnsupportedOperationException} exception.</p>
144      * @param o The object
145      * @since 1.0
146      * @return The boolean representation of an object
147      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
148      */
149     @Override
150     protected JsBoolean toJsBoolean(JsObject o) {
151         throw new UnsupportedOperationException("Server Side only!");
152     }
153 
154     /**
155      * <p>Internally down cast an object to date type.</p>
156      * <p>This method simply throws an {@link UnsupportedOperationException} exception.</p>
157      * @param o The object
158      * @since 1.0
159      * @return The date representation of an object
160      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
161      */
162     @Override
163     protected JsDate toJsDate(JsObject o) {
164         throw new UnsupportedOperationException("Server Side only!");
165     }
166 
167     /**
168      * <p>Internally down cast an object to function type.</p>
169      * <p>This method simply throws an {@link UnsupportedOperationException} exception.</p>
170      * @param o The object
171      * @since 1.0
172      * @return The function representation of an object
173      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
174      */
175     @Override
176     protected <T> JsFunction<T> toJsFunction(JsObject o) {
177         throw new UnsupportedOperationException("Server Side only!");
178     }
179 
180     /**
181      * <p>Internally down cast an object to function type.</p>
182      * <p>This method simply throws an {@link UnsupportedOperationException} exception.</p>
183      * @param o The object
184      * @param w A wrapper to perform the cast
185      * @since 1.0
186      * @return The function representation of an object
187      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
188      */
189     @Override
190     protected <T> JsFunction<T> toJsFunction(JsObject o, Generic<T> w) {
191         throw new UnsupportedOperationException("Server Side only!");
192     }
193 
194     /**
195      * <p>Internally down cast an object to number type.</p>
196      * <p>This method simply throws an {@link UnsupportedOperationException} exception.</p>
197      * @param o The object
198      * @since 1.0
199      * @return The number representation of an object
200      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
201      */
202     @Override
203     protected JsNumber toJsNumber(JsObject o) {
204         throw new UnsupportedOperationException("Server Side only!");
205     }
206 
207     /**
208      * <p>Internally down cast an object to regular expression type.</p>
209      * <p>This method simply throws an {@link UnsupportedOperationException} exception.</p>
210      * @param o The object
211      * @since 1.0
212      * @return The regular expression representation of an object
213      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
214      */
215     @Override
216     protected JsRegExp toJsRegExp(JsObject o) {
217         throw new UnsupportedOperationException("Server Side only!");
218     }
219 
220     /**
221      * <p>Internally down cast an object to string type.</p>
222      * <p>This method simply throws an {@link UnsupportedOperationException} exception.</p>
223      * @param o The object
224      * @since 1.0
225      * @return The string representation of an object
226      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
227      */
228     @Override
229     protected JsString toJsString(JsObject o) {
230         throw new UnsupportedOperationException("Server Side only!");
231     }
232 
233     /**
234      * <p>Internally creates a variable list from a value or object.</p>
235      * <p>This method simply throws an {@link UnsupportedOperationException} exception.</p>
236      * @param args A value or object.
237      * @return The variable list created.
238      * @since 1.0
239      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
240      */
241     @Override
242     protected Vars<?> vars(Object args) {
243         throw new UnsupportedOperationException("Server Side only!");
244     }
245 
246     /**
247      * <p>Gets the list of the property names of an object.</p>
248      * <p>This method simply throws an {@link UnsupportedOperationException} exception.</p>
249      * @param o The object.
250      * @return The list of the property names of the object.
251      * @since 1.0
252      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
253      */
254     @Override
255     protected ArrayLike<String> keys(JsObject o) {
256         throw new UnsupportedOperationException("Server Side only!");
257     }
258 
259     /**
260      * <p>Copies all the properties of <tt>a</tt> to <tt>o</tt>.</p>
261      * <p>This method simply throws an {@link UnsupportedOperationException} exception.</p>
262      * @param o The object that the properties being copied to.
263      * @param a The object that the properties being copied from.
264      * @since 1.0
265      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
266      */
267     @Override
268     protected void apply(JsObject o, ObjectLike a) {
269         throw new UnsupportedOperationException();
270     }
271 
272     /**
273      * <p>Creates a JavaScript function.</p>
274      * <p>A function is a fundamental data-type in JavaScript. Note that although functions 
275      * may be created with this method, this is not efficient, and the preferred way to 
276      * define functions, in most cases, is to extend {@link Function}.</p>
277      * @param args A list of the argument values, each naming one or more arguments of the 
278      * function being created, ended with a string that specifies the body of the function.
279      * @return A newly created function. Invoking it executes the JavaScript code specified 
280      * by last string value of the variable argument <tt>args</tt>.
281      * @throws RuntimeException JavaScript throws a <tt>SyntaxError</tt> if there was a 
282      * JavaScript syntax error in one of the value of the variable arguments. See {@link Js#err(Object)} 
283      * and {@link js.core.JsSyntaxError} for JS Simulation.
284      * @see Function
285      * @since 1.0
286      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
287      */
288     @Override
289     protected <T> JsFunction<T> function(Vars<String> args) {
290         throw new UnsupportedOperationException("Server Side only!");
291     }
292 
293     /**
294      * <p>Gets the hash code of a value.</p>
295      * @param o Any value.
296      * @return The hash code of a value.
297      * @since 1.0
298      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
299      */
300     @Override
301     protected final int hashCode(Object o) {
302         return o.hashCode();
303     }
304 
305     /**
306      * <p>Checks if a value equals another object.</p>
307      * @param v Any value
308      * @param o Any value
309      * @return <tt>true</tt> if <tt>v</tt> equals <tt>o</tt>; false, otherwise.
310      * @since 1.0
311      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
312      */
313     @Override
314     protected final boolean equals(Object v, Object o) {
315         return eqs(v, o);
316     }
317 
318     /**
319      * <p>Checks whether the two operands are "equal" using a more relaxed definition of 
320      * sameness that allows type conversions, resembling the equality operator in 
321      * JavaScript.</p>
322      * <p>The equality and identity operations check whether two values are the same, using 
323      * two different definitions of sameness. Both operations accept operands of any type, 
324      * and both return <tt>true</tt> if their operands are the same and <tt>false</tt> 
325      * if they are different. The identity operation checks whether its two operands are 
326      * "identical" using a strict definition of sameness. The equality operation checks 
327      * whether its two operands are "equal" using a more relaxed definition of sameness 
328      * that allows type conversions.</p>
329      * <p>The identity operation is standardized by ECMAScript v3 and implemented in 
330      * JavaScript 1.3 and later. Be sure you understand the differences between the 
331      * assignment, equality, and identity operations, and be careful to use the correct one 
332      * when coding! Although it is tempting to call all three operations "equals," it may 
333      * help to reduce confusion if you read "gets or is assigned" for assignment operation, 
334      * "is equal to" for equality operation, and "is identical to" for identity operation.</p>
335      * <p>In JavaScript, numbers, strings, and boolean values are compared by value. In this 
336      * case, two separate values are involved, and the equality and identity operations 
337      * check that these two values are identical. This means that two variables are equal 
338      * or identical only if they contain the same value. For example, two strings are equal 
339      * only if they each contain exactly the same characters.</p>
340      * <p>On the other hand, objects, arrays, and functions are compared by reference. This 
341      * means that two variables are equal only if they refer to the same object. Two 
342      * separate arrays are never equal or identical, even if they contain equal or identical 
343      * elements. Two variables that contain references to objects, arrays, or functions are 
344      * equal only if they refer to the same object, array, or function. If you want to test 
345      * that two distinct objects contain the same properties or that two distinct arrays 
346      * contain the same elements, you'll have to check the properties or elements individually 
347      * for equality or identity. And, if any of the properties or elements are themselves 
348      * objects or arrays, you'll have to decide how deep you want the comparison to go.</p>
349      * <p>The following rules determine whether two values are equal according to the 
350      * equality operation:
351      * <ul>
352      * <li>If the two values have the same type, test them for identity. If the values are 
353      * identical, they are equal; if they are not identical, they are not equal.</li>
354      * <li>If the two values do not have the same type, they may still be equal. Use the 
355      * following rules and type conversions to check for equality:</li>
356      * <ul>
357      * <li>If one value is null and the other is undefined, they are equal.</li>
358      * <li>If one value is a number and the other is a string, convert the string to a 
359      * number and try the comparison again, using the converted value.</li>
360      * <li>If either value is <tt>true</tt>, convert it to 1 and try the comparison 
361      * again. If either value is <tt>false</tt>, convert it to 0 and try the comparison 
362      * again.</li>
363      * <li>If one value is an object and the other is a number or string, convert the 
364      * object to a primitive and try the comparison again. An object is converted to a 
365      * primitive value by either its <tt>toString()</tt> method or its <tt>valueOf()</tt> 
366      * method. The built-in classes of core JavaScript attempt <tt>valueOf()</tt> 
367      * conversion before <tt>toString()</tt> conversion, except for the Date class, 
368      * which performs <tt>toString()</tt> conversion. Objects that are not part of core 
369      * JavaScript may convert themselves to primitive values in an implementation-defined 
370      * way.</li>
371      * <li>Any other combinations of values are not equal.</li>
372      * </ul>
373      * </ul>
374      * @param v Any value or object.
375      * @param o Any value or object.
376      * @return <tt>true</tt> if the first operand equals the second; <tt>false</tt>, 
377      * otherwise;
378      * @since 1.0
379      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
380      */
381     @Override
382     protected final boolean eq(Object v, Object o) {
383         v = v instanceof Var<?> ? ((Var<?>)v).var() : v;
384         o = o instanceof Var<?> ? ((Var<?>)o).var() : o;
385         boolean nv = Js.undefined(v);
386         boolean no = Js.undefined(o);
387         if (nv && no) {
388             return true;
389         } else if (nv || no) {
390             return false;
391         }
392         return eqv(Js.valueOf(v), Js.valueOf(o));
393     }
394 
395     /**
396      * <p>Checks whether the two operands are "identical" using a strict definition of 
397      * sameness, resembling the identity operator in JavaScript.</p>
398      * <p>The equality and identity operations check whether two values are the same, using 
399      * two different definitions of sameness. Both operations accept operands of any type, 
400      * and both return <tt>true</tt> if their operands are the same and <tt>false</tt> 
401      * if they are different. The identity operation checks whether its two operands are 
402      * "identical" using a strict definition of sameness. The equality operation checks 
403      * whether its two operands are "equal" using a more relaxed definition of sameness 
404      * that allows type conversions.</p>
405      * <p>The identity operation is standardized by ECMAScript v3 and implemented in 
406      * JavaScript 1.3 and later. Be sure you understand the differences between the 
407      * assignment, equality, and identity operations, and be careful to use the correct one 
408      * when coding! Although it is tempting to call all three operations "equals," it may 
409      * help to reduce confusion if you read "gets or is assigned" for assignment operation, 
410      * "is equal to" for equality operation, and "is identical to" for identity operation.</p>
411      * <p>In JavaScript, numbers, strings, and boolean values are compared by value. In this 
412      * case, two separate values are involved, and the equality and identity operations 
413      * check that these two values are identical. This means that two variables are equal 
414      * or identical only if they contain the same value. For example, two strings are equal 
415      * only if they each contain exactly the same characters.</p>
416      * <p>On the other hand, objects, arrays, and functions are compared by reference. This 
417      * means that two variables are equal only if they refer to the same object. Two 
418      * separate arrays are never equal or identical, even if they contain equal or identical 
419      * elements. Two variables that contain references to objects, arrays, or functions are 
420      * equal only if they refer to the same object, array, or function. If you want to test 
421      * that two distinct objects contain the same properties or that two distinct arrays 
422      * contain the same elements, you'll have to check the properties or elements individually 
423      * for equality or identity. And, if any of the properties or elements are themselves 
424      * objects or arrays, you'll have to decide how deep you want the comparison to go.</p>
425      * <p>The following rules determine whether two values are identical according to the identity operation:
426      * <ul>
427      * <li>If the two values have different types, they are not identical.</li>
428      * <li>If both values are numbers and have the same value, they are identical, unless 
429      * either or both values are <tt>NaN</tt>, in which case they are not identical. 
430      * The <tt>NaN</tt> value is never identical to any other value, including itself! 
431      * To check whether a value is <tt>NaN</tt>, use the global {@link Js#isNaN(Object)} 
432      * function.</li>
433      * <li>If both values are strings and contain exactly the same characters in the same 
434      * positions, they are identical. If the strings differ in length or content, they are 
435      * not identical. Note that in some cases, the Unicode standard allows more than one 
436      * way to encode the same string. For efficiency, however, JavaScript's string 
437      * comparison compares strictly on a character-by-character basis, and it assumes that 
438      * all strings have been converted to a "normalized form" before they are compared. 
439      * See the {@link StringLike#localeCompare(Object)} for another way to compare strings.</li>
440      * <li>If both values are the boolean value <tt>true</tt> or both are the boolean 
441      * value <tt>false</tt>, they are identical.</li>
442      * <li>If both values refer to the same object, array, or function, they are identical. 
443      * If they refer to different objects (or arrays or functions) they are not identical, 
444      * even if both objects have identical properties or both arrays have identical elements.</li>
445      * <li>If both values are null or both values are undefined, they are identical.</li>
446      * </ul>
447      * @param v Any value or object.
448      * @param o Any value or object.
449      * @return <tt>true</tt> if the first operand is identical to the second; 
450      * <tt>false</tt>, otherwise;
451      * @since 1.0
452      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
453      */
454     @Override
455     protected final boolean eqs(Object v, Object o) {
456         v = v instanceof Var<?> ? ((Var<?>)v).var() : v;
457         o = o instanceof Var<?> ? ((Var<?>)o).var() : o;
458         boolean nv = Js.undefined(v);
459         boolean no = Js.undefined(o);
460         if (nv && no) {
461             return true;
462         } else if (nv || no) {
463             return false;
464         }
465         boolean lv = v instanceof Var<?>;
466         boolean lo = o instanceof Var<?>;
467         if (lv && lo) {
468             throw new UnsupportedOperationException("Server Side only!");
469         }
470         return !lv && !lo && v.equals(o);
471     }
472 
473     /**
474      * <p>Checks if the first operand is the name of a property of the second, resembling 
475      * the <tt>in</tt> operator in JavaScript.</p>
476      * <p>This operation converts the first operand to a string and expects the second 
477      * operand be an object (or array).</p>
478      * @param v Any value that is or can be converted to a string.
479      * @param o Any object or array.
480      * @return <tt>true</tt> if the first operand is the name of a property of the 
481      * second operand; <tt>false</tt>, otherwise;
482      * @since 1.0
483      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
484      */
485     @Override
486     protected boolean in(Object v, Object o) {
487         v = v instanceof Var<?> ? ((Var<?>)v).var() : v;
488         o = o instanceof Var<?> ? ((Var<?>)o).var() : o;
489         return o instanceof JsObject && Js.be(((JsObject)o).var(v.toString()));
490     }
491 
492     /**
493      * <p>Checks if the first operand is an instance of the second, resembling the 
494      * <tt>instanceof</tt> operator in JavaScript.</p>
495      * <p>This operation expects the first operand be an object and the second be a class 
496      * of objects. In JavaScript, classes of objects are defined by the constructor function 
497      * that initializes them.</p>
498      * @param v Any value or object.
499      * @param o A constructor function.
500      * @return <tt>true</tt> if the first operand is an instance of the second; 
501      * <tt>false</tt>, otherwise;
502      * @since 1.0
503      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
504      */
505     @Override
506     protected boolean instanceOf(Object v, Object o) {
507         v = v instanceof Var<?> ? ((Var<?>)v).var() : v;
508         o = o instanceof Var<?> ? ((Var<?>)o).var() : o;
509         return v instanceof JsObject && o instanceof JsFunction<?> &&
510             equals(JsObject.constructor.with((JsObject)v), o);
511     }
512 
513     /**
514      * <p>Gets the value or object contained in a <tt>RuntimeException</tt> object 
515      * thrown by JS Simulation.</p>
516      * @param e The <tt>RuntimeException</tt> object thrown by JS Simulation.
517      * @return The value or object contained in the <tt>RuntimeException</tt> object.
518      * @since 1.0
519      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
520      */
521     @Override
522     protected Object err(RuntimeException e) {
523         return e;
524     }
525 
526     /**
527      * <p>Checks if a variable represents a Java object.</p>
528      * @param v Any value or object.
529      * @return <tt>true</tt> if <tt>v</tt> is Java; <tt>false</tt>, otherwise.
530      * @since 1.0
531      * @javascript Re-compilers must report error on the invocation to an <b>internal</b> method. 
532      */
533     @Override
534     protected boolean isJavaObject(Object v) {
535         return true;
536     }
537 }