1 /*******************************************************************************
2  * Copyright (c) 2005, 2017 IBM Corporation and others.
3  *
4  * This program and the accompanying materials
5  * are made available under the terms of the Eclipse Public License 2.0
6  * which accompanies this distribution, and is available at
7  * https://www.eclipse.org/legal/epl-2.0/
8  *
9  * SPDX-License-Identifier: EPL-2.0
10  *
11  * Contributors:
12  *      IBM Corporation - initial API and implementation
13  *******************************************************************************/
14 package org.eclipse.pde.internal.build.packager;
15 
16 import java.io.*;
17 import java.util.*;
18 import org.eclipse.core.runtime.*;
19 import org.eclipse.osgi.service.resolver.BundleDescription;
20 import org.eclipse.osgi.util.NLS;
21 import org.eclipse.pde.internal.build.*;
22 import org.eclipse.pde.internal.build.ant.FileSet;
23 import org.eclipse.pde.internal.build.builder.BuildDirector;
24 import org.eclipse.pde.internal.build.builder.ModelBuildScriptGenerator;
25 import org.eclipse.pde.internal.build.site.BuildTimeFeature;
26 
27 public class PackageConfigScriptGenerator extends AssembleConfigScriptGenerator {
28 
29 	private Properties packagingProperties;
30 	private Collection<BuildTimeFeature> archiveRootProviders = Collections.emptyList();
31 
32 	@Override
initialize(String directoryName, String feature, Config configurationInformation, Collection<BundleDescription> elementList, Collection<BuildTimeFeature> featureList, Collection<BuildTimeFeature> allFeaturesList, Collection<BuildTimeFeature> rootProviders)33 	public void initialize(String directoryName, String feature, Config configurationInformation, Collection<BundleDescription> elementList, Collection<BuildTimeFeature> featureList, Collection<BuildTimeFeature> allFeaturesList, Collection<BuildTimeFeature> rootProviders) throws CoreException {
34 		/* package scripts require the root file providers for creating the file archive, but don't want them for other rootfile
35 		 * stuff done by the assembly scripts, so keep them separate here */
36 		super.initialize(directoryName, feature, configurationInformation, elementList, featureList, allFeaturesList, new ArrayList<BuildTimeFeature>(0));
37 		if (rootProviders != null) {
38 			archiveRootProviders = rootProviders;
39 		} else {
40 			archiveRootProviders = Collections.emptyList();
41 		}
42 	}
43 
44 	@Override
getArchiveRootFileProviders()45 	protected Collection<BuildTimeFeature> getArchiveRootFileProviders() {
46 		if (archiveRootProviders.size() > 0)
47 			return archiveRootProviders;
48 		return super.getArchiveRootFileProviders();
49 	}
50 
getFinalName(BundleDescription bundle, String shape)51 	private String getFinalName(BundleDescription bundle, String shape) {
52 		final String JAR = "jar"; //$NON-NLS-1$
53 		final String DOT_JAR = '.' + JAR;
54 		if (!AbstractScriptGenerator.getPropertyAsBoolean(IBuildPropertiesConstants.PROPERTY_PACKAGER_AS_NORMALIZER)) {
55 			Path path = new Path(bundle.getLocation());
56 			if (shape.equals(ShapeAdvisor.FILE) && !JAR.equalsIgnoreCase(path.getFileExtension()))
57 				return path.lastSegment().concat(DOT_JAR);
58 			return path.lastSegment();
59 		}
60 		if (shape.equals(ShapeAdvisor.FILE))
61 			return ModelBuildScriptGenerator.getNormalizedName(bundle) + DOT_JAR;
62 		return ModelBuildScriptGenerator.getNormalizedName(bundle);
63 	}
64 
getFinalName(BuildTimeFeature feature)65 	private String getFinalName(BuildTimeFeature feature) {
66 		if (!AbstractScriptGenerator.getPropertyAsBoolean(IBuildPropertiesConstants.PROPERTY_PACKAGER_AS_NORMALIZER)) {
67 			Path featurePath = new Path(feature.getURL().getPath());
68 			return featurePath.segment(featurePath.segmentCount() - 2);
69 		}
70 		return feature.getId() + "_" + feature.getVersion(); //$NON-NLS-1$
71 	}
72 
73 	@Override
generateGatherBinPartsTarget()74 	protected void generateGatherBinPartsTarget() { //TODO Here we should try to use cp because otherwise we will loose the permissions
75 		script.printTargetDeclaration(TARGET_GATHER_BIN_PARTS, null, null, null, null);
76 		String excludedFiles = null;
77 		if (AbstractScriptGenerator.getPropertyAsBoolean(IBuildPropertiesConstants.PROPERTY_PACKAGER_AS_NORMALIZER))
78 			excludedFiles = "build.properties, .project, .classpath"; //$NON-NLS-1$
79 		IPath baseLocation = null;
80 		try {
81 			String url = getSite(false).getSiteContentProvider().getInstalledBaseURL();
82 			if (url != null)
83 				baseLocation = new Path(url);
84 		} catch (CoreException e) {
85 			//nothing
86 		}
87 
88 		ArrayList<FileSet> p2Features = BuildDirector.p2Gathering ? new ArrayList<>() : null;
89 		ArrayList<FileSet> p2Bundles = BuildDirector.p2Gathering ? new ArrayList<>() : null;
90 		for (int i = 0; i < plugins.length; i++) {
91 			Path pluginLocation = new Path(plugins[i].getLocation());
92 			String location = pluginLocation.toOSString();
93 			boolean isFolder = isFolder(pluginLocation);
94 
95 			//try to relate the plugin location to the ${baseLocation} property
96 			if (baseLocation != null && baseLocation.isPrefixOf(pluginLocation)) {
97 				IPath relative = pluginLocation.removeFirstSegments(baseLocation.segmentCount());
98 				location = new Path(Utils.getPropertyFormat(PROPERTY_BASE_LOCATION)).append(relative).toOSString();
99 			}
100 			if (BuildDirector.p2Gathering) {
101 				p2Bundles.add(new FileSet(pluginLocation.removeLastSegments(1).toOSString(), null, pluginLocation.lastSegment(), null, null, null, null));
102 			} else if (isFolder) {
103 				script.printCopyTask(null, Utils.getPropertyFormat(PROPERTY_ECLIPSE_PLUGINS) + '/' + getFinalName(plugins[i], ShapeAdvisor.FOLDER), new FileSet[] {new FileSet(location, null, null, null, excludedFiles, null, null)}, false, false);
104 			} else {
105 				script.printCopyFileTask(location, Utils.getPropertyFormat(PROPERTY_ECLIPSE_PLUGINS) + '/' + getFinalName(plugins[i], ShapeAdvisor.FILE), false);
106 			}
107 		}
108 
109 		for (int i = 0; i < features.length; i++) {
110 			IPath featureLocation = new Path(features[i].getRootLocation()); // Here we assume that all the features are local
111 			String location = featureLocation.toOSString();
112 			if (baseLocation != null && baseLocation.isPrefixOf(featureLocation)) {
113 				IPath relative = featureLocation.removeFirstSegments(baseLocation.segmentCount());
114 				location = new Path(Utils.getPropertyFormat(PROPERTY_BASE_LOCATION)).append(relative).toOSString();
115 			}
116 
117 			if (BuildDirector.p2Gathering) {
118 				p2Features.add(new FileSet(featureLocation.removeLastSegments(1).toOSString(), null, featureLocation.lastSegment(), null, null, null, null));
119 			} else {
120 				script.printCopyTask(null, Utils.getPropertyFormat(PROPERTY_ECLIPSE_FEATURES) + '/' + getFinalName(features[i]), new FileSet[] {new FileSet(location, null, null, null, null, null, null)}, false, false);
121 			}
122 		}
123 
124 		if (BuildDirector.p2Gathering) {
125 			String repo = "file:" + getWorkingDirectory() + "/buildRepo"; //$NON-NLS-1$ //$NON-NLS-2$
126 			script.printP2PublishFeaturesAndBundles(repo, repo, p2Bundles.toArray(new FileSet[p2Bundles.size()]), p2Features.toArray(new FileSet[p2Features.size()]), Utils.getPropertyFormat(PROPERTY_P2_CATEGORY_SITE), Utils.getPropertyFormat(PROPERTY_P2_CATEGORY_PREFIX), Utils.getPropertyFormat(PROPERTY_P2_CATEGORY_DEFINITION), Utils.getPropertyFormat(PROPERTY_P2_CATEGORY_VERSION), contextMetadata);
127 		}
128 
129 		if (packagingProperties.size() != 0) {
130 			String filesToPackage = null;
131 			filesToPackage = packagingProperties.getProperty(ROOT, null);
132 			if (filesToPackage != null)
133 				filesToPackage += ',';
134 
135 			String tmp = packagingProperties.getProperty(ROOT_PREFIX + configInfo.toString("."), null); //$NON-NLS-1$
136 			if (tmp != null)
137 				filesToPackage += tmp;
138 
139 			if (filesToPackage == null)
140 				filesToPackage = "**/**"; //$NON-NLS-1$
141 
142 			FileSet rootFiles = new FileSet(Utils.getPropertyFormat("tempDirectory") + '/' + configInfo.toStringReplacingAny(".", ANY_STRING) + "/eclipse", null, filesToPackage, null, null, null, null); //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$
143 			String target = Utils.getPropertyFormat(PROPERTY_ECLIPSE_BASE) + '/' + configInfo.toStringReplacingAny(".", ANY_STRING) + '/' + Utils.getPropertyFormat(PROPERTY_COLLECTING_FOLDER); //$NON-NLS-1$
144 			script.printCopyTask(null, target, new FileSet[] {rootFiles}, false, false);
145 
146 			Utils.generatePermissions(packagingProperties, configInfo, PROPERTY_ECLIPSE_BASE, script);
147 		}
148 		script.printTargetEnd();
149 		script.println();
150 	}
151 
152 	@Override
getTargetName()153 	public String getTargetName() {
154 		String config = getTargetConfig();
155 		return "package" + '.' + getTargetElement() + (config.length() > 0 ? "." : "") + config; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
156 	}
157 
isFolder(Path pluginLocation)158 	private boolean isFolder(Path pluginLocation) {
159 		return pluginLocation.toFile().isDirectory();
160 	}
161 
setPackagingPropertiesLocation(String packagingPropertiesLocation)162 	public void setPackagingPropertiesLocation(String packagingPropertiesLocation) throws CoreException {
163 		packagingProperties = new Properties();
164 		if (packagingPropertiesLocation == null || packagingPropertiesLocation.equals("")) //$NON-NLS-1$
165 			return;
166 
167 		try (InputStream propertyStream = new BufferedInputStream(new FileInputStream(packagingPropertiesLocation))) {
168 			packagingProperties.load(propertyStream);
169 		} catch (FileNotFoundException e) {
170 			String message = NLS.bind(Messages.exception_readingFile, packagingPropertiesLocation);
171 			throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_READING_FILE, message, e));
172 		} catch (IOException e) {
173 			String message = NLS.bind(Messages.exception_readingFile, packagingPropertiesLocation);
174 			throw new CoreException(new Status(IStatus.ERROR, PI_PDEBUILD, EXCEPTION_READING_FILE, message, e));
175 		}
176 
177 		if (packagingProperties.size() > 0) {
178 			//This is need so that the call in assemble config script generator gather the root files
179 			if (rootFileProviders == null)
180 				rootFileProviders = new ArrayList<>(1);
181 			// TODO Unclear why "elt" was added as a root provider, instead we will add an empty feature
182 			//	rootFileProviders.add("elt"); //$NON-NLS-1$
183 			rootFileProviders.add(new BuildTimeFeature());
184 		}
185 	}
186 
187 	@Override
generateGatherSourceTarget()188 	protected void generateGatherSourceTarget() {
189 		//In the packager, we do not gather source
190 		script.printTargetDeclaration(TARGET_GATHER_SOURCES, null, null, null, null);
191 		script.printTargetEnd();
192 		script.println();
193 	}
194 
195 	@Override
generatePermissions(String root, boolean zip)196 	protected FileSet[] generatePermissions(String root, boolean zip) {
197 		if (packagingProperties != null && packagingProperties.size() > 0) {
198 			//In the packager there is nothing to do since, the features we are packaging are pre-built and do not have a build.properties
199 			return new FileSet[0];
200 		}
201 		return super.generatePermissions(root, zip);
202 	}
203 
204 	@Override
generateGZipTarget(boolean assembling)205 	protected void generateGZipTarget(boolean assembling) {
206 		super.generateGZipTarget(false);
207 	}
208 
209 	@Override
generateTarGZTasks(boolean assembling)210 	public void generateTarGZTasks(boolean assembling) {
211 		super.generateTarGZTasks(false);
212 	}
213 
214 	@Override
generateDirectorTarget(boolean assembling)215 	protected void generateDirectorTarget(boolean assembling) {
216 		super.generateDirectorTarget(false);
217 	}
218 
219 	@Override
generateMirrorTask(boolean assembling)220 	protected void generateMirrorTask(boolean assembling) {
221 		super.generateMirrorTask(false);
222 	}
223 
224 	@Override
generateCleanupAssembly(boolean assembling)225 	protected void generateCleanupAssembly(boolean assembling) {
226 		super.generateCleanupAssembly(false);
227 	}
228 
229 	@Override
generateArchivingTarget(boolean assembling)230 	protected void generateArchivingTarget(boolean assembling) {
231 		super.generateArchivingTarget(false);
232 	}
233 
getFinalShape(BundleDescription bundle)234 	protected Object[] getFinalShape(BundleDescription bundle) {
235 		if (AbstractScriptGenerator.getPropertyAsBoolean(IBuildPropertiesConstants.PROPERTY_PACKAGER_MODE) == true) {
236 			String shape = isFolder(new Path(bundle.getLocation())) ? ShapeAdvisor.FOLDER : ShapeAdvisor.FILE;
237 			return new Object[] {getFinalName(bundle, shape), shape};
238 		}
239 		return shapeAdvisor.getFinalShape(bundle);
240 	}
241 
getFinalShape(BuildTimeFeature feature)242 	protected Object[] getFinalShape(BuildTimeFeature feature) {
243 		if (AbstractScriptGenerator.getPropertyAsBoolean(IBuildPropertiesConstants.PROPERTY_PACKAGER_MODE) == true)
244 			return new Object[] {getFinalName(feature), ShapeAdvisor.FOLDER};
245 		return shapeAdvisor.getFinalShape(feature);
246 	}
247 
248 	@Override
printP2GenerationModeCondition()249 	protected void printP2GenerationModeCondition() {
250 		// "final" if we are overriding, else "incremental"
251 		script.printConditionIsSet(PROPERTY_P2_GENERATION_MODE, "final", PROPERTY_P2_FINAL_MODE_OVERRIDE, "incremental"); //$NON-NLS-1$//$NON-NLS-2$
252 	}
253 }
254