http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/template/Version.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/template/Version.java b/src/main/java/freemarker/template/Version.java deleted file mode 100644 index 91ee900..0000000 --- a/src/main/java/freemarker/template/Version.java +++ /dev/null @@ -1,297 +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.template; - -import java.io.Serializable; -import java.util.Date; - -import freemarker.template.utility.StringUtil; - -/** - * Represents a version number plus the further qualifiers and build info. This is - * mostly used for representing a FreeMarker version number, but should also be able - * to parse the version strings of 3rd party libraries. - * - * @see Configuration#getVersion() - * - * @since 2.3.20 - */ -public final class Version implements Serializable { - - private final int major; - private final int minor; - private final int micro; - private final String extraInfo; - private final String originalStringValue; - - private final Boolean gaeCompliant; - private final Date buildDate; - - private final int intValue; - private volatile String calculatedStringValue; // not final because it's calculated on demand - private int hashCode; // not final because it's calculated on demand - - /** - * @throws IllegalArgumentException if the version string is malformed - */ - public Version(String stringValue) { - this(stringValue, null, null); - } - - /** - * @throws IllegalArgumentException if the version string is malformed - */ - public Version(String stringValue, Boolean gaeCompliant, Date buildDate) { - stringValue = stringValue.trim(); - originalStringValue = stringValue; - - int[] parts = new int[3]; - String extraInfoTmp = null; - { - int partIdx = 0; - for (int i = 0; i < stringValue.length(); i++) { - char c = stringValue.charAt(i); - if (isNumber(c)) { - parts[partIdx] = parts[partIdx] * 10 + (c - '0'); - } else { - if (i == 0) { - throw new IllegalArgumentException( - "The version number string " + StringUtil.jQuote(stringValue) - + " doesn't start with a number."); - } - if (c == '.') { - char nextC = i + 1 >= stringValue.length() ? 0 : stringValue.charAt(i + 1); - if (nextC == '.') { - throw new IllegalArgumentException( - "The version number string " + StringUtil.jQuote(stringValue) - + " contains multiple dots after a number."); - } - if (partIdx == 2 || !isNumber(nextC)) { - extraInfoTmp = stringValue.substring(i); - break; - } else { - partIdx++; - } - } else { - extraInfoTmp = stringValue.substring(i); - break; - } - } - } - - if (extraInfoTmp != null) { - char firstChar = extraInfoTmp.charAt(0); - if (firstChar == '.' || firstChar == '-' || firstChar == '_') { - extraInfoTmp = extraInfoTmp.substring(1); - if (extraInfoTmp.length() == 0) { - throw new IllegalArgumentException( - "The version number string " + StringUtil.jQuote(stringValue) - + " has an extra info section opened with \"" + firstChar + "\", but it's empty."); - } - } - } - } - extraInfo = extraInfoTmp; - - major = parts[0]; - minor = parts[1]; - micro = parts[2]; - intValue = calculateIntValue(); - - this.gaeCompliant = gaeCompliant; - this.buildDate = buildDate; - - } - - private boolean isNumber(char c) { - return c >= '0' && c <= '9'; - } - - public Version(int major, int minor, int micro) { - this(major, minor, micro, null, null, null); - } - - /** - * Creates an object based on the {@code int} value that uses the same kind of encoding as {@link #intValue()}. - * - * @since 2.3.24 - */ - public Version(int intValue) { - this.intValue = intValue; - - this.micro = intValue % 1000; - this.minor = (intValue / 1000) % 1000; - this.major = intValue / 1000000; - - this.extraInfo = null; - this.gaeCompliant = null; - this.buildDate = null; - originalStringValue = null; - } - - public Version(int major, int minor, int micro, String extraInfo, Boolean gaeCompatible, Date buildDate) { - this.major = major; - this.minor = minor; - this.micro = micro; - this.extraInfo = extraInfo; - this.gaeCompliant = gaeCompatible; - this.buildDate = buildDate; - intValue = calculateIntValue(); - originalStringValue = null; - } - - private int calculateIntValue() { - return intValueFor(major, minor, micro); - } - - static public int intValueFor(int major, int minor, int micro) { - return major * 1000000 + minor * 1000 + micro; - } - - private String getStringValue() { - if (originalStringValue != null) return originalStringValue; - - String calculatedStringValue = this.calculatedStringValue; - if (calculatedStringValue == null) { - synchronized (this) { - calculatedStringValue = this.calculatedStringValue; - if (calculatedStringValue == null) { - calculatedStringValue = major + "." + minor + "." + micro; - if (extraInfo != null) calculatedStringValue += "-" + extraInfo; - this.calculatedStringValue = calculatedStringValue; - } - } - } - return calculatedStringValue; - } - - /** - * Contains the major.minor.micor numbers and the extraInfo part, not the other information. - */ - @Override - public String toString() { - return getStringValue(); - } - - /** - * The 1st version number, like 1 in "1.2.3". - */ - public int getMajor() { - return major; - } - - /** - * The 2nd version number, like 2 in "1.2.3". - */ - public int getMinor() { - return minor; - } - - /** - * The 3rd version number, like 3 in "1.2.3". - */ - public int getMicro() { - return micro; - } - - /** - * The arbitrary string after the micro version number without leading dot, dash or underscore, - * like "RC03" in "2.4.0-RC03". - * This is usually a qualifier (RC, SNAPHOST, nightly, beta, etc) and sometimes build info (like - * date). - */ - public String getExtraInfo() { - return extraInfo; - } - - /** - * @return The Google App Engine compliance, or {@code null}. - */ - public Boolean isGAECompliant() { - return gaeCompliant; - } - - /** - * @return The build date if known, or {@code null}. - */ - public Date getBuildDate() { - return buildDate; - } - - /** - * @return major * 1000000 + minor * 1000 + micro. - */ - public int intValue() { - return intValue; - } - - @Override - public int hashCode() { - int r = hashCode; - if (r != 0) return r; - synchronized (this) { - if (hashCode == 0) { - final int prime = 31; - int result = 1; - result = prime * result + (buildDate == null ? 0 : buildDate.hashCode()); - result = prime * result + (extraInfo == null ? 0 : extraInfo.hashCode()); - result = prime * result + (gaeCompliant == null ? 0 : gaeCompliant.hashCode()); - result = prime * result + intValue; - if (result == 0) result = -1; // 0 is reserved for "not set" - hashCode = result; - } - return hashCode; - } - } - - @Override - public boolean equals(Object obj) { - if (this == obj) return true; - if (obj == null) return false; - if (getClass() != obj.getClass()) return false; - - Version other = (Version) obj; - - if (intValue != other.intValue) return false; - - if (other.hashCode() != hashCode()) return false; - - if (buildDate == null) { - if (other.buildDate != null) return false; - } else if (!buildDate.equals(other.buildDate)) { - return false; - } - - if (extraInfo == null) { - if (other.extraInfo != null) return false; - } else if (!extraInfo.equals(other.extraInfo)) { - return false; - } - - if (gaeCompliant == null) { - if (other.gaeCompliant != null) return false; - } else if (!gaeCompliant.equals(other.gaeCompliant)) { - return false; - } - - return true; - } - -}
http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/template/WrappingTemplateModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/template/WrappingTemplateModel.java b/src/main/java/freemarker/template/WrappingTemplateModel.java deleted file mode 100644 index e2a9c00..0000000 --- a/src/main/java/freemarker/template/WrappingTemplateModel.java +++ /dev/null @@ -1,115 +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.template; - -/** - * Convenience base-class for containers that wrap their contained arbitrary Java objects into {@link TemplateModel} - * instances. - */ -abstract public class WrappingTemplateModel { - - /** @deprecated Because it's a VM-wide modifiable field */ - @Deprecated - private static ObjectWrapper defaultObjectWrapper = DefaultObjectWrapper.instance; - - private ObjectWrapper objectWrapper; - - /** - * Sets the default object wrapper that is used when a wrapping template - * model is constructed without being passed an explicit object wrapper. - * The default value is {@link ObjectWrapper#SIMPLE_WRAPPER}. - * Note that {@link Configuration#setSharedVariable(String, Object)} and - * {@link Template#process(Object, java.io.Writer)} don't use this setting, - * they rather use whatever object wrapper their - * {@link Configuration#getObjectWrapper()} method returns. - * - * @deprecated This method has VM-wide effect, which makes it unsuitable for application where multiple components - * might use FreeMarker internally. - */ - @Deprecated - public static void setDefaultObjectWrapper(ObjectWrapper objectWrapper) { - defaultObjectWrapper = objectWrapper; - } - - /** - * Returns the default object wrapper that is used when a wrapping template - * model is constructed without being passed an explicit object wrapper. - * Note that {@link Configuration#setSharedVariable(String, Object)} and - * {@link Template#process(Object, java.io.Writer)} don't use this setting, - * they rather use whatever object wrapper their - * {@link Configuration#getObjectWrapper()} method returns. - * - * @deprecated Don't depend on this object, as it can be replace by anybody in the same JVM. - */ - @Deprecated - public static ObjectWrapper getDefaultObjectWrapper() { - return defaultObjectWrapper; - } - - /** - * Protected constructor that creates a new wrapping template model using - * the default object wrapper. - * - * @deprecated Use {@link #WrappingTemplateModel(ObjectWrapper)} instead; this method uses the deprecated. - */ - @Deprecated - protected WrappingTemplateModel() { - this(defaultObjectWrapper); - } - - /** - * Protected constructor that creates a new wrapping template model using the specified object wrapper. - * - * @param objectWrapper the wrapper to use. Passing {@code null} to it - * is allowed but deprecated. If {@code null} is passed, the deprecated default object wrapper - * is used. - */ - protected WrappingTemplateModel(ObjectWrapper objectWrapper) { - this.objectWrapper = - objectWrapper != null ? objectWrapper : defaultObjectWrapper; - if (this.objectWrapper == null) { - this.objectWrapper = defaultObjectWrapper = new DefaultObjectWrapper(); - } - } - - /** - * Returns the object wrapper instance used by this wrapping template model. - */ - public ObjectWrapper getObjectWrapper() { - return objectWrapper; - } - - public void setObjectWrapper(ObjectWrapper objectWrapper) { - this.objectWrapper = objectWrapper; - } - - /** - * Wraps the passed object into a template model using this object's object - * wrapper. - * @param obj the object to wrap - * @return the template model that wraps the object - * @throws TemplateModelException if the wrapper does not know how to - * wrap the passed object. - */ - protected final TemplateModel wrap(Object obj) throws TemplateModelException { - return objectWrapper.wrap(obj); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/template/_TemplateAPI.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/template/_TemplateAPI.java b/src/main/java/freemarker/template/_TemplateAPI.java deleted file mode 100644 index bf6b227..0000000 --- a/src/main/java/freemarker/template/_TemplateAPI.java +++ /dev/null @@ -1,148 +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.template; - -import java.util.Set; - -import freemarker.cache.CacheStorage; -import freemarker.cache.TemplateLookupStrategy; -import freemarker.cache.TemplateNameFormat; -import freemarker.core.Expression; -import freemarker.core.OutputFormat; -import freemarker.core.TemplateObject; -import freemarker.template.utility.NullArgumentException; - -/** - * For internal use only; don't depend on this, there's no backward compatibility guarantee at all! - * This class is to work around the lack of module system in Java, i.e., so that other FreeMarker packages can - * access things inside this package that users shouldn't. - */ -public class _TemplateAPI { - - public static final int VERSION_INT_2_3_0 = Configuration.VERSION_2_3_0.intValue(); - public static final int VERSION_INT_2_3_19 = Configuration.VERSION_2_3_19.intValue(); - public static final int VERSION_INT_2_3_20 = Configuration.VERSION_2_3_20.intValue(); - public static final int VERSION_INT_2_3_21 = Configuration.VERSION_2_3_21.intValue(); - public static final int VERSION_INT_2_3_22 = Configuration.VERSION_2_3_22.intValue(); - public static final int VERSION_INT_2_3_23 = Configuration.VERSION_2_3_23.intValue(); - public static final int VERSION_INT_2_3_24 = Configuration.VERSION_2_3_24.intValue(); - public static final int VERSION_INT_2_3_25 = Configuration.VERSION_2_3_25.intValue(); - public static final int VERSION_INT_2_3_26 = Configuration.VERSION_2_3_26.intValue(); - public static final int VERSION_INT_2_4_0 = Version.intValueFor(2, 4, 0); - - public static void checkVersionNotNullAndSupported(Version incompatibleImprovements) { - NullArgumentException.check("incompatibleImprovements", incompatibleImprovements); - int iciV = incompatibleImprovements.intValue(); - if (iciV > Configuration.getVersion().intValue()) { - throw new IllegalArgumentException("The FreeMarker version requested by \"incompatibleImprovements\" was " - + incompatibleImprovements + ", but the installed FreeMarker version is only " - + Configuration.getVersion() + ". You may need to upgrade FreeMarker in your project."); - } - if (iciV < VERSION_INT_2_3_0) { - throw new IllegalArgumentException("\"incompatibleImprovements\" must be at least 2.3.0."); - } - } - - public static int getTemplateLanguageVersionAsInt(TemplateObject to) { - return getTemplateLanguageVersionAsInt(to.getTemplate()); - } - - public static int getTemplateLanguageVersionAsInt(Template t) { - return t.getTemplateLanguageVersion().intValue(); - } - - /** For unit testing only */ - public static void DefaultObjectWrapperFactory_clearInstanceCache() { - DefaultObjectWrapperBuilder.clearInstanceCache(); - } - - public static TemplateExceptionHandler getDefaultTemplateExceptionHandler( - Version incompatibleImprovements) { - return Configuration.getDefaultTemplateExceptionHandler(incompatibleImprovements); - } - - public static boolean getDefaultLogTemplateExceptions(Version incompatibleImprovements) { - return Configuration.getDefaultLogTemplateExceptions(incompatibleImprovements); - } - - public static CacheStorage createDefaultCacheStorage(Version incompatibleImprovements) { - return Configuration.createDefaultCacheStorage(incompatibleImprovements); - } - - public static TemplateLookupStrategy getDefaultTemplateLookupStrategy(Version incompatibleImprovements) { - return Configuration.getDefaultTemplateLookupStrategy(incompatibleImprovements); - } - - public static TemplateNameFormat getDefaultTemplateNameFormat(Version incompatibleImprovements) { - return Configuration.getDefaultTemplateNameFormat(incompatibleImprovements); - } - - /** - * [2.4] getSettingNames() becomes to public; remove this. - */ - public static Set/*<String>*/ getConfigurationSettingNames(Configuration cfg, boolean camelCase) { - return cfg.getSettingNames(camelCase); - } - - public static void setAutoEscaping(Template t, boolean autoEscaping) { - t.setAutoEscaping(autoEscaping); - } - - public static void setOutputFormat(Template t, OutputFormat outputFormat) { - t.setOutputFormat(outputFormat); - } - - public static void validateAutoEscapingPolicyValue(int autoEscaping) { - if (autoEscaping != Configuration.ENABLE_IF_DEFAULT_AUTO_ESCAPING_POLICY - && autoEscaping != Configuration.ENABLE_IF_SUPPORTED_AUTO_ESCAPING_POLICY - && autoEscaping != Configuration.DISABLE_AUTO_ESCAPING_POLICY) { - throw new IllegalArgumentException("\"auto_escaping\" can only be set to one of these: " - + "Configuration.ENABLE_AUTO_ESCAPING_IF_DEFAULT, " - + "or Configuration.ENABLE_AUTO_ESCAPING_IF_SUPPORTED" - + "or Configuration.DISABLE_AUTO_ESCAPING"); - } - } - - public static void validateNamingConventionValue(int namingConvention) { - if (namingConvention != Configuration.AUTO_DETECT_NAMING_CONVENTION - && namingConvention != Configuration.LEGACY_NAMING_CONVENTION - && namingConvention != Configuration.CAMEL_CASE_NAMING_CONVENTION) { - throw new IllegalArgumentException("\"naming_convention\" can only be set to one of these: " - + "Configuration.AUTO_DETECT_NAMING_CONVENTION, " - + "or Configuration.LEGACY_NAMING_CONVENTION" - + "or Configuration.CAMEL_CASE_NAMING_CONVENTION"); - } - } - - public static void valideTagSyntaxValue(int tagSyntax) { - if (tagSyntax != Configuration.AUTO_DETECT_TAG_SYNTAX - && tagSyntax != Configuration.SQUARE_BRACKET_TAG_SYNTAX - && tagSyntax != Configuration.ANGLE_BRACKET_TAG_SYNTAX) { - throw new IllegalArgumentException("\"tag_syntax\" can only be set to one of these: " - + "Configuration.AUTO_DETECT_TAG_SYNTAX, Configuration.ANGLE_BRACKET_SYNTAX, " - + "or Configuration.SQAUARE_BRACKET_SYNTAX"); - } - } - - public static Expression getBlamedExpression(TemplateException e) { - return e.getBlamedExpression(); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/template/package.html ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/template/package.html b/src/main/java/freemarker/template/package.html deleted file mode 100644 index e81035a..0000000 --- a/src/main/java/freemarker/template/package.html +++ /dev/null @@ -1,27 +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> -</head> -<body> -<p><b>The fundamental, most commonly used API-s of FreeMarker;</b> -start with {@link freemarker.template.Configuration Configuration} (see also the -<a href="http://freemarker.org/docs/pgui_quickstart.html" target="_blank">Getting Stared</a> in the Manual.)</p> -</body> -</html> http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/template/utility/CaptureOutput.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/template/utility/CaptureOutput.java b/src/main/java/freemarker/template/utility/CaptureOutput.java deleted file mode 100644 index fa98871..0000000 --- a/src/main/java/freemarker/template/utility/CaptureOutput.java +++ /dev/null @@ -1,147 +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.template.utility; - -import java.io.IOException; -import java.io.Writer; -import java.util.Map; - -import freemarker.core.Environment; -import freemarker.template.SimpleScalar; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; -import freemarker.template.TemplateScalarModel; -import freemarker.template.TemplateTransformModel; - -/** - * A transform that captures the output of a block of FTL code and stores that in a variable. - * - * <p>As this transform is initially present in the shared variable set, you can always - * access it from the templates:</p> - * - * <pre> - * <@capture_output var="captured"> - * ... - * </@capture_output> - * </pre> - * - * <p>And later in the template you can use the captured output:</p> - * - * ${captured} - * - * <p>This transform requires one of three parameters: <code>var</code>, <code>local</code>, or <code>global</code>. - * Each of them specifies the name of the variable that stores the captured output, but the first creates a - * variable in a name-space (as <#assign>), the second creates a macro-local variable (as <#local>), - * and the last creates a global variable (as <#global>). - * </p> - * <p>In the case of an assignment within a namespace, there is an optional parameter - * <code>namespace</code> that indicates in which namespace to do the assignment. - * if this is omitted, the current namespace is used, and this will be, by far, the most - * common usage pattern.</p> - * - * @deprecated Use block-assignments instead, like <code><assign x>...</assign></code>. - */ -@Deprecated -public class CaptureOutput implements TemplateTransformModel { - - @Override - public Writer getWriter(final Writer out, final Map args) throws TemplateModelException { - String errmsg = "Must specify the name of the variable in " - + "which to capture the output with the 'var' or 'local' or 'global' parameter."; - if (args == null) throw new TemplateModelException(errmsg); - - boolean local = false, global = false; - final TemplateModel nsModel = (TemplateModel) args.get("namespace"); - Object varNameModel = args.get("var"); - if (varNameModel == null) { - varNameModel = args.get("local"); - if (varNameModel == null) { - varNameModel = args.get("global"); - global = true; - } else { - local = true; - } - if (varNameModel == null) { - throw new TemplateModelException(errmsg); - } - } - if (args.size() == 2) { - if (nsModel == null) { - throw new TemplateModelException("Second parameter can only be namespace"); - } - if (local) { - throw new TemplateModelException("Cannot specify namespace for a local assignment"); - } - if (global) { - throw new TemplateModelException("Cannot specify namespace for a global assignment"); - } - if (!(nsModel instanceof Environment.Namespace)) { - throw new TemplateModelException("namespace parameter does not specify a namespace. It is a " + nsModel.getClass().getName()); - } - } else if (args.size() != 1) throw new TemplateModelException( - "Bad parameters. Use only one of 'var' or 'local' or 'global' parameters."); - - if (!(varNameModel instanceof TemplateScalarModel)) { - throw new TemplateModelException("'var' or 'local' or 'global' parameter doesn't evaluate to a string"); - } - final String varName = ((TemplateScalarModel) varNameModel).getAsString(); - if (varName == null) { - throw new TemplateModelException("'var' or 'local' or 'global' parameter evaluates to null string"); - } - - final StringBuilder buf = new StringBuilder(); - final Environment env = Environment.getCurrentEnvironment(); - final boolean localVar = local; - final boolean globalVar = global; - - return new Writer() { - - @Override - public void write(char cbuf[], int off, int len) { - buf.append(cbuf, off, len); - } - - @Override - public void flush() throws IOException { - out.flush(); - } - - @Override - public void close() throws IOException { - SimpleScalar result = new SimpleScalar(buf.toString()); - try { - if (localVar) { - env.setLocalVariable(varName, result); - } else if (globalVar) { - env.setGlobalVariable(varName, result); - } else { - if (nsModel == null) { - env.setVariable(varName, result); - } else { - ((Environment.Namespace) nsModel).put(varName, result); - } - } - } catch (java.lang.IllegalStateException ise) { // if somebody uses 'local' outside a macro - throw new IOException("Could not set variable " + varName + ": " + ise.getMessage()); - } - } - }; - } -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/template/utility/ClassUtil.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/template/utility/ClassUtil.java b/src/main/java/freemarker/template/utility/ClassUtil.java deleted file mode 100644 index 7a767bd..0000000 --- a/src/main/java/freemarker/template/utility/ClassUtil.java +++ /dev/null @@ -1,382 +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.template.utility; - -import java.util.HashSet; -import java.util.Set; - -import freemarker.core.Environment; -import freemarker.core.Macro; -import freemarker.core.TemplateMarkupOutputModel; -import freemarker.ext.beans.BeanModel; -import freemarker.ext.beans.BooleanModel; -import freemarker.ext.beans.CollectionModel; -import freemarker.ext.beans.DateModel; -import freemarker.ext.beans.EnumerationModel; -import freemarker.ext.beans.IteratorModel; -import freemarker.ext.beans.MapModel; -import freemarker.ext.beans.NumberModel; -import freemarker.ext.beans.OverloadedMethodsModel; -import freemarker.ext.beans.SimpleMethodModel; -import freemarker.ext.beans.StringModel; -import freemarker.ext.util.WrapperTemplateModel; -import freemarker.template.AdapterTemplateModel; -import freemarker.template.TemplateBooleanModel; -import freemarker.template.TemplateCollectionModel; -import freemarker.template.TemplateCollectionModelEx; -import freemarker.template.TemplateDateModel; -import freemarker.template.TemplateDirectiveModel; -import freemarker.template.TemplateHashModel; -import freemarker.template.TemplateHashModelEx; -import freemarker.template.TemplateMethodModel; -import freemarker.template.TemplateMethodModelEx; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelIterator; -import freemarker.template.TemplateNodeModel; -import freemarker.template.TemplateNodeModelEx; -import freemarker.template.TemplateNumberModel; -import freemarker.template.TemplateScalarModel; -import freemarker.template.TemplateSequenceModel; -import freemarker.template.TemplateTransformModel; - -/** - */ -public class ClassUtil { - private ClassUtil() { - } - - /** - * Similar to {@link Class#forName(java.lang.String)}, but attempts to load - * through the thread context class loader. Only if thread context class - * loader is inaccessible, or it can't find the class will it attempt to - * fall back to the class loader that loads the FreeMarker classes. - */ - public static Class forName(String className) - throws ClassNotFoundException { - try { - ClassLoader ctcl = Thread.currentThread().getContextClassLoader(); - if (ctcl != null) { // not null: we don't want to fall back to the bootstrap class loader - return Class.forName(className, true, ctcl); - } - } catch (ClassNotFoundException e) { - ;// Intentionally ignored - } catch (SecurityException e) { - ;// Intentionally ignored - } - // Fall back to the defining class loader of the FreeMarker classes - return Class.forName(className); - } - - /** - * Same as {@link #getShortClassName(Class, boolean) getShortClassName(pClass, false)}. - * - * @since 2.3.20 - */ - public static String getShortClassName(Class pClass) { - return getShortClassName(pClass, false); - } - - /** - * Returns a class name without "java.lang." and "java.util." prefix, also shows array types in a format like - * {@code int[]}; useful for printing class names in error messages. - * - * @param pClass can be {@code null}, in which case the method returns {@code null}. - * @param shortenFreeMarkerClasses if {@code true}, it will also shorten FreeMarker class names. The exact rules - * aren't specified and might change over time, but right now, {@code freemarker.ext.beans.NumberModel} for - * example becomes to {@code f.e.b.NumberModel}. - * - * @since 2.3.20 - */ - public static String getShortClassName(Class pClass, boolean shortenFreeMarkerClasses) { - if (pClass == null) { - return null; - } else if (pClass.isArray()) { - return getShortClassName(pClass.getComponentType()) + "[]"; - } else { - String cn = pClass.getName(); - if (cn.startsWith("java.lang.") || cn.startsWith("java.util.")) { - return cn.substring(10); - } else { - if (shortenFreeMarkerClasses) { - if (cn.startsWith("freemarker.template.")) { - return "f.t" + cn.substring(19); - } else if (cn.startsWith("freemarker.ext.beans.")) { - return "f.e.b" + cn.substring(20); - } else if (cn.startsWith("freemarker.core.")) { - return "f.c" + cn.substring(15); - } else if (cn.startsWith("freemarker.ext.")) { - return "f.e" + cn.substring(14); - } else if (cn.startsWith("freemarker.")) { - return "f" + cn.substring(10); - } - // Falls through - } - return cn; - } - } - } - - /** - * Same as {@link #getShortClassNameOfObject(Object, boolean) getShortClassNameOfObject(pClass, false)}. - * - * @since 2.3.20 - */ - public static String getShortClassNameOfObject(Object obj) { - return getShortClassNameOfObject(obj, false); - } - - /** - * {@link #getShortClassName(Class, boolean)} called with {@code object.getClass()}, but returns the fictional - * class name {@code Null} for a {@code null} value. - * - * @since 2.3.20 - */ - public static String getShortClassNameOfObject(Object obj, boolean shortenFreeMarkerClasses) { - if (obj == null) { - return "Null"; - } else { - return ClassUtil.getShortClassName(obj.getClass(), shortenFreeMarkerClasses); - } - } - - /** - * Returns the {@link TemplateModel} interface that is the most characteristic of the object, or {@code null}. - */ - private static Class getPrimaryTemplateModelInterface(TemplateModel tm) { - if (tm instanceof BeanModel) { - if (tm instanceof CollectionModel) { - return TemplateSequenceModel.class; - } else if (tm instanceof IteratorModel || tm instanceof EnumerationModel) { - return TemplateCollectionModel.class; - } else if (tm instanceof MapModel) { - return TemplateHashModelEx.class; - } else if (tm instanceof NumberModel) { - return TemplateNumberModel.class; - } else if (tm instanceof BooleanModel) { - return TemplateBooleanModel.class; - } else if (tm instanceof DateModel) { - return TemplateDateModel.class; - } else if (tm instanceof StringModel) { - Object wrapped = ((BeanModel) tm).getWrappedObject(); - return wrapped instanceof String - ? TemplateScalarModel.class - : (tm instanceof TemplateHashModelEx ? TemplateHashModelEx.class : null); - } else { - return null; - } - } else if (tm instanceof SimpleMethodModel || tm instanceof OverloadedMethodsModel) { - return TemplateMethodModelEx.class; - } else { - return null; - } - } - - private static void appendTemplateModelTypeName(StringBuilder sb, Set typeNamesAppended, Class cl) { - int initalLength = sb.length(); - - if (TemplateNodeModelEx.class.isAssignableFrom(cl)) { - appendTypeName(sb, typeNamesAppended, "extended node"); - } else if (TemplateNodeModel.class.isAssignableFrom(cl)) { - appendTypeName(sb, typeNamesAppended, "node"); - } - - if (TemplateDirectiveModel.class.isAssignableFrom(cl)) { - appendTypeName(sb, typeNamesAppended, "directive"); - } else if (TemplateTransformModel.class.isAssignableFrom(cl)) { - appendTypeName(sb, typeNamesAppended, "transform"); - } - - if (TemplateSequenceModel.class.isAssignableFrom(cl)) { - appendTypeName(sb, typeNamesAppended, "sequence"); - } else if (TemplateCollectionModel.class.isAssignableFrom(cl)) { - appendTypeName(sb, typeNamesAppended, - TemplateCollectionModelEx.class.isAssignableFrom(cl) ? "extended_collection" : "collection"); - } else if (TemplateModelIterator.class.isAssignableFrom(cl)) { - appendTypeName(sb, typeNamesAppended, "iterator"); - } - - if (TemplateMethodModel.class.isAssignableFrom(cl)) { - appendTypeName(sb, typeNamesAppended, "method"); - } - - if (Environment.Namespace.class.isAssignableFrom(cl)) { - appendTypeName(sb, typeNamesAppended, "namespace"); - } else if (TemplateHashModelEx.class.isAssignableFrom(cl)) { - appendTypeName(sb, typeNamesAppended, "extended_hash"); - } else if (TemplateHashModel.class.isAssignableFrom(cl)) { - appendTypeName(sb, typeNamesAppended, "hash"); - } - - if (TemplateNumberModel.class.isAssignableFrom(cl)) { - appendTypeName(sb, typeNamesAppended, "number"); - } - - if (TemplateDateModel.class.isAssignableFrom(cl)) { - appendTypeName(sb, typeNamesAppended, "date_or_time_or_datetime"); - } - - if (TemplateBooleanModel.class.isAssignableFrom(cl)) { - appendTypeName(sb, typeNamesAppended, "boolean"); - } - - if (TemplateScalarModel.class.isAssignableFrom(cl)) { - appendTypeName(sb, typeNamesAppended, "string"); - } - - if (TemplateMarkupOutputModel.class.isAssignableFrom(cl)) { - appendTypeName(sb, typeNamesAppended, "markup_output"); - } - - if (sb.length() == initalLength) { - appendTypeName(sb, typeNamesAppended, "misc_template_model"); - } - } - - private static Class getUnwrappedClass(TemplateModel tm) { - Object unwrapped; - try { - if (tm instanceof WrapperTemplateModel) { - unwrapped = ((WrapperTemplateModel) tm).getWrappedObject(); - } else if (tm instanceof AdapterTemplateModel) { - unwrapped = ((AdapterTemplateModel) tm).getAdaptedObject(Object.class); - } else { - unwrapped = null; - } - } catch (Throwable e) { - unwrapped = null; - } - return unwrapped != null ? unwrapped.getClass() : null; - } - - private static void appendTypeName(StringBuilder sb, Set typeNamesAppended, String name) { - if (!typeNamesAppended.contains(name)) { - if (sb.length() != 0) sb.append("+"); - sb.append(name); - typeNamesAppended.add(name); - } - } - - /** - * Returns the type description of a value with FTL terms (not plain class name), as it should be used in - * type-related error messages and for debugging purposes. The exact format is not specified and might change over - * time, but currently it's something like {@code "string (wrapper: f.t.SimpleScalar)"} or - * {@code "sequence+hash+string (ArrayList wrapped into f.e.b.CollectionModel)"}. - * - * @since 2.3.20 - */ - public static String getFTLTypeDescription(TemplateModel tm) { - if (tm == null) { - return "Null"; - } else { - Set typeNamesAppended = new HashSet(); - - StringBuilder sb = new StringBuilder(); - - Class primaryInterface = getPrimaryTemplateModelInterface(tm); - if (primaryInterface != null) { - appendTemplateModelTypeName(sb, typeNamesAppended, primaryInterface); - } - - if (tm instanceof Macro) { - appendTypeName(sb, typeNamesAppended, ((Macro) tm).isFunction() ? "function" : "macro"); - } - - appendTemplateModelTypeName(sb, typeNamesAppended, tm.getClass()); - - String javaClassName; - Class unwrappedClass = getUnwrappedClass(tm); - if (unwrappedClass != null) { - javaClassName = getShortClassName(unwrappedClass, true); - } else { - javaClassName = null; - } - - sb.append(" ("); - String modelClassName = getShortClassName(tm.getClass(), true); - if (javaClassName == null) { - sb.append("wrapper: "); - sb.append(modelClassName); - } else { - sb.append(javaClassName); - sb.append(" wrapped into "); - sb.append(modelClassName); - } - sb.append(")"); - - return sb.toString(); - } - } - - /** - * Gets the wrapper class for a primitive class, like {@link Integer} for {@code int}, also returns {@link Void} - * for {@code void}. - * - * @param primitiveClass A {@link Class} like {@code int.type}, {@code boolean.type}, etc. If it's not a primitive - * class, or it's {@code null}, then the parameter value is returned as is. Note that performance-wise the - * method assumes that it's a primitive class. - * - * @since 2.3.21 - */ - public static Class primitiveClassToBoxingClass(Class primitiveClass) { - // Tried to sort these with decreasing frequency in API-s: - if (primitiveClass == int.class) return Integer.class; - if (primitiveClass == boolean.class) return Boolean.class; - if (primitiveClass == long.class) return Long.class; - if (primitiveClass == double.class) return Double.class; - if (primitiveClass == char.class) return Character.class; - if (primitiveClass == float.class) return Float.class; - if (primitiveClass == byte.class) return Byte.class; - if (primitiveClass == short.class) return Short.class; - if (primitiveClass == void.class) return Void.class; // not really a primitive, but we normalize it - return primitiveClass; - } - - /** - * The exact reverse of {@link #primitiveClassToBoxingClass}. - * - * @since 2.3.21 - */ - public static Class boxingClassToPrimitiveClass(Class boxingClass) { - // Tried to sort these with decreasing frequency in API-s: - if (boxingClass == Integer.class) return int.class; - if (boxingClass == Boolean.class) return boolean.class; - if (boxingClass == Long.class) return long.class; - if (boxingClass == Double.class) return double.class; - if (boxingClass == Character.class) return char.class; - if (boxingClass == Float.class) return float.class; - if (boxingClass == Byte.class) return byte.class; - if (boxingClass == Short.class) return short.class; - if (boxingClass == Void.class) return void.class; // not really a primitive, but we normalize to it - return boxingClass; - } - - /** - * Tells if a type is numerical; works both for primitive types and classes. - * - * @param type can't be {@code null} - * - * @since 2.3.21 - */ - public static boolean isNumerical(Class type) { - return Number.class.isAssignableFrom(type) - || type.isPrimitive() && type != Boolean.TYPE && type != Character.TYPE && type != Void.TYPE; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/template/utility/CollectionUtils.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/template/utility/CollectionUtils.java b/src/main/java/freemarker/template/utility/CollectionUtils.java deleted file mode 100644 index 38e1b91..0000000 --- a/src/main/java/freemarker/template/utility/CollectionUtils.java +++ /dev/null @@ -1,36 +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.template.utility; - -/** @since 2.3.21 */ -public class CollectionUtils { - - private CollectionUtils() { } - - public static final Object[] EMPTY_OBJECT_ARRAY = new Object[] { }; - - public static final Class[] EMPTY_CLASS_ARRAY = new Class[] { }; - - /** - * @since 2.3.22 - */ - public static final char[] EMPTY_CHAR_ARRAY = new char[] { }; - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/template/utility/Collections12.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/template/utility/Collections12.java b/src/main/java/freemarker/template/utility/Collections12.java deleted file mode 100644 index d8c3708..0000000 --- a/src/main/java/freemarker/template/utility/Collections12.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.template.utility; - -import java.util.Collections; -import java.util.List; -import java.util.Map; - -import freemarker.template.EmptyMap; - -/** - * Implementation of missing JDK 1.3 collection features for JDK 1.2 - * - * @deprecated Not needed anymore, as FreeMarker now requires higher than Java 1.3 - */ -@Deprecated -public class Collections12 { - public static final Map EMPTY_MAP = new EmptyMap(); - - private Collections12() { - } - - public static Map singletonMap(Object key, Object value) { - return Collections.singletonMap(key, value); - } - - public static List singletonList(Object o) { - return Collections.singletonList(o); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/template/utility/Constants.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/template/utility/Constants.java b/src/main/java/freemarker/template/utility/Constants.java deleted file mode 100644 index 1c74243..0000000 --- a/src/main/java/freemarker/template/utility/Constants.java +++ /dev/null @@ -1,122 +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.template.utility; - -import java.io.Serializable; - -import freemarker.template.SimpleNumber; -import freemarker.template.TemplateBooleanModel; -import freemarker.template.TemplateCollectionModel; -import freemarker.template.TemplateHashModelEx; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; -import freemarker.template.TemplateModelIterator; -import freemarker.template.TemplateNumberModel; -import freemarker.template.TemplateScalarModel; -import freemarker.template.TemplateSequenceModel; - -/** - * Frequently used constant {@link TemplateModel} values. - * - * <p>These constants should be stored in the {@link TemplateModel} - * sub-interfaces, but for bacward compatibility they are stored here instead. - * Starting from FreeMarker 2.4 they should be copyed (not moved!) into the - * {@link TemplateModel} sub-interfaces, and this class should be marked as - * deprecated.</p> - */ -public class Constants { - - public static final TemplateBooleanModel TRUE = TemplateBooleanModel.TRUE; - - public static final TemplateBooleanModel FALSE = TemplateBooleanModel.FALSE; - - public static final TemplateScalarModel EMPTY_STRING = (TemplateScalarModel) TemplateScalarModel.EMPTY_STRING; - - public static final TemplateNumberModel ZERO = new SimpleNumber(0); - - public static final TemplateNumberModel ONE = new SimpleNumber(1); - - public static final TemplateNumberModel MINUS_ONE = new SimpleNumber(-1); - - public static final TemplateModelIterator EMPTY_ITERATOR = new EmptyIteratorModel(); - - private static class EmptyIteratorModel implements TemplateModelIterator, Serializable { - - public TemplateModel next() throws TemplateModelException { - throw new TemplateModelException("The collection has no more elements."); - } - - public boolean hasNext() throws TemplateModelException { - return false; - } - - } - - public static final TemplateCollectionModel EMPTY_COLLECTION = new EmptyCollectionModel(); - - private static class EmptyCollectionModel implements TemplateCollectionModel, Serializable { - - public TemplateModelIterator iterator() throws TemplateModelException { - return EMPTY_ITERATOR; - } - - } - - public static final TemplateSequenceModel EMPTY_SEQUENCE = new EmptySequenceModel(); - - private static class EmptySequenceModel implements TemplateSequenceModel, Serializable { - - public TemplateModel get(int index) throws TemplateModelException { - return null; - } - - public int size() throws TemplateModelException { - return 0; - } - - } - - public static final TemplateHashModelEx EMPTY_HASH = new EmptyHashModel(); - - private static class EmptyHashModel implements TemplateHashModelEx, Serializable { - - public int size() throws TemplateModelException { - return 0; - } - - public TemplateCollectionModel keys() throws TemplateModelException { - return EMPTY_COLLECTION; - } - - public TemplateCollectionModel values() throws TemplateModelException { - return EMPTY_COLLECTION; - } - - public TemplateModel get(String key) throws TemplateModelException { - return null; - } - - public boolean isEmpty() throws TemplateModelException { - return true; - } - - } - -} http://git-wip-us.apache.org/repos/asf/incubator-freemarker/blob/ecb4e230/src/main/java/freemarker/template/utility/DOMNodeModel.java ---------------------------------------------------------------------- diff --git a/src/main/java/freemarker/template/utility/DOMNodeModel.java b/src/main/java/freemarker/template/utility/DOMNodeModel.java deleted file mode 100644 index 1a0dd57..0000000 --- a/src/main/java/freemarker/template/utility/DOMNodeModel.java +++ /dev/null @@ -1,268 +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.template.utility; - -import java.util.HashMap; -import java.util.List; - -import org.w3c.dom.Attr; -import org.w3c.dom.Element; -import org.w3c.dom.NamedNodeMap; -import org.w3c.dom.Node; -import org.w3c.dom.NodeList; -import org.w3c.dom.Text; - -import freemarker.template.SimpleHash; -import freemarker.template.SimpleScalar; -import freemarker.template.TemplateBooleanModel; -import freemarker.template.TemplateHashModel; -import freemarker.template.TemplateMethodModel; -import freemarker.template.TemplateModel; -import freemarker.template.TemplateModelException; -import freemarker.template.TemplateSequenceModel; - -/** - * A convenient wrapper class for wrapping a Node in the W3C DOM API. - */ - -public class DOMNodeModel implements TemplateHashModel { - - static private HashMap equivalenceTable = new HashMap(); - static { - equivalenceTable.put("*", "children"); - equivalenceTable.put("@*", "attributes"); - } - - private Node node; - private HashMap cache = new HashMap(); - - public DOMNodeModel(Node node) { - this.node = node; - } - - public TemplateModel get(String key) throws TemplateModelException { - TemplateModel result = null; - if (equivalenceTable.containsKey(key)) { - key = (String) equivalenceTable.get(key); - } - if (cache.containsKey(key)) { - result = (TemplateModel) cache.get(key); - } - if (result == null) { - if ("attributes".equals(key)) { - NamedNodeMap attributes = node.getAttributes(); - if (attributes != null) { - SimpleHash hash = new SimpleHash(); - for (int i = 0; i < attributes.getLength(); i++) { - Attr att = (Attr) attributes.item(i); - hash.put(att.getName(), att.getValue()); - } - result = hash; - } - } else if (key.charAt(0) == '@') { - if (node instanceof Element) { - String attValue = ((Element) node).getAttribute(key.substring(1)); - result = new SimpleScalar(attValue); - } else { - throw new TemplateModelException("Trying to get an attribute value for a non-element node"); - } - } else if ("is_element".equals(key)) { - result = (node instanceof Element) ? - TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE; - } else if ("is_text".equals(key)) { - result = (node instanceof Text) ? - TemplateBooleanModel.TRUE : TemplateBooleanModel.FALSE; - } else if ("name".equals(key)) { - result = new SimpleScalar(node.getNodeName()); - } else if ("children".equals(key)) { - result = new NodeListTM(node.getChildNodes()); - } else if ("parent".equals(key)) { - Node parent = node.getParentNode(); - result = (parent == null) ? null : new DOMNodeModel(parent); - } else if ("ancestorByName".equals(key)) { - result = new AncestorByName(); - } else if ("nextSibling".equals(key)) { - Node next = node.getNextSibling(); - result = (next == null) ? null : new DOMNodeModel(next); - } else if ("previousSibling".equals(key)) { - Node previous = node.getPreviousSibling(); - result = (previous == null) ? null : new DOMNodeModel(previous); - } else if ("nextSiblingElement".equals(key)) { - Node next = nextSiblingElement(node); - result = (next == null) ? null : new DOMNodeModel(next); - } else if ("previousSiblingElement".equals(key)) { - Node previous = previousSiblingElement(node); - result = (previous == null) ? null : new DOMNodeModel(previous); - } else if ("nextElement".equals(key)) { - Node next = nextElement(node); - result = (next == null) ? null : new DOMNodeModel(next); - } else if ("previousElement".equals(key)) { - Node previous = previousElement(node); - result = (previous == null) ? null : new DOMNodeModel(previous); - } else if ("text".equals(key)) { - result = new SimpleScalar(getText(node)); - } - cache.put(key, result); - } - return result; - } - - public boolean isEmpty() { - return false; - } - - static private String getText(Node node) { - String result = ""; - if (node instanceof Text) { - result = ((Text) node).getData(); - } else if (node instanceof Element) { - NodeList children = node.getChildNodes(); - for (int i = 0; i < children.getLength(); i++) { - result += getText(children.item(i)); - } - } - return result; - } - - static private Element nextSiblingElement(Node node) { - Node next = node; - while (next != null) { - next = next.getNextSibling(); - if (next instanceof Element) { - return (Element) next; - } - } - return null; - } - - static private Element previousSiblingElement(Node node) { - Node previous = node; - while (previous != null) { - previous = previous.getPreviousSibling(); - if (previous instanceof Element) { - return (Element) previous; - } - } - return null; - } - - static private Element nextElement(Node node) { - if (node.hasChildNodes()) { - NodeList children = node.getChildNodes(); - for (int i = 0; i < children.getLength(); i++) { - Node child = children.item(i); - if (child instanceof Element) { - return (Element) child; - } - } - } - Element nextSiblingElement = nextSiblingElement(node); - if (nextSiblingElement != null) { - return nextSiblingElement; - } - Node parent = node.getParentNode(); - while (parent instanceof Element) { - Element next = nextSiblingElement(parent); - if (next != null) { - return next; - } - parent = parent.getParentNode(); - } - return null; - } - - static private Element previousElement(Node node) { - Element result = previousSiblingElement(node); - if (result != null) { - return result; - } - Node parent = node.getParentNode(); - if (parent instanceof Element) { - return (Element) parent; - } - return null; - } - - void setParent(DOMNodeModel parent) { - if (parent != null) { - cache.put("parent", parent); - } - } - - String getNodeName() { - return node.getNodeName(); - } - - - class AncestorByName implements TemplateMethodModel { - public Object exec(List arguments) throws TemplateModelException { - if (arguments.size() != 1) { - throw new TemplateModelException("Expecting exactly one string argument here"); - } - String nodeName = (String) arguments.get(0); - DOMNodeModel ancestor = (DOMNodeModel) DOMNodeModel.this.get("parent"); - while (ancestor != null) { - if (nodeName.equals(ancestor.getNodeName())) { - return ancestor; - } - ancestor = (DOMNodeModel) ancestor.get("parent"); - } - return null; - } - } - - - class NodeListTM implements TemplateSequenceModel, TemplateMethodModel { - - private NodeList nodeList; - private TemplateModel[] nodes; - - NodeListTM(NodeList nodeList) { - this.nodeList = nodeList; - nodes = new TemplateModel[nodeList.getLength()]; - } - - public TemplateModel get(int index) { - DOMNodeModel result = (DOMNodeModel) nodes[index]; - if (result == null) { - result = new DOMNodeModel(nodeList.item(index)); - nodes[index] = result; - result.setParent(DOMNodeModel.this); - } - return result; - } - - public int size() { - return nodes.length; - } - - public Object exec(List arguments) throws TemplateModelException { - if (arguments.size() != 1) { - throw new TemplateModelException("Expecting exactly one string argument here"); - } - if (!(node instanceof Element)) { - throw new TemplateModelException("Expecting element here."); - } - Element elem = (Element) node; - return new NodeListTM(elem.getElementsByTagName((String) arguments.get(0))); - } - } -} -
