001 
002 /*
003  *  Descripter 1.0 - Java Script Engines
004  *  Copyright (C) 2010-2015  Jianjun Liu (J.J.Liu)
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.descripter.js.api.global;
021 
022 import org.descripter.js.api.Core;
023 import org.descripter.js.api.Function;
024 import org.descripter.js.api.Functor;
025 import org.descripter.js.api.Objective;
026 import org.descripter.js.api.Script;
027 import org.descripter.js.api.core.CObject;
028 
029 /**
030  * <p>Emulates the global Object function in JavaScript.</p>
031  * 
032  * @author <a href="mailto:jianjunliu@126.com">J.J.Liu (Jianjun Liu)</a> at <a href="http://www.descripter.org" target="_blank">http://www.descripter.org</a>
033  * @since Descripter 1.0
034  */
035 public class Object_ extends Function<Core>
036 {
037     /**
038      * <p>Creates the singleton of the global {@link Function} object of this type.</p>
039      * @param core The {@link Core} global script context
040      * @since Descripter 1.0
041      */
042     public static final void create(Core core) {
043         if (core.get(core._Object) == null) {
044             core.put(core._Object, new Object_(core));
045         }
046     }
047 
048     private Object_(Core core) {
049         super(core);
050         CObject prototype = prototype();
051         prototype.put(core._hasOwnProperty, new Function<Core>(core) {
052             @Override
053             protected Functor<Core> functor() {
054                 return new Functor<Core>(this) {
055                     @Override
056                     public Object function() {
057                         return this_().owns(key(toString(arguments().get(0))));
058                     }
059                 };
060             }
061         });
062         prototype.put(core._isPrototypeOf, new Function<Core>(core) {
063             @Override
064             protected Functor<Core> functor() {
065                 return new Functor<Core>(this) {
066                     @Override
067                     public Object function() {
068                         return ((Objective<?>)this_()).with((Objective<?>)arguments().get(0));
069                     }
070                 };
071             }
072         });
073         prototype.put(core._propertyIsEnumerable, new Function<Core>(core) {
074             @Override
075             protected Functor<Core> functor() {
076                 return new Functor<Core>(this) {
077                     @Override
078                     public Object function() {
079                         return this_().owns(key(toString(arguments().get(0))));
080                     }
081                 };
082             }
083         });
084         prototype.put(core._toLocaleString, new Function<Core>(core) {
085             @Override
086             protected Functor<Core> functor() {
087                 return new Functor<Core>(this) {
088                     @Override
089                     public Object function() {
090                         return toString(this_());
091                     }
092                 };
093             }
094         });
095         prototype.put(core._toString, new Function<Core>(core) {
096             @Override
097             protected Functor<Core> functor() {
098                 return new Functor<Core>(this) {
099                     @Override
100                     public Object function() {
101                         return toString(this_());
102                     }
103                 };
104             }
105         });
106         prototype.put(core._valueOf, new Function<Core>(core) {
107             @Override
108             protected Functor<Core> functor() {
109                 return new Functor<Core>(this) {
110                     @Override
111                     public Object function() {
112                         return ((CObject)this_()).valueOf();
113                     }
114                 };
115             }
116         });
117     }
118 
119     /**
120      * <p>Allocates a new object with this {@link Function}.</p>
121      * @param script The script context that invoked this service
122      * @param args An array of the arguments passed by the invocation
123      * @return The newly allocated object
124      * @since Descripter 1.0
125      */
126     @Override
127     public <S extends Script<?>> CObject alloc(S script, Object ...args) {
128         if (args != null && args.length > 0) {
129             Object o = valueOf(args[0]);
130             if (o instanceof Boolean) {
131                 return core()._Boolean().alloc(script, o);
132             } else if (o instanceof Number) {
133                 return core()._Number().alloc(script, o);
134             } else if (o instanceof String) {
135                 return core()._String().alloc(script, o);
136             } else if (o != null) {
137                 return core()._String().alloc(script, o.toString());
138             }
139         }
140         return new CObject(this);
141     }
142 
143     /**
144      * <p>Gets the {@link Functor} of the {@link Function} object.</p>
145      * <p>This is a concrete implementation of the super abstract method.</p>
146      * @return The {@link Functor} of the {@link Function} object
147      * @since Descripter 1.0
148      */
149     @Override
150     protected Functor<Core> functor() {
151         return new Functor<Core>(this) {
152             @Override
153             public Object function() {
154                 return Object_.this.alloc(with, arguments().get(0));
155             }
156         };
157     }
158 }