source: other-projects/trunk/gs3-release-maker/apache-ant-1.6.5/src/main/org/apache/tools/ant/taskdefs/optional/extension/JarLibManifestTask.java@ 14627

Last change on this file since 14627 was 14627, checked in by oranfry, 17 years ago

initial import of the gs3-release-maker

File size: 10.7 KB
Line 
1/*
2 * Copyright 2002-2004 The Apache Software Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 *
16 */
17package org.apache.tools.ant.taskdefs.optional.extension;
18
19import java.io.File;
20import java.io.FileOutputStream;
21import java.io.IOException;
22import java.util.ArrayList;
23import java.util.Iterator;
24import java.util.jar.Attributes;
25import java.util.jar.Manifest;
26import org.apache.tools.ant.BuildException;
27import org.apache.tools.ant.Project;
28import org.apache.tools.ant.Task;
29
30/**
31 * Generates a manifest that declares all the dependencies.
32 * The dependencies are determined by looking in the
33 * specified path and searching for Extension / "Optional Package"
34 * specifications in the manifests of the jars.
35 *
36 * <p>Prior to JDK1.3, an "Optional Package" was known as an Extension.
37 * The specification for this mechanism is available in the JDK1.3
38 * documentation in the directory
39 * $JDK_HOME/docs/guide/extensions/versioning.html. Alternatively it is
40 * available online at <a href="http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html">
41 * http://java.sun.com/j2se/1.3/docs/guide/extensions/versioning.html</a>.</p>
42 *
43 * @ant.task name="jarlib-manifest"
44 */
45public final class JarLibManifestTask extends Task {
46 /**
47 * Version of manifest spec that task generates.
48 */
49 private static final String MANIFEST_VERSION = "1.0";
50
51 /**
52 * "Created-By" string used when creating manifest.
53 */
54 private static final String CREATED_BY = "Created-By";
55
56 /**
57 * The library to display information about.
58 */
59 private File destFile;
60
61 /**
62 * The extension supported by this library (if any).
63 */
64 private Extension extension;
65
66 /**
67 * ExtensionAdapter objects representing
68 * dependencies required by library.
69 */
70 private final ArrayList dependencies = new ArrayList();
71
72 /**
73 * ExtensionAdapter objects representing optional
74 * dependencies required by library.
75 */
76 private final ArrayList optionals = new ArrayList();
77
78 /**
79 * Extra attributes the user specifies for main section
80 * in manifest.
81 */
82 private final ArrayList extraAttributes = new ArrayList();
83
84 /**
85 * The location where generated manifest is placed.
86 *
87 * @param destFile The location where generated manifest is placed.
88 */
89 public void setDestfile(final File destFile) {
90 this.destFile = destFile;
91 }
92
93 /**
94 * Adds an extension that this library implements.
95 *
96 * @param extensionAdapter an extension that this library implements.
97 *
98 * @throws BuildException if there is multiple extensions detected
99 * in the library.
100 */
101 public void addConfiguredExtension(final ExtensionAdapter extensionAdapter)
102 throws BuildException {
103 if (null != extension) {
104 final String message =
105 "Can not have multiple extensions defined in one library.";
106 throw new BuildException(message);
107 } else {
108 extension = extensionAdapter.toExtension();
109 }
110 }
111
112 /**
113 * Adds a set of extensions that this library requires.
114 *
115 * @param extensionSet a set of extensions that this library requires.
116 */
117 public void addConfiguredDepends(final ExtensionSet extensionSet) {
118 dependencies.add(extensionSet);
119 }
120
121 /**
122 * Adds a set of extensions that this library optionally requires.
123 *
124 * @param extensionSet a set of extensions that this library optionally requires.
125 */
126 public void addConfiguredOptions(final ExtensionSet extensionSet) {
127 optionals.add(extensionSet);
128 }
129
130 /**
131 * Adds an attribute that is to be put in main section of manifest.
132 *
133 * @param attribute an attribute that is to be put in main section of manifest.
134 */
135 public void addConfiguredAttribute(final ExtraAttribute attribute) {
136 extraAttributes.add(attribute);
137 }
138
139 /**
140 * Execute the task.
141 *
142 * @throws BuildException if the task fails.
143 */
144 public void execute() throws BuildException {
145 validate();
146
147 final Manifest manifest = new Manifest();
148 final Attributes attributes = manifest.getMainAttributes();
149
150 attributes.put(Attributes.Name.MANIFEST_VERSION, MANIFEST_VERSION);
151 final String createdBy = "Apache Ant " + getProject().getProperty("ant.version");
152 attributes.putValue(CREATED_BY, createdBy);
153
154 appendExtraAttributes(attributes);
155
156 if (null != extension) {
157 Extension.addExtension(extension, attributes);
158 }
159
160 //Add all the dependency data to manifest for dependencies
161 final ArrayList depends = toExtensions(dependencies);
162 appendExtensionList(attributes,
163 Extension.EXTENSION_LIST,
164 "lib",
165 depends.size());
166 appendLibraryList(attributes, "lib", depends);
167
168 //Add all the dependency data to manifest for "optional"
169 //dependencies
170 final ArrayList option = toExtensions(optionals);
171 appendExtensionList(attributes,
172 Extension.OPTIONAL_EXTENSION_LIST,
173 "opt",
174 option.size());
175 appendLibraryList(attributes, "opt", option);
176
177 try {
178 final String message = "Generating manifest " + destFile.getAbsoluteFile();
179 log(message, Project.MSG_INFO);
180 writeManifest(manifest);
181 } catch (final IOException ioe) {
182 throw new BuildException(ioe.getMessage(), ioe);
183 }
184 }
185
186 /**
187 * Validate the tasks parameters.
188 *
189 * @throws BuildException if invalid parameters found
190 */
191 private void validate() throws BuildException {
192 if (null == destFile) {
193 final String message = "Destfile attribute not specified.";
194 throw new BuildException(message);
195 }
196 if (destFile.exists() && !destFile.isFile()) {
197 final String message = destFile + " is not a file.";
198 throw new BuildException(message);
199 }
200 }
201
202 /**
203 * Add any extra attributes to the manifest.
204 *
205 * @param attributes the manifest section to write
206 * attributes to
207 */
208 private void appendExtraAttributes(final Attributes attributes) {
209 final Iterator iterator = extraAttributes.iterator();
210 while (iterator.hasNext()) {
211 final ExtraAttribute attribute =
212 (ExtraAttribute) iterator.next();
213 attributes.putValue(attribute.getName(),
214 attribute.getValue());
215 }
216 }
217
218 /**
219 * Write out manifest to destfile.
220 *
221 * @param manifest the manifest
222 * @throws IOException if error writing file
223 */
224 private void writeManifest(final Manifest manifest)
225 throws IOException {
226 FileOutputStream output = null;
227 try {
228 output = new FileOutputStream(destFile);
229 manifest.write(output);
230 output.flush();
231 } finally {
232 if (null != output) {
233 try {
234 output.close();
235 } catch (IOException e) {
236 // ignore
237 }
238 }
239 }
240 }
241
242 /**
243 * Append specified extensions to specified attributes.
244 * Use the extensionKey to list the extensions, usually "Extension-List:"
245 * for required dependencies and "Optional-Extension-List:" for optional
246 * dependencies. NOTE: "Optional" dependencies are not part of the
247 * specification.
248 *
249 * @param attributes the attributes to add extensions to
250 * @param extensions the list of extensions
251 * @throws BuildException if an error occurs
252 */
253 private void appendLibraryList(final Attributes attributes,
254 final String listPrefix,
255 final ArrayList extensions)
256 throws BuildException {
257 final int size = extensions.size();
258 for (int i = 0; i < size; i++) {
259 final Extension extension = (Extension) extensions.get(i);
260 final String prefix = listPrefix + i + "-";
261 Extension.addExtension(extension, prefix, attributes);
262 }
263 }
264
265 /**
266 * Append an attribute such as "Extension-List: lib0 lib1 lib2"
267 * using specified prefix and counting up to specified size.
268 * Also use specified extensionKey so that can generate list of
269 * optional dependencies aswell.
270 *
271 * @param size the number of librarys to list
272 * @param listPrefix the prefix for all librarys
273 * @param attributes the attributes to add key-value to
274 * @param extensionKey the key to use
275 */
276 private void appendExtensionList(final Attributes attributes,
277 final Attributes.Name extensionKey,
278 final String listPrefix,
279 final int size) {
280 final StringBuffer sb = new StringBuffer();
281 for (int i = 0; i < size; i++) {
282 sb.append(listPrefix + i);
283 sb.append(' ');
284 }
285
286 //add in something like
287 //"Extension-List: javahelp java3d"
288 attributes.put(extensionKey, sb.toString());
289 }
290
291 /**
292 * Convert a list of ExtensionSet objects to extensions.
293 *
294 * @param extensionSets the list of ExtensionSets to add to list
295 * @throws BuildException if an error occurs
296 */
297 private ArrayList toExtensions(final ArrayList extensionSets)
298 throws BuildException {
299 final ArrayList results = new ArrayList();
300
301 final int size = extensionSets.size();
302 for (int i = 0; i < size; i++) {
303 final ExtensionSet set = (ExtensionSet) extensionSets.get(i);
304 final Extension[] extensions = set.toExtensions(getProject());
305 for (int j = 0; j < extensions.length; j++) {
306 results.add(extensions[ j ]);
307 }
308 }
309
310 return results;
311 }
312}
Note: See TracBrowser for help on using the repository browser.