KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > java > plugin > tools > ant > VersionUpdateTask


1 /*****************************************************************************
2  * Java Plug-in Framework (JPF)
3  * Copyright (C) 2006-2007 Dmitry Olshansky
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2.1 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18  *****************************************************************************/

19 package org.java.plugin.tools.ant;
20
21 import java.io.BufferedInputStream JavaDoc;
22 import java.io.BufferedOutputStream JavaDoc;
23 import java.io.File JavaDoc;
24 import java.io.FileInputStream JavaDoc;
25 import java.io.FileOutputStream JavaDoc;
26 import java.io.IOException JavaDoc;
27 import java.io.InputStream JavaDoc;
28 import java.io.OutputStream JavaDoc;
29 import java.net.URL JavaDoc;
30 import java.text.DateFormat JavaDoc;
31 import java.text.ParseException JavaDoc;
32 import java.text.SimpleDateFormat JavaDoc;
33 import java.util.Date JavaDoc;
34 import java.util.HashMap JavaDoc;
35 import java.util.Iterator JavaDoc;
36 import java.util.Locale JavaDoc;
37 import java.util.Map JavaDoc;
38 import java.util.Properties JavaDoc;
39
40 import javax.xml.parsers.DocumentBuilder JavaDoc;
41 import javax.xml.parsers.DocumentBuilderFactory JavaDoc;
42 import javax.xml.parsers.ParserConfigurationException JavaDoc;
43 import javax.xml.transform.OutputKeys JavaDoc;
44 import javax.xml.transform.Transformer JavaDoc;
45 import javax.xml.transform.TransformerConfigurationException JavaDoc;
46 import javax.xml.transform.TransformerFactory JavaDoc;
47 import javax.xml.transform.TransformerFactoryConfigurationError JavaDoc;
48 import javax.xml.transform.dom.DOMSource JavaDoc;
49 import javax.xml.transform.stream.StreamResult JavaDoc;
50
51 import org.apache.tools.ant.BuildException;
52 import org.java.plugin.registry.PluginDescriptor;
53 import org.java.plugin.registry.PluginFragment;
54 import org.java.plugin.registry.Version;
55 import org.java.plugin.util.IoUtil;
56 import org.w3c.dom.Document JavaDoc;
57 import org.w3c.dom.Element JavaDoc;
58 import org.w3c.dom.NodeList JavaDoc;
59
60 /**
61  * <p>
62  * This class can upgrade all version and plugin-version tags in all plugin
63  * manifest files, to the latest version specified in a text file (in Java
64  * properties format). This class also handles updating the build number in the
65  * specified file.
66  * <p>
67  * This class will only upgrade 'version' and 'plugin-version' tags that already
68  * exist in the manifest files, so it won't add any to the manifest files.
69  * <p>
70  * This class tracks plug-in modification timestamp's and keep them together
71  * with versions info in the given text file. The actual plug-in version will be
72  * upgraded only if plug-in timestamp changes.
73  *
74  * @author Jonathan Giles
75  * @author Dmitry Olshansky
76  */

