KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > tools > ant > taskdefs > optional > extension > JarLibManifestTask


1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  */

18 package org.apache.tools.ant.taskdefs.optional.extension;
19
20 import java.io.File JavaDoc;
21 import java.io.FileOutputStream JavaDoc;
22 import java.io.IOException JavaDoc;
23 import java.util.ArrayList JavaDoc;
24 import java.util.Iterator JavaDoc;
25 import java.util.jar.Attributes JavaDoc;
26 import java.util.jar.Manifest JavaDoc;
27 import org.apache.tools.ant.BuildException;
28 import org.apache.tools.ant.MagicNames;
29 import org.apache.tools.ant.Project;
30 import org.apache.tools.ant.Task;
31
32 /**
33  * Generates a manifest that declares all the dependencies.
34  * The dependencies are determined by looking in the
35  * specified path and searching for Extension / "Optional Package"
36  * specifications in the manifests of the jars.
37  *
38  * <p>Prior to JDK1.3, an "Optional Package" was known as an Extension.
39  * The specification for this mechanism is available in the JDK1.3
40  * documentation in the directory
41  * $JDK_HOME/docs/guide/extensions/versioning.html. Alternatively it is
42  * available online at <a HREF="http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html">
43  * http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html</a>.</p>
44  *
45  * @ant.task name="jarlib-manifest"
46  */

