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 js.Js;
023 import js.ObjectLike;
024 import js.Value;
025 import js.Vars;
026 import js.core.JsArray;
027 import js.core.JsGlobal;
028 import js.core.JsObject;
029 
030 /**
031  * <p>An <tt>internal</tt> class for the emulation of Java objects.</p>
032  * <p>This class is only used internally by JS re-compiler implementations.</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  * @javascript This class is only loaded and resolved by re-compiler implementations.
037  */
038 public class JavaObject
039 {
040     /**
041      * <p>Internally stores the Java class object for this Java object.</p>
042      * @since 1.0
043      * @javascript Re-compilers must report error on end-users directly using this field.
044      */
045     public JavaClass jclass;
046 
047     /**
048      * <p>Internally clones the Java object.</p>
049      * @return A copy of the current Java object.
050      * @since 1.0
051      * @javascript Re-compilers must report error on end-users directly using this method.
052      */
053     @Override
054     public Object clone() throws CloneNotSupportedException {
055         if (!java.lang.Cloneable.class.isInstance(this)) {
056             return clone(this);
057         }
058         final JsObject jso = jclass.constructor.create();
059         Js.apply(jso, (ObjectLike)this);
060         return jso;
061     }
062 
063     /**
064      * <p>Internally clones a Java object.</p>
065      * <p>This method simply throws a {link CloneNotSupportedException} exception.</p>
066      * @param o An object to clone.
067      * @return A copy of the Java object.
068      * @since 1.0
069      * @javascript Re-compilers must report error on end-users directly using this method.
070      */
071     public final static Object clone(Object o) throws CloneNotSupportedException {
072         throw new java.lang.CloneNotSupportedException();
073     }
074 
075     /**
076      * <p>Internally compares the current Java object with another value.</p>
077      * @param other A value or object.
078      * @return <tt>true</tt> if the two values are equal; <tt>false</tt>, otherwise.
079      * @since 1.0
080      * @javascript Re-compilers must report error on end-users directly using this method.
081      */
082     @Override
083     public boolean equals(Object other) {
084         return other instanceof JavaObject && 
085                 Js.eq(((JavaObject)(Object)other).jclass, jclass) &&
086                 Js.eq(this, other);
087     }
088 
089     private static interface hashCode {
090         static final java.lang.String $ = Js.add(":", "hashCode");
091     }
092     private static interface nextHashCode {
093         static final Value.Number $ = new Value.Number(0);
094     }
095 
096     /**
097      * <p>Internally computes the hash code for an object.</p>
098      * @param o An object.
099      * @return The hash code for the object.
100      * @since 1.0
101      * @javascript Re-compilers must report error on end-users directly using this method.
102      */
103     public final static int hashCode(Object o) {
104         if (Js.undefined(Js.object(o).var(hashCode.$))) {
105             Js.object(o).var(hashCode.$, nextHashCode.$.inc());
106         }
107         java.lang.Object h = Js.object(o).var(hashCode.$);
108         return ((Integer)h).intValue();
109     }
110 
111     /**
112      * <p>Internally computes the hash code for the current Java object.</p>
113      * @return The hash code for the current Java object.
114      * @since 1.0
115      * @javascript Re-compilers must report error on end-users directly using this method.
116      */
117     @Override
118     public int hashCode() {
119         return hashCode(this);
120     }
121 
122     /**
123      * <p>Internally returns a string representation for the current Java object.</p>
124      * @return The string representation for the current Java object.
125      * @since 1.0
126      * @javascript Re-compilers must report error on end-users directly using this method.
127      */
128     @Override
129     public String toString() {
130         return new Value.String("[")
131                            .add("object")
132                            .add(" ")
133                            .add(JavaInterface.getName(jclass))
134                            .add("]")
135                            .var();
136     }
137 
138     @Override
139     public void finalize() {
140     }
141 
142     /**
143      * <p>Internally creates a Java object by a Java class object.</p>
144      * @param jclass A Java class object.
145      * @return The newly created Java object.
146      * @since 1.0
147      * @javascript Re-compilers must report error on end-users directly using this method.
148      */
149     public final static JavaObject createObject(JavaClass jclass) {
150         JavaObject jo = (JavaObject)(Object)jclass.constructor.create();
151         jo.jclass = jclass;
152         return jo;
153     }
154 
155     /**
156      * <p>Internally creates a Java array object with the sizes provided.</p>
157      * @param sizes An array of sizes for the Java array being created. The length of this 
158      * argument indicates the dimension of the Java array to create.
159      * @return The newly created Java array object.
160      * @since 1.0
161      * @javascript Re-compilers must report error on end-users directly using this method.
162      */
163     protected final static JsArray createArray(JsArray sizes) {
164         int dimensions = sizes.length();
165         JsArray jsa = new Vars<Object>().var().var();
166         int size = ((Integer)sizes.get(0)).intValue();
167         jsa.var(JsArray.length, size);
168         if (dimensions > 1) {
169             for (int i = 0; i < size; ++i) {
170                 jsa.set(
171                         i,
172                         createArray(
173                                 sizes.slice(1)
174                         )
175                 );
176             }
177         }
178         ((JavaObject)(Object)jsa).jclass = (JavaClass)(Object)JsGlobal.Array.with();
179         return jsa;
180     }
181 }