001: /* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
002: *
003: * ***** BEGIN LICENSE BLOCK *****
004: * Version: MPL 1.1/GPL 2.0
005: *
006: * The contents of this file are subject to the Mozilla Public License Version
007: * 1.1 (the "License"); you may not use this file except in compliance with
008: * the License. You may obtain a copy of the License at
009: * http://www.mozilla.org/MPL/
010: *
011: * Software distributed under the License is distributed on an "AS IS" basis,
012: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
013: * for the specific language governing rights and limitations under the
014: * License.
015: *
016: * The Original Code is Rhino code, released
017: * May 6, 1999.
018: *
019: * The Initial Developer of the Original Code is
020: * Netscape Communications Corporation.
021: * Portions created by the Initial Developer are Copyright (C) 1997-2000
022: * the Initial Developer. All Rights Reserved.
023: *
024: * Contributor(s):
025: * Ethan Hugg
026: * Terry Lucas
027: * Milen Nankov
028: *
029: * Alternatively, the contents of this file may be used under the terms of
030: * the GNU General Public License Version 2 or later (the "GPL"), in which
031: * case the provisions of the GPL are applicable instead of those above. If
032: * you wish to allow use of your version of this file only under the terms of
033: * the GPL and not to allow others to use your version of this file under the
034: * MPL, indicate your decision by deleting the provisions above and replacing
035: * them with the notice and other provisions required by the GPL. If you do
036: * not delete the provisions above, a recipient may use your version of this
037: * file under either the MPL or the GPL.
038: *
039: * ***** END LICENSE BLOCK ***** */
040:
041: package org.mozilla.javascript.xmlimpl;
042:
043: import org.mozilla.javascript.*;
044:
045: /**
046: * Class Namespace
047: *
048: */
049: class Namespace extends IdScriptableObject {
050: static final long serialVersionUID = -5765755238131301744L;
051:
052: private static final Object NAMESPACE_TAG = new Object();
053:
054: private Namespace prototype;
055: private XmlNode.Namespace ns;
056:
057: private Namespace() {
058: }
059:
060: static Namespace create(Scriptable scope, Namespace prototype,
061: XmlNode.Namespace namespace) {
062: Namespace rv = new Namespace();
063: rv.setParentScope(scope);
064: rv.prototype = prototype;
065: rv.setPrototype(prototype);
066: rv.ns = namespace;
067: return rv;
068: }
069:
070: final XmlNode.Namespace getDelegate() {
071: return ns;
072: }
073:
074: public void exportAsJSClass(boolean sealed) {
075: exportAsJSClass(MAX_PROTOTYPE_ID, this .getParentScope(), sealed);
076: }
077:
078: public String uri() {
079: return ns.getUri();
080: }
081:
082: public String prefix() {
083: return ns.getPrefix();
084: }
085:
086: public String toString() {
087: return uri();
088: }
089:
090: public String toLocaleString() {
091: return toString();
092: }
093:
094: private boolean equals(Namespace n) {
095: return uri().equals(n.uri());
096: }
097:
098: public boolean equals(Object obj) {
099: if (!(obj instanceof Namespace))
100: return false;
101: return equals((Namespace) obj);
102: }
103:
104: protected Object equivalentValues(Object value) {
105: if (!(value instanceof Namespace))
106: return Scriptable.NOT_FOUND;
107: boolean result = equals((Namespace) value);
108: return result ? Boolean.TRUE : Boolean.FALSE;
109: }
110:
111: public String getClassName() {
112: return "Namespace";
113: }
114:
115: public Object getDefaultValue(Class hint) {
116: return uri();
117: }
118:
119: // #string_id_map#
120: private static final int Id_prefix = 1, Id_uri = 2,
121: MAX_INSTANCE_ID = 2;
122:
123: protected int getMaxInstanceId() {
124: return super .getMaxInstanceId() + MAX_INSTANCE_ID;
125: }
126:
127: protected int findInstanceIdInfo(String s) {
128: int id;
129: // #generated# Last update: 2007-08-20 08:23:22 EDT
130: L0: {
131: id = 0;
132: String X = null;
133: int s_length = s.length();
134: if (s_length == 3) {
135: X = "uri";
136: id = Id_uri;
137: } else if (s_length == 6) {
138: X = "prefix";
139: id = Id_prefix;
140: }
141: if (X != null && X != s && !X.equals(s))
142: id = 0;
143: break L0;
144: }
145: // #/generated#
146:
147: if (id == 0)
148: return super .findInstanceIdInfo(s);
149:
150: int attr;
151: switch (id) {
152: case Id_prefix:
153: case Id_uri:
154: attr = PERMANENT | READONLY;
155: break;
156: default:
157: throw new IllegalStateException();
158: }
159: return instanceIdInfo(attr, super .getMaxInstanceId() + id);
160: }
161:
162: // #/string_id_map#
163:
164: protected String getInstanceIdName(int id) {
165: switch (id - super .getMaxInstanceId()) {
166: case Id_prefix:
167: return "prefix";
168: case Id_uri:
169: return "uri";
170: }
171: return super .getInstanceIdName(id);
172: }
173:
174: protected Object getInstanceIdValue(int id) {
175: switch (id - super .getMaxInstanceId()) {
176: case Id_prefix:
177: if (ns.getPrefix() == null)
178: return Undefined.instance;
179: return ns.getPrefix();
180: case Id_uri:
181: return ns.getUri();
182: }
183: return super .getInstanceIdValue(id);
184: }
185:
186: // #string_id_map#
187: private static final int Id_constructor = 1, Id_toString = 2,
188: Id_toSource = 3, MAX_PROTOTYPE_ID = 3;
189:
190: protected int findPrototypeId(String s) {
191: int id;
192: // #generated# Last update: 2007-08-20 08:23:22 EDT
193: L0: {
194: id = 0;
195: String X = null;
196: int c;
197: int s_length = s.length();
198: if (s_length == 8) {
199: c = s.charAt(3);
200: if (c == 'o') {
201: X = "toSource";
202: id = Id_toSource;
203: } else if (c == 't') {
204: X = "toString";
205: id = Id_toString;
206: }
207: } else if (s_length == 11) {
208: X = "constructor";
209: id = Id_constructor;
210: }
211: if (X != null && X != s && !X.equals(s))
212: id = 0;
213: break L0;
214: }
215: // #/generated#
216: return id;
217: }
218:
219: // #/string_id_map#
220:
221: protected void initPrototypeId(int id) {
222: String s;
223: int arity;
224: switch (id) {
225: case Id_constructor:
226: arity = 2;
227: s = "constructor";
228: break;
229: case Id_toString:
230: arity = 0;
231: s = "toString";
232: break;
233: case Id_toSource:
234: arity = 0;
235: s = "toSource";
236: break;
237: default:
238: throw new IllegalArgumentException(String.valueOf(id));
239: }
240: initPrototypeMethod(NAMESPACE_TAG, id, s, arity);
241: }
242:
243: public Object execIdCall(IdFunctionObject f, Context cx,
244: Scriptable scope, Scriptable this Obj, Object[] args) {
245: if (!f.hasTag(NAMESPACE_TAG)) {
246: return super .execIdCall(f, cx, scope, this Obj, args);
247: }
248: int id = f.methodId();
249: switch (id) {
250: case Id_constructor:
251: return jsConstructor(cx, (this Obj == null), args);
252: case Id_toString:
253: return realThis(this Obj, f).toString();
254: case Id_toSource:
255: return realThis(this Obj, f).js_toSource();
256: }
257: throw new IllegalArgumentException(String.valueOf(id));
258: }
259:
260: private Namespace realThis(Scriptable this Obj, IdFunctionObject f) {
261: if (!(this Obj instanceof Namespace))
262: throw incompatibleCallError(f);
263: return (Namespace) this Obj;
264: }
265:
266: Namespace newNamespace(String uri) {
267: Namespace prototype = (this .prototype == null) ? this
268: : this .prototype;
269: return create(this .getParentScope(), prototype,
270: XmlNode.Namespace.create(uri));
271: }
272:
273: Namespace newNamespace(String prefix, String uri) {
274: if (prefix == null)
275: return newNamespace(uri);
276: Namespace prototype = (this .prototype == null) ? this
277: : this .prototype;
278: return create(this .getParentScope(), prototype,
279: XmlNode.Namespace.create(prefix, uri));
280: }
281:
282: Namespace constructNamespace(Object uriValue) {
283: String prefix;
284: String uri;
285:
286: if (uriValue instanceof Namespace) {
287: Namespace ns = (Namespace) uriValue;
288: prefix = ns.prefix();
289: uri = ns.uri();
290: } else if (uriValue instanceof QName) {
291: QName qname = (QName) uriValue;
292: uri = qname.uri();
293: if (uri != null) {
294: // TODO Is there a way to push this back into QName so that we can make prefix() private?
295: prefix = qname.prefix();
296: } else {
297: uri = qname.toString();
298: prefix = null;
299: }
300: } else {
301: uri = ScriptRuntime.toString(uriValue);
302: prefix = (uri.length() == 0) ? "" : null;
303: }
304:
305: return newNamespace(prefix, uri);
306: }
307:
308: Namespace castToNamespace(Object namespaceObj) {
309: if (namespaceObj instanceof Namespace) {
310: return (Namespace) namespaceObj;
311: }
312: return constructNamespace(namespaceObj);
313: }
314:
315: private Namespace constructNamespace(Object prefixValue,
316: Object uriValue) {
317: String prefix;
318: String uri;
319:
320: if (uriValue instanceof QName) {
321: QName qname = (QName) uriValue;
322: uri = qname.uri();
323: if (uri == null) {
324: uri = qname.toString();
325: }
326: } else {
327: uri = ScriptRuntime.toString(uriValue);
328: }
329:
330: if (uri.length() == 0) {
331: if (prefixValue == Undefined.instance) {
332: prefix = "";
333: } else {
334: prefix = ScriptRuntime.toString(prefixValue);
335: if (prefix.length() != 0) {
336: throw ScriptRuntime.typeError("Illegal prefix '"
337: + prefix + "' for 'no namespace'.");
338: }
339: }
340: } else if (prefixValue == Undefined.instance) {
341: prefix = "";
342: } else if (!XMLName.accept(prefixValue)) {
343: prefix = "";
344: } else {
345: prefix = ScriptRuntime.toString(prefixValue);
346: }
347:
348: return newNamespace(prefix, uri);
349: }
350:
351: private Namespace constructNamespace() {
352: return newNamespace("", "");
353: }
354:
355: private Object jsConstructor(Context cx, boolean inNewExpr,
356: Object[] args) {
357: if (!inNewExpr && args.length == 1) {
358: return castToNamespace(args[0]);
359: }
360:
361: if (args.length == 0) {
362: return constructNamespace();
363: } else if (args.length == 1) {
364: return constructNamespace(args[0]);
365: } else {
366: return constructNamespace(args[0], args[1]);
367: }
368: }
369:
370: private String js_toSource() {
371: StringBuffer sb = new StringBuffer();
372: sb.append('(');
373: toSourceImpl(ns.getPrefix(), ns.getUri(), sb);
374: sb.append(')');
375: return sb.toString();
376: }
377:
378: static void toSourceImpl(String prefix, String uri, StringBuffer sb) {
379: sb.append("new Namespace(");
380: if (uri.length() == 0) {
381: if (!"".equals(prefix))
382: throw new IllegalArgumentException(prefix);
383: } else {
384: sb.append('\'');
385: if (prefix != null) {
386: sb.append(ScriptRuntime.escapeString(prefix, '\''));
387: sb.append("', '");
388: }
389: sb.append(ScriptRuntime.escapeString(uri, '\''));
390: sb.append('\'');
391: }
392: sb.append(')');
393: }
394: }
|