47 public final class JarLibManifestTask extends Task {
48     /**
49      * Version of manifest spec that task generates.
50      */

51     private static final String JavaDoc MANIFEST_VERSION = "1.0";
52
53     /**
54      * "Created-By" string used when creating manifest.
55      */

56     private static final String JavaDoc CREATED_BY = "Created-By";
57
58     /**
59      * The library to display information about.
60      */

61     private File JavaDoc destFile;
62
63     /**
64      * The extension supported by this library (if any).
65      */

66     private Extension extension;
67
68     /**
69      * ExtensionAdapter objects representing
70      * dependencies required by library.
71      */

72     private final ArrayList JavaDoc dependencies = new ArrayList JavaDoc();
73
74     /**
75      * ExtensionAdapter objects representing optional
76      * dependencies required by library.
77      */

78     private final ArrayList JavaDoc optionals = new ArrayList JavaDoc();
79
80     /**
81      * Extra attributes the user specifies for main section
82      * in manifest.
83      */

84     private final ArrayList JavaDoc extraAttributes = new ArrayList JavaDoc();
85
86     /**
87      * The location where generated manifest is placed.
88      *
89      * @param destFile The location where generated manifest is placed.
90      */

91     public void setDestfile(final File JavaDoc destFile) {
92         this.destFile = destFile;
93     }
94
95     /**
96      * Adds an extension that this library implements.
97      *
98      * @param extensionAdapter an extension that this library implements.
99      *
100      * @throws BuildException if there is multiple extensions detected
101      * in the library.
102      */

103     public void addConfiguredExtension(final ExtensionAdapter extensionAdapter)
104         throws BuildException {
105         if (null != extension) {
106             final String JavaDoc message =
107                 "Can not have multiple extensions defined in one library.";
108             throw new BuildException(message);
109         }
110         extension = extensionAdapter.toExtension();
111     }
112
113     /**
114      * Adds a set of extensions that this library requires.
115      *
116      * @param extensionSet a set of extensions that this library requires.
117      */

118     public void addConfiguredDepends(final ExtensionSet extensionSet) {
119         dependencies.add(extensionSet);
120     }
121
122     /**
123      * Adds a set of extensions that this library optionally requires.
124      *
125      * @param extensionSet a set of extensions that this library optionally requires.
126      */

127     public void addConfiguredOptions(final ExtensionSet extensionSet) {
128         optionals.add(extensionSet);
129     }
130
131     /**
132      * Adds an attribute that is to be put in main section of manifest.
133      *
134      * @param attribute an attribute that is to be put in main section of manifest.
135      */

136     public void addConfiguredAttribute(final ExtraAttribute attribute) {
137         extraAttributes.add(attribute);
138     }
139
140     /**
141      * Execute the task.
142      *
143      * @throws BuildException if the task fails.
144      */

145     public void execute() throws BuildException {
146         validate();
147
148         final Manifest JavaDoc manifest = new Manifest JavaDoc();
149         final Attributes JavaDoc attributes = manifest.getMainAttributes();
150
151         attributes.put(Attributes.Name.MANIFEST_VERSION, MANIFEST_VERSION);
152         final String JavaDoc createdBy = "Apache Ant " + getProject().getProperty(MagicNames.ANT_VERSION);
153         attributes.putValue(CREATED_BY, createdBy);
154
155         appendExtraAttributes(attributes);
156
157         if (null != extension) {
158             Extension.addExtension(extension, attributes);
159         }
160
161         //Add all the dependency data to manifest for dependencies
162
final ArrayList JavaDoc depends = toExtensions(dependencies);
163         appendExtensionList(attributes,
164                              Extension.EXTENSION_LIST,
165                              "lib",
166                              depends.size());
167         appendLibraryList(attributes, "lib", depends);
168
169         //Add all the dependency data to manifest for "optional"
170
//dependencies
171
final ArrayList JavaDoc option = toExtensions(optionals);
172         appendExtensionList(attributes,
173                              Extension.OPTIONAL_EXTENSION_LIST,
174                              "opt",
175                              option.size());
176         appendLibraryList(attributes, "opt", option);
177
178         try {
179             final String JavaDoc message = "Generating manifest " + destFile.getAbsoluteFile();
180             log(message, Project.MSG_INFO);
181             writeManifest(manifest);
182         } catch (final IOException JavaDoc ioe) {
183             throw new BuildException(ioe.getMessage(), ioe);
184         }
185     }
186
187     /**
188      * Validate the tasks parameters.
189      *
190      * @throws BuildException if invalid parameters found
191      */

192     private void validate() throws BuildException {
193         if (null == destFile) {
194             final String JavaDoc message = "Destfile attribute not specified.";
195             throw new BuildException(message);
196         }
197         if (destFile.exists() && !destFile.isFile()) {
198             final String JavaDoc message = destFile + " is not a file.";
199             throw new BuildException(message);
200         }
201     }
202
203     /**
204      * Add any extra attributes to the manifest.
205      *
206      * @param attributes the manifest section to write
207      * attributes to
208      */

209     private void appendExtraAttributes(final Attributes JavaDoc attributes) {
210         final Iterator JavaDoc iterator = extraAttributes.iterator();
211         while (iterator.hasNext()) {
212             final ExtraAttribute attribute =
213                 (ExtraAttribute) iterator.next();
214             attributes.putValue(attribute.getName(),
215                                  attribute.getValue());
216         }
217     }
218
219     /**
220      * Write out manifest to destfile.
221      *
222      * @param manifest the manifest
223      * @throws IOException if error writing file
224      */

225     private void writeManifest(final Manifest JavaDoc manifest)
226         throws IOException JavaDoc {
227         FileOutputStream JavaDoc output = null;
228         try {
229             output = new FileOutputStream JavaDoc(destFile);
230             manifest.write(output);
231             output.flush();
232         } finally {
233             if (null != output) {
234                 try {
235                     output.close();
236                 } catch (IOException JavaDoc e) {
237                     // ignore
238
}
239             }
240         }
241     }
242
243     /**
244      * Append specified extensions to specified attributes.
245      * Use the extensionKey to list the extensions, usually "Extension-List:"
246      * for required dependencies and "Optional-Extension-List:" for optional
247      * dependencies. NOTE: "Optional" dependencies are not part of the
248      * specification.
249      *
250      * @param attributes the attributes to add extensions to
251      * @param extensions the list of extensions
252      * @throws BuildException if an error occurs
253      */

254     private void appendLibraryList(final Attributes JavaDoc attributes,
255                                     final String JavaDoc listPrefix,
256                                     final ArrayList JavaDoc extensions)
257         throws BuildException {
258         final int size = extensions.size();
259         for (int i = 0; i < size; i++) {
260             final Extension ext = (Extension) extensions.get(i);
261             final String JavaDoc prefix = listPrefix + i + "-";
262             Extension.addExtension(ext, prefix, attributes);
263         }
264     }
265
266     /**
267      * Append an attribute such as "Extension-List: lib0 lib1 lib2"
268      * using specified prefix and counting up to specified size.
269      * Also use specified extensionKey so that can generate list of
270      * optional dependencies aswell.
271      *
272      * @param size the number of librarys to list
273      * @param listPrefix the prefix for all librarys
274      * @param attributes the attributes to add key-value to
275      * @param extensionKey the key to use
276      */

277     private void appendExtensionList(final Attributes JavaDoc attributes,
278                                       final Attributes.Name JavaDoc extensionKey,
279                                       final String JavaDoc listPrefix,
280                                       final int size) {
281         final StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
282         for (int i = 0; i < size; i++) {
283             sb.append(listPrefix);
284             sb.append(i);
285             sb.append(' ');
286         }
287
288         //add in something like
289
//"Extension-List: javahelp java3d"
290
attributes.put(extensionKey, sb.toString());
291     }
292
293     /**
294      * Convert a list of ExtensionSet objects to extensions.
295      *
296      * @param extensionSets the list of ExtensionSets to add to list
297      * @throws BuildException if an error occurs
298      */

299     private ArrayList JavaDoc toExtensions(final ArrayList JavaDoc extensionSets)
300         throws BuildException {
301         final ArrayList JavaDoc results = new ArrayList JavaDoc();
302
303         final int size = extensionSets.size();
304         for (int i = 0; i < size; i++) {
305             final ExtensionSet set = (ExtensionSet) extensionSets.get(i);
306             final Extension[] extensions = set.toExtensions(getProject());
307             for (int j = 0; j < extensions.length; j++) {
308                 results.add(extensions[ j ]);
309             }
310         }
311
312         return results;
313     }
314 }
315
Popular Tags