001: /*******************************************************************************
002: * Copyright (c) 2006, 2007 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 Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.pde.internal.core.exports;
011:
012: import java.io.File;
013: import java.io.FileOutputStream;
014: import java.io.IOException;
015: import java.lang.reflect.InvocationTargetException;
016: import java.net.MalformedURLException;
017: import java.net.URL;
018: import java.util.Dictionary;
019: import java.util.HashMap;
020: import java.util.Hashtable;
021: import java.util.List;
022: import java.util.ListIterator;
023: import java.util.Map;
024: import java.util.Properties;
025:
026: import javax.xml.parsers.DocumentBuilderFactory;
027: import javax.xml.parsers.FactoryConfigurationError;
028: import javax.xml.parsers.ParserConfigurationException;
029:
030: import org.eclipse.ant.core.AntCorePlugin;
031: import org.eclipse.ant.core.AntCorePreferences;
032: import org.eclipse.ant.core.AntRunner;
033: import org.eclipse.ant.core.IAntClasspathEntry;
034: import org.eclipse.ant.core.Property;
035: import org.eclipse.core.resources.IFile;
036: import org.eclipse.core.resources.IWorkspaceRunnable;
037: import org.eclipse.core.runtime.CoreException;
038: import org.eclipse.core.runtime.IPath;
039: import org.eclipse.core.runtime.IProgressMonitor;
040: import org.eclipse.core.runtime.IStatus;
041: import org.eclipse.core.runtime.OperationCanceledException;
042: import org.eclipse.core.runtime.Path;
043: import org.eclipse.core.runtime.Platform;
044: import org.eclipse.core.runtime.Preferences;
045: import org.eclipse.core.runtime.Status;
046: import org.eclipse.core.runtime.SubProgressMonitor;
047: import org.eclipse.jdt.core.JavaCore;
048: import org.eclipse.jdt.launching.JavaRuntime;
049: import org.eclipse.jdt.launching.environments.IExecutionEnvironment;
050: import org.eclipse.jdt.launching.environments.IExecutionEnvironmentsManager;
051: import org.eclipse.osgi.service.resolver.BundleDescription;
052: import org.eclipse.osgi.service.resolver.State;
053: import org.eclipse.pde.core.IModel;
054: import org.eclipse.pde.core.build.IBuild;
055: import org.eclipse.pde.core.build.IBuildEntry;
056: import org.eclipse.pde.core.build.IBuildModel;
057: import org.eclipse.pde.core.plugin.IPluginModelBase;
058: import org.eclipse.pde.core.plugin.PluginRegistry;
059: import org.eclipse.pde.core.plugin.TargetPlatform;
060: import org.eclipse.pde.internal.build.AbstractScriptGenerator;
061: import org.eclipse.pde.internal.build.BuildScriptGenerator;
062: import org.eclipse.pde.internal.build.IXMLConstants;
063: import org.eclipse.pde.internal.build.site.QualifierReplacer;
064: import org.eclipse.pde.internal.core.ClasspathHelper;
065: import org.eclipse.pde.internal.core.PDECore;
066: import org.eclipse.pde.internal.core.PDECoreMessages;
067: import org.eclipse.pde.internal.core.TargetPlatformHelper;
068: import org.eclipse.pde.internal.core.XMLPrintHandler;
069: import org.eclipse.pde.internal.core.build.WorkspaceBuildModel;
070: import org.eclipse.pde.internal.core.feature.FeatureChild;
071: import org.eclipse.pde.internal.core.ifeature.IFeature;
072: import org.eclipse.pde.internal.core.ifeature.IFeatureChild;
073: import org.eclipse.pde.internal.core.ifeature.IFeatureModel;
074: import org.eclipse.pde.internal.core.ifeature.IFeaturePlugin;
075: import org.eclipse.pde.internal.core.util.CoreUtility;
076: import org.osgi.framework.InvalidSyntaxException;
077: import org.w3c.dom.DOMException;
078: import org.w3c.dom.Document;
079: import org.w3c.dom.Element;
080:
081: import com.ibm.icu.util.Calendar;
082:
083: public class FeatureExportOperation implements IWorkspaceRunnable {
084:
085: // write to the ant build listener log
086: private static boolean fHasErrors;
087:
088: // Location where the build takes place
089: protected String fBuildTempLocation;
090: private String fDevProperties;
091:
092: protected HashMap fAntBuildProperties;
093:
094: protected State fStateCopy;
095:
096: protected static String FEATURE_POST_PROCESSING = "features.postProcessingSteps.properties"; //$NON-NLS-1$
097: protected static String PLUGIN_POST_PROCESSING = "plugins.postProcessingSteps.properties"; //$NON-NLS-1$
098:
099: public static String getDate() {
100: final String empty = ""; //$NON-NLS-1$
101: int monthNbr = Calendar.getInstance().get(Calendar.MONTH) + 1;
102: String month = (monthNbr < 10 ? "0" : empty) + monthNbr; //$NON-NLS-1$
103:
104: int dayNbr = Calendar.getInstance().get(Calendar.DAY_OF_MONTH);
105: String day = (dayNbr < 10 ? "0" : empty) + dayNbr; //$NON-NLS-1$
106:
107: int hourNbr = Calendar.getInstance().get(Calendar.HOUR_OF_DAY);
108: String hour = (hourNbr < 10 ? "0" : empty) + hourNbr; //$NON-NLS-1$
109:
110: int minuteNbr = Calendar.getInstance().get(Calendar.MINUTE);
111: String minute = (minuteNbr < 10 ? "0" : empty) + minuteNbr; //$NON-NLS-1$
112:
113: return empty + Calendar.getInstance().get(Calendar.YEAR)
114: + month + day + hour + minute;
115: }
116:
117: protected FeatureExportInfo fInfo;
118:
119: public FeatureExportOperation(FeatureExportInfo info) {
120: fInfo = info;
121: String qualifier = info.qualifier;
122: if (qualifier == null)
123: qualifier = getDate();
124: QualifierReplacer.setGlobalQualifier(qualifier);
125: fBuildTempLocation = PDECore.getDefault().getStateLocation()
126: .append("temp").toString(); //$NON-NLS-1$
127: }
128:
129: public void run(IProgressMonitor monitor) throws CoreException {
130: try {
131: createDestination();
132: String[][] configurations = fInfo.targets;
133: if (configurations == null)
134: configurations = new String[][] { null };
135:
136: monitor
137: .beginTask(
138: "", configurations.length * fInfo.items.length * 10); //$NON-NLS-1$
139: for (int i = 0; i < configurations.length; i++) {
140: for (int j = 0; j < fInfo.items.length; j++) {
141: if (monitor.isCanceled())
142: throw new OperationCanceledException();
143: try {
144: doExport((IFeatureModel) fInfo.items[j],
145: configurations[i],
146: new SubProgressMonitor(monitor, 9));
147: } finally {
148: cleanup(configurations[i],
149: new SubProgressMonitor(monitor, 1));
150: }
151: }
152: }
153: } catch (InvocationTargetException e) {
154: throwCoreException(e);
155: }
156: monitor.done();
157: }
158:
159: protected void throwCoreException(InvocationTargetException e)
160: throws CoreException {
161: String message = e.getTargetException().getMessage();
162: if (message != null && message.length() > 0) {
163: throw new CoreException(new Status(IStatus.ERROR,
164: PDECore.PLUGIN_ID, IStatus.ERROR, message, null));
165: }
166: }
167:
168: private void createDestination(String os, String ws, String arch)
169: throws InvocationTargetException {
170: if (!fInfo.toDirectory)
171: return;
172: File file = new File(fInfo.destinationDirectory, os + '.' + ws
173: + '.' + arch);
174: if (!file.exists() || !file.isDirectory()) {
175: if (!file.mkdirs())
176: throw new InvocationTargetException(new Exception(
177: PDECoreMessages.ExportWizard_badDirectory));
178: }
179: }
180:
181: private void doExport(IFeatureModel model, String os, String ws,
182: String arch, IProgressMonitor monitor)
183: throws CoreException, InvocationTargetException {
184: try {
185: String location = model.getInstallLocation();
186: if (fInfo.useJarFormat) {
187: createPostProcessingFile(new File(location,
188: FEATURE_POST_PROCESSING));
189: createPostProcessingFile(new File(location,
190: PLUGIN_POST_PROCESSING));
191: }
192: IFeature feature = model.getFeature();
193: doExport(feature.getId(), feature.getVersion(), location,
194: os, ws, arch, monitor);
195: } finally {
196: deleteBuildFiles(model);
197: }
198: }
199:
200: protected void createPostProcessingFile(File file) {
201: FileOutputStream stream = null;
202: try {
203: stream = new FileOutputStream(file);
204: Properties prop = new Properties();
205: prop.put("*", "updateJar"); //$NON-NLS-1$ //$NON-NLS-2$
206: prop.store(stream, ""); //$NON-NLS-1$
207: stream.flush();
208: } catch (IOException e) {
209: } finally {
210: try {
211: if (stream != null)
212: stream.close();
213: } catch (IOException e) {
214: }
215: }
216: }
217:
218: protected void doExport(String featureID, String version,
219: String featureLocation, String os, String ws, String arch,
220: IProgressMonitor monitor) throws CoreException,
221: InvocationTargetException {
222: fHasErrors = false;
223: monitor.beginTask("", 9); //$NON-NLS-1$
224: monitor.setTaskName(PDECoreMessages.FeatureExportJob_taskName);
225: try {
226: HashMap properties = createAntBuildProperties(os, ws, arch);
227: BuildScriptGenerator generator = new BuildScriptGenerator();
228: setupGenerator(generator, featureID, version, os, ws, arch,
229: featureLocation);
230: generator.generate();
231: monitor.worked(1);
232: runScript(getBuildScriptName(featureLocation),
233: getBuildExecutionTargets(), properties,
234: new SubProgressMonitor(monitor, 2));
235: runScript(getAssemblyScriptName(featureID, os, ws, arch,
236: featureLocation), new String[] { "main" }, //$NON-NLS-1$
237: properties, new SubProgressMonitor(monitor, 2));
238: runScript(getPackagerScriptName(featureID, os, ws, arch,
239: featureLocation), null, properties,
240: new SubProgressMonitor(monitor, 2));
241: properties
242: .put(
243: "destination.temp.folder", fBuildTempLocation + "/pde.logs"); //$NON-NLS-1$ //$NON-NLS-2$
244: runScript(
245: getBuildScriptName(featureLocation),
246: new String[] { "gather.logs" }, properties, new SubProgressMonitor(monitor, 2)); //$NON-NLS-1$
247: } finally {
248: monitor.done();
249: }
250: }
251:
252: public void deleteBuildFiles(Object object) throws CoreException {
253: IModel model = null;
254: if (object instanceof BundleDescription) {
255: model = PluginRegistry
256: .findModel((BundleDescription) object);
257: } else if (object instanceof IModel) {
258: model = (IModel) object;
259: }
260:
261: if (model == null)
262: return;
263:
264: if (model.getUnderlyingResource() != null
265: && !isCustomBuild(model)) {
266: String directory = (model instanceof IFeatureModel) ? ((IFeatureModel) model)
267: .getInstallLocation()
268: : ((IPluginModelBase) model).getInstallLocation();
269: File dir = new File(directory);
270: File[] children = dir.listFiles();
271: if (children != null) {
272: for (int i = 0; i < children.length; i++) {
273: if (!children[i].isDirectory()) {
274: String filename = children[i].getName();
275: if (filename.equals("build.xml") //$NON-NLS-1$
276: || (filename
277: .startsWith("javaCompiler.") && filename.endsWith(".args")) //$NON-NLS-1$ //$NON-NLS-2$
278: || (filename.startsWith("assemble.") && filename.endsWith(".xml")) //$NON-NLS-1$ //$NON-NLS-2$
279: || (filename.startsWith("package.") && filename.endsWith(".xml")) //$NON-NLS-1$ //$NON-NLS-2$
280: || filename
281: .equals(FEATURE_POST_PROCESSING)
282: || filename
283: .equals(PLUGIN_POST_PROCESSING)) {
284: children[i].delete();
285: }
286: } else if (children[i].getName().equals(
287: "temp.folder")) { //$NON-NLS-1$
288: CoreUtility.deleteContent(children[i]);
289: }
290: }
291: }
292: }
293:
294: if (model instanceof IFeatureModel) {
295: IFeature feature = ((IFeatureModel) model).getFeature();
296: IFeatureChild[] children = feature.getIncludedFeatures();
297: for (int i = 0; i < children.length; i++) {
298: IFeature ref = ((FeatureChild) children[i])
299: .getReferencedFeature();
300: if (ref != null) {
301: deleteBuildFiles(ref.getModel());
302: }
303: }
304:
305: IFeaturePlugin[] plugins = feature.getPlugins();
306: for (int i = 0; i < plugins.length; i++) {
307: IPluginModelBase plugin = PluginRegistry
308: .findModel(plugins[i].getId());
309: if (plugin != null) {
310: deleteBuildFiles(plugin);
311: }
312: }
313: }
314: }
315:
316: private String getBuildScriptName(String featureLocation) {
317: return featureLocation + IPath.SEPARATOR + "build.xml"; //$NON-NLS-1$
318: }
319:
320: protected String getAssemblyScriptName(String featureID, String os,
321: String ws, String arch, String featureLocation) {
322: return featureLocation + IPath.SEPARATOR + "assemble." //$NON-NLS-1$
323: + featureID + "." + os + "." //$NON-NLS-1$ //$NON-NLS-2$
324: + ws + "." + arch //$NON-NLS-1$
325: + ".xml"; //$NON-NLS-1$
326: }
327:
328: private String[] getBuildExecutionTargets() {
329: if (fInfo.exportSource)
330: return new String[] { "build.jars", "build.sources" }; //$NON-NLS-1$ //$NON-NLS-2$
331: return new String[] { "build.jars" }; //$NON-NLS-1$
332: }
333:
334: protected void runScript(String location, String[] targets,
335: Map properties, IProgressMonitor monitor)
336: throws InvocationTargetException, CoreException {
337: AntRunner runner = new AntRunner();
338: runner.addUserProperties(properties);
339: runner.setAntHome(location);
340: runner.setBuildFileLocation(location);
341: runner
342: .addBuildListener("org.eclipse.pde.internal.core.ant.ExportBuildListener"); //$NON-NLS-1$
343: runner.setExecutionTargets(targets);
344: if (fInfo.signingInfo != null) {
345: AntCorePreferences preferences = AntCorePlugin.getPlugin()
346: .getPreferences();
347: IAntClasspathEntry entry = preferences.getToolsJarEntry();
348: if (entry != null) {
349: IAntClasspathEntry[] classpath = preferences
350: .getAntHomeClasspathEntries();
351: URL[] urls = new URL[classpath.length + 2];
352: for (int i = 0; i < classpath.length; i++) {
353: urls[i] = classpath[i].getEntryURL();
354: }
355: IPath path = new Path(entry.getEntryURL().toString())
356: .removeLastSegments(2);
357: path = path.append("bin"); //$NON-NLS-1$
358: try {
359: urls[classpath.length] = new URL(path.toString());
360: } catch (MalformedURLException e) {
361: urls[classpath.length] = entry.getEntryURL();
362: } finally {
363: urls[classpath.length + 1] = entry.getEntryURL();
364: }
365: runner.setCustomClasspath(urls);
366: }
367: }
368: runner.run(monitor);
369: }
370:
371: protected String getPackagerScriptName(String featureID, String os,
372: String ws, String arch, String featureLocation) {
373: return featureLocation + IPath.SEPARATOR + "package." //$NON-NLS-1$
374: + featureID + "." + os + "." //$NON-NLS-1$ //$NON-NLS-2$
375: + ws + "." + arch //$NON-NLS-1$
376: + ".xml"; //$NON-NLS-1$
377: }
378:
379: protected HashMap createAntBuildProperties(String os, String ws,
380: String arch) {
381: if (fAntBuildProperties == null) {
382: fAntBuildProperties = new HashMap(15);
383:
384: List defaultProperties = AntCorePlugin.getPlugin()
385: .getPreferences().getProperties();
386: ListIterator li = defaultProperties.listIterator();
387: while (li.hasNext()) {
388: Property prop = (Property) li.next();
389: fAntBuildProperties
390: .put(prop.getName(), prop.getValue());
391: }
392:
393: if (fInfo.signingInfo != null) {
394: fAntBuildProperties.put(
395: "sign.alias", fInfo.signingInfo[0]); //$NON-NLS-1$
396: fAntBuildProperties.put(
397: "sign.keystore", fInfo.signingInfo[1]); //$NON-NLS-1$
398: fAntBuildProperties.put(
399: "sign.storepass", fInfo.signingInfo[2]); //$NON-NLS-1$
400: }
401: if (fInfo.jnlpInfo != null) {
402: fAntBuildProperties.put(
403: "jnlp.codebase", fInfo.jnlpInfo[0]); //$NON-NLS-1$
404: fAntBuildProperties.put("jnlp.j2se", fInfo.jnlpInfo[1]); //$NON-NLS-1$
405: }
406:
407: fAntBuildProperties.put(IXMLConstants.PROPERTY_BUILD_TEMP,
408: fBuildTempLocation + "/destination"); //$NON-NLS-1$
409: fAntBuildProperties.put(
410: IXMLConstants.PROPERTY_FEATURE_TEMP_FOLDER,
411: fBuildTempLocation + "/destination"); //$NON-NLS-1$
412: fAntBuildProperties.put(
413: IXMLConstants.PROPERTY_INCLUDE_CHILDREN, "true"); //$NON-NLS-1$
414: fAntBuildProperties.put("eclipse.running", "true"); //$NON-NLS-1$ //$NON-NLS-2$
415: fAntBuildProperties.put(IXMLConstants.PROPERTY_BASE_OS, os);
416: fAntBuildProperties.put(IXMLConstants.PROPERTY_BASE_WS, ws);
417: fAntBuildProperties.put(IXMLConstants.PROPERTY_BASE_ARCH,
418: arch);
419: fAntBuildProperties.put(IXMLConstants.PROPERTY_BASE_NL,
420: TargetPlatform.getNL());
421: fAntBuildProperties.put(
422: IXMLConstants.PROPERTY_BOOTCLASSPATH,
423: BuildUtilities.getBootClasspath());
424: IExecutionEnvironmentsManager manager = JavaRuntime
425: .getExecutionEnvironmentsManager();
426: IExecutionEnvironment[] envs = manager
427: .getExecutionEnvironments();
428: for (int i = 0; i < envs.length; i++) {
429: String id = envs[i].getId();
430: if (id != null)
431: fAntBuildProperties.put(id, BuildUtilities
432: .getBootClasspath(id));
433: }
434: fAntBuildProperties
435: .put(IXMLConstants.PROPERTY_JAVAC_FAIL_ON_ERROR,
436: "false"); //$NON-NLS-1$
437: fAntBuildProperties.put(
438: IXMLConstants.PROPERTY_JAVAC_DEBUG_INFO, "on"); //$NON-NLS-1$
439: fAntBuildProperties.put(
440: IXMLConstants.PROPERTY_JAVAC_VERBOSE, "false"); //$NON-NLS-1$
441:
442: Preferences pref = JavaCore.getPlugin()
443: .getPluginPreferences();
444: String source = pref.getString(JavaCore.COMPILER_SOURCE);
445: fAntBuildProperties.put(
446: IXMLConstants.PROPERTY_JAVAC_SOURCE, source);
447: String target = pref
448: .getString(JavaCore.COMPILER_CODEGEN_TARGET_PLATFORM);
449: fAntBuildProperties.put(
450: IXMLConstants.PROPERTY_JAVAC_TARGET, target);
451:
452: // for the assembler...
453: fAntBuildProperties.put(
454: IXMLConstants.PROPERTY_BUILD_DIRECTORY,
455: fBuildTempLocation + "/assemblyLocation"); //$NON-NLS-1$
456: fAntBuildProperties.put(IXMLConstants.PROPERTY_BUILD_LABEL,
457: "."); //$NON-NLS-1$
458: fAntBuildProperties.put(
459: IXMLConstants.PROPERTY_COLLECTING_FOLDER, "."); //$NON-NLS-1$
460: String prefix = Platform.getOS().equals("macosx") ? "." : ""; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
461: fAntBuildProperties.put(
462: IXMLConstants.PROPERTY_ARCHIVE_PREFIX, prefix);
463:
464: if (!fInfo.toDirectory) {
465: String filename = fInfo.zipFileName;
466: if (fInfo.targets != null) {
467: int i = filename.lastIndexOf('.');
468: filename = filename.substring(0, i) + '.' + os
469: + '.' + ws + '.' + arch
470: + filename.substring(i);
471: }
472: fAntBuildProperties.put(
473: IXMLConstants.PROPERTY_ARCHIVE_FULLPATH,
474: fInfo.destinationDirectory + File.separator
475: + filename);
476: } else {
477: String dir = fInfo.destinationDirectory;
478: if (fInfo.targets != null)
479: dir += File.separatorChar + os + '.' + ws + '.'
480: + arch;
481: fAntBuildProperties.put(
482: IXMLConstants.PROPERTY_ASSEMBLY_TMP, dir);
483: }
484: fAntBuildProperties
485: .put(IXMLConstants.PROPERTY_TAR_ARGS, ""); //$NON-NLS-1$
486: }
487: return fAntBuildProperties;
488: }
489:
490: private String getOS(IFeature feature) {
491: String os = feature.getOS();
492: if (os == null || os.trim().length() == 0
493: || os.indexOf(',') != -1 || os.equals("*")) //$NON-NLS-1$
494: return TargetPlatform.getOS();
495: return os;
496: }
497:
498: private String getWS(IFeature feature) {
499: String ws = feature.getWS();
500: if (ws == null || ws.trim().length() == 0
501: || ws.indexOf(',') != -1 || ws.equals("*")) //$NON-NLS-1$
502: return TargetPlatform.getWS();
503: return ws;
504: }
505:
506: private String getOSArch(IFeature feature) {
507: String arch = feature.getArch();
508: if (arch == null || arch.trim().length() == 0
509: || arch.indexOf(',') != -1 || arch.equals("*")) //$NON-NLS-1$
510: return TargetPlatform.getOSArch();
511: return arch;
512: }
513:
514: protected void createDestination() throws InvocationTargetException {
515: File file = new File(fInfo.destinationDirectory);
516: if (!file.exists() || !file.isDirectory()) {
517: if (!file.mkdirs())
518: throw new InvocationTargetException(new Exception(
519: PDECoreMessages.ExportWizard_badDirectory));
520: }
521: }
522:
523: protected void doExport(IFeatureModel model, String[] config,
524: IProgressMonitor monitor) throws CoreException,
525: InvocationTargetException {
526: if (config == null) {
527: IFeature feature = model.getFeature();
528: doExport(model, getOS(feature), getWS(feature),
529: getOSArch(feature), monitor);
530: } else {
531: createDestination(config[0], config[1], config[2]);
532: doExport(model, config[0], config[1], config[2], monitor);
533: }
534: }
535:
536: protected void setupGenerator(BuildScriptGenerator generator,
537: String featureID, String versionId, String os, String ws,
538: String arch, String featureLocation) throws CoreException {
539: generator.setBuildingOSGi(true);
540: generator.setChildren(true);
541: generator.setWorkingDirectory(featureLocation);
542: generator.setDevEntries(getDevProperties());
543: generator
544: .setElements(new String[] { "feature@" + featureID + (versionId == null ? "" : ":" + versionId) }); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
545: generator.setPluginPath(getPaths());
546: generator.setReportResolutionErrors(false);
547: generator.setIgnoreMissingPropertiesFile(true);
548: generator.setSignJars(fInfo.signingInfo != null);
549: generator.setGenerateJnlp(fInfo.jnlpInfo != null);
550: String config = os + ',' + ws + ',' + arch;
551: AbstractScriptGenerator.setConfigInfo(config); //This needs to be set before we set the format
552: String format;
553: if (fInfo.toDirectory)
554: format = config + '-' + IXMLConstants.FORMAT_FOLDER;
555: else
556: format = config + '-' + IXMLConstants.FORMAT_ANTZIP;
557: generator.setArchivesFormat(format);
558: generator.setPDEState(getState(os, ws, arch));
559: generator.setNextId(TargetPlatformHelper.getPDEState()
560: .getNextId());
561: generator.setStateExtraData(
562: TargetPlatformHelper
563: .getBundleClasspaths(TargetPlatformHelper
564: .getPDEState()),
565: TargetPlatformHelper.getPatchMap(TargetPlatformHelper
566: .getPDEState()));
567: AbstractScriptGenerator.setForceUpdateJar(false);
568: AbstractScriptGenerator.setEmbeddedSource(fInfo.exportSource);
569: }
570:
571: protected State getState(String os, String ws, String arch) {
572: State main = TargetPlatformHelper.getState();
573: if (os.equals(TargetPlatform.getOS())
574: && ws.equals(TargetPlatform.getWS())
575: && arch.equals(TargetPlatform.getOSArch())) {
576: return main;
577: }
578: if (fStateCopy == null) {
579: copyState(main);
580: }
581:
582: Dictionary[] dictionaries = fStateCopy.getPlatformProperties();
583: for (int i = 0; i < dictionaries.length; i++) {
584: Dictionary properties = dictionaries[i];
585: properties.put("osgi.os", os); //$NON-NLS-1$
586: properties.put("osgi.ws", ws); //$NON-NLS-1$
587: properties.put("osgi.arch", arch); //$NON-NLS-1$
588: }
589: fStateCopy.resolve(false);
590: return fStateCopy;
591: }
592:
593: protected void copyState(State state) {
594: fStateCopy = state.getFactory().createState(state);
595: fStateCopy.setResolver(Platform.getPlatformAdmin()
596: .getResolver());
597: fStateCopy.setPlatformProperties(state.getPlatformProperties());
598: }
599:
600: private String getDevProperties() {
601: if (fDevProperties == null) {
602: fDevProperties = ClasspathHelper.getDevEntriesProperties(
603: fBuildTempLocation + "/dev.properties", false); //$NON-NLS-1$
604: }
605: return fDevProperties;
606: }
607:
608: protected boolean isCustomBuild(IModel model) throws CoreException {
609: IBuildModel buildModel = null;
610: IFile buildFile = model.getUnderlyingResource().getProject()
611: .getFile("build.properties"); //$NON-NLS-1$
612: if (buildFile.exists()) {
613: buildModel = new WorkspaceBuildModel(buildFile);
614: buildModel.load();
615: }
616: if (buildModel != null) {
617: IBuild build = buildModel.getBuild();
618: if (build == null)
619: return false;
620: IBuildEntry entry = build.getEntry("custom"); //$NON-NLS-1$
621: if (entry != null) {
622: String[] tokens = entry.getTokens();
623: for (int i = 0; i < tokens.length; i++) {
624: if (tokens[i].equals("true")) //$NON-NLS-1$
625: return true;
626: }
627: }
628: }
629: return false;
630: }
631:
632: protected String[] getPaths() {
633: return TargetPlatformHelper.getFeaturePaths();
634: }
635:
636: protected void cleanup(String[] config, IProgressMonitor monitor) {
637: monitor.beginTask("", 2); //$NON-NLS-1$
638: // clear out some cached values that depend on the configuration being built.
639: fDevProperties = null;
640: fAntBuildProperties = null;
641:
642: File scriptFile = null;
643: try {
644: scriptFile = createScriptFile("zip.xml"); //$NON-NLS-1$
645: DocumentBuilderFactory factory = DocumentBuilderFactory
646: .newInstance();
647: Document doc = factory.newDocumentBuilder().newDocument();
648:
649: Element root = doc.createElement("project"); //$NON-NLS-1$
650: root.setAttribute("name", "temp"); //$NON-NLS-1$ //$NON-NLS-2$
651: root.setAttribute("default", "clean"); //$NON-NLS-1$ //$NON-NLS-2$
652: root.setAttribute("basedir", "."); //$NON-NLS-1$ //$NON-NLS-2$
653: doc.appendChild(root);
654:
655: Element target = doc.createElement("target"); //$NON-NLS-1$
656: target.setAttribute("name", "clean"); //$NON-NLS-1$ //$NON-NLS-2$
657: Element child = doc.createElement("delete"); //$NON-NLS-1$
658: child.setAttribute("dir", fBuildTempLocation); //$NON-NLS-1$
659: target.appendChild(child);
660: root.appendChild(target);
661:
662: if (fHasErrors) {
663: target = doc.createElement("target"); //$NON-NLS-1$
664: target.setAttribute("name", "zip.logs"); //$NON-NLS-1$ //$NON-NLS-2$
665: child = doc.createElement("zip"); //$NON-NLS-1$
666: child
667: .setAttribute(
668: "zipfile", fInfo.destinationDirectory + logName(config)); //$NON-NLS-1$
669: child.setAttribute(
670: "basedir", fBuildTempLocation + "/pde.logs"); //$NON-NLS-1$ //$NON-NLS-2$
671: target.appendChild(child);
672: root.appendChild(target);
673: }
674: XMLPrintHandler.writeFile(doc, scriptFile);
675:
676: String[] targets = fHasErrors ? new String[] {
677: "zip.logs", "clean" } //$NON-NLS-1$ //$NON-NLS-2$
678: : new String[] { "clean" }; //$NON-NLS-1$
679: AntRunner runner = new AntRunner();
680: runner.setBuildFileLocation(scriptFile.getAbsolutePath());
681: runner.setExecutionTargets(targets);
682: runner.run(new SubProgressMonitor(monitor, 1));
683: } catch (FactoryConfigurationError e) {
684: } catch (ParserConfigurationException e) {
685: } catch (CoreException e) {
686: } catch (IOException e) {
687: } finally {
688: if (scriptFile != null && scriptFile.exists())
689: scriptFile.delete();
690: monitor.done();
691: }
692: }
693:
694: protected File createScriptFile(String filename) throws IOException {
695: String path = PDECore.getDefault().getStateLocation()
696: .toOSString();
697: File zip = new File(path, filename);
698: if (zip.exists()) {
699: zip.delete();
700: zip.createNewFile();
701: }
702: return zip;
703: }
704:
705: private String logName(String[] config) {
706: if (config == null)
707: return "/logs.zip"; //$NON-NLS-1$
708: return "/logs." + config[0] + '.' + config[1] + '.' + config[2] + ".zip"; //$NON-NLS-1$ //$NON-NLS-2$
709: }
710:
711: protected void createFeature(String featureID,
712: String featureLocation, String[] config,
713: boolean includeLauncher) throws IOException {
714: File file = new File(featureLocation);
715: if (!file.exists() || !file.isDirectory())
716: file.mkdirs();
717:
718: try {
719: DocumentBuilderFactory factory = DocumentBuilderFactory
720: .newInstance();
721: Document doc = factory.newDocumentBuilder().newDocument();
722: Element root = doc.createElement("feature"); //$NON-NLS-1$
723: root.setAttribute("id", featureID); //$NON-NLS-1$
724: root.setAttribute("version", "1.0"); //$NON-NLS-1$ //$NON-NLS-2$
725: doc.appendChild(root);
726:
727: if (includeLauncher) {
728: IFeatureModel model = PDECore.getDefault()
729: .getFeatureModelManager().getDeltaPackFeature();
730: if (model != null) {
731: IFeature feature = model.getFeature();
732: Element includes = doc.createElement("includes"); //$NON-NLS-1$
733: includes.setAttribute("id", feature.getId()); //$NON-NLS-1$
734: includes.setAttribute(
735: "version", feature.getVersion()); //$NON-NLS-1$
736: root.appendChild(includes);
737: }
738: }
739: Dictionary environment = new Hashtable(4);
740: environment.put("osgi.os", config[0]); //$NON-NLS-1$
741: environment.put("osgi.ws", config[1]); //$NON-NLS-1$
742: environment.put("osgi.arch", config[2]); //$NON-NLS-1$
743: environment.put("osgi.nl", config[3]); //$NON-NLS-1$
744:
745: for (int i = 0; i < fInfo.items.length; i++) {
746: if (fInfo.items[i] instanceof IFeatureModel) {
747: IFeature feature = ((IFeatureModel) fInfo.items[i])
748: .getFeature();
749: Element includes = doc.createElement("includes"); //$NON-NLS-1$
750: includes.setAttribute("id", feature.getId()); //$NON-NLS-1$
751: includes.setAttribute(
752: "version", feature.getVersion()); //$NON-NLS-1$
753: root.appendChild(includes);
754: } else {
755: BundleDescription bundle = null;
756: if (fInfo.items[i] instanceof IPluginModelBase) {
757: bundle = ((IPluginModelBase) fInfo.items[i])
758: .getBundleDescription();
759: }
760: if (bundle == null) {
761: if (fInfo.items[i] instanceof BundleDescription)
762: bundle = (BundleDescription) fInfo.items[i];
763: }
764: if (bundle == null)
765: continue;
766: if (shouldAddPlugin(bundle, environment)) {
767: Element plugin = doc.createElement("plugin"); //$NON-NLS-1$
768: plugin.setAttribute(
769: "id", bundle.getSymbolicName()); //$NON-NLS-1$
770: plugin
771: .setAttribute(
772: "version", bundle.getVersion().toString()); //$NON-NLS-1$
773: setAdditionalAttributes(plugin, bundle);
774: root.appendChild(plugin);
775: }
776: }
777: }
778: XMLPrintHandler.writeFile(doc,
779: new File(file, "feature.xml")); //$NON-NLS-1$
780: } catch (DOMException e1) {
781: } catch (FactoryConfigurationError e1) {
782: } catch (ParserConfigurationException e1) {
783: }
784: }
785:
786: protected void setAdditionalAttributes(Element plugin,
787: BundleDescription bundle) {
788: }
789:
790: public boolean hasErrors() {
791: return fHasErrors;
792: }
793:
794: public static void errorFound() {
795: fHasErrors = true;
796: }
797:
798: protected boolean shouldAddPlugin(BundleDescription bundle,
799: Dictionary environment) {
800: String filterSpec = bundle.getPlatformFilter();
801: try {
802: return (filterSpec == null || PDECore.getDefault()
803: .getBundleContext().createFilter(filterSpec).match(
804: environment));
805: } catch (InvalidSyntaxException e) {
806: }
807: return false;
808: }
809: }
|