KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > izforge > izpack > compiler > Property


1 /*
2  * IzPack - Copyright 2001-2007 Julien Ponge, All Rights Reserved.
3  *
4  * http://www.izforge.com/izpack/
5  * http://developer.berlios.de/projects/izpack/
6  *
7  * Copyright 2004 Chadwick McHenry
8  *
9  * Licensed under the Apache License, Version 2.0 (the "License");
10  * you may not use this file except in compliance with the License.
11  * You may obtain a copy of the License at
12  *
13  * http://www.apache.org/licenses/LICENSE-2.0
14  *
15  * Unless required by applicable law or agreed to in writing, software
16  * distributed under the License is distributed on an "AS IS" BASIS,
17  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18  * See the License for the specific language governing permissions and
19  * limitations under the License.
20  */

21
22 package com.izforge.izpack.compiler;
23
24 import java.io.File JavaDoc;
25 import java.io.FileInputStream JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.StringReader JavaDoc;
28 import java.io.StringWriter JavaDoc;
29 import java.util.Enumeration JavaDoc;
30 import java.util.Properties JavaDoc;
31 import java.util.Vector JavaDoc;
32
33 import net.n3.nanoxml.XMLElement;
34
35 import org.apache.tools.ant.taskdefs.Execute;
36
37 import com.izforge.izpack.util.VariableSubstitutor;
38
39 /**
40  * Sets a property by name, or set of properties (from file or resource) in the project. This is
41  * modeled after ant properties
42  * <p>
43  *
44  * Properties are immutable: once a property is set it cannot be changed. They are most definately
45  * not variable.
46  * <p>
47  *
48  * There are five ways to set properties:
49  * <ul>
50  * <li>By supplying both the <i>name</i> and <i>value</i> attributes.</li>
51  * <li>By setting the <i>file</i> attribute with the filename of the property file to load. This
52  * property file has the format as defined by the file used in the class java.util.Properties.</li>
53  * <li>By setting the <i>environment</i> attribute with a prefix to use. Properties will be
54  * defined for every environment variable by prefixing the supplied name and a period to the name of
55  * the variable.</li>
56  * </ul>
57  *
58  * Combinations of the above are considered an error.
59  * <p>
60  *
61  * The value part of the properties being set, might contain references to other properties. These
62  * references are resolved when the properties are set.
63  * <p>
64  *
65  * This also holds for properties loaded from a property file.
66  * <p>
67  *
68  * Properties are case sensitive.
69  * <p>
70  *
71  * When specifying the environment attribute, it's value is used as a prefix to use when retrieving
72  * environment variables. This functionality is currently only implemented on select platforms.
73  * <p>
74  *
75  * Thus if you specify environment=&quot;myenv&quot; you will be able to access OS-specific
76  * environment variables via property names &quot;myenv.PATH&quot; or &quot;myenv.TERM&quot;.
77  * <p>
78  *
79  * Note also that properties are case sensitive, even if the environment variables on your operating
80  * system are not, e.g. it will be ${env.Path} not ${env.PATH} on Windows 2000.
81  * <p>
82  *
83  * Note that when specifying either the <code>prefix</code> or <code>environment</code>
84  * attributes, if you supply a property name with a final &quot;.&quot; it will not be doubled. ie
85  * environment=&quot;myenv.&quot; will still allow access of environment variables through
86  * &quot;myenv.PATH&quot; and &quot;myenv.TERM&quot;.
87  * <p>
88  */

