source: other-projects/trunk/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/ant/types/DataType.java@ 14627

Last change on this file since 14627 was 14627, checked in by oranfry, 17 years ago

initial import of the gs3-release-maker

File size: 7.0 KB
Line 
1/*
2 * Copyright 2000-2004 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17
18package org.apache.tools.ant.types;
19
20
21import java.util.Stack;
22import org.apache.tools.ant.BuildException;
23import org.apache.tools.ant.Project;
24import org.apache.tools.ant.ProjectComponent;
25
26/**
27 * Base class for those classes that can appear inside the build file
28 * as stand alone data types.
29 *
30 * <p>This class handles the common description attribute and provides
31 * a default implementation for reference handling and checking for
32 * circular references that is appropriate for types that can not be
33 * nested inside elements of the same type (i.e. &lt;patternset&gt;
34 * but not &lt;path&gt;).</p>
35 *
36 */
37public abstract class DataType extends ProjectComponent {
38 /**
39 * The description the user has set.
40 *
41 * @deprecated The user should not be directly referencing
42 * variable. Please use {@link #setDescription} or
43 * {@link #getDescription} instead.
44 */
45 protected String description;
46
47 /**
48 * Value to the refid attribute.
49 *
50 * @deprecated The user should not be directly referencing
51 * variable. Please use {@link #getRefid} instead.
52 */
53 protected Reference ref;
54
55 /**
56 * Are we sure we don't hold circular references?
57 *
58 * <p>Subclasses are responsible for setting this value to false
59 * if we'd need to investigate this condition (usually because a
60 * child element has been added that is a subclass of
61 * DataType).</p>
62 *
63 * @deprecated The user should not be directly referencing
64 * variable. Please use {@link #setChecked} or
65 * {@link #isChecked} instead.
66 */
67 protected boolean checked = true;
68
69 /**
70 * Sets a description of the current data type. It will be useful
71 * in commenting what we are doing.
72 */
73 public void setDescription(final String desc) {
74 description = desc;
75 }
76
77 /**
78 * Return the description for the current data type.
79 */
80 public String getDescription() {
81 return description;
82 }
83
84 /**
85 * Has the refid attribute of this element been set?
86 */
87 public boolean isReference() {
88 return ref != null;
89 }
90
91 /**
92 * Set the value of the refid attribute.
93 *
94 * <p>Subclasses may need to check whether any other attributes
95 * have been set as well or child elements have been created and
96 * thus override this method. if they do the must call
97 * <code>super.setRefid</code>.</p>
98 */
99 public void setRefid(final Reference ref) {
100 this.ref = ref;
101 checked = false;
102 }
103
104 /**
105 * Check to see whether any DataType we hold references to is
106 * included in the Stack (which holds all DataType instances that
107 * directly or indirectly reference this instance, including this
108 * instance itself).
109 *
110 * <p>If one is included, throw a BuildException created by {@link
111 * #circularReference circularReference}.</p>
112 *
113 * <p>This implementation is appropriate only for a DataType that
114 * cannot hold other DataTypes as children.</p>
115 *
116 * <p>The general contract of this method is that it shouldn't do
117 * anything if {@link #checked <code>checked</code>} is true and
118 * set it to true on exit.</p>
119 */
120 protected void dieOnCircularReference(final Stack stack,
121 final Project project)
122 throws BuildException {
123
124 if (checked || !isReference()) {
125 return;
126 }
127 Object o = ref.getReferencedObject(project);
128
129 if (o instanceof DataType) {
130 if (stack.contains(o)) {
131 throw circularReference();
132 } else {
133 stack.push(o);
134 ((DataType) o).dieOnCircularReference(stack, project);
135 stack.pop();
136 }
137 }
138 checked = true;
139 }
140
141 /**
142 * Performs the check for circular references and returns the
143 * referenced object.
144 */
145 protected Object getCheckedRef(final Class requiredClass,
146 final String dataTypeName) {
147 if (!checked) {
148 Stack stk = new Stack();
149 stk.push(this);
150 dieOnCircularReference(stk, getProject());
151 }
152
153 Object o = ref.getReferencedObject(getProject());
154 if (!(requiredClass.isAssignableFrom(o.getClass()))) {
155 String msg = ref.getRefId() + " doesn\'t denote a " + dataTypeName;
156 throw new BuildException(msg);
157 } else {
158 return o;
159 }
160 }
161
162 /**
163 * Creates an exception that indicates that refid has to be the
164 * only attribute if it is set.
165 */
166 protected BuildException tooManyAttributes() {
167 return new BuildException("You must not specify more than one "
168 + "attribute when using refid");
169 }
170
171 /**
172 * Creates an exception that indicates that this XML element must
173 * not have child elements if the refid attribute is set.
174 */
175 protected BuildException noChildrenAllowed() {
176 return new BuildException("You must not specify nested elements "
177 + "when using refid");
178 }
179
180 /**
181 * Creates an exception that indicates the user has generated a
182 * loop of data types referencing each other.
183 */
184 protected BuildException circularReference() {
185 return new BuildException("This data type contains a circular "
186 + "reference.");
187 }
188
189 protected boolean isChecked() {
190 return checked;
191 }
192
193 protected void setChecked(final boolean checked) {
194 this.checked = checked;
195 }
196
197 /**
198 * get the reference set on this object
199 * @return the reference or null
200 */
201 protected Reference getRefid() {
202 return ref;
203 }
204
205 /**
206 * check that it is ok to set attributes, i.e that no reference is defined
207 * @since Ant 1.6
208 * @throws BuildException if not allowed
209 */
210 protected void checkAttributesAllowed() {
211 if (isReference()) {
212 throw tooManyAttributes();
213 }
214 }
215
216 /**
217 * check that it is ok to add children, i.e that no reference is defined
218 * @since Ant 1.6
219 * @throws BuildException if not allowed
220 */
221 protected void checkChildrenAllowed() {
222 if (isReference()) {
223 throw noChildrenAllowed();
224 }
225 }
226}
Note: See TracBrowser for help on using the repository browser.