XMLCtor.java
/* -*- Mode: java; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
package org.mozilla.javascript.xmlimpl;
import org.mozilla.javascript.Context;
import org.mozilla.javascript.IdFunctionObject;
import org.mozilla.javascript.LambdaFunction;
import org.mozilla.javascript.ScriptRuntime;
import org.mozilla.javascript.Scriptable;
import org.mozilla.javascript.ScriptableObject;
import org.mozilla.javascript.SerializableCallable;
import org.mozilla.javascript.Undefined;
class XMLCtor extends IdFunctionObject {
static final long serialVersionUID = -8708195078359817341L;
private static final Object XMLCTOR_TAG = "XMLCtor";
private XmlProcessor options;
private XMLLibImpl lib;
public XMLCtor(Context cx, ScriptableObject scope, XML xml, Object tag, int id, int arity) {
super(xml, tag, id, arity);
// this.lib = xml.lib;
this.options = xml.getProcessor();
createProperties(cx, scope, this);
}
public static IdFunctionObject init() {
return null;
}
private static void createProperties(Context cx, ScriptableObject scope, XMLCtor obj) {
defineMethod(
obj,
scope,
"defaultSettings",
0,
(lcx, lscope, lthisObj, largs) -> {
obj.options.setDefault();
var res = lcx.newObject(lscope);
writeSetting(obj, res);
return res;
});
defineMethod(
obj,
scope,
"settings",
0,
(lcx, lscope, lthisObj, largs) -> {
var res = lcx.newObject(lscope);
writeSetting(obj, res);
return res;
});
defineMethod(
obj,
scope,
"setSettings",
1,
(lcx, lscope, lthisObj, largs) -> {
if (largs.length == 0 || largs[0] == null || largs[0] == Undefined.instance) {
obj.options.setDefault();
} else if (largs[0] instanceof Scriptable) {
readSettings(obj, (Scriptable) largs[0]);
}
return Undefined.instance;
});
ScriptableObject.defineBuiltInProperty(
obj,
"prettyPrinting",
0,
(b, s) -> ScriptRuntime.wrapBoolean(b.options.isPrettyPrinting()),
(b, v, o, s, t) -> {
b.options.setPrettyPrinting(ScriptRuntime.toBoolean(v));
return true;
});
ScriptableObject.defineBuiltInProperty(
obj,
"prettyIndent",
0,
(b, s) -> ScriptRuntime.wrapInt(b.options.getPrettyIndent()),
(b, v, o, s, t) -> {
b.options.setPrettyIndent(ScriptRuntime.toInt32(v));
return true;
});
ScriptableObject.defineBuiltInProperty(
obj,
"ignoreWhitespace",
0,
(b, s) -> ScriptRuntime.wrapBoolean(b.options.isIgnoreWhitespace()),
(b, v, o, s, t) -> {
b.options.setIgnoreWhitespace(ScriptRuntime.toBoolean(v));
return true;
});
ScriptableObject.defineBuiltInProperty(
obj,
"ignoreProcessingInstructions",
0,
(b, s) -> ScriptRuntime.wrapBoolean(b.options.isIgnoreProcessingInstructions()),
(b, v, o, s, t) -> {
b.options.setIgnoreProcessingInstructions(ScriptRuntime.toBoolean(v));
return true;
});
ScriptableObject.defineBuiltInProperty(
obj,
"ignoreComments",
0,
(b, s) -> ScriptRuntime.wrapBoolean(b.options.isIgnoreComments()),
(b, v, o, s, t) -> {
b.options.setIgnoreComments(ScriptRuntime.toBoolean(v));
return true;
});
}
private static void defineMethod(
ScriptableObject obj,
ScriptableObject scope,
String name,
int length,
SerializableCallable target) {
defineMethod(obj, scope, name, length, target, DONTENUM, DONTENUM | READONLY, true);
}
private static void defineMethod(
ScriptableObject obj,
Scriptable scope,
String name,
int length,
SerializableCallable target,
int attributes,
int propertyAttributes,
boolean defaultPrototype) {
LambdaFunction f = new LambdaFunction(scope, name, length, target, defaultPrototype);
f.setStandardPropertyAttributes(propertyAttributes);
obj.defineProperty(name, f, attributes);
}
private static void writeSetting(XMLCtor thisObj, Scriptable target) {
for (var p : propNames) {
Object value = thisObj.get(p, thisObj);
ScriptableObject.putProperty(target, p, value);
}
}
private static void readSettings(XMLCtor thisObj, Scriptable source) {
for (var p : propNames) {
Object value = ScriptableObject.getProperty(source, p);
if (value == Scriptable.NOT_FOUND) {
continue;
}
switch (p) {
case "ignoreComments":
case "ignoreProcessingInstructions":
case "ignoreWhitespace":
case "prettyPrinting":
if (!(value instanceof Boolean)) {
continue;
}
break;
case "prettyIndent":
if (!(value instanceof Number)) {
continue;
}
break;
default:
throw new IllegalStateException();
}
ScriptableObject.putProperty(thisObj, p, value);
}
}
// #string_id_map#
private static final String[] propNames =
new String[] {
"ignoreComments",
"ignoreProcessingInstructions",
"ignoreWhitespace",
"prettyIndent",
"prettyPrinting"
};
/** hasInstance for XML objects works differently than other objects; see ECMA357 13.4.3.10. */
@Override
public boolean hasInstance(Scriptable instance) {
return (instance instanceof XML || instance instanceof XMLList);
}
}