89 public class Property
90 {
91
92     protected String JavaDoc name;
93
94     protected String JavaDoc value;
95
96     protected File JavaDoc file;
97
98     // protected String resource;
99
// protected Path classpath;
100
protected String JavaDoc env;
101
102     // protected Reference ref;
103
protected String JavaDoc prefix;
104
105     protected XMLElement xmlProp;
106
107     protected CompilerConfig config;
108     protected Compiler JavaDoc compiler;
109
110     public Property(XMLElement xmlProp, CompilerConfig config)
111     {
112         this.xmlProp = xmlProp;
113         this.config = config;
114         this.compiler = config.getCompiler();
115         name = xmlProp.getAttribute("name");
116         value = xmlProp.getAttribute("value");
117         env = xmlProp.getAttribute("environment");
118         if (env != null && !env.endsWith(".")) env += ".";
119
120         prefix = xmlProp.getAttribute("prefix");
121         if (prefix != null && !prefix.endsWith(".")) prefix += ".";
122
123         String JavaDoc filename = xmlProp.getAttribute("file");
124         if (filename != null) file = new File JavaDoc(filename);
125     }
126
127     /**
128      * get the value of this property
129      *
130      * @return the current value or the empty string
131      */

132     public String JavaDoc getValue()
133     {
134         return toString();
135     }
136
137     /**
138      * get the value of this property
139      *
140      * @return the current value or the empty string
141      */

142     public String JavaDoc toString()
143     {
144         return value == null ? "" : value;
145     }
146
147     /**
148      * Set the property in the project to the value. If the task was give a file, resource or env
149      * attribute here is where it is loaded.
150      */

151     public void execute() throws CompilerException
152     {
153         if (name != null)
154         {
155             if (value == null)
156                 config.parseError(xmlProp, "You must specify a value with the name attribute");
157         }
158         else
159         {
160             if (file == null && env == null)
161                 config.parseError(xmlProp,
162                         "You must specify file, or environment when not using the name attribute");
163         }
164
165         if (file == null && prefix != null)
166             config.parseError(xmlProp, "Prefix is only valid when loading from a file ");
167
168         if ((name != null) && (value != null))
169             addProperty(name, value);
170
171         else if (file != null)
172             loadFile(file);
173
174         else if (env != null) loadEnvironment(env);
175     }
176
177     /**
178      * load properties from a file
179      *
180      * @param file file to load
181      */

182     protected void loadFile(File JavaDoc file) throws CompilerException
183     {
184         Properties JavaDoc props = new Properties JavaDoc();
185         config.getPackagerListener().packagerMsg("Loading " + file.getAbsolutePath(),
186                 PackagerListener.MSG_VERBOSE);
187         try
188         {
189             if (file.exists())
190             {
191                 FileInputStream JavaDoc fis = new FileInputStream JavaDoc(file);
192                 try
193                 {
194                     props.load(fis);
195                 }
196                 finally
197                 {
198                     if (fis != null) fis.close();
199                 }
200                 addProperties(props);
201             }
202             else
203             {
204                 config.getPackagerListener().packagerMsg(
205                         "Unable to find property file: " + file.getAbsolutePath(),
206                         PackagerListener.MSG_VERBOSE);
207             }
208         }
209         catch (IOException JavaDoc ex)
210         {
211             config.parseError(xmlProp, "Faild to load file: " + file.getAbsolutePath(), ex);
212         }
213     }
214
215     /**
216      * load the environment values
217      *
218      * @param prefix prefix to place before them
219      */

220     protected void loadEnvironment(String JavaDoc prefix) throws CompilerException
221     {
222         Properties JavaDoc props = new Properties JavaDoc();
223         config.getPackagerListener().packagerMsg("Loading Environment " + prefix,
224                 PackagerListener.MSG_VERBOSE);
225         Vector JavaDoc osEnv = Execute.getProcEnvironment();
226         for (Enumeration JavaDoc e = osEnv.elements(); e.hasMoreElements();)
227         {
228             String JavaDoc entry = (String JavaDoc) e.nextElement();
229             int pos = entry.indexOf('=');
230             if (pos == -1)
231             {
232                 config.getPackagerListener().packagerMsg("Ignoring " + prefix,
233                         PackagerListener.MSG_WARN);
234             }
235             else
236             {
237                 props.put(prefix + entry.substring(0, pos), entry.substring(pos + 1));
238             }
239         }
240         addProperties(props);
241     }
242
243     /**
244      * Add a name value pair to the project property set
245      *
246      * @param name name of property
247      * @param value value to set
248      */

249     protected void addProperty(String JavaDoc name, String JavaDoc value) throws CompilerException
250     {
251         value = compiler.replaceProperties(value);
252
253         compiler.addProperty(name, value);
254     }
255
256     /**
257      * iterate through a set of properties, resolve them then assign them
258      */

259     protected void addProperties(Properties JavaDoc props) throws CompilerException
260     {
261         resolveAllProperties(props);
262         Enumeration JavaDoc e = props.keys();
263         while (e.hasMoreElements())
264         {
265             String JavaDoc name = (String JavaDoc) e.nextElement();
266             String JavaDoc value = props.getProperty(name);
267
268             if (prefix != null)
269             {
270                 name = prefix + name;
271             }
272
273             addProperty(name, value);
274         }
275     }
276
277     /**
278      * resolve properties inside a properties object
279      *
280      * @param props properties to resolve
281      */

282     private void resolveAllProperties(Properties JavaDoc props) throws CompilerException
283     {
284         VariableSubstitutor subs = new VariableSubstitutor(props);
285         subs.setBracesRequired(true);
286
287         for (Enumeration JavaDoc e = props.keys(); e.hasMoreElements();)
288         {
289             String JavaDoc name = (String JavaDoc) e.nextElement();
290             String JavaDoc value = props.getProperty(name);
291
292             int mods = -1;
293             do
294             {
295                 StringReader JavaDoc read = new StringReader JavaDoc(value);
296                 StringWriter JavaDoc write = new StringWriter JavaDoc();
297
298                 try
299                 {
300                     mods = subs.substitute(read, write, "at");
301                     // TODO: check for circular references. We need to know
302
// which
303
// variables were substituted to do that
304
props.put(name, value);
305                 }
306                 catch (IOException JavaDoc ex)
307                 {
308                     config.parseError(xmlProp, "Faild to load file: " + file.getAbsolutePath(),
309                             ex);
310                 }
311             }
312             while (mods != 0);
313         }
314     }
315 }
316
Popular Tags