aboutsummaryrefslogtreecommitdiffstats
path: root/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/DataType.java
diff options
context:
space:
mode:
Diffstat (limited to 'framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/DataType.java')
-rw-r--r--framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/DataType.java367
1 files changed, 367 insertions, 0 deletions
diff --git a/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/DataType.java b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/DataType.java
new file mode 100644
index 00000000..fda4af62
--- /dev/null
+++ b/framework/src/ant/apache-ant-1.9.6/src/main/org/apache/tools/ant/types/DataType.java
@@ -0,0 +1,367 @@
+/*
+ * 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 org.apache.tools.ant.types;
+
+import java.util.Stack;
+
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.ComponentHelper;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.ProjectComponent;
+import org.apache.tools.ant.util.IdentityStack;
+
+/**
+ * Base class for those classes that can appear inside the build file
+ * as stand alone data types.
+ *
+ * <p>This class handles the common description attribute and provides
+ * a default implementation for reference handling and checking for
+ * circular references that is appropriate for types that can not be
+ * nested inside elements of the same type (i.e. &lt;patternset&gt;
+ * but not &lt;path&gt;).</p>
+ *
+ */
+public abstract class DataType extends ProjectComponent implements Cloneable {
+ // CheckStyle:VisibilityModifier OFF
+
+ /**
+ * Value to the refid attribute.
+ *
+ * @deprecated since 1.7.
+ * The user should not be directly referencing
+ * variable. Please use {@link #getRefid} instead.
+ */
+ protected Reference ref;
+
+ /**
+ * Are we sure we don't hold circular references?
+ *
+ * <p>Subclasses are responsible for setting this value to false
+ * if we'd need to investigate this condition (usually because a
+ * child element has been added that is a subclass of
+ * DataType).</p>
+ *
+ * @deprecated since 1.7.
+ * The user should not be directly referencing
+ * variable. Please use {@link #setChecked} or
+ * {@link #isChecked} instead.
+ */
+ protected boolean checked = true;
+ // CheckStyle:VisibilityModifier ON
+
+ /**
+ * Has the refid attribute of this element been set?
+ * @return true if the refid attribute has been set
+ */
+ public boolean isReference() {
+ return ref != null;
+ }
+
+ /**
+ * Set the value of the refid attribute.
+ *
+ * <p>Subclasses may need to check whether any other attributes
+ * have been set as well or child elements have been created and
+ * thus override this method. if they do the must call
+ * <code>super.setRefid</code>.</p>
+ * @param ref the reference to use
+ */
+ public void setRefid(final Reference ref) {
+ this.ref = ref;
+ checked = false;
+ }
+
+ /**
+ * Gets as descriptive as possible a name used for this datatype instance.
+ * @return <code>String</code> name.
+ */
+ protected String getDataTypeName() {
+ return ComponentHelper.getElementName(getProject(), this, true);
+ }
+
+ /**
+ * Convenience method.
+ * @since Ant 1.7
+ */
+ protected void dieOnCircularReference() {
+ dieOnCircularReference(getProject());
+ }
+
+ /**
+ * Convenience method.
+ * @param p the Ant Project instance against which to resolve references.
+ * @since Ant 1.7
+ */
+ protected void dieOnCircularReference(Project p) {
+ if (checked || !isReference()) {
+ return;
+ }
+ dieOnCircularReference(new IdentityStack<Object>(this), p);
+ }
+
+ /**
+ * Check to see whether any DataType we hold references to is
+ * included in the Stack (which holds all DataType instances that
+ * directly or indirectly reference this instance, including this
+ * instance itself).
+ *
+ * <p>If one is included, throw a BuildException created by {@link
+ * #circularReference circularReference}.</p>
+ *
+ * <p>This implementation is appropriate only for a DataType that
+ * cannot hold other DataTypes as children.</p>
+ *
+ * <p>The general contract of this method is that it shouldn't do
+ * anything if {@link #checked <code>checked</code>} is true and
+ * set it to true on exit.</p>
+ * @param stack the stack of references to check.
+ * @param project the project to use to dereference the references.
+ * @throws BuildException on error.
+ */
+ protected void dieOnCircularReference(final Stack<Object> stack,
+ final Project project)
+ throws BuildException {
+
+ if (checked || !isReference()) {
+ return;
+ }
+ Object o = ref.getReferencedObject(project);
+
+ if (o instanceof DataType) {
+ IdentityStack<Object> id = IdentityStack.getInstance(stack);
+
+ if (id.contains(o)) {
+ throw circularReference();
+ } else {
+ id.push(o);
+ ((DataType) o).dieOnCircularReference(id, project);
+ id.pop();
+ }
+ }
+ checked = true;
+ }
+
+ /**
+ * Allow DataTypes outside org.apache.tools.ant.types to indirectly call
+ * dieOnCircularReference on nested DataTypes.
+ * @param dt the DataType to check.
+ * @param stk the stack of references to check.
+ * @param p the project to use to dereference the references.
+ * @throws BuildException on error.
+ * @since Ant 1.7
+ */
+ public static void invokeCircularReferenceCheck(DataType dt, Stack<Object> stk,
+ Project p) {
+ dt.dieOnCircularReference(stk, p);
+ }
+
+ /**
+ * Allow DataTypes outside org.apache.tools.ant.types to indirectly call
+ * dieOnCircularReference on nested DataTypes.
+ *
+ * <p>Pushes dt on the stack, runs dieOnCircularReference and pops
+ * it again.</p>
+ * @param dt the DataType to check.
+ * @param stk the stack of references to check.
+ * @param p the project to use to dereference the references.
+ * @throws BuildException on error.
+ * @since Ant 1.8.0
+ */
+ public static void pushAndInvokeCircularReferenceCheck(DataType dt,
+ Stack<Object> stk,
+ Project p) {
+ stk.push(dt);
+ dt.dieOnCircularReference(stk, p);
+ stk.pop();
+ }
+
+ /**
+ * Performs the check for circular references and returns the
+ * referenced object.
+ * @return the dereferenced object.
+ * @throws BuildException if the reference is invalid (circular ref, wrong class, etc).
+ * @since Ant 1.7
+ */
+ protected Object getCheckedRef() {
+ return getCheckedRef(getProject());
+ }
+
+ /**
+ * Performs the check for circular references and returns the
+ * referenced object.
+ * @param p the Ant Project instance against which to resolve references.
+ * @return the dereferenced object.
+ * @throws BuildException if the reference is invalid (circular ref, wrong class, etc).
+ * @since Ant 1.7
+ */
+ protected Object getCheckedRef(Project p) {
+ return getCheckedRef(getClass(), getDataTypeName(), p);
+ }
+
+ /**
+ * Performs the check for circular references and returns the
+ * referenced object.
+ * @param requiredClass the class that this reference should be a subclass of.
+ * @param dataTypeName the name of the datatype that the reference should be
+ * (error message use only).
+ * @return the dereferenced object.
+ * @throws BuildException if the reference is invalid (circular ref, wrong class, etc).
+ */
+ protected <T> T getCheckedRef(final Class<T> requiredClass,
+ final String dataTypeName) {
+ return getCheckedRef(requiredClass, dataTypeName, getProject());
+ }
+
+ /**
+ * Performs the check for circular references and returns the
+ * referenced object. This version allows the fallback Project instance to be specified.
+ * @param requiredClass the class that this reference should be a subclass of.
+ * @param dataTypeName the name of the datatype that the reference should be
+ * (error message use only).
+ * @param project the fallback Project instance for dereferencing.
+ * @return the dereferenced object.
+ * @throws BuildException if the reference is invalid (circular ref, wrong class, etc),
+ * or if <code>project</code> is <code>null</code>.
+ * @since Ant 1.7
+ */
+ protected <T> T getCheckedRef(final Class<T> requiredClass,
+ final String dataTypeName, final Project project) {
+ if (project == null) {
+ throw new BuildException("No Project specified");
+ }
+ dieOnCircularReference(project);
+ Object o = ref.getReferencedObject(project);
+ if (!(requiredClass.isAssignableFrom(o.getClass()))) {
+ log("Class " + displayName(o.getClass())
+ + " is not a subclass of "
+ + displayName(requiredClass),
+ Project.MSG_VERBOSE);
+ String msg = ref.getRefId() + " doesn\'t denote a " + dataTypeName;
+ throw new BuildException(msg);
+ }
+ @SuppressWarnings("unchecked")
+ final T result = (T) o;
+ return result;
+ }
+
+ /**
+ * Creates an exception that indicates that refid has to be the
+ * only attribute if it is set.
+ * @return the exception to throw
+ */
+ protected BuildException tooManyAttributes() {
+ return new BuildException("You must not specify more than one "
+ + "attribute when using refid");
+ }
+
+ /**
+ * Creates an exception that indicates that this XML element must
+ * not have child elements if the refid attribute is set.
+ * @return the exception to throw
+ */
+ protected BuildException noChildrenAllowed() {
+ return new BuildException("You must not specify nested elements "
+ + "when using refid");
+ }
+
+ /**
+ * Creates an exception that indicates the user has generated a
+ * loop of data types referencing each other.
+ * @return the exception to throw
+ */
+ protected BuildException circularReference() {
+ return new BuildException("This data type contains a circular "
+ + "reference.");
+ }
+
+ /**
+ * The flag that is used to indicate that circular references have been checked.
+ * @return true if circular references have been checked
+ */
+ protected boolean isChecked() {
+ return checked;
+ }
+
+ /**
+ * Set the flag that is used to indicate that circular references have been checked.
+ * @param checked if true, if circular references have been checked
+ */
+ protected void setChecked(final boolean checked) {
+ this.checked = checked;
+ }
+
+ /**
+ * get the reference set on this object
+ * @return the reference or null
+ */
+ public Reference getRefid() {
+ return ref;
+ }
+
+ /**
+ * check that it is ok to set attributes, i.e that no reference is defined
+ * @since Ant 1.6
+ * @throws BuildException if not allowed
+ */
+ protected void checkAttributesAllowed() {
+ if (isReference()) {
+ throw tooManyAttributes();
+ }
+ }
+
+ /**
+ * check that it is ok to add children, i.e that no reference is defined
+ * @since Ant 1.6
+ * @throws BuildException if not allowed
+ */
+ protected void checkChildrenAllowed() {
+ if (isReference()) {
+ throw noChildrenAllowed();
+ }
+ }
+
+ /**
+ * Basic DataType toString().
+ * @return this DataType formatted as a String.
+ */
+ public String toString() {
+ String d = getDescription();
+ return d == null ? getDataTypeName() : getDataTypeName() + " " + d;
+ }
+
+ /**
+ * @since Ant 1.7
+ * @return a shallow copy of this DataType.
+ * @throws CloneNotSupportedException if there is a problem.
+ */
+ public Object clone() throws CloneNotSupportedException {
+ DataType dt = (DataType) super.clone();
+ dt.setDescription(getDescription());
+ if (getRefid() != null) {
+ dt.setRefid(getRefid());
+ }
+ dt.setChecked(isChecked());
+ return dt;
+ }
+
+ private String displayName(Class<?> clazz) {
+ return clazz.getName() + " (loaded via " + clazz.getClassLoader() +")";
+ }
+}
+