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 020package prantl.ant.eclipse; 021 022import java.util.Iterator; 023import java.util.Set; 024import java.util.Vector; 025 026import 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 */ 037public 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}