001 // Copyright 2005-2006 Ferdinand Prantl <prantl@users.sourceforge.net>
002 // Copyright 2001-2004 The Apache Software Foundation
003 // All rights reserved.
004 //
005 // Licensed under the Apache License, Version 2.0 (the "License");
006 // you may not use this file except in compliance with the License.
007 // You may obtain a copy of the License at
008 //
009 // http://www.apache.org/licenses/LICENSE-2.0
010 //
011 // Unless required by applicable law or agreed to in writing, software
012 // distributed under the License is distributed on an "AS IS" BASIS,
013 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 // See the License for the specific language governing permissions and
015 // limitations under the License.
016 //
017 // See http://ant-eclipse.sourceforge.net for the most recent version
018 // and more information.
019
020 package prantl.ant.eclipse;
021
022 import java.util.Iterator;
023 import java.util.Set;
024 import java.util.Vector;
025
026 import org.apache.tools.ant.BuildException;
027
028 /**
029 * Configures a component preferences in a file under the directory <tt>.settings</tt>
030 * using variable elements. The version element is mandatory and will be generated
031 * automatically if not provided. The attributes <tt>name</tt> of all elements
032 * describing the preferences must be distinct.
033 *
034 * @since Ant-Eclipse 1.0
035 * @author Ferdinand Prantl <prantl@users.sourceforge.net>
036 */
037 public abstract class PreferencesElement {
038
039 private static final String VERSION_NAME = "eclipse.preferences.version";
040
041 private static final String VERSION_VALUE = "1";
042
043 private SettingsElement settings = null;
044
045 private String name = null;
046
047 private Vector variables = new Vector();
048
049 /**
050 * Creates a new instance of the element for preferences under the settings element.
051 *
052 * @param parent
053 * The parent settings element of this preferences one.
054 * @since Ant-Eclipse 1.0
055 */
056 PreferencesElement(SettingsElement parent) {
057 settings = parent;
058 }
059
060 /**
061 * Returns the name of the file with preferences. The name must not be <tt>null</tt>,
062 * it is a mandatory attribute.
063 *
064 * @return The name of the file with preferences or <tt>null</tt> if not having been
065 * set.
066 */
067 public String getName() {
068 return name;
069 }
070
071 /**
072 * Sets the name of the file with preferences. Used internally to set default names of
073 * the files for preferences.
074 *
075 * @param value
076 * A name of the file with preferences.
077 * @since Ant-Eclipse 1.0
078 */
079 void internalSetName(String value) {
080 settings.validatePreferencesName(value);
081 name = value;
082 }
083
084 /**
085 * Returns the version of the preferences set by this element (<tt>1</tt> is used
086 * as a default). The default value should be left.
087 *
088 * @return The version of the Eclipse preferences (<tt>1</tt> is used as a
089 * default).
090 */
091 public String getVersion() {
092 // return version;
093 VariableElement variable = getVariable(VERSION_NAME);
094 return variable == null ? VERSION_VALUE : variable.getValue();
095 }
096
097 /**
098 * Sets the version of the Eclipse preferences. The default value should be left and
099 * not set explicitely.
100 *
101 * @param value
102 * A valid version of the Eclipse preferences.
103 * @since Ant-Eclipse 1.0
104 */
105 public void setVersion(String value) {
106 internalCreateVariable(VERSION_NAME, value);
107 }
108
109 /**
110 * Returns a list with instances of the class VariableElement defining variables for a
111 * file <em><full qualified class
112 * name></em> under the directory
113 * <tt>.settings</tt>. If it is empty the version element will be generated
114 * automatically.
115 *
116 * @return A list with instances of the descendants of the class PreferencesElement.
117 */
118 public Vector getVariables() {
119 return variables;
120 }
121
122 /**
123 * Adds a definition of a new variable element. Used internally to add undeclared
124 * variable definitions and allow the low-level variable element.
125 *
126 * @return A definition of a new variable element.
127 * @since Ant-Eclipse 1.0
128 */
129 VariableElement internalCreateVariable() {
130 variables.addElement(new VariableElement(this));
131 return (VariableElement) variables.lastElement();
132 }
133
134 /**
135 * Adds a definition of a new variable element, with its name and value. Used
136 * internally to add undeclared variable definitions.
137 *
138 * @param name
139 * A name of the configuration variable.
140 * @param value
141 * A value of the configuration variable.
142 * @since Ant-Eclipse 1.0
143 */
144 void internalCreateVariable(String name, String value) {
145 VariableElement variable = internalCreateVariable();
146 variable.setName(name);
147 variable.setValue(value);
148 }
149
150 /**
151 * Adds a definition of a new variable element, with its name and value, only if not
152 * yet defined. Used internally to add default variable definitions.
153 *
154 * @param name
155 * A name of the configuration variable.
156 * @param value
157 * A value of the configuration variable.
158 * @since Ant-Eclipse 1.0
159 */
160 void internalAddVariable(String name, String value) {
161 if (!hasVariable(name))
162 internalCreateVariable(name, value);
163 }
164
165 /**
166 * Performs the validation of the element at the time when the whole build file was
167 * parsed checking the content of the element and possibly adding mandatory variables
168 * with default settings.
169 *
170 * @since Ant-Eclipse 1.0
171 */
172 public void validate() {
173 if (!hasVariable(VERSION_NAME))
174 setVersion(VERSION_VALUE);
175 for (int i = 0, size = variables.size(); i != size; ++i) {
176 VariableElement variable = (VariableElement) variables.get(i);
177 variable.validate();
178 }
179 }
180
181 /**
182 * Checks if the variable with the specified name is allowed to be defined according
183 * to the already parsed content.
184 *
185 * @param name
186 * The name of the configuration variable to validate.
187 * @since Ant-Eclipse 1.0
188 */
189 void validateVariableName(String name) {
190 if (hasVariable(name))
191 throw new BuildException(
192 name.equals(VERSION_NAME) ? "The variable \""
193 + VERSION_NAME
194 + "\" cannot be defined as an element if there has been an attribute \"version\" used for the whole preferences."
195 : "The variable named \"" + name
196 + "\" has alredy been defined.");
197 }
198
199 /**
200 * Checks if the variable with the specified name has already been defined for this
201 * preferences.
202 *
203 * @param name
204 * The name of the configuration variable to look for.
205 * @return <tt>True</tt> if the variable with the specified name is present.
206 * @since Ant-Eclipse 1.0
207 */
208 boolean hasVariable(String name) {
209 return getVariable(name) != null;
210 }
211
212 /**
213 * Returns the element defining the variable with the specified name or <tt>null</tt>
214 * if not having been defined.
215 *
216 * @param name
217 * The element defining the configuration variable or <tt>null</tt> if not
218 * present.
219 * @return The element defining the variable with the specified name or <tt>null</tt>
220 * if not present.
221 * @since Ant-Eclipse 1.0
222 */
223 VariableElement getVariable(String name) {
224 for (int i = 0, size = variables.size(); i != size; ++i) {
225 VariableElement variable = (VariableElement) variables.get(i);
226 if (name.equals(variable.getName()))
227 return variable;
228 }
229 return null;
230 }
231
232 /**
233 * Returns a new string with a list of string representations of the items from the
234 * passed set in the format "item1", "item2" and "item3" useful to display allowed
235 * value list as a string.
236 *
237 * @param set
238 * Set to list as a string.
239 * @return A new string with a list of string representations of the items from the
240 * passed set in the format "item1", "item2" and "item3".
241 * @since Ant-Eclipse 1.0
242 */
243 String getValidValues(Set set) {
244 StringBuffer result = new StringBuffer();
245 Iterator iterator = set.iterator();
246 for (int i = 0, size = set.size(); i != size; ++i) {
247 result.append('\"');
248 result.append(iterator.next());
249 if (i == size - 2)
250 result.append("\" and ");
251 else if (i == size - 1)
252 result.append('\"');
253 else
254 // if (i < count - 2)
255 result.append("\", ");
256 }
257 return result.toString();
258 }
259
260 }