001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. 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: * $Header:$
018: */
019: package org.apache.beehive.controls.runtime.packaging;
020:
021: import java.io.File;
022: import java.io.FileInputStream;
023: import java.io.InputStreamReader;
024: import java.io.IOException;
025: import java.util.List;
026: import java.util.Map;
027: import java.util.Vector;
028:
029: import org.apache.tools.ant.BuildException;
030: import org.apache.tools.ant.taskdefs.Jar;
031: import org.apache.tools.ant.taskdefs.Manifest;
032: import org.apache.tools.ant.taskdefs.ManifestException;
033: import org.apache.tools.ant.types.Resource;
034: import org.apache.tools.ant.types.FileSet;
035: import org.apache.tools.ant.util.FileUtils;
036: import org.apache.tools.zip.ZipOutputStream;
037:
038: /**
039: * The ControlTask class extends the standard ant Jar task to perform
040: * additional processing for JAR files that contain Beehive Controls.
041: */
042: public class ControlJarTask extends Jar {
043: private static FileUtils fileUtils = FileUtils.newFileUtils();
044:
045: /**
046: * Step #1: Wrap the implementation of Zip.grabResources. This method identifies the
047: * set of resources to be stored in the JAR file. For each added/updated resource,
048: * the overrided method will look for an associated .manifest file that any
049: * JAR manifest data to add/update in the JAR manifest.
050: */
051: protected Resource[][] grabResources(FileSet[] filesets) {
052: //
053: // Get the list of resources being added/updated by calling Zip.grabResources
054: //
055: Resource[][] resources = super .grabResources(filesets);
056:
057: //
058: // Iterate through the resources for each input FileSet, looking for an associated
059: // manifest file.
060: //
061: for (int i = 0; i < filesets.length; i++) {
062: if (resources[i].length == 0)
063: continue;
064:
065: File base = filesets[i].getDir(getProject());
066: Resource[] setResources = resources[i];
067:
068: for (int j = 0; j < setResources.length; j++) {
069: File manifestFile = fileUtils.resolveFile(base,
070: setResources[j].getName() + ".manifest");
071: if (manifestFile.exists())
072: manifestFiles.add(manifestFile);
073: }
074: }
075:
076: return resources;
077: }
078:
079: /**
080: * Step #2: Override Jar.initZipOutputStream to inject manifest sections. This is done
081: * by treating them as if they were 'inline' entries, from a <jar> task perspective.
082: */
083: protected void initZipOutputStream(ZipOutputStream zOut)
084: throws IOException, BuildException {
085: if (manifestFiles.size() != 0) {
086: //
087: // Create a default (empty) manifest
088: //
089: Manifest mergeManifest = Manifest.getDefaultManifest();
090:
091: //
092: // Iterate through each found manifest file, merging its contents into the
093: // merge manifest
094: //
095: for (File manifestFile : manifestFiles) {
096: FileInputStream fis = null;
097: try {
098: fis = new FileInputStream(manifestFile);
099: Manifest resourceManifest = new Manifest(
100: new InputStreamReader(fis));
101: mergeManifest.merge(resourceManifest);
102: } catch (IOException ioe) {
103: throw new BuildException(
104: "Unable to read manifest file:"
105: + manifestFile, ioe);
106: } catch (ManifestException me) {
107: throw new BuildException(
108: "Unable to process manifest file: "
109: + manifestFile, me);
110: } finally {
111: if (fis != null)
112: fis.close();
113: }
114: }
115:
116: //
117: // Set the merge manifest as the 'configured' manifest. This will treat its
118: // contents as if they had been included inline with the <jar> task, with
119: // similar precedence rules.
120: //
121: try {
122: addConfiguredManifest(mergeManifest);
123: } catch (ManifestException me) {
124: throw new BuildException(
125: "Unable to add new manifest entries:" + me);
126: }
127: }
128:
129: super .initZipOutputStream(zOut);
130: }
131:
132: protected void addToManifest(Manifest jarManifest,
133: List<File> mergeList) {
134: }
135:
136: /**
137: * Reset the manifest file list to be empty
138: */
139: protected void cleanUp() {
140: manifestFiles = new Vector<File>();
141: }
142:
143: /**
144: * Contains the set of manifest entries to merge into the JAR manifest
145: */
146: private List<File> manifestFiles = new Vector<File>();
147: }
|