001 
002 /*
003  *  JScripter Emulation 1.0 - To Script 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 org.jscripter.emu.java;
021 
022 import org.jscripter.emu.java.lang.Class;
023 
024 import js.ArrayLike;
025 import js.Js;
026 import js.Value;
027 import js.core.JsFunction;
028 import js.core.JsGlobal;
029 import js.core.JsObject;
030 import jsx.core.ArrayLikes;
031 
032 /**
033  * <p>An <tt>internal</tt> class for the emulation of Java class objects.</p>
034  * <p>This class is only used internally by JS re-compiler implementations.</p>
035  * 
036  * @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>
037  * 
038  * @javascript This class is only loaded and resolved by re-compiler implementations.
039  */
040 public class JavaClass extends JavaInterface
041 {
042     /**
043      * <p>Internally stores the constructor for this Java class object.</p>
044      * @since 1.0
045      * @javascript Re-compilers must report error on end-users directly using this field.
046      */
047     public JsFunction<JsObject> constructor;
048     /**
049      * <p>Internally stores the superclass for this Java class object.</p>
050      * @since 1.0
051      * @javascript Re-compilers must report error on end-users directly using this field.
052      */
053     public JavaClass superClass;
054     /**
055      * <p>Internally stores the prototype for this Java class object.</p>
056      * @since 1.0
057      * @javascript Re-compilers must report error on end-users directly using this field.
058      */
059     public JsObject prototype;
060     /**
061      * <p>Internally stores the initialization function for this Java class object.</p>
062      * @since 1.0
063      * @javascript Re-compilers must report error on end-users directly using this field.
064      */
065     public JsFunction<Void> init;
066 
067     /**
068      * <p>Internally returns a string representation for the current Java class object.</p>
069      * @return The string representation for the current Java class object.
070      * @since 1.0
071      * @javascript Re-compilers must report error on end-users directly using this method.
072      */
073     @Override
074     public String toString() {
075         return new Value.String("Class").add(" ").add(getName(this)).var();
076     }
077 
078     /**
079      * <p>Internally gets the Java class of an object.</p>
080      * @param o An object or value.
081      * @return A Java class object representing the Java class of the object or
082      * <tt>null</tt> if the value is not a Java object.
083      * @since 1.0
084      * @javascript Re-compilers must report error on end-users directly using this method.
085      */
086     public final static JavaClass getClass(Object o) {
087         return (JavaClass)(Object)Js.cond(
088                 o instanceof JavaObject,
089                 ((JavaObject)(Object)o).jclass,
090                 (JavaClass)null
091         );
092     }
093 
094     /**
095      * <p>Internally determines whether a Java class object represents a super
096      * class of that another Java class object does.</p>
097      * @param sup A Java class object.
098      * @param sub A Java class object.
099      * @return <tt>true</tt> if the 1st Java class object represents a super class
100      * of that the 2nd Java class object does; <tt>false</tt>, otherwise.
101      * @since 1.0
102      * @javascript Re-compilers must report error on end-users directly using this method.
103      */
104     public static final boolean isSuperClass(JavaClass sup, JavaClass sub) {
105         if (Js.eq(sub, Class.class)) {
106             return Js.eq(sup, Class.class);
107         }
108         do {
109             if (Js.eq(sup, sub)) {
110                 return true;
111             }
112             sub = sub.superClass;
113         } while (Js.be(sub) && Js.neq(sub, Class.class));
114         return false;
115     }
116 
117     /**
118      * <p>Internally creates a Java class object with its name and super class.</p>
119      * @param name Represents the name of a Java class.
120      * @param superClass Represents the name of a Java class.
121      * @return The newly created Java class object.
122      * @since 1.0
123      * @javascript Re-compilers must report error on end-users directly using this method.
124      */
125     protected final static JavaClass createClass(ArrayLike<String> name, JavaClass superClass) {
126         JavaClass jc = new JavaClass();
127         jc.name = name;
128         JsFunction<JsObject> c = JsGlobal.Function.with().create();
129         c.var(JsFunction.prototype, superClass.constructor.create());
130         jc.constructor = c;
131         jc.superClass = superClass;
132         jc.prototype = JsFunction.prototype.with(c);
133         return jc;
134     }
135 
136     /**
137      * <p>Internally stores the implemented interfaces to a Java class object.</p>
138      * @param jc Represents a Java class.
139      * @param si Represents all the interfaces for a Java class.
140      * @since 1.0
141      * @javascript Re-compilers must report error on end-users directly using this method.
142      */
143     protected final static void setInterfaces(JavaClass jc, ArrayLike<JavaInterface> si) {
144         JsObject p = jc.prototype;
145         for (int i = 0, n = ArrayLikes.length(si); i < n; ++i) {
146             JavaInterface ji = si.get(i);
147             p.var(JavaInterface.getName(ji), ji);
148         }
149     }
150 }