1 /* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
2  *
3  * This Source Code Form is subject to the terms of the Mozilla Public
4  * License, v. 2.0. If a copy of the MPL was not distributed with this
5  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 
7 package org.mozilla.javascript.xmlimpl;
8 
9 import org.mozilla.javascript.*;
10 
11 class XMLCtor extends IdFunctionObject
12 {
13     static final long serialVersionUID = -8708195078359817341L;
14 
15     private static final Object XMLCTOR_TAG = "XMLCtor";
16 
17     private XmlProcessor options;
18 //    private XMLLibImpl lib;
19 
XMLCtor(XML xml, Object tag, int id, int arity)20     XMLCtor(XML xml, Object tag, int id, int arity)
21     {
22         super(xml, tag, id, arity);
23 //        this.lib = xml.lib;
24         this.options = xml.getProcessor();
25         activatePrototypeMap(MAX_FUNCTION_ID);
26     }
27 
writeSetting(Scriptable target)28     private void writeSetting(Scriptable target)
29     {
30         for (int i = 1; i <= MAX_INSTANCE_ID; ++i) {
31             int id = super.getMaxInstanceId() + i;
32             String name = getInstanceIdName(id);
33             Object value = getInstanceIdValue(id);
34             ScriptableObject.putProperty(target, name, value);
35         }
36     }
37 
readSettings(Scriptable source)38     private void readSettings(Scriptable source)
39     {
40         for (int i = 1; i <= MAX_INSTANCE_ID; ++i) {
41             int id = super.getMaxInstanceId() + i;
42             String name = getInstanceIdName(id);
43             Object value = ScriptableObject.getProperty(source, name);
44             if (value == Scriptable.NOT_FOUND) {
45                 continue;
46             }
47             switch (i) {
48               case Id_ignoreComments:
49               case Id_ignoreProcessingInstructions:
50               case Id_ignoreWhitespace:
51               case Id_prettyPrinting:
52                 if (!(value instanceof Boolean)) {
53                     continue;
54                 }
55                 break;
56               case Id_prettyIndent:
57                 if (!(value instanceof Number)) {
58                     continue;
59                 }
60                 break;
61               default:
62                 throw new IllegalStateException();
63             }
64             setInstanceIdValue(id, value);
65         }
66     }
67 
68 // #string_id_map#
69 
70     private static final int
71         Id_ignoreComments               = 1,
72         Id_ignoreProcessingInstructions = 2,
73         Id_ignoreWhitespace             = 3,
74         Id_prettyIndent                 = 4,
75         Id_prettyPrinting               = 5,
76 
77         MAX_INSTANCE_ID                 = 5;
78 
79     @Override
getMaxInstanceId()80     protected int getMaxInstanceId()
81     {
82         return super.getMaxInstanceId() + MAX_INSTANCE_ID;
83     }
84 
85     @Override
findInstanceIdInfo(String s)86     protected int findInstanceIdInfo(String s) {
87         int id;
88 // #generated# Last update: 2007-08-20 09:01:10 EDT
89         L0: { id = 0; String X = null; int c;
90             L: switch (s.length()) {
91             case 12: X="prettyIndent";id=Id_prettyIndent; break L;
92             case 14: c=s.charAt(0);
93                 if (c=='i') { X="ignoreComments";id=Id_ignoreComments; }
94                 else if (c=='p') { X="prettyPrinting";id=Id_prettyPrinting; }
95                 break L;
96             case 16: X="ignoreWhitespace";id=Id_ignoreWhitespace; break L;
97             case 28: X="ignoreProcessingInstructions";id=Id_ignoreProcessingInstructions; break L;
98             }
99             if (X!=null && X!=s && !X.equals(s)) id = 0;
100             break L0;
101         }
102 // #/generated#
103 
104         if (id == 0) return super.findInstanceIdInfo(s);
105 
106         int attr;
107         switch (id) {
108           case Id_ignoreComments:
109           case Id_ignoreProcessingInstructions:
110           case Id_ignoreWhitespace:
111           case Id_prettyIndent:
112           case Id_prettyPrinting:
113             attr = PERMANENT | DONTENUM;
114             break;
115           default: throw new IllegalStateException();
116         }
117         return instanceIdInfo(attr, super.getMaxInstanceId() + id);
118     }
119 
120 // #/string_id_map#
121 
122     @Override
getInstanceIdName(int id)123     protected String getInstanceIdName(int id)
124     {
125         switch (id - super.getMaxInstanceId()) {
126           case Id_ignoreComments:               return "ignoreComments";
127           case Id_ignoreProcessingInstructions: return "ignoreProcessingInstructions";
128           case Id_ignoreWhitespace:             return "ignoreWhitespace";
129           case Id_prettyIndent:                 return "prettyIndent";
130           case Id_prettyPrinting:               return "prettyPrinting";
131         }
132         return super.getInstanceIdName(id);
133     }
134 
135     @Override
getInstanceIdValue(int id)136     protected Object getInstanceIdValue(int id)
137     {
138         switch (id - super.getMaxInstanceId()) {
139           case Id_ignoreComments:
140             return ScriptRuntime.wrapBoolean(options.isIgnoreComments());
141           case Id_ignoreProcessingInstructions:
142             return ScriptRuntime.wrapBoolean(options.isIgnoreProcessingInstructions());
143           case Id_ignoreWhitespace:
144             return ScriptRuntime.wrapBoolean(options.isIgnoreWhitespace());
145           case Id_prettyIndent:
146             return ScriptRuntime.wrapInt(options.getPrettyIndent());
147           case Id_prettyPrinting:
148             return ScriptRuntime.wrapBoolean(options.isPrettyPrinting());
149         }
150         return super.getInstanceIdValue(id);
151     }
152 
153     @Override
setInstanceIdValue(int id, Object value)154     protected void setInstanceIdValue(int id, Object value) {
155         switch (id - super.getMaxInstanceId()) {
156             case Id_ignoreComments:
157                 options.setIgnoreComments(ScriptRuntime.toBoolean(value));
158                 return;
159             case Id_ignoreProcessingInstructions:
160                 options.setIgnoreProcessingInstructions(ScriptRuntime.toBoolean(value));
161                 return;
162             case Id_ignoreWhitespace:
163                 options.setIgnoreWhitespace(ScriptRuntime.toBoolean(value));
164                 return;
165             case Id_prettyIndent:
166                 options.setPrettyIndent(ScriptRuntime.toInt32(value));
167                 return;
168             case Id_prettyPrinting:
169                 options.setPrettyPrinting(ScriptRuntime.toBoolean(value));
170                 return;
171         }
172         super.setInstanceIdValue(id, value);
173     }
174 
175 // #string_id_map#
176     private static final int
177         Id_defaultSettings              = 1,
178         Id_settings                     = 2,
179         Id_setSettings                  = 3,
180         MAX_FUNCTION_ID                 = 3;
181 
182     @Override
findPrototypeId(String s)183     protected int findPrototypeId(String s)
184     {
185         int id;
186 // #generated# Last update: 2007-08-20 09:01:10 EDT
187         L0: { id = 0; String X = null;
188             int s_length = s.length();
189             if (s_length==8) { X="settings";id=Id_settings; }
190             else if (s_length==11) { X="setSettings";id=Id_setSettings; }
191             else if (s_length==15) { X="defaultSettings";id=Id_defaultSettings; }
192             if (X!=null && X!=s && !X.equals(s)) id = 0;
193             break L0;
194         }
195 // #/generated#
196         return id;
197     }
198 // #/string_id_map#
199 
200     @Override
initPrototypeId(int id)201     protected void initPrototypeId(int id)
202     {
203         String s;
204         int arity;
205         switch (id) {
206           case Id_defaultSettings:  arity=0; s="defaultSettings";  break;
207           case Id_settings:         arity=0; s="settings";         break;
208           case Id_setSettings:      arity=1; s="setSettings";      break;
209           default: throw new IllegalArgumentException(String.valueOf(id));
210         }
211         initPrototypeMethod(XMLCTOR_TAG, id, s, arity);
212     }
213 
214     @Override
execIdCall(IdFunctionObject f, Context cx, Scriptable scope, Scriptable thisObj, Object[] args)215     public Object execIdCall(IdFunctionObject f, Context cx, Scriptable scope,
216                              Scriptable thisObj, Object[] args)
217     {
218         if (!f.hasTag(XMLCTOR_TAG)) {
219             return super.execIdCall(f, cx, scope, thisObj, args);
220         }
221         int id = f.methodId();
222         switch (id) {
223           case Id_defaultSettings: {
224             options.setDefault();
225             Scriptable obj = cx.newObject(scope);
226             writeSetting(obj);
227             return obj;
228           }
229           case Id_settings: {
230             Scriptable obj = cx.newObject(scope);
231             writeSetting(obj);
232             return obj;
233           }
234           case Id_setSettings: {
235             if (args.length == 0
236                 || args[0] == null
237                 || args[0] == Undefined.instance)
238             {
239                 options.setDefault();
240             } else if (args[0] instanceof Scriptable) {
241                 readSettings((Scriptable)args[0]);
242             }
243             return Undefined.instance;
244           }
245         }
246         throw new IllegalArgumentException(String.valueOf(id));
247     }
248 
249     /**
250         hasInstance for XML objects works differently than other objects; see ECMA357 13.4.3.10.
251      */
252     @Override
hasInstance(Scriptable instance)253     public boolean hasInstance(Scriptable instance) {
254         return (instance instanceof XML || instance instanceof XMLList);
255     }
256 }
257