You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@freemarker.apache.org by dd...@apache.org on 2017/01/20 16:50:49 UTC
[3/5] incubator-freemarker git commit: Removed legacy extensions:
rhyno, jython, xml (not to be confused with dom), jdom,
ant. Also removed JSP 2.0 support (2.1 is the minimum for now,
but maybe it will be 2.2 later).
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jython/JythonVersionAdapter.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jython/JythonVersionAdapter.java b/src/main/java/freemarker/ext/jython/JythonVersionAdapter.java
deleted file mode 100644
index 6ec42f4..0000000
--- a/src/main/java/freemarker/ext/jython/JythonVersionAdapter.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.ext.jython;
-
-import org.python.core.PyObject;
-
-/**
- * Functions that has a different implementation depending on the Jython version
- * used. This was introduced to work around class-loading errors because of
- * different classes/methods being present in different Jython versions.
- */
-public abstract class JythonVersionAdapter {
-
- /**
- * Returns
- * <code>obj instanceof Py[Java]Instance</code>.
- */
- public abstract boolean isPyInstance(Object obj);
-
- /**
- * Returns
- * <code>((PyInstance) py[Java]Instance).__tojava__(java.lang.Object.class)</code>.
- */
- public abstract Object pyInstanceToJava(Object pyInstance);
-
- /**
- * Returns <code>pyObject.__class__.__name__</code>
- */
- public abstract String getPythonClassName(PyObject pyObject);
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jython/JythonVersionAdapterHolder.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jython/JythonVersionAdapterHolder.java b/src/main/java/freemarker/ext/jython/JythonVersionAdapterHolder.java
deleted file mode 100644
index 013b32c..0000000
--- a/src/main/java/freemarker/ext/jython/JythonVersionAdapterHolder.java
+++ /dev/null
@@ -1,74 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.ext.jython;
-
-import org.python.core.PySystemState;
-
-import freemarker.template.utility.StringUtil;
-
-/**
- * Holds the {@link JythonVersionAdapter} so that it's only initialized when this class is accessed.
- * This utilizes that the JVM is required to initialize the fields of a class not earlier than the class is
- * first accessed. Furthermore, it utilizes that the JVM guarantees that the objects created as part of the class
- * initialization will be visible with their after-initialization state for the threads that access it.
- */
-class JythonVersionAdapterHolder {
-
- final static JythonVersionAdapter INSTANCE;
- static {
- // Note: Only the textual version number is available in Jython 2.0.
- int version;
- try {
- // Although PySystemState.version is present in all versions,
- // its type changes, so we must use reflection to get it.
- version = StringUtil.versionStringToInt(
- PySystemState.class.getField("version").get(null).toString());
- } catch (Exception e) {
- throw new RuntimeException("Failed to get Jython version: " + e);
- }
- ClassLoader cl = JythonVersionAdapter.class.getClassLoader();
- try {
- if (version >= 2005000) {
- INSTANCE = (JythonVersionAdapter) cl.loadClass(
- "freemarker.ext.jython._Jython25VersionAdapter")
- .newInstance();
- } else if (version >= 2002000) {
- INSTANCE = (JythonVersionAdapter) cl.loadClass(
- "freemarker.ext.jython._Jython22VersionAdapter")
- .newInstance();
- } else {
- INSTANCE = (JythonVersionAdapter) cl.loadClass(
- "freemarker.ext.jython._Jython20And21VersionAdapter")
- .newInstance();
- }
- } catch (ClassNotFoundException e) {
- throw adapterCreationException(e);
- } catch (IllegalAccessException e) {
- throw adapterCreationException(e);
- } catch (InstantiationException e) {
- throw adapterCreationException(e);
- }
- }
-
- private static RuntimeException adapterCreationException(Exception e) {
- return new RuntimeException("Unexpected exception when creating JythonVersionAdapter", e);
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jython/JythonWrapper.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jython/JythonWrapper.java b/src/main/java/freemarker/ext/jython/JythonWrapper.java
deleted file mode 100644
index eb82818..0000000
--- a/src/main/java/freemarker/ext/jython/JythonWrapper.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.ext.jython;
-
-import java.math.BigDecimal;
-import java.math.BigInteger;
-import java.util.ArrayList;
-import java.util.List;
-
-import org.python.core.Py;
-import org.python.core.PyDictionary;
-import org.python.core.PyFloat;
-import org.python.core.PyInteger;
-import org.python.core.PyLong;
-import org.python.core.PyObject;
-import org.python.core.PySequence;
-import org.python.core.PyString;
-import org.python.core.PyStringMap;
-
-import freemarker.ext.util.ModelCache;
-import freemarker.ext.util.WrapperTemplateModel;
-import freemarker.template.AdapterTemplateModel;
-import freemarker.template.ObjectWrapper;
-import freemarker.template.TemplateBooleanModel;
-import freemarker.template.TemplateHashModel;
-import freemarker.template.TemplateHashModelEx;
-import freemarker.template.TemplateMethodModel;
-import freemarker.template.TemplateMethodModelEx;
-import freemarker.template.TemplateModel;
-import freemarker.template.TemplateModelAdapter;
-import freemarker.template.TemplateModelException;
-import freemarker.template.TemplateNumberModel;
-import freemarker.template.TemplateScalarModel;
-import freemarker.template.TemplateSequenceModel;
-import freemarker.template.utility.OptimizerUtil;
-
-/**
- * An object wrapper that wraps Jython objects into FreeMarker template models
- * and vice versa.
- */
-public class JythonWrapper implements ObjectWrapper {
- private static final Class PYOBJECT_CLASS = PyObject.class;
- public static final JythonWrapper INSTANCE = new JythonWrapper();
-
- private final ModelCache modelCache = new JythonModelCache(this);
-
- private boolean attributesShadowItems = true;
-
- public JythonWrapper() {
- }
-
- /**
- * Sets whether this wrapper caches model instances. Default is false.
- * When set to true, calling {@link #wrap(Object)} multiple times for
- * the same object will return the same model.
- */
- public void setUseCache(boolean useCache) {
- modelCache.setUseCache(useCache);
- }
-
- /**
- * Sets whether attributes shadow items in wrapped objects. When true
- * (this is the default value), <code>${object.name}</code> will first
- * try to locate a python attribute with the specified name on the object
- * using {@link PyObject#__findattr__(java.lang.String)}, and only if it
- * doesn't find the attribute will it call
- * {@link PyObject#__getitem__(org.python.core.PyObject)}.
- * When set to false, the lookup order is reversed and items
- * are looked up before attributes.
- */
- public synchronized void setAttributesShadowItems(boolean attributesShadowItems) {
- this.attributesShadowItems = attributesShadowItems;
- }
-
- boolean isAttributesShadowItems() {
- return attributesShadowItems;
- }
-
- /**
- * Wraps the passed Jython object into a FreeMarker template model. If
- * the object is not a Jython object, it's first coerced into one using
- * {@link Py#java2py(java.lang.Object)}. {@link PyDictionary} and {@link
- * PyStringMap} are wrapped into a hash model, {@link PySequence}
- * descendants are wrapped into a sequence model, {@link PyInteger}, {@link
- * PyLong}, and {@link PyFloat} are wrapped into a number model. All objects
- * are wrapped into a scalar model (using {@link Object#toString()} and a
- * boolean model (using {@link PyObject#__nonzero__()}. For internal
- * general-purpose {@link PyObject}s returned from a call to {@link
- * #unwrap(TemplateModel)}, the template model that was passed to
- * <code>unwrap</code> is returned.
- */
- public TemplateModel wrap(Object obj) {
- if (obj == null) {
- return null;
- }
- return modelCache.getInstance(obj);
- }
-
- /**
- * Coerces a template model into a {@link PyObject}.
- * @param model the model to coerce
- * @return the coerced model.
- * <ul>
- * <li>
- * <li>{@link AdapterTemplateModel}s (i.e. {@link freemarker.ext.beans.BeanModel}) are marshalled
- * using the standard Python marshaller {@link Py#java2py(Object)} on
- * the result of <code>getWrappedObject(PyObject.class)</code>s. The
- * native JythonModel instances will just return the underlying PyObject.
- * <li>All other models that are {@link TemplateScalarModel scalars} are
- * marshalled as {@link PyString}.
- * <li>All other models that are {@link TemplateNumberModel numbers} are
- * marshalled using the standard Python marshaller
- * {@link Py#java2py(Object)} on their underlying <code>Number</code></li>
- * <li>All other models are marshalled to a generic internal
- * <code>PyObject</code> subclass that'll correctly pass
- * <code>__finditem__</code>, <code>__len__</code>,
- * <code>__nonzero__</code>, and <code>__call__</code> invocations to
- * appropriate hash, sequence, and method models.</li>
- * </ul>
- */
- public PyObject unwrap(TemplateModel model) throws TemplateModelException {
- if (model instanceof AdapterTemplateModel) {
- return Py.java2py(((AdapterTemplateModel) model).getAdaptedObject(
- PYOBJECT_CLASS));
- }
- if (model instanceof WrapperTemplateModel) {
- return Py.java2py(((WrapperTemplateModel) model).getWrappedObject());
- }
-
- // Scalars are marshalled to PyString.
- if (model instanceof TemplateScalarModel) {
- return new PyString(((TemplateScalarModel) model).getAsString());
- }
-
- // Numbers are wrapped to Python built-in numeric types.
- if (model instanceof TemplateNumberModel) {
- Number number = ((TemplateNumberModel) model).getAsNumber();
- if (number instanceof BigDecimal) {
- number = OptimizerUtil.optimizeNumberRepresentation(number);
- }
- if (number instanceof BigInteger) {
- // Py.java2py can't automatically coerce a BigInteger into
- // a PyLong. This will probably get fixed in later Jython
- // release.
- return new PyLong((BigInteger) number);
- } else {
- return Py.java2py(number);
- }
- }
- // Return generic TemplateModel-to-Python adapter
- return new TemplateModelToJythonAdapter(model);
- }
-
- private class TemplateModelToJythonAdapter extends PyObject
- implements TemplateModelAdapter {
- private final TemplateModel model;
-
- TemplateModelToJythonAdapter(TemplateModel model) {
- this.model = model;
- }
-
- public TemplateModel getTemplateModel() {
- return model;
- }
-
- @Override
- public PyObject __finditem__(PyObject key) {
- if (key instanceof PyInteger) {
- return __finditem__(((PyInteger) key).getValue());
- }
- return __finditem__(key.toString());
- }
-
- @Override
- public PyObject __finditem__(String key) {
- if (model instanceof TemplateHashModel) {
- try {
- return unwrap(((TemplateHashModel) model).get(key));
- } catch (TemplateModelException e) {
- throw Py.JavaError(e);
- }
- }
- throw Py.TypeError("item lookup on non-hash model (" + getModelClass() + ")");
- }
-
- @Override
- public PyObject __finditem__(int index) {
- if (model instanceof TemplateSequenceModel) {
- try {
- return unwrap(((TemplateSequenceModel) model).get(index));
- } catch (TemplateModelException e) {
- throw Py.JavaError(e);
- }
- }
- throw Py.TypeError("item lookup on non-sequence model (" + getModelClass() + ")");
- }
-
- @Override
- public PyObject __call__(PyObject args[], String keywords[]) {
- if (model instanceof TemplateMethodModel) {
- boolean isEx = model instanceof TemplateMethodModelEx;
- List list = new ArrayList(args.length);
- try {
- for (int i = 0; i < args.length; ++i) {
- list.add(
- isEx
- ? (Object) wrap(args[i])
- : (Object) (
- args[i] == null
- ? null
- : args[i].toString()));
- }
- return unwrap((TemplateModel) ((TemplateMethodModelEx) model).exec(list));
- } catch (TemplateModelException e) {
- throw Py.JavaError(e);
- }
- }
- throw Py.TypeError("call of non-method model (" + getModelClass() + ")");
- }
-
- @Override
- public int __len__() {
- try {
- if (model instanceof TemplateSequenceModel) {
- return ((TemplateSequenceModel) model).size();
- }
- if (model instanceof TemplateHashModelEx) {
- return ((TemplateHashModelEx) model).size();
- }
- } catch (TemplateModelException e) {
- throw Py.JavaError(e);
- }
-
- return 0;
- }
-
- @Override
- public boolean __nonzero__() {
- try {
- if (model instanceof TemplateBooleanModel) {
- return ((TemplateBooleanModel) model).getAsBoolean();
- }
- if (model instanceof TemplateSequenceModel) {
- return ((TemplateSequenceModel) model).size() > 0;
- }
- if (model instanceof TemplateHashModel) {
- return !((TemplateHashModelEx) model).isEmpty();
- }
- } catch (TemplateModelException e) {
- throw Py.JavaError(e);
- }
- return false;
- }
-
- private String getModelClass() {
- return model == null ? "null" : model.getClass().getName();
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jython/_Jython20And21VersionAdapter.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jython/_Jython20And21VersionAdapter.java b/src/main/java/freemarker/ext/jython/_Jython20And21VersionAdapter.java
deleted file mode 100644
index fe905dd..0000000
--- a/src/main/java/freemarker/ext/jython/_Jython20And21VersionAdapter.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.ext.jython;
-
-import org.python.core.PyJavaInstance;
-import org.python.core.PyObject;
-
-/**
- * Don't use this class; it's only public to work around Google App Engine Java
- * compliance issues. FreeMarker developers only: treat this class as package-visible.
- *
- * {@link JythonVersionAdapter} for Jython 2.0 and 2.1.
- */
-public class _Jython20And21VersionAdapter extends JythonVersionAdapter {
-
- public boolean isPyInstance(Object obj) {
- return obj instanceof PyJavaInstance;
- }
-
- public Object pyInstanceToJava(Object pyInstance) {
- return ((PyJavaInstance) pyInstance).__tojava__(java.lang.Object.class);
- }
-
- public String getPythonClassName(PyObject pyObject) {
- return pyObject.__class__.__name__;
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jython/_Jython22VersionAdapter.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jython/_Jython22VersionAdapter.java b/src/main/java/freemarker/ext/jython/_Jython22VersionAdapter.java
deleted file mode 100644
index 30173df..0000000
--- a/src/main/java/freemarker/ext/jython/_Jython22VersionAdapter.java
+++ /dev/null
@@ -1,45 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.ext.jython;
-
-import org.python.core.PyJavaInstance;
-import org.python.core.PyObject;
-
-/**
- * Don't use this class; it's only public to work around Google App Engine Java
- * compliance issues. FreeMarker developers only: treat this class as package-visible.
- *
- * {@link JythonVersionAdapter} for Jython 2.2.
- */
-public class _Jython22VersionAdapter extends JythonVersionAdapter {
-
- public boolean isPyInstance(Object obj) {
- return obj instanceof PyJavaInstance;
- }
-
- public Object pyInstanceToJava(Object pyInstance) {
- return ((PyJavaInstance) pyInstance).__tojava__(java.lang.Object.class);
- }
-
- public String getPythonClassName(PyObject pyObject) {
- return pyObject.getType().getFullName();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jython/_Jython25VersionAdapter.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jython/_Jython25VersionAdapter.java b/src/main/java/freemarker/ext/jython/_Jython25VersionAdapter.java
deleted file mode 100644
index 27d58a8..0000000
--- a/src/main/java/freemarker/ext/jython/_Jython25VersionAdapter.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.ext.jython;
-
-import org.python.core.PyInstance;
-import org.python.core.PyObject;
-
-/**
- * Don't use this class; it's only public to work around Google App Engine Java
- * compliance issues. FreeMarker developers only: treat this class as package-visible.
- *
- * {@link JythonVersionAdapter} for Jython 2.5.
- */
-public class _Jython25VersionAdapter extends JythonVersionAdapter {
-
- @Override
- public boolean isPyInstance(Object obj) {
- return obj instanceof PyInstance;
- }
-
- @Override
- public Object pyInstanceToJava(Object pyInstance) {
- return ((PyInstance) pyInstance).__tojava__(java.lang.Object.class);
- }
-
- @Override
- public String getPythonClassName(PyObject pyObject) {
- return pyObject.getType().getName();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/jython/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/jython/package.html b/src/main/java/freemarker/ext/jython/package.html
deleted file mode 100644
index b979552..0000000
--- a/src/main/java/freemarker/ext/jython/package.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-<html>
-<head>
-<title></title>
-</head>
-<body>
-
-<p>Exposes <a href="http://www.jython.org" target="_blank">Jython</a> objects to templates.
-The {@link freemarker.template.DefaultObjectWrapper default object wrapper} of FreeMarker
-automatically wraps Jython nodes with this.
-
-<p>Most of the issues dealing with Jython objects are handled by the
-{@link freemarker.ext.jython.JythonWrapper#wrap(Object)} method. In
-normal cases, this is the only method you should use to turn an
-arbitrary Jython object into a FreeMarker
-{@link freemarker.template.TemplateModel}. Additionally, you can
-manually create instances of any wrapper class using its constructors.
-
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/rhino/RhinoFunctionModel.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/rhino/RhinoFunctionModel.java b/src/main/java/freemarker/ext/rhino/RhinoFunctionModel.java
deleted file mode 100644
index 61674a1..0000000
--- a/src/main/java/freemarker/ext/rhino/RhinoFunctionModel.java
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.ext.rhino;
-
-import java.util.List;
-
-import org.mozilla.javascript.Context;
-import org.mozilla.javascript.Function;
-import org.mozilla.javascript.Scriptable;
-import org.mozilla.javascript.ScriptableObject;
-
-import freemarker.ext.beans.BeansWrapper;
-import freemarker.template.TemplateMethodModelEx;
-import freemarker.template.TemplateModel;
-import freemarker.template.TemplateModelException;
-
-/**
- */
-public class RhinoFunctionModel extends RhinoScriptableModel
-implements TemplateMethodModelEx {
-
- private final Scriptable fnThis;
-
- public RhinoFunctionModel(Function function, Scriptable fnThis,
- BeansWrapper wrapper) {
- super(function, wrapper);
- this.fnThis = fnThis;
- }
-
- public Object exec(List arguments) throws TemplateModelException {
- Context cx = Context.getCurrentContext();
- Object[] args = arguments.toArray();
- BeansWrapper wrapper = getWrapper();
- for (int i = 0; i < args.length; i++) {
- args[i] = wrapper.unwrap((TemplateModel) args[i]);
- }
- return wrapper.wrap(((Function) getScriptable()).call(cx,
- ScriptableObject.getTopLevelScope(fnThis), fnThis, args));
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/rhino/RhinoScriptableModel.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/rhino/RhinoScriptableModel.java b/src/main/java/freemarker/ext/rhino/RhinoScriptableModel.java
deleted file mode 100644
index a39ae70..0000000
--- a/src/main/java/freemarker/ext/rhino/RhinoScriptableModel.java
+++ /dev/null
@@ -1,136 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.ext.rhino;
-
-import org.mozilla.javascript.Context;
-import org.mozilla.javascript.EvaluatorException;
-import org.mozilla.javascript.Function;
-import org.mozilla.javascript.NativeJavaObject;
-import org.mozilla.javascript.Scriptable;
-import org.mozilla.javascript.ScriptableObject;
-
-import freemarker.ext.beans.BeansWrapper;
-import freemarker.ext.util.ModelFactory;
-import freemarker.template.AdapterTemplateModel;
-import freemarker.template.ObjectWrapper;
-import freemarker.template.TemplateBooleanModel;
-import freemarker.template.TemplateCollectionModel;
-import freemarker.template.TemplateHashModelEx;
-import freemarker.template.TemplateModel;
-import freemarker.template.TemplateModelException;
-import freemarker.template.TemplateNumberModel;
-import freemarker.template.TemplateScalarModel;
-import freemarker.template.TemplateSequenceModel;
-
-/**
- */
-public class RhinoScriptableModel implements TemplateHashModelEx,
-TemplateSequenceModel, AdapterTemplateModel, TemplateScalarModel,
-TemplateBooleanModel, TemplateNumberModel {
- static final ModelFactory FACTORY = new ModelFactory() {
- public TemplateModel create(Object object, ObjectWrapper wrapper) {
- return new RhinoScriptableModel((Scriptable) object,
- (BeansWrapper) wrapper);
- }
- };
-
- private final Scriptable scriptable;
- private final BeansWrapper wrapper;
-
- public RhinoScriptableModel(Scriptable scriptable, BeansWrapper wrapper) {
- this.scriptable = scriptable;
- this.wrapper = wrapper;
- }
-
- public TemplateModel get(String key) throws TemplateModelException {
- Object retval = ScriptableObject.getProperty(scriptable, key);
- if (retval instanceof Function) {
- return new RhinoFunctionModel((Function) retval, scriptable, wrapper);
- } else {
- return wrapper.wrap(retval);
- }
- }
-
- public TemplateModel get(int index) throws TemplateModelException {
- Object retval = ScriptableObject.getProperty(scriptable, index);
- if (retval instanceof Function) {
- return new RhinoFunctionModel((Function) retval, scriptable, wrapper);
- } else {
- return wrapper.wrap(retval);
- }
- }
-
- public boolean isEmpty() {
- return scriptable.getIds().length == 0;
- }
-
- public TemplateCollectionModel keys() throws TemplateModelException {
- return (TemplateCollectionModel) wrapper.wrap(scriptable.getIds());
- }
-
- public int size() {
- return scriptable.getIds().length;
- }
-
- public TemplateCollectionModel values() throws TemplateModelException {
- Object[] ids = scriptable.getIds();
- Object[] values = new Object[ids.length];
- for (int i = 0; i < values.length; i++) {
- Object id = ids[i];
- if (id instanceof Number) {
- values[i] = ScriptableObject.getProperty(scriptable,
- ((Number) id).intValue());
- } else {
- values[i] = ScriptableObject.getProperty(scriptable,
- String.valueOf(id));
- }
- }
- return (TemplateCollectionModel) wrapper.wrap(values);
- }
-
- public boolean getAsBoolean() {
- return Context.toBoolean(scriptable);
- }
-
- public Number getAsNumber() {
- return Double.valueOf(Context.toNumber(scriptable));
- }
-
- public String getAsString() {
- return Context.toString(scriptable);
- }
-
- Scriptable getScriptable() {
- return scriptable;
- }
-
- BeansWrapper getWrapper() {
- return wrapper;
- }
-
- public Object getAdaptedObject(Class hint) {
- // FIXME: This does LS3 conversion, which is not very useful for us. Like it won't convert to List, Map, etc.
- try {
- return NativeJavaObject.coerceType(hint, scriptable);
- } catch (EvaluatorException e) {
- return NativeJavaObject.coerceType(Object.class, scriptable);
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/rhino/RhinoWrapper.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/rhino/RhinoWrapper.java b/src/main/java/freemarker/ext/rhino/RhinoWrapper.java
deleted file mode 100644
index 9b06bac..0000000
--- a/src/main/java/freemarker/ext/rhino/RhinoWrapper.java
+++ /dev/null
@@ -1,87 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.ext.rhino;
-
-import java.security.AccessController;
-import java.security.PrivilegedExceptionAction;
-
-import org.mozilla.javascript.Scriptable;
-import org.mozilla.javascript.Undefined;
-import org.mozilla.javascript.UniqueTag;
-import org.mozilla.javascript.Wrapper;
-
-import freemarker.ext.beans.BeansWrapper;
-import freemarker.ext.util.ModelFactory;
-import freemarker.template.TemplateModel;
-import freemarker.template.TemplateModelException;
-import freemarker.template.utility.UndeclaredThrowableException;
-
-/**
- */
-public class RhinoWrapper extends BeansWrapper {
- // The type of the "instance" field changed between Rhino versions, so a
- // GETSTATIC with wrong type declaration would cause a NoSuchFieldError;
- // we're avoiding it by acquiring it reflectively.
- private static final Object UNDEFINED_INSTANCE;
- static {
- try {
- UNDEFINED_INSTANCE = AccessController.doPrivileged(new PrivilegedExceptionAction() {
- public Object run() throws Exception {
- return Undefined.class.getField("instance").get(null);
- }
- });
- } catch (RuntimeException e) {
- throw e;
- } catch (Exception e) {
- throw new UndeclaredThrowableException(e);
- }
- }
-
- @Override
- public TemplateModel wrap(Object obj) throws TemplateModelException {
- // So our existence builtins work as expected.
- if (obj == UNDEFINED_INSTANCE || obj == UniqueTag.NOT_FOUND) {
- return null;
- }
- // UniqueTag.NULL_VALUE represents intentionally set null in Rhino, and
- // BeansWrapper#nullModel also represents intentionally returned null.
- // I [A.Sz.] am fairly certain that this value is never passed out of
- // any of the Rhino code back to clients, but is instead always being
- // converted back to null. However, since this object is available to
- // any 3rd party Scriptable implementations as well, they might return
- // it, so we'll just be on the safe side, and handle it.
- if (obj == UniqueTag.NULL_VALUE) {
- return super.wrap(null);
- }
- // So, say, a JavaAdapter for FreeMarker interfaces works
- if (obj instanceof Wrapper) {
- obj = ((Wrapper) obj).unwrap();
- }
- return super.wrap(obj);
- }
-
- @Override
- protected ModelFactory getModelFactory(Class clazz) {
- if (Scriptable.class.isAssignableFrom(clazz)) {
- return RhinoScriptableModel.FACTORY;
- }
- return super.getModelFactory(clazz);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/rhino/package.html
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/rhino/package.html b/src/main/java/freemarker/ext/rhino/package.html
deleted file mode 100644
index ede49a8..0000000
--- a/src/main/java/freemarker/ext/rhino/package.html
+++ /dev/null
@@ -1,28 +0,0 @@
-<!--
- Licensed to the Apache Software Foundation (ASF) under one
- or more contributor license agreements. See the NOTICE file
- distributed with this work for additional information
- regarding copyright ownership. The ASF licenses this file
- to you under the Apache License, Version 2.0 (the
- "License"); you may not use this file except in compliance
- with the License. You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing,
- software distributed under the License is distributed on an
- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- KIND, either express or implied. See the License for the
- specific language governing permissions and limitations
- under the License.
--->
-<html>
-<head>
-<title></title>
-</head>
-<body>
-
-<p>Exposes Rhino (ECMAScript) objects to templates.
-
-</body>
-</html>
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/servlet/FreemarkerServlet.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/servlet/FreemarkerServlet.java b/src/main/java/freemarker/ext/servlet/FreemarkerServlet.java
index 4bc7504..504bbeb 100644
--- a/src/main/java/freemarker/ext/servlet/FreemarkerServlet.java
+++ b/src/main/java/freemarker/ext/servlet/FreemarkerServlet.java
@@ -403,7 +403,6 @@ public class FreemarkerServlet extends HttpServlet {
private static final String DEPR_INITPARAM_OBJECT_WRAPPER = "ObjectWrapper";
private static final String DEPR_INITPARAM_WRAPPER_SIMPLE = "simple";
private static final String DEPR_INITPARAM_WRAPPER_BEANS = "beans";
- private static final String DEPR_INITPARAM_WRAPPER_JYTHON = "jython";
private static final String DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER = "TemplateExceptionHandler";
private static final String DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER_RETHROW = "rethrow";
private static final String DEPR_INITPARAM_TEMPLATE_EXCEPTION_HANDLER_DEBUG = "debug";
@@ -1293,19 +1292,6 @@ public class FreemarkerServlet extends HttpServlet {
if (DEPR_INITPARAM_WRAPPER_SIMPLE.equals(wrapper)) {
return ObjectWrapper.SIMPLE_WRAPPER;
}
- if (DEPR_INITPARAM_WRAPPER_JYTHON.equals(wrapper)) {
- // Avoiding compile-time dependency on Jython package
- try {
- return (ObjectWrapper) Class.forName("freemarker.ext.jython.JythonWrapper")
- .newInstance();
- } catch (InstantiationException e) {
- throw new InstantiationError(e.getMessage());
- } catch (IllegalAccessException e) {
- throw new IllegalAccessError(e.getMessage());
- } catch (ClassNotFoundException e) {
- throw new NoClassDefFoundError(e.getMessage());
- }
- }
return createDefaultObjectWrapper();
} else {
wrapper = getInitParameter(Configurable.OBJECT_WRAPPER_KEY);
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/xml/Namespaces.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/xml/Namespaces.java b/src/main/java/freemarker/ext/xml/Namespaces.java
deleted file mode 100644
index 8c4ce75..0000000
--- a/src/main/java/freemarker/ext/xml/Namespaces.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.ext.xml;
-import java.util.HashMap;
-import java.util.List;
-
-import freemarker.template.TemplateMethodModel;
-import freemarker.template.TemplateModelException;
-import freemarker.template.TemplateScalarModel;
-
-/**
- */
-class Namespaces
-implements
- TemplateMethodModel,
- Cloneable {
- private HashMap namespaces;
- private boolean shared;
-
- Namespaces() {
- namespaces = new HashMap();
- namespaces.put("", "");
- namespaces.put("xml", "http://www.w3.org/XML/1998/namespace");
- shared = false;
- }
-
- @Override
- public Object clone() {
- try {
- Namespaces clone = (Namespaces) super.clone();
- clone.namespaces = (HashMap) namespaces.clone();
- clone.shared = false;
- return clone;
- } catch (CloneNotSupportedException e) {
- throw new Error(); // Cannot happen
- }
- }
-
- public String translateNamespacePrefixToUri(String prefix) {
- synchronized (namespaces) {
- return (String) namespaces.get(prefix);
- }
- }
-
- public Object exec(List arguments) throws TemplateModelException {
- if (arguments.size() != 2) {
- throw new TemplateModelException("_registerNamespace(prefix, uri) requires two arguments");
- }
- registerNamespace((String) arguments.get(0), (String) arguments.get(1));
- return TemplateScalarModel.EMPTY_STRING;
- }
-
- void registerNamespace(String prefix, String uri) {
- synchronized (namespaces) {
- namespaces.put(prefix, uri);
- }
- }
-
- void markShared() {
- if (!shared) {
- shared = true;
- }
- }
-
- boolean isShared() {
- return shared;
- }
-}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/xml/Navigator.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/xml/Navigator.java b/src/main/java/freemarker/ext/xml/Navigator.java
deleted file mode 100644
index 2a2542f..0000000
--- a/src/main/java/freemarker/ext/xml/Navigator.java
+++ /dev/null
@@ -1,276 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.ext.xml;
-
-import java.io.StringWriter;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.WeakHashMap;
-
-import org.jaxen.NamespaceContext;
-
-import freemarker.template.TemplateModelException;
-
-/**
- */
-abstract class Navigator {
- // Cache of already parsed XPath expressions
- private final Map xpathCache = new WeakHashMap();
- // Operators this navigator defines
- private final Map operators = createOperatorMap();
- private final NodeOperator attributeOperator = getOperator("_attributes");
- private final NodeOperator childrenOperator = getOperator("_children");
-
- NodeOperator getOperator(String key) {
- return (NodeOperator) operators.get(key);
- }
-
- NodeOperator getAttributeOperator() {
- return attributeOperator;
- }
-
- NodeOperator getChildrenOperator() {
- return childrenOperator;
- }
-
- abstract void getAsString(Object node, StringWriter sw)
- throws TemplateModelException;
-
- List applyXPath(List nodes, String xpathString, Object namespaces)
- throws TemplateModelException {
- XPathEx xpath = null;
- try {
- synchronized (xpathCache) {
- xpath = (XPathEx) xpathCache.get(xpathString);
- if (xpath == null) {
- xpath = createXPathEx(xpathString);
- xpathCache.put(xpathString, xpath);
- }
- }
- return xpath.selectNodes(nodes, (NamespaceContext) namespaces);
- } catch (Exception e) {
- throw new TemplateModelException("Could not evaulate XPath expression " + xpathString, e);
- }
- }
-
- interface XPathEx {
- List selectNodes(Object nodes, NamespaceContext namespaces) throws TemplateModelException;
- }
-
- abstract XPathEx createXPathEx(String xpathString) throws TemplateModelException;
-
- abstract void getChildren(Object node, String localName, String namespaceUri, List result);
-
- abstract void getAttributes(Object node, String localName, String namespaceUri, List result);
-
- abstract void getDescendants(Object node, List result);
-
- abstract Object getParent(Object node);
-
- abstract Object getDocument(Object node);
-
- abstract Object getDocumentType(Object node);
-
- private void getAncestors(Object node, List result) {
- for (; ; ) {
- Object parent = getParent(node);
- if (parent == null) {
- break;
- }
- result.add(parent);
- node = parent;
- }
- }
-
- abstract void getContent(Object node, List result);
-
- abstract String getText(Object node);
-
- abstract String getLocalName(Object node);
-
- abstract String getNamespacePrefix(Object node);
-
- String getQualifiedName(Object node) {
- String lname = getLocalName(node);
- if (lname == null) {
- return null;
- }
- String nsprefix = getNamespacePrefix(node);
- if (nsprefix == null || nsprefix.length() == 0) {
- return lname;
- } else {
- return nsprefix + ":" + lname;
- }
- }
-
- abstract String getType(Object node);
-
- abstract String getNamespaceUri(Object node);
-
- boolean equal(String s1, String s2) {
- return s1 == null ? s2 == null : s1.equals(s2);
- }
-
- private Map createOperatorMap() {
- Map map = new HashMap();
- map.put("_attributes", new AttributesOp());
- map.put("@*", map.get("_attributes"));
- map.put("_children", new ChildrenOp());
- map.put("*", map.get("_children"));
- map.put("_descendantOrSelf", new DescendantOrSelfOp());
- map.put("_descendant", new DescendantOp());
- map.put("_document", new DocumentOp());
- map.put("_doctype", new DocumentTypeOp());
- map.put("_ancestor", new AncestorOp());
- map.put("_ancestorOrSelf", new AncestorOrSelfOp());
- map.put("_content", new ContentOp());
- map.put("_name", new LocalNameOp());
- map.put("_nsprefix", new NamespacePrefixOp());
- map.put("_nsuri", new NamespaceUriOp());
- map.put("_parent", new ParentOp());
- map.put("_qname", new QualifiedNameOp());
- map.put("_text", new TextOp());
- map.put("_type", new TypeOp());
- return map;
- }
-
- private class ChildrenOp implements NodeOperator {
- public void process(Object node, String localName, String namespaceUri, List result) {
- getChildren(node, localName, namespaceUri, result);
- }
- }
-
- private class AttributesOp implements NodeOperator {
- public void process(Object node, String localName, String namespaceUri, List result) {
- getAttributes(node, localName, namespaceUri, result);
- }
- }
-
- private class DescendantOrSelfOp implements NodeOperator {
- public void process(Object node, String localName, String namespaceUri, List result) {
- result.add(node);
- getDescendants(node, result);
- }
- }
-
- private class DescendantOp implements NodeOperator {
- public void process(Object node, String localName, String namespaceUri, List result) {
- getDescendants(node, result);
- }
- }
-
- private class AncestorOrSelfOp implements NodeOperator {
- public void process(Object node, String localName, String namespaceUri, List result) {
- result.add(node);
- getAncestors(node, result);
- }
- }
-
- private class AncestorOp implements NodeOperator {
- public void process(Object node, String localName, String namespaceUri, List result) {
- getAncestors(node, result);
- }
- }
-
- private class ParentOp implements NodeOperator {
- public void process(Object node, String localName, String namespaceUri, List result) {
- Object parent = getParent(node);
- if (parent != null) {
- result.add(parent);
- }
- }
- }
-
- private class DocumentOp implements NodeOperator {
- public void process(Object node, String localName, String namespaceUri, List result) {
- Object document = getDocument(node);
- if (document != null) {
- result.add(document);
- }
- }
- }
-
- private class DocumentTypeOp implements NodeOperator {
- public void process(Object node, String localName, String namespaceUri, List result) {
- Object documentType = getDocumentType(node);
- if (documentType != null) {
- result.add(documentType);
- }
- }
- }
-
- private class ContentOp implements NodeOperator {
- public void process(Object node, String localName, String namespaceUri, List result) {
- getContent(node, result);
- }
- }
-
- private class TextOp implements NodeOperator {
- public void process(Object node, String localName, String namespaceUri, List result) {
- String text = getText(node);
- if (text != null) {
- result.add(text);
- }
- }
- }
-
- private class LocalNameOp implements NodeOperator {
- public void process(Object node, String localName, String namespaceUri, List result) {
- String text = getLocalName(node);
- if (text != null) {
- result.add(text);
- }
- }
- }
-
- private class QualifiedNameOp implements NodeOperator {
- public void process(Object node, String localName, String namespaceUri, List result) {
- String qname = getQualifiedName(node);
- if (qname != null) {
- result.add(qname);
- }
- }
- }
-
- private class NamespacePrefixOp implements NodeOperator {
- public void process(Object node, String localName, String namespaceUri, List result) {
- String text = getNamespacePrefix(node);
- if (text != null) {
- result.add(text);
- }
- }
- }
-
- private class NamespaceUriOp implements NodeOperator {
- public void process(Object node, String localName, String namespaceUri, List result) {
- String text = getNamespaceUri(node);
- if (text != null) {
- result.add(text);
- }
- }
- }
-
- private class TypeOp implements NodeOperator {
- public void process(Object node, String localName, String namespaceUri, List result) {
- result.add(getType(node));
- }
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/xml/NodeListModel.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/xml/NodeListModel.java b/src/main/java/freemarker/ext/xml/NodeListModel.java
deleted file mode 100644
index d42643d..0000000
--- a/src/main/java/freemarker/ext/xml/NodeListModel.java
+++ /dev/null
@@ -1,554 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.ext.xml;
-
-import java.io.StringWriter;
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-import freemarker.log.Logger;
-import freemarker.template.TemplateHashModel;
-import freemarker.template.TemplateMethodModel;
-import freemarker.template.TemplateModel;
-import freemarker.template.TemplateModelException;
-import freemarker.template.TemplateNodeModel;
-import freemarker.template.TemplateScalarModel;
-import freemarker.template.TemplateSequenceModel;
-import freemarker.template.utility.ClassUtil;
-
-/**
- * <p>A data model adapter for three widespread XML document object model
- * representations: W3C DOM, dom4j, and JDOM. The adapter automatically
- * recognizes the used XML object model and provides a unified interface for it
- * toward the template. The model provides access to all XML InfoSet features
- * of the XML document and includes XPath support if it has access to the XPath-
- * evaluator library Jaxen. The model's philosophy (which closely follows that
- * of XML InfoSet and XPath) is as follows: it always wraps a list of XML nodes
- * (the "nodelist"). The list can be empty, can have a single element, or can
- * have multiple elements. Every operation applied to the model is applied to
- * all nodes in its nodelist. You usually start with a single- element nodelist,
- * usually the root element node or the document node of the XML tree.
- * Additionally, the nodes can contain String objects as a result of certain
- * evaluations (getting the names of elements, values of attributes, etc.)</p>
- * <p><strong>Implementation note:</strong> If you are using W3C DOM documents
- * built by the Crimson XML parser (or you are using the built-in JDK 1.4 XML
- * parser, which is essentially Crimson), make sure you call
- * <tt>setNamespaceAware(true)</tt> on the
- * <tt>javax.xml.parsers.DocumentBuilderFactory</tt> instance used for document
- * building even when your documents don't use XML namespaces. Failing to do so,
- * you will experience incorrect behavior when using the documents wrapped with
- * this model.</p>
- *
- * @deprecated Use {@link freemarker.ext.dom.NodeModel} instead.
- */
-@Deprecated
-public class NodeListModel
-implements
- TemplateHashModel,
- TemplateMethodModel,
- TemplateScalarModel,
- TemplateSequenceModel,
- TemplateNodeModel {
- private static final Logger LOG = Logger.getLogger("freemarker.xml");
-
- private static final Class DOM_NODE_CLASS = getClass("org.w3c.dom.Node");
- private static final Class DOM4J_NODE_CLASS = getClass("org.dom4j.Node");
- private static final Navigator DOM_NAVIGATOR = getNavigator("Dom");
- private static final Navigator DOM4J_NAVIGATOR = getNavigator("Dom4j");
- private static final Navigator JDOM_NAVIGATOR = getNavigator("Jdom");
- private static volatile boolean useJaxenNamespaces = true;
-
- // The navigator object that implements document model-specific behavior.
- private final Navigator navigator;
- // The contained nodes
- private final List nodes;
- // The namespaces object (potentially shared by multiple models)
- private Namespaces namespaces;
-
- /**
- * Creates a new NodeListModel, wrapping the passed nodes.
- * @param nodes you can pass it a single XML node from any supported
- * document model, or a Java collection containing any number of nodes.
- * Passing null is prohibited. To create an empty model, pass it an empty
- * collection. If a collection is passed, all passed nodes must belong to
- * the same XML object model, i.e. you can't mix JDOM and dom4j in a single
- * instance of NodeListModel. The model itself doesn't check for this condition,
- * as it can be time consuming, but will throw spurious
- * {@link ClassCastException}s when it encounters mixed objects.
- * @throws IllegalArgumentException if you pass null
- */
- public NodeListModel(Object nodes) {
- Object node = nodes;
- if (nodes instanceof Collection) {
- this.nodes = new ArrayList((Collection) nodes);
- node = this.nodes.isEmpty() ? null : this.nodes.get(0);
- } else if (nodes != null) {
- this.nodes = Collections.singletonList(nodes);
- } else {
- throw new IllegalArgumentException("nodes == null");
- }
- if (DOM_NODE_CLASS != null && DOM_NODE_CLASS.isInstance(node)) {
- navigator = DOM_NAVIGATOR;
- } else if (DOM4J_NODE_CLASS != null && DOM4J_NODE_CLASS.isInstance(node)) {
- navigator = DOM4J_NAVIGATOR;
- } else {
- // Assume JDOM
- navigator = JDOM_NAVIGATOR;
- }
- namespaces = createNamespaces();
- }
-
- private Namespaces createNamespaces() {
- if (useJaxenNamespaces) {
- try {
- return (Namespaces)
- Class.forName("freemarker.ext.xml._JaxenNamespaces")
- .newInstance();
- } catch (Throwable t) {
- useJaxenNamespaces = false;
- }
- }
- return new Namespaces();
- }
-
- private NodeListModel(Navigator navigator, List nodes, Namespaces namespaces) {
- this.navigator = navigator;
- this.nodes = nodes;
- this.namespaces = namespaces;
- }
-
- private NodeListModel deriveModel(List derivedNodes) {
- namespaces.markShared();
- return new NodeListModel(navigator, derivedNodes, namespaces);
- }
-
- /**
- * Returns the number of nodes in this model's nodelist.
- * @see freemarker.template.TemplateSequenceModel#size()
- */
- public int size() {
- return nodes.size();
- }
-
- /**
- * Evaluates an XPath expression on XML nodes in this model.
- * @param arguments the arguments to the method invocation. Expectes exactly
- * one argument - the XPath expression.
- * @return a new NodeListModel with nodes selected by applying the XPath
- * expression to this model's nodelist.
- * @see freemarker.template.TemplateMethodModel#exec(List)
- */
- public Object exec(List arguments) throws TemplateModelException {
- if (arguments.size() != 1) {
- throw new TemplateModelException(
- "Expecting exactly one argument - an XPath expression");
- }
- return deriveModel(navigator.applyXPath(nodes, (String) arguments.get(0), namespaces));
- }
-
- /**
- * Returns the string representation of the wrapped nodes. String objects in
- * the nodelist are rendered as-is (with no XML escaping applied). All other
- * nodes are rendered in the default XML serialization format ("plain XML").
- * This makes the model quite suited for use as an XML-transformation tool.
- * @return the string representation of the wrapped nodes. String objects
- * in the nodelist are rendered as-is (with no XML escaping applied). All
- * other nodes are rendered in the default XML serialization format ("plain
- * XML").
- * @see freemarker.template.TemplateScalarModel#getAsString()
- */
- public String getAsString() throws TemplateModelException {
- StringWriter sw = new StringWriter(size() * 128);
- for (Iterator iter = nodes.iterator(); iter.hasNext(); ) {
- Object o = iter.next();
- if (o instanceof String) {
- sw.write((String) o);
- } else {
- navigator.getAsString(o, sw);
- }
- }
- return sw.toString();
- }
-
- /**
- * Selects a single node from this model's nodelist by its list index and
- * returns a new NodeListModel containing that single node.
- * @param index the ordinal number of the selected node
- * @see freemarker.template.TemplateSequenceModel#get(int)
- */
- public TemplateModel get(int index) {
- return deriveModel(Collections.singletonList(nodes.get(index)));
- }
-
- /**
- * Returns a new NodeListModel containing the nodes that result from applying
- * an operator to this model's nodes.
- * @param key the operator to apply to nodes. Available operators are:
- * <table style="width: auto; border-collapse: collapse" border="1" summary="XML node hash keys">
- * <thead>
- * <tr>
- * <th align="left">Key name</th>
- * <th align="left">Evaluates to</th>
- * </tr>
- * </thead>
- * <tbody>
- * <tr>
- * <td><tt>*</tt> or <tt>_children</tt></td>
- * <td>all direct element children of current nodes (non-recursive).
- * Applicable to element and document nodes.</td>
- * </tr>
- * <tr>
- * <td><tt>@*</tt> or <tt>_attributes</tt></td>
- * <td>all attributes of current nodes. Applicable to elements only.
- * </td>
- * </tr>
- * <tr>
- * <td><tt>@<i>attributeName</i></tt></td>
- * <td>named attributes of current nodes. Applicable to elements,
- * doctypes and processing instructions. On doctypes it supports
- * attributes <tt>publicId</tt>, <tt>systemId</tt> and
- * <tt>elementName</tt>. On processing instructions, it supports
- * attributes <tt>target</tt> and <tt>data</tt>, as well as any
- * other attribute name specified in data as
- * <tt>name="value"</tt> pair on dom4j or JDOM models.
- * The attribute nodes for doctype and processing instruction are
- * synthetic, and as such have no parent. Note, however that
- * <tt>@*</tt> does NOT operate on doctypes or processing
- * instructions.</td>
- * </tr>
- *
- * <tr>
- * <td><tt>_ancestor</tt></td>
- * <td>all ancestors up to root element (recursive) of current nodes.
- * Applicable to same node types as <tt>_parent</tt>.</td>
- * </tr>
- * <tr>
- * <td><tt>_ancestorOrSelf</tt></td>
- * <td>all ancestors of current nodes plus current nodes. Applicable
- * to same node types as <tt>_parent</tt>.</td>
- * </tr>
- * <tr>
- * <td><tt>_cname</tt></td>
- * <td>the canonical names of current nodes (namespace URI + local
- * name), one string per node (non-recursive). Applicable to
- * elements and attributes</td>
- * </tr>
- * <tr>
- * <td><tt>_content</tt></td>
- * <td>the complete content of current nodes, including children
- * elements, text, entity references, and processing instructions
- * (non-recursive). Applicable to elements and documents.</td>
- * </tr>
- * <tr>
- * <td><tt>_descendant</tt></td>
- * <td>all recursive descendant element children of current nodes.
- * Applicable to document and element nodes.</td>
- * </tr>
- * <tr>
- * <td><tt>_descendantOrSelf</tt></td>
- * <td>all recursive descendant element children of current nodes
- * plus current nodes. Applicable to document and element nodes.
- * </td>
- * </tr>
- * <tr>
- * <td><tt>_document</tt></td>
- * <td>all documents the current nodes belong to. Applicable to all
- * nodes except text.</td>
- * </tr>
- * <tr>
- * <td><tt>_doctype</tt></td>
- * <td>doctypes of the current nodes. Applicable to document nodes
- * only.</td>
- * </tr>
- * <tr>
- * <td><tt>_filterType</tt></td>
- * <td>is a filter-by-type template method model. When called, it
- * will yield a node list that contains only those current nodes
- * whose type matches one of types passed as argument. You can pass
- * as many string arguments as you want, each representing one of
- * the types to select: "attribute", "cdata",
- * "comment", "document",
- * "documentType", "element",
- * "entity", "entityReference",
- * "namespace", "processingInstruction", or
- * "text".</td>
- * </tr>
- * <tr>
- * <td><tt>_name</tt></td>
- * <td>the names of current nodes, one string per node
- * (non-recursive). Applicable to elements and attributes
- * (returns their local names), entity references, processing
- * instructions (returns its target), doctypes (returns its public
- * ID)</td>
- * </tr>
- * <tr>
- * <td><tt>_nsprefix</tt></td>
- * <td>the namespace prefixes of current nodes, one string per node
- * (non-recursive). Applicable to elements and attributes</td>
- * </tr>
- * <tr>
- * <td><tt>_nsuri</tt></td>
- * <td>the namespace URIs of current nodes, one string per node
- * (non-recursive). Applicable to elements and attributes</td>
- * </tr>
- * <tr>
- * <td><tt>_parent</tt></td>
- * <td>parent elements of current nodes. Applicable to element,
- * attribute, comment, entity, processing instruction.</td>
- * </tr>
- * <tr>
- * <td><tt>_qname</tt></td>
- * <td>the qualified names of current nodes in
- * <tt>[namespacePrefix:]localName</tt> form, one string per node
- * (non-recursive). Applicable to elements and attributes</td>
- * </tr>
- * <tr>
- * <td><tt>_registerNamespace(prefix, uri)</tt></td>
- * <td>register a XML namespace with the specified prefix and URI for
- * the current node list and all node lists that are derived from
- * the current node list. After registering, you can use the
- * <tt>nodelist["prefix:localname"]</tt> or
- * <tt>nodelist["@prefix:localname"]</tt> syntaxes to
- * reach elements and attributes whose names are namespace-scoped.
- * Note that the namespace prefix need not match the actual prefix
- * used by the XML document itself since namespaces are compared
- * solely by their URI.</td>
- * </tr>
- * <tr>
- * <td><tt>_text</tt></td>
- * <td>the text of current nodes, one string per node
- * (non-recursive). Applicable to elements, attributes, comments,
- * processing instructions (returns its data) and CDATA sections.
- * The reserved XML characters ('<' and '&') are NOT
- * escaped.</td>
- * </tr>
- * <tr>
- * <td><tt>_type</tt></td>
- * <td>Returns a string describing the type of nodes, one
- * string per node. The returned values are "attribute",
- * "cdata", "comment", "document",
- * "documentType", "element",
- * "entity", "entityReference",
- * "namespace", "processingInstruction",
- * "text", or "unknown".</td>
- * </tr>
- * <tr>
- * <td><tt>_unique</tt></td>
- * <td>a copy of the current nodes that keeps only the first
- * occurrence of every node, eliminating duplicates. Duplicates can
- * occur in the node list by applying uptree-traversals
- * <tt>_parent</tt>, <tt>_ancestor</tt>, <tt>_ancestorOrSelf</tt>,
- * and <tt>_document</tt> on a node list with multiple elements.
- * I.e. <tt>foo._children._parent</tt> will return a node list that
- * has duplicates of nodes in foo - each node will have the number
- * of occurrences equal to the number of its children. In these
- * cases, use <tt>foo._children._parent._unique</tt> to eliminate
- * duplicates. Applicable to all node types.</td>
- * </tr>
- * <tr>
- * <td>any other key</td>
- * <td>element children of current nodes with name matching the key.
- * This allows for convenience child traversal in
- * <tt>book.chapter.title</tt> style syntax. Applicable to document
- * and element nodes.</td>
- * </tr>
- * </tbody>
- * </table>
- * @return a new NodeListModel containing the nodes that result from applying
- * the operator to this model's nodes.
- * @see freemarker.template.TemplateHashModel#get(String)
- */
- public TemplateModel get(String key) throws TemplateModelException {
- // Try a built-in navigator operator
- NodeOperator op = navigator.getOperator(key);
- String localName = null;
- String namespaceUri = "";
- // If not a nav op, then check for special keys.
- if (op == null && key.length() > 0 && key.charAt(0) == '_') {
- if (key.equals("_unique")) {
- return deriveModel(removeDuplicates(nodes));
- } else if (key.equals("_filterType") || key.equals("_ftype")) {
- return new FilterByType();
- } else if (key.equals("_registerNamespace")) {
- if (namespaces.isShared()) {
- namespaces = (Namespaces) namespaces.clone();
- }
- }
- }
- // Last, do a named child element or attribute lookup
- if (op == null) {
- int colon = key.indexOf(':');
- if (colon == -1) {
- // No namespace prefix specified
- localName = key;
- } else {
- // Namespace prefix specified
- localName = key.substring(colon + 1);
- String prefix = key.substring(0, colon);
- namespaceUri = namespaces.translateNamespacePrefixToUri(prefix);
- if (namespaceUri == null) {
- throw new TemplateModelException("Namespace prefix " + prefix + " is not registered.");
- }
- }
- if (localName.charAt(0) == '@') {
- op = navigator.getAttributeOperator();
- localName = localName.substring(1);
- } else {
- op = navigator.getChildrenOperator();
- }
- }
- List result = new ArrayList();
- for (Iterator iter = nodes.iterator(); iter.hasNext(); ) {
- try {
- op.process(iter.next(), localName, namespaceUri, result);
- } catch (RuntimeException e) {
- throw new TemplateModelException(e);
- }
- }
- return deriveModel(result);
- }
-
- /**
- * Returns true if this NodeListModel contains no nodes.
- * @see freemarker.template.TemplateHashModel#isEmpty()
- */
- public boolean isEmpty() {
- return nodes.isEmpty();
- }
-
- /**
- * Registers a namespace prefix-URI pair for subsequent use in {@link
- * #get(String)} as well as for use in XPath expressions.
- * @param prefix the namespace prefix to use for the namespace
- * @param uri the namespace URI that identifies the namespace.
- */
- public void registerNamespace(String prefix, String uri) {
- if (namespaces.isShared()) {
- namespaces = (Namespaces) namespaces.clone();
- }
- namespaces.registerNamespace(prefix, uri);
- }
-
- private class FilterByType
- implements
- TemplateMethodModel {
- public Object exec(List arguments) {
- List filteredNodes = new ArrayList();
- for (Iterator iter = arguments.iterator(); iter.hasNext(); ) {
- Object node = iter.next();
- if (arguments.contains(navigator.getType(node))) {
- filteredNodes.add(node);
- }
- }
- return deriveModel(filteredNodes);
- }
- }
-
- private static final List removeDuplicates(List list) {
- int s = list.size();
- ArrayList ulist = new ArrayList(s);
- Set set = new HashSet(s * 4 / 3, .75f);
- Iterator it = list.iterator();
- while (it.hasNext()) {
- Object o = it.next();
- if (set.add(o)) {
- ulist.add(o);
- }
- }
- return ulist;
- }
-
- private static Class getClass(String className) {
- try {
- return ClassUtil.forName(className);
- } catch (Exception e) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Couldn't load class " + className, e);
- }
- return null;
- }
- }
-
- private static Navigator getNavigator(String navType) {
- try {
- return (Navigator) ClassUtil.forName("freemarker.ext.xml._" +
- navType + "Navigator").newInstance();
- } catch (Throwable t) {
- if (LOG.isDebugEnabled()) {
- LOG.debug("Could not load navigator for " + navType, t);
- }
- return null;
- }
- }
-
- public TemplateSequenceModel getChildNodes() throws TemplateModelException {
- return (TemplateSequenceModel) get("_content");
- }
-
- public String getNodeName() throws TemplateModelException {
- return getUniqueText((NodeListModel) get("_name"), "name");
- }
-
- public String getNodeNamespace() throws TemplateModelException {
- return getUniqueText((NodeListModel) get("_nsuri"), "namespace");
- }
-
- public String getNodeType() throws TemplateModelException {
- return getUniqueText((NodeListModel) get("_type"), "type");
- }
- public TemplateNodeModel getParentNode() throws TemplateModelException {
- return (TemplateNodeModel) get("_parent");
- }
-
- private String getUniqueText(NodeListModel model, String property) throws TemplateModelException {
- String s1 = null;
- Set s = null;
- for (Iterator it = model.nodes.iterator(); it.hasNext(); ) {
- String s2 = (String) it.next();
- if (s2 != null) {
- // No text yet, make this text the current text
- if (s1 == null) {
- s1 = s2;
- }
- // else if there's already a text and they differ, start
- // accumulating them for an error message
- else if (!s1.equals(s2)) {
- if (s == null) {
- s = new HashSet();
- s.add(s1);
- }
- s.add(s2);
- }
- }
- }
- // If the set for the error messages is empty, return the retval
- if (s == null) {
- return s1;
- }
- // Else throw an exception signaling ambiguity
- throw new TemplateModelException(
- "Value for node " + property + " is ambiguos: " + s);
- }
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/xml/NodeOperator.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/xml/NodeOperator.java b/src/main/java/freemarker/ext/xml/NodeOperator.java
deleted file mode 100644
index 27b80b6..0000000
--- a/src/main/java/freemarker/ext/xml/NodeOperator.java
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.ext.xml;
-
-import java.util.List;
-
-/**
- */
-interface NodeOperator {
- void process(Object node, String localName, String namespaceUri, List result);
-}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/1588a7f5/src/main/java/freemarker/ext/xml/_Dom4jNavigator.java
----------------------------------------------------------------------
diff --git a/src/main/java/freemarker/ext/xml/_Dom4jNavigator.java b/src/main/java/freemarker/ext/xml/_Dom4jNavigator.java
deleted file mode 100644
index 747953d..0000000
--- a/src/main/java/freemarker/ext/xml/_Dom4jNavigator.java
+++ /dev/null
@@ -1,246 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-
-package freemarker.ext.xml;
-
-import java.io.StringWriter;
-import java.util.Iterator;
-import java.util.List;
-
-import org.dom4j.Attribute;
-import org.dom4j.Branch;
-import org.dom4j.Document;
-import org.dom4j.DocumentType;
-import org.dom4j.Element;
-import org.dom4j.Node;
-import org.dom4j.ProcessingInstruction;
-import org.dom4j.tree.DefaultAttribute;
-import org.jaxen.Context;
-import org.jaxen.NamespaceContext;
-import org.jaxen.dom4j.Dom4jXPath;
-
-import freemarker.template.TemplateModelException;
-
-/**
- * Don't use this class; it's only public to work around Google App Engine Java
- * compliance issues. FreeMarker developers only: treat this class as package-visible.
- */
-public class _Dom4jNavigator extends Navigator {
-
- public _Dom4jNavigator() {
- }
-
- @Override
- void getAsString(Object node, StringWriter sw) {
- sw.getBuffer().append(((Node) node).asXML());
- }
-
- @Override
- void getChildren(Object node, String localName, String namespaceUri, List result) {
- if (node instanceof Element) {
- Element e = (Element) node;
- if (localName == null) {
- result.addAll(e.elements());
- } else {
- result.addAll(e.elements(e.getQName().getDocumentFactory().createQName(localName, "", namespaceUri)));
- }
- } else if (node instanceof Document) {
- Element root = ((Document) node).getRootElement();
- if (localName == null || (equal(root.getName(), localName) && equal(root.getNamespaceURI(), namespaceUri))) {
- result.add(root);
- }
- }
- }
-
- @Override
- void getAttributes(Object node, String localName, String namespaceUri, List result) {
- if (node instanceof Element) {
- Element e = (Element) node;
- if (localName == null) {
- result.addAll(e.attributes());
- } else {
- Attribute attr = e.attribute(e.getQName().getDocumentFactory().createQName(localName, "", namespaceUri));
- if (attr != null) {
- result.add(attr);
- }
- }
- } else if (node instanceof ProcessingInstruction) {
- ProcessingInstruction pi = (ProcessingInstruction) node;
- if ("target".equals(localName)) {
- result.add(new DefaultAttribute("target", pi.getTarget()));
- } else if ("data".equals(localName)) {
- result.add(new DefaultAttribute("data", pi.getText()));
- } else {
- result.add(new DefaultAttribute(localName, pi.getValue(localName)));
- }
- } else if (node instanceof DocumentType) {
- DocumentType doctype = (DocumentType) node;
- if ("publicId".equals(localName)) {
- result.add(new DefaultAttribute("publicId", doctype.getPublicID()));
- } else if ("systemId".equals(localName)) {
- result.add(new DefaultAttribute("systemId", doctype.getSystemID()));
- } else if ("elementName".equals(localName)) {
- result.add(new DefaultAttribute("elementName", doctype.getElementName()));
- }
- }
- }
-
- @Override
- void getDescendants(Object node, List result) {
- if (node instanceof Branch) {
- getDescendants((Branch) node, result);
- }
- }
-
- private void getDescendants(Branch node, List result) {
- List content = node.content();
- for (Iterator iter = content.iterator(); iter.hasNext(); ) {
- Node subnode = (Node) iter.next();
- if (subnode instanceof Element) {
- result.add(subnode);
- getDescendants(subnode, result);
- }
- }
- }
-
- @Override
- Object getParent(Object node) {
- return ((Node) node).getParent();
- }
-
- @Override
- Object getDocument(Object node) {
- return ((Node) node).getDocument();
- }
-
- @Override
- Object getDocumentType(Object node) {
- return
- node instanceof Document
- ? ((Document) node).getDocType()
- : null;
- }
-
- @Override
- void getContent(Object node, List result) {
- if (node instanceof Branch) {
- result.addAll(((Branch) node).content());
- }
- }
-
- @Override
- String getText(Object node) {
- return ((Node) node).getText();
- }
-
- @Override
- String getLocalName(Object node) {
- return ((Node) node).getName();
- }
-
- @Override
- String getNamespacePrefix(Object node) {
- if (node instanceof Element) {
- return ((Element) node).getNamespacePrefix();
- }
- if (node instanceof Attribute) {
- return ((Attribute) node).getNamespacePrefix();
- }
- return null;
- }
-
- @Override
- String getNamespaceUri(Object node) {
- if (node instanceof Element) {
- return ((Element) node).getNamespaceURI();
- }
- if (node instanceof Attribute) {
- return ((Attribute) node).getNamespaceURI();
- }
- return null;
- }
-
- @Override
- String getType(Object node) {
- switch(((Node) node).getNodeType()) {
- case Node.ATTRIBUTE_NODE: {
- return "attribute";
- }
- case Node.CDATA_SECTION_NODE: {
- return "cdata";
- }
- case Node.COMMENT_NODE: {
- return "comment";
- }
- case Node.DOCUMENT_NODE: {
- return "document";
- }
- case Node.DOCUMENT_TYPE_NODE: {
- return "documentType";
- }
- case Node.ELEMENT_NODE: {
- return "element";
- }
- case Node.ENTITY_REFERENCE_NODE: {
- return "entityReference";
- }
- case Node.NAMESPACE_NODE: {
- return "namespace";
- }
- case Node.PROCESSING_INSTRUCTION_NODE: {
- return "processingInstruction";
- }
- case Node.TEXT_NODE: {
- return "text";
- }
- }
- return "unknown";
- }
-
- @Override
- XPathEx createXPathEx(String xpathString) throws TemplateModelException {
- try {
- return new Dom4jXPathEx(xpathString);
- } catch (Exception e) {
- throw new TemplateModelException(e);
- }
- }
-
- private static final class Dom4jXPathEx
- extends
- Dom4jXPath
- implements
- XPathEx {
- Dom4jXPathEx(String path)
- throws Exception {
- super(path);
- }
-
- public List selectNodes(Object object, NamespaceContext namespaces)
- throws TemplateModelException {
- Context context = getContext(object);
- context.getContextSupport().setNamespaceContext(namespaces);
- try {
- return selectNodesForContext(context);
- } catch (Exception e) {
- throw new TemplateModelException(e);
- }
- }
- }
-}