77 public class VersionUpdateTask extends BaseJpfTask {
78     private File JavaDoc versionsFile;
79     private boolean alterReferences = false;
80     private boolean timestampVersion = false;
81     
82     /**
83      * @param value <code>true</code> if version references should be upgraded
84      */

85     public final void setAlterReferences(final boolean value) {
86         alterReferences = value;
87     }
88
89     /**
90      * @param value file where to store versioning related info
91      */

92     public void setVersionsFile(final File JavaDoc value) {
93         versionsFile = value;
94     }
95     
96     /**
97      * @param value if <code>true</code>, the plug-in timestamp will be included
98      * into version {@link Version#getName() name} attribute
99      */

100     public void setTimestampVersion(final boolean value) {
101         timestampVersion = value;
102     }
103
104     /**
105      * @see org.apache.tools.ant.Task#execute()
106      */

107     public void execute() throws BuildException {
108         log("Starting JPF version updater..."); //$NON-NLS-1$
109
if (versionsFile == null) {
110             throw new BuildException("versionsfile attribute must be set!", //$NON-NLS-1$
111
getLocation());
112         }
113         initRegistry(true);
114         // reading contents of versions file
115
if (getVerbose()) {
116             log("Loading versions file " + versionsFile); //$NON-NLS-1$
117
}
118         Properties JavaDoc versions = new Properties JavaDoc();
119         if (versionsFile.exists()) {
120             try {
121                 InputStream JavaDoc in =
122                     new BufferedInputStream JavaDoc(new FileInputStream JavaDoc(versionsFile));
123                 try {
124                     versions.load(in);
125                 } finally {
126                     in.close();
127                 }
128             } catch (IOException JavaDoc ioe) {
129                 throw new BuildException("failed reading versions file " //$NON-NLS-1$
130
+ versionsFile, ioe, getLocation());
131             }
132         } else {
133             log("Versions file " + versionsFile //$NON-NLS-1$
134
+ " not found, new one will be created."); //$NON-NLS-1$
135
}
136         Map JavaDoc infos = new HashMap JavaDoc();// <plug-in or fragment id, PluginInfo>
137
// collecting manifests
138
for (Iterator JavaDoc it = getRegistry().getPluginDescriptors().iterator();
139                 it.hasNext();) {
140             PluginDescriptor descr = (PluginDescriptor) it.next();
141             File JavaDoc manifestFile = IoUtil.url2file(descr.getLocation());
142             if (manifestFile == null) {
143                 throw new BuildException(
144                         "non-local plug-in manifest URL given " //$NON-NLS-1$
145
+ descr.getLocation());
146             }
147             URL JavaDoc homeUrl = getPathResolver().resolvePath(descr, "/"); //$NON-NLS-1$
148
File JavaDoc homeFile = IoUtil.url2file(homeUrl);
149             if (homeFile == null) {
150                 throw new BuildException(
151                         "non-local plug-in home URL given " //$NON-NLS-1$
152
+ homeUrl);
153             }
154             try {
155                 infos.put(descr.getId(), new PluginInfo(descr.getId(),
156                         versions, manifestFile, homeFile, descr.getVersion()));
157             } catch (ParseException JavaDoc pe) {
158                 throw new BuildException("failed parsing versions data " //$NON-NLS-1$
159
+ " for manifest " + manifestFile, pe, getLocation()); //$NON-NLS-1$
160
}
161             if (getVerbose()) {
162                 log("Collected manifest file " + manifestFile); //$NON-NLS-1$
163
}
164         }
165         for (Iterator JavaDoc it = getRegistry().getPluginFragments().iterator();
166                 it.hasNext();) {
167             PluginFragment descr = (PluginFragment) it.next();
168             File JavaDoc manifestFile = IoUtil.url2file(descr.getLocation());
169             if (manifestFile == null) {
170                 throw new BuildException(
171                         "non-local plug-in fragment manifest URL given " //$NON-NLS-1$
172
+ descr.getLocation());
173             }
174             URL JavaDoc homeUrl = getPathResolver().resolvePath(descr, "/"); //$NON-NLS-1$
175
File JavaDoc homeFile = IoUtil.url2file(homeUrl);
176             if (homeFile == null) {
177                 throw new BuildException(
178                         "non-local plug-in fragment home URL given " //$NON-NLS-1$
179
+ homeUrl);
180             }
181             try {
182                 infos.put(descr.getId(), new PluginInfo(descr.getId(),
183                         versions, manifestFile, homeFile, descr.getVersion()));
184             } catch (ParseException JavaDoc pe) {
185                 throw new BuildException("failed parsing versions data " //$NON-NLS-1$
186
+ " for manifest " + manifestFile, pe, getLocation()); //$NON-NLS-1$
187
}
188             if (getVerbose()) {
189                 log("Populated manifest file " + manifestFile); //$NON-NLS-1$
190
}
191         }
192         // processing manifest versions
193
DocumentBuilderFactory JavaDoc builderFactory = DocumentBuilderFactory.newInstance();
194         builderFactory.setValidating(false);
195         DocumentBuilder JavaDoc builder;
196         try {
197             builder = builderFactory.newDocumentBuilder();
198         } catch (ParserConfigurationException JavaDoc pce) {
199             throw new BuildException("can't obtain XML document builder ", //$NON-NLS-1$
200
pce, getLocation());
201         }
202         if (getVerbose()) {
203             log("Processing versions"); //$NON-NLS-1$
204
}
205         for (Iterator JavaDoc it = infos.values().iterator(); it.hasNext();) {
206             PluginInfo info = (PluginInfo) it.next();
207             try {
208                 info.processVersion(versions, builder, timestampVersion);
209             } catch (Exception JavaDoc e) {
210                 throw new BuildException("failed processing manifest " //$NON-NLS-1$
211
+ info.getManifestFile(), e, getLocation());
212             }
213         }
214         if (alterReferences) {
215             if (getVerbose()) {
216                 log("Processing version references"); //$NON-NLS-1$
217
}
218             for (Iterator JavaDoc it = infos.values().iterator(); it.hasNext();) {
219                 PluginInfo info = (PluginInfo) it.next();
220                 try {
221                     info.processVersionReferences(versions, builder);
222                 } catch (Exception JavaDoc e) {
223                     throw new BuildException("failed processing manifest " //$NON-NLS-1$
224
+ info.getManifestFile(), e, getLocation());
225                 }
226             }
227         }
228         Transformer JavaDoc transformer;
229         try {
230             transformer = TransformerFactory.newInstance().newTransformer();
231         } catch (TransformerConfigurationException JavaDoc tce) {
232             throw new BuildException("can't obtain XML document transformer ", //$NON-NLS-1$
233
tce, getLocation());
234         } catch (TransformerFactoryConfigurationError JavaDoc tfce) {
235             throw new BuildException(
236                     "can't obtain XML document transformer factory ", //$NON-NLS-1$
237
tfce, getLocation());
238         }
239         transformer.setOutputProperty(OutputKeys.METHOD, "xml"); //$NON-NLS-1$
240
transformer.setOutputProperty(OutputKeys.INDENT, "yes"); //$NON-NLS-1$
241
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "no"); //$NON-NLS-1$
242
transformer.setOutputProperty(OutputKeys.STANDALONE, "no"); //$NON-NLS-1$
243
transformer.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC,
244                 "-//JPF//Java Plug-in Manifest 1.0"); //$NON-NLS-1$
245
transformer.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,
246                 "http://jpf.sourceforge.net/plugin_1_0.dtd"); //$NON-NLS-1$
247
if (getVerbose()) {
248             log("Saving manifests"); //$NON-NLS-1$
249
}
250         for (Iterator JavaDoc it = infos.values().iterator(); it.hasNext();) {
251             PluginInfo info = (PluginInfo) it.next();
252             try {
253                 info.save(versions, transformer);
254             } catch (Exception JavaDoc e) {
255                 throw new BuildException("failed saving manifest " //$NON-NLS-1$
256
+ info.getManifestFile(), e, getLocation());
257             }
258         }
259         // saving versions
260
if (getVerbose()) {
261             log("Saving versions file " + versionsFile); //$NON-NLS-1$
262
}
263         try {
264             OutputStream JavaDoc out =
265                 new BufferedOutputStream JavaDoc(new FileOutputStream JavaDoc(versionsFile));
266             try {
267                 versions.store(out, "Plug-in and plug-in fragment versions file"); //$NON-NLS-1$
268
} finally {
269                 out.close();
270             }
271         } catch (IOException JavaDoc ioe) {
272             throw new BuildException("failed writing versions file " //$NON-NLS-1$
273
+ versionsFile, ioe, getLocation());
274         }
275         log("... finished JPF version updater"); //$NON-NLS-1$
276
}
277     
278     static final class PluginInfo {
279         private static Date JavaDoc getTimestamp(final File JavaDoc file,
280                 final Date JavaDoc parentTimestamp) {
281             Date JavaDoc result;
282             if (parentTimestamp == null) {
283                 result = new Date JavaDoc(file.lastModified());
284             } else {
285                 result = new Date JavaDoc(Math.max(parentTimestamp.getTime(),
286                         file.lastModified()));
287             }
288             File JavaDoc[] files = file.listFiles();
289             if (files != null) {
290                 for (int i = 0; i < files.length; i++) {
291                     result = getTimestamp(files[i], result);
292                 }
293             }
294             return result;
295         }
296         
297         private static Version upgradeVersion(final Version ver) {
298             if (ver == null) {
299                 return new Version(0, 0, 1, null);
300             }
301             return new Version(ver.getMajor(), ver.getMinor(),
302                     ver.getBuild() + 1, ver.getName());
303         }
304
305         private static Version upgradeVersion(final Version ver,
306                 final Date JavaDoc timestamp) {
307             DateFormat JavaDoc dtf =
308                 new SimpleDateFormat JavaDoc("yyyyMMddHHmmss", Locale.ENGLISH); //$NON-NLS-1$
309
if (ver == null) {
310                 return new Version(0, 0, 1, dtf.format(timestamp));
311             }
312             return new Version(ver.getMajor(), ver.getMinor(),
313                     ver.getBuild() + 1, dtf.format(timestamp));
314         }
315
316         private final String JavaDoc id;
317         private final File JavaDoc manifestFile;
318         private final Version oldVersion;
319         private final Date JavaDoc oldTimestamp;
320         private final DateFormat JavaDoc dtf =
321             new SimpleDateFormat JavaDoc("yyyy-MM-dd HH:mm:ss", Locale.ENGLISH); //$NON-NLS-1$
322
private Document JavaDoc doc;
323         private Version newVersion;
324         private Date JavaDoc currentTimestamp;
325         
326         PluginInfo(final String JavaDoc anId, final Properties JavaDoc versions,
327                 final File JavaDoc aMnifestFile, final File JavaDoc homeFile,
328                 final Version currentVersion) throws ParseException JavaDoc {
329             id = anId;
330             String JavaDoc versionStr = versions.getProperty(anId, null);
331             String JavaDoc timestampStr = versions.getProperty(anId + ".timestamp", null); //$NON-NLS-1$
332
if (versionStr != null) {
333                 oldVersion = Version.parse(versionStr);
334             } else {
335                 oldVersion = currentVersion;
336             }
337             if (timestampStr != null) {
338                 oldTimestamp = dtf.parse(timestampStr);
339             } else {
340                 oldTimestamp = null;
341             }
342             manifestFile = aMnifestFile;
343             currentTimestamp = getTimestamp(homeFile, null);
344             versions.setProperty(id + ".timestamp", //$NON-NLS-1$
345
dtf.format(currentTimestamp));
346         }
347         
348         File JavaDoc getManifestFile() {
349             return manifestFile;
350         }
351         
352         void processVersion(final Properties JavaDoc versions,
353                 final DocumentBuilder JavaDoc builder, final boolean timestampVersion)
354                 throws Exception JavaDoc {
355             if (IoUtil.compareFileDates(oldTimestamp, currentTimestamp)) {
356                 newVersion = oldVersion;
357             } else {
358                 newVersion = !timestampVersion ? upgradeVersion(oldVersion)
359                         : upgradeVersion(oldVersion, currentTimestamp);
360             }
361             versions.setProperty(id, newVersion.toString());
362             if (oldVersion.equals(newVersion)) {
363                 return;
364             }
365             doc = builder.parse(manifestFile);
366             Element JavaDoc root = doc.getDocumentElement();
367             if (root.hasAttribute("version")) { //$NON-NLS-1$
368
root.setAttribute("version", newVersion.toString()); //$NON-NLS-1$
369
}
370         }
371         
372         void processVersionReferences(final Properties JavaDoc versions,
373                 final DocumentBuilder JavaDoc builder) throws Exception JavaDoc {
374             if (doc == null) {
375                 doc = builder.parse(manifestFile);
376             }
377             Element JavaDoc root = doc.getDocumentElement();
378             if ("plugin-fragment".equals(root.getNodeName())) { //$NON-NLS-1$
379
processVersionReference(versions, root);
380             }
381             NodeList JavaDoc imports = root.getElementsByTagName("import"); //$NON-NLS-1$
382
for (int i = 0; i < imports.getLength(); i++) {
383                 processVersionReference(versions, (Element JavaDoc) imports.item(i));
384             }
385         }
386         
387         private void processVersionReference(final Properties JavaDoc versions,
388                 final Element JavaDoc elm) {
389             if (!elm.hasAttribute("plugin-version")) { //$NON-NLS-1$
390
return;
391             }
392             String JavaDoc version = versions.getProperty(
393                     elm.getAttribute("plugin-id"), id); //$NON-NLS-1$
394
if (version != null) {
395                 elm.setAttribute("plugin-version", version); //$NON-NLS-1$
396
}
397         }
398
399         void save(final Properties JavaDoc versions, final Transformer JavaDoc transformer)
400                 throws Exception JavaDoc {
401             if (doc == null) {
402                 return;
403             }
404             long modified = manifestFile.lastModified();
405             transformer.transform(new DOMSource JavaDoc(doc),
406                     new StreamResult JavaDoc(manifestFile));
407             manifestFile.setLastModified(modified);
408         }
409     }
410 }
411
Popular Tags