001: /*******************************************************************************
002: * Copyright (c) 2000, 2005 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM - Initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.build.tasks;
011:
012: import java.io.*;
013: import java.util.*;
014: import org.apache.tools.ant.BuildException;
015: import org.apache.tools.ant.Task;
016: import org.eclipse.core.runtime.*;
017: import org.eclipse.osgi.util.NLS;
018: import org.eclipse.pde.internal.build.*;
019: import org.eclipse.update.core.Feature;
020: import org.eclipse.update.core.IPluginEntry;
021: import org.eclipse.update.internal.core.FeatureExecutableFactory;
022:
023: /**
024: * Used to create a build manifest file describing what plug-ins and versions
025: * were included in a build. It has to be executed after a fetch task.
026: */
027: public class BuildManifestTask extends Task implements
028: IPDEBuildConstants, IXMLConstants {
029: private String buildId;
030: protected String buildName;
031: private String buildQualifier;
032: private String buildType;
033: protected boolean children = true;
034: protected String destination;
035: protected Properties directory;
036: protected String directoryLocation;
037: protected String[] elements;
038: protected String installLocation;
039:
040: /**
041: * @see org.apache.tools.ant.Task#execute()
042: */
043: public void execute() throws BuildException {
044: try {
045: if (this .elements == null) {
046: String message = TaskMessages.error_missingElement;
047: throw new CoreException(new Status(IStatus.ERROR,
048: PI_PDEBUILD, EXCEPTION_ELEMENT_MISSING,
049: message, null));
050: }
051: readDirectory();
052: PrintWriter output = new PrintWriter(
053: new BufferedOutputStream(new FileOutputStream(
054: destination)));
055: try {
056: List entries = new ArrayList(20);
057: for (int i = 0; i < elements.length; i++)
058: collectEntries(entries, elements[i]);
059: generatePrologue(output);
060: generateEntries(output, entries);
061: } finally {
062: output.close();
063: }
064: } catch (Exception e) {
065: throw new BuildException(e);
066: }
067: }
068:
069: /**
070: *
071: * @param output
072: */
073: protected void generatePrologue(PrintWriter output) {
074: output.print("# Build Manifest for "); //$NON-NLS-1$
075: output.println(buildName);
076: output.println();
077: output.println("# The format of this file is:"); //$NON-NLS-1$
078: output.println("# <type>@<element>=<CVS tag>"); //$NON-NLS-1$
079: output.println();
080: String id = getBuildId();
081: if (id != null) {
082: output.print(PROPERTY_BUILD_ID + "="); //$NON-NLS-1$
083: output.println(id);
084: }
085: String type = getBuildType();
086: if (type != null) {
087: output.print(PROPERTY_BUILD_TYPE + "="); //$NON-NLS-1$
088: output.println(type);
089: }
090: String qualifier = getBuildQualifier();
091: if (qualifier != null) {
092: output.print(PROPERTY_BUILD_QUALIFIER + "="); //$NON-NLS-1$
093: output.println(qualifier);
094: }
095: output.println();
096: }
097:
098: /**
099: *
100: * @return String
101: */
102: protected String getBuildId() {
103: if (buildId == null)
104: buildId = getProject().getProperty(PROPERTY_BUILD_ID);
105: return buildId;
106: }
107:
108: /**
109: *
110: * @return String
111: */
112: protected String getBuildQualifier() {
113: if (buildQualifier == null)
114: buildQualifier = getProject().getProperty(
115: PROPERTY_BUILD_QUALIFIER);
116: return buildQualifier;
117: }
118:
119: /**
120: *
121: * @return String
122: */
123: protected String getBuildType() {
124: if (buildType == null)
125: buildType = getProject().getProperty(PROPERTY_BUILD_TYPE);
126: return buildType;
127: }
128:
129: /**
130: *
131: * @param output
132: * @param entries
133: */
134: protected void generateEntries(PrintWriter output, List entries) {
135: Collections.sort(entries);
136: for (Iterator iterator = entries.iterator(); iterator.hasNext();) {
137: String entry = (String) iterator.next();
138: output.println(entry);
139: }
140: }
141:
142: /**
143: * Collects all the elements that are part of this build.
144: */
145: protected void collectEntries(List entries, String entry)
146: throws CoreException {
147: String cvsInfo = directory.getProperty(entry);
148: if (cvsInfo == null) {
149: String message = NLS.bind(
150: TaskMessages.error_missingDirectoryEntry, entry);
151: throw new CoreException(
152: new Status(IStatus.ERROR, PI_PDEBUILD,
153: EXCEPTION_ENTRY_MISSING, message, null));
154: }
155:
156: int index = entry.indexOf('@');
157: String type = entry.substring(0, index);
158: String element = entry.substring(index + 1);
159: if (type.equals("plugin") || type.equals("fragment")) { //$NON-NLS-1$ //$NON-NLS-2$
160: String[] cvsFields = Utils.getArrayFromString(cvsInfo);
161: String tag = cvsFields[0];
162: StringBuffer sb = new StringBuffer();
163: sb.append(entry);
164: sb.append("="); //$NON-NLS-1$
165: sb.append(tag);
166: entries.add(sb.toString());
167: } else if (children && type.equals("feature")) { //$NON-NLS-1$
168: Feature feature = readFeature(element);
169: collectChildrenEntries(entries, feature);
170: }
171: }
172:
173: /**
174: *
175: * @param entries
176: * @param feature
177: * @throws CoreException
178: */
179: protected void collectChildrenEntries(List entries, Feature feature)
180: throws CoreException {
181: IPluginEntry[] pluginEntries = feature.getPluginEntries();
182: for (int i = 0; i < pluginEntries.length; i++) {
183: String elementId = pluginEntries[i]
184: .getVersionedIdentifier().getIdentifier();
185: if (pluginEntries[i].isFragment())
186: collectEntries(entries, "fragment@" + elementId); //$NON-NLS-1$
187: else
188: collectEntries(entries, "plugin@" + elementId); //$NON-NLS-1$
189: }
190: }
191:
192: /**
193: *
194: * @param element
195: * @return Feature
196: * @throws CoreException
197: */
198: protected Feature readFeature(String element) throws CoreException {
199: IPath root = new Path(installLocation);
200: root = root.append(DEFAULT_FEATURE_LOCATION);
201: root = root.append(element);
202: try {
203: FeatureExecutableFactory factory = new FeatureExecutableFactory();
204: return (Feature) factory.createFeature(root.toFile()
205: .toURL(), null, null);
206: } catch (Exception e) {
207: String message = NLS.bind(
208: TaskMessages.error_creatingFeature, element);
209: throw new CoreException(new Status(IStatus.ERROR,
210: PI_PDEBUILD, EXCEPTION_FEATURE_MISSING, message, e));
211: }
212: }
213:
214: /**
215: * Sets the installLocation.
216: */
217: public void setInstall(String installLocation) {
218: this .installLocation = installLocation;
219: }
220:
221: /**
222: * Reads directory file at the directoryLocation.
223: */
224: protected void readDirectory() throws CoreException {
225: try {
226: directory = new Properties();
227: File file = new File(directoryLocation);
228: InputStream is = new BufferedInputStream(
229: new FileInputStream(file));
230: try {
231: directory.load(is);
232: } finally {
233: is.close();
234: }
235: } catch (IOException e) {
236: String message = NLS.bind(
237: TaskMessages.error_readingDirectory,
238: directoryLocation);
239: throw new CoreException(new Status(IStatus.ERROR,
240: PI_PDEBUILD, EXCEPTION_READ_DIRECTORY, message, e));
241: }
242: }
243:
244: /**
245: *
246: * @param directory
247: */
248: public void setDirectory(String directory) {
249: directoryLocation = directory;
250: }
251:
252: /**
253: *
254: * @param value
255: */
256: public void setElements(String value) {
257: elements = Utils.getArrayFromString(value);
258: }
259:
260: /**
261: * Sets the full location of the manifest file.
262: */
263: public void setDestination(String value) {
264: destination = value;
265: }
266:
267: /**
268: * Whether children of this element should be taken into account.
269: */
270: public void setChildren(boolean children) {
271: this .children = children;
272: }
273:
274: /**
275: *
276: * @param value
277: */
278: public void setBuildName(String value) {
279: buildName = value;
280: }
281:
282: /**
283: * Sets the buildId.
284: */
285: public void setBuildId(String buildId) {
286: this .buildId = buildId;
287: }
288:
289: /**
290: * Sets the buildQualifier.
291: */
292: public void setBuildQualifier(String buildQualifier) {
293: this .buildQualifier = buildQualifier;
294: }
295:
296: /**
297: * Sets the buildType.
298: */
299: public void setBuildType(String buildType) {
300: this.buildType = buildType;
301: }
302:
303: }
|