1 /*******************************************************************************
2  * Copyright (c) 2003, 2016 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.osgi.internal.resolver;
15 
16 import java.io.*;
17 import java.util.*;
18 import org.eclipse.osgi.internal.module.ResolverImpl;
19 import org.eclipse.osgi.service.resolver.*;
20 import org.eclipse.osgi.service.resolver.VersionRange;
21 import org.eclipse.osgi.storagemanager.StorageManager;
22 import org.eclipse.osgi.util.ManifestElement;
23 import org.osgi.framework.*;
24 
25 public class StateObjectFactoryImpl implements StateObjectFactory {
26 
27 	/**
28 	 * @deprecated
29 	 */
createBundleDescription(Dictionary<String, String> manifest, String location, long id)30 	public BundleDescription createBundleDescription(Dictionary<String, String> manifest, String location, long id) throws BundleException {
31 		return createBundleDescription(null, manifest, location, id);
32 	}
33 
createBundleDescription(State state, Dictionary<String, String> manifest, String location, long id)34 	public BundleDescription createBundleDescription(State state, Dictionary<String, String> manifest, String location, long id) throws BundleException {
35 		BundleDescriptionImpl result = (BundleDescriptionImpl) StateBuilder.createBundleDescription((StateImpl) state, manifest, location);
36 		result.setBundleId(id);
37 		return result;
38 	}
39 
40 	/**
41 	 * @deprecated
42 	 */
createBundleDescription(long id, String symbolicName, Version version, String location, BundleSpecification[] required, HostSpecification host, ImportPackageSpecification[] imports, ExportPackageDescription[] exports, String[] providedPackages, boolean singleton)43 	public BundleDescription createBundleDescription(long id, String symbolicName, Version version, String location, BundleSpecification[] required, HostSpecification host, ImportPackageSpecification[] imports, ExportPackageDescription[] exports, String[] providedPackages, boolean singleton) {
44 		return createBundleDescription(id, symbolicName, version, location, required, host, imports, exports, providedPackages, singleton, true, true, null, null, null, null);
45 	}
46 
47 	/**
48 	 * @deprecated
49 	 */
createBundleDescription(long id, String symbolicName, Version version, String location, BundleSpecification[] required, HostSpecification host, ImportPackageSpecification[] imports, ExportPackageDescription[] exports, String[] providedPackages, boolean singleton, boolean attachFragments, boolean dynamicFragments, String platformFilter, String executionEnvironment, GenericSpecification[] genericRequires, GenericDescription[] genericCapabilities)50 	public BundleDescription createBundleDescription(long id, String symbolicName, Version version, String location, BundleSpecification[] required, HostSpecification host, ImportPackageSpecification[] imports, ExportPackageDescription[] exports, String[] providedPackages, boolean singleton, boolean attachFragments, boolean dynamicFragments, String platformFilter, String executionEnvironment, GenericSpecification[] genericRequires, GenericDescription[] genericCapabilities) {
51 		// bug 154137 we need to parse the executionEnvironment param; no need to check for null, ManifestElement does that for us.
52 		return createBundleDescription(id, symbolicName, version, location, required, host, imports, exports, singleton, attachFragments, dynamicFragments, platformFilter, ManifestElement.getArrayFromList(executionEnvironment), genericRequires, genericCapabilities);
53 	}
54 
createBundleDescription(long id, String symbolicName, Version version, String location, BundleSpecification[] required, HostSpecification host, ImportPackageSpecification[] imports, ExportPackageDescription[] exports, boolean singleton, boolean attachFragments, boolean dynamicFragments, String platformFilter, String[] executionEnvironments, GenericSpecification[] genericRequires, GenericDescription[] genericCapabilities)55 	public BundleDescription createBundleDescription(long id, String symbolicName, Version version, String location, BundleSpecification[] required, HostSpecification host, ImportPackageSpecification[] imports, ExportPackageDescription[] exports, boolean singleton, boolean attachFragments, boolean dynamicFragments, String platformFilter, String[] executionEnvironments, GenericSpecification[] genericRequires, GenericDescription[] genericCapabilities) {
56 		return createBundleDescription(id, symbolicName, version, location, required, host, imports, exports, singleton, attachFragments, dynamicFragments, platformFilter, executionEnvironments, genericRequires, genericCapabilities, null);
57 	}
58 
createBundleDescription(long id, String symbolicName, Version version, String location, BundleSpecification[] required, HostSpecification host, ImportPackageSpecification[] imports, ExportPackageDescription[] exports, boolean singleton, boolean attachFragments, boolean dynamicFragments, String platformFilter, String[] executionEnvironments, GenericSpecification[] genericRequires, GenericDescription[] genericCapabilities, NativeCodeSpecification nativeCode)59 	public BundleDescription createBundleDescription(long id, String symbolicName, Version version, String location, BundleSpecification[] required, HostSpecification host, ImportPackageSpecification[] imports, ExportPackageDescription[] exports, boolean singleton, boolean attachFragments, boolean dynamicFragments, String platformFilter, String[] executionEnvironments, GenericSpecification[] genericRequires, GenericDescription[] genericCapabilities, NativeCodeSpecification nativeCode) {
60 		BundleDescriptionImpl bundle = new BundleDescriptionImpl();
61 		bundle.setBundleId(id);
62 		bundle.setSymbolicName(symbolicName);
63 		bundle.setVersion(version);
64 		bundle.setLocation(location);
65 		bundle.setRequiredBundles(required);
66 		bundle.setHost(host);
67 		bundle.setImportPackages(imports);
68 		bundle.setExportPackages(exports);
69 		bundle.setStateBit(BundleDescriptionImpl.SINGLETON, singleton);
70 		bundle.setStateBit(BundleDescriptionImpl.ATTACH_FRAGMENTS, attachFragments);
71 		bundle.setStateBit(BundleDescriptionImpl.DYNAMIC_FRAGMENTS, dynamicFragments);
72 		bundle.setPlatformFilter(platformFilter);
73 		bundle.setExecutionEnvironments(executionEnvironments);
74 		bundle.setGenericRequires(genericRequires);
75 		bundle.setGenericCapabilities(genericCapabilities);
76 		bundle.setNativeCodeSpecification(nativeCode);
77 		return bundle;
78 	}
79 
createBundleDescription(long id, String symbolicName, Version version, String location, BundleSpecification[] required, HostSpecification host, ImportPackageSpecification[] imports, ExportPackageDescription[] exports, String platformFilter, String[] executionEnvironments, GenericSpecification[] genericRequires, GenericDescription[] genericCapabilities, NativeCodeSpecification nativeCode)80 	public BundleDescription createBundleDescription(long id, String symbolicName, Version version, String location, BundleSpecification[] required, HostSpecification host, ImportPackageSpecification[] imports, ExportPackageDescription[] exports, String platformFilter, String[] executionEnvironments, GenericSpecification[] genericRequires, GenericDescription[] genericCapabilities, NativeCodeSpecification nativeCode) {
81 		BundleDescriptionImpl bundle = new BundleDescriptionImpl();
82 		bundle.setBundleId(id);
83 
84 		try {
85 			ManifestElement[] symbolicNameElements = ManifestElement.parseHeader(Constants.BUNDLE_SYMBOLICNAME, symbolicName);
86 			if (symbolicNameElements != null && symbolicNameElements.length > 0) {
87 				ManifestElement bsnElement = symbolicNameElements[0];
88 				bundle.setSymbolicName(bsnElement.getValue());
89 				bundle.setStateBit(BundleDescriptionImpl.SINGLETON, "true".equals(bsnElement.getDirective(Constants.SINGLETON_DIRECTIVE))); //$NON-NLS-1$
90 				String fragmentAttachment = bsnElement.getDirective(Constants.FRAGMENT_ATTACHMENT_DIRECTIVE);
91 				if (fragmentAttachment != null) {
92 					if (fragmentAttachment.equals(Constants.FRAGMENT_ATTACHMENT_RESOLVETIME)) {
93 						bundle.setStateBit(BundleDescriptionImpl.ATTACH_FRAGMENTS, true);
94 						bundle.setStateBit(BundleDescriptionImpl.DYNAMIC_FRAGMENTS, false);
95 					} else if (fragmentAttachment.equals(Constants.FRAGMENT_ATTACHMENT_NEVER)) {
96 						bundle.setStateBit(BundleDescriptionImpl.ATTACH_FRAGMENTS, false);
97 						bundle.setStateBit(BundleDescriptionImpl.DYNAMIC_FRAGMENTS, false);
98 					}
99 				}
100 				bundle.setDirective(Constants.MANDATORY_DIRECTIVE, ManifestElement.getArrayFromList(bsnElement.getDirective(Constants.MANDATORY_DIRECTIVE)));
101 				bundle.setAttributes(StateBuilder.getAttributes(bsnElement, StateBuilder.DEFINED_BSN_MATCHING_ATTRS));
102 				bundle.setArbitraryDirectives(StateBuilder.getDirectives(bsnElement, StateBuilder.DEFINED_BSN_DIRECTIVES));
103 			}
104 		} catch (BundleException e) {
105 			throw new IllegalArgumentException("Illegal symbolic name: " + symbolicName, e); //$NON-NLS-1$
106 		}
107 
108 		bundle.setVersion(version);
109 		bundle.setLocation(location);
110 		bundle.setRequiredBundles(required);
111 		bundle.setHost(host);
112 		bundle.setImportPackages(imports);
113 		bundle.setExportPackages(exports);
114 		bundle.setPlatformFilter(platformFilter);
115 		bundle.setExecutionEnvironments(executionEnvironments);
116 		bundle.setGenericRequires(genericRequires);
117 
118 		List<GenericDescription> includeIdentity = new ArrayList<>(genericCapabilities == null ? 1 : genericCapabilities.length + 1);
119 		GenericDescription genericIdentity = StateBuilder.createOsgiIdentityCapability(bundle);
120 		if (genericIdentity != null) {
121 			includeIdentity.add(genericIdentity);
122 		}
123 		if (genericCapabilities != null) {
124 			Collections.addAll(includeIdentity, genericCapabilities);
125 		}
126 		if (!includeIdentity.isEmpty()) {
127 			bundle.setGenericCapabilities(includeIdentity.toArray(new GenericDescription[includeIdentity.size()]));
128 		}
129 		bundle.setNativeCodeSpecification(nativeCode);
130 		return bundle;
131 	}
132 
createBundleDescription(BundleDescription original)133 	public BundleDescription createBundleDescription(BundleDescription original) {
134 		BundleDescriptionImpl bundle = new BundleDescriptionImpl();
135 		bundle.setBundleId(original.getBundleId());
136 		bundle.setSymbolicName(original.getSymbolicName());
137 		bundle.setVersion(original.getVersion());
138 		bundle.setLocation(original.getLocation());
139 		BundleSpecification[] originalRequired = original.getRequiredBundles();
140 		BundleSpecification[] newRequired = new BundleSpecification[originalRequired.length];
141 		for (int i = 0; i < newRequired.length; i++)
142 			newRequired[i] = createBundleSpecification(originalRequired[i]);
143 		bundle.setRequiredBundles(newRequired);
144 		ExportPackageDescription[] originalExports = original.getExportPackages();
145 		ExportPackageDescription[] newExports = new ExportPackageDescription[originalExports.length];
146 		for (int i = 0; i < newExports.length; i++)
147 			newExports[i] = createExportPackageDescription(originalExports[i]);
148 		bundle.setExportPackages(newExports);
149 		ImportPackageSpecification[] originalImports = original.getImportPackages();
150 		ImportPackageSpecification[] newImports = new ImportPackageSpecification[originalImports.length];
151 		for (int i = 0; i < newImports.length; i++)
152 			newImports[i] = createImportPackageSpecification(originalImports[i]);
153 		bundle.setImportPackages(newImports);
154 		if (original.getHost() != null)
155 			bundle.setHost(createHostSpecification(original.getHost()));
156 		bundle.setStateBit(BundleDescriptionImpl.SINGLETON, original.isSingleton());
157 		bundle.setStateBit(BundleDescriptionImpl.ATTACH_FRAGMENTS, original.attachFragments());
158 		bundle.setStateBit(BundleDescriptionImpl.DYNAMIC_FRAGMENTS, original.dynamicFragments());
159 		bundle.setStateBit(BundleDescriptionImpl.HAS_DYNAMICIMPORT, original.hasDynamicImports());
160 		bundle.setPlatformFilter(original.getPlatformFilter());
161 		bundle.setExecutionEnvironments(original.getExecutionEnvironments());
162 		bundle.setGenericCapabilities(createGenericCapabilities(original.getGenericCapabilities()));
163 		bundle.setGenericRequires(createGenericRequires(original.getGenericRequires()));
164 		bundle.setNativeCodeSpecification(createNativeCodeSpecification(original.getNativeCodeSpecification()));
165 		bundle.setAttributes(original.getAttributes());
166 		if (original instanceof BundleDescriptionImpl) {
167 			bundle.setDirective(Constants.MANDATORY_DIRECTIVE, ((BundleDescriptionImpl) original).getDirective(Constants.MANDATORY_DIRECTIVE));
168 			bundle.setArbitraryDirectives(((BundleDescriptionImpl) original).getArbitraryDirectives());
169 		}
170 		return bundle;
171 	}
172 
createNativeCodeSpecification(NativeCodeSpecification original)173 	private NativeCodeSpecification createNativeCodeSpecification(NativeCodeSpecification original) {
174 		if (original == null)
175 			return null;
176 		NativeCodeSpecificationImpl result = new NativeCodeSpecificationImpl();
177 		result.setName(original.getName());
178 		result.setOptional(original.isOptional());
179 		NativeCodeDescription[] originalDescriptions = original.getPossibleSuppliers();
180 		NativeCodeDescriptionImpl[] newDescriptions = new NativeCodeDescriptionImpl[originalDescriptions.length];
181 		for (int i = 0; i < originalDescriptions.length; i++) {
182 			newDescriptions[i] = new NativeCodeDescriptionImpl();
183 			newDescriptions[i].setName(originalDescriptions[i].getName());
184 			newDescriptions[i].setNativePaths(originalDescriptions[i].getNativePaths());
185 			newDescriptions[i].setProcessors(originalDescriptions[i].getProcessors());
186 			newDescriptions[i].setOSNames(originalDescriptions[i].getOSNames());
187 			newDescriptions[i].setOSVersions(originalDescriptions[i].getOSVersions());
188 			newDescriptions[i].setLanguages(originalDescriptions[i].getLanguages());
189 			try {
190 				newDescriptions[i].setFilter(originalDescriptions[i].getFilter() == null ? null : originalDescriptions[i].getFilter().toString());
191 			} catch (InvalidSyntaxException e) {
192 				// this is already tested from the orginal filter
193 			}
194 		}
195 		result.setPossibleSuppliers(newDescriptions);
196 		return result;
197 	}
198 
createGenericCapabilities(GenericDescription[] genericCapabilities)199 	private GenericDescription[] createGenericCapabilities(GenericDescription[] genericCapabilities) {
200 		if (genericCapabilities == null || genericCapabilities.length == 0)
201 			return null;
202 		GenericDescription[] result = new GenericDescription[genericCapabilities.length];
203 		for (int i = 0; i < genericCapabilities.length; i++) {
204 			GenericDescriptionImpl cap = new GenericDescriptionImpl();
205 			cap.setType(genericCapabilities[i].getType());
206 			cap.setAttributes(genericCapabilities[i].getAttributes());
207 			cap.setDirectives(genericCapabilities[i].getDeclaredDirectives());
208 			result[i] = cap;
209 		}
210 		return result;
211 	}
212 
createGenericRequires(GenericSpecification[] genericRequires)213 	private GenericSpecification[] createGenericRequires(GenericSpecification[] genericRequires) {
214 		if (genericRequires == null || genericRequires.length == 0)
215 			return null;
216 		GenericSpecification[] result = new GenericSpecification[genericRequires.length];
217 		for (int i = 0; i < genericRequires.length; i++) {
218 			GenericSpecificationImpl req = new GenericSpecificationImpl();
219 			req.setName(genericRequires[i].getName());
220 			req.setType(genericRequires[i].getType());
221 			req.setResolution(genericRequires[i].getResolution());
222 			try {
223 				req.setMatchingFilter(genericRequires[i].getMatchingFilter(), false);
224 			} catch (InvalidSyntaxException e) {
225 				// do nothing; this filter should already have been tested
226 			}
227 			if (genericRequires[i] instanceof GenericSpecificationImpl) {
228 				req.setAttributes(((GenericSpecificationImpl) genericRequires[i]).getAttributes());
229 				req.setArbitraryDirectives(((GenericSpecificationImpl) genericRequires[i]).getArbitraryDirectives());
230 			}
231 			result[i] = req;
232 		}
233 		return result;
234 	}
235 
createBundleSpecification(String requiredSymbolicName, VersionRange requiredVersionRange, boolean export, boolean optional)236 	public BundleSpecification createBundleSpecification(String requiredSymbolicName, VersionRange requiredVersionRange, boolean export, boolean optional) {
237 		BundleSpecificationImpl bundleSpec = new BundleSpecificationImpl();
238 		bundleSpec.setName(requiredSymbolicName);
239 		bundleSpec.setVersionRange(requiredVersionRange);
240 		bundleSpec.setExported(export);
241 		bundleSpec.setOptional(optional);
242 		return bundleSpec;
243 	}
244 
createBundleSpecification(BundleSpecification original)245 	public BundleSpecification createBundleSpecification(BundleSpecification original) {
246 		BundleSpecificationImpl bundleSpec = new BundleSpecificationImpl();
247 		bundleSpec.setName(original.getName());
248 		bundleSpec.setVersionRange(original.getVersionRange());
249 		bundleSpec.setExported(original.isExported());
250 		bundleSpec.setOptional(original.isOptional());
251 		if (original instanceof BundleSpecificationImpl) {
252 			bundleSpec.setAttributes(((BundleSpecificationImpl) original).getAttributes());
253 			bundleSpec.setArbitraryDirectives(((BundleSpecificationImpl) original).getArbitraryDirectives());
254 		}
255 		return bundleSpec;
256 	}
257 
createHostSpecification(String hostSymbolicName, VersionRange versionRange)258 	public HostSpecification createHostSpecification(String hostSymbolicName, VersionRange versionRange) {
259 		HostSpecificationImpl hostSpec = new HostSpecificationImpl();
260 		hostSpec.setName(hostSymbolicName);
261 		hostSpec.setVersionRange(versionRange);
262 		return hostSpec;
263 	}
264 
createHostSpecification(HostSpecification original)265 	public HostSpecification createHostSpecification(HostSpecification original) {
266 		HostSpecificationImpl hostSpec = new HostSpecificationImpl();
267 		hostSpec.setName(original.getName());
268 		hostSpec.setVersionRange(original.getVersionRange());
269 		if (original instanceof HostSpecificationImpl) {
270 			hostSpec.setAttributes(((HostSpecificationImpl) original).getAttributes());
271 			hostSpec.setArbitraryDirectives(((HostSpecificationImpl) original).getArbitraryDirectives());
272 		}
273 		return hostSpec;
274 	}
275 
createImportPackageSpecification(String packageName, VersionRange versionRange, String bundleSymbolicName, VersionRange bundleVersionRange, Map<String, ?> directives, Map<String, ?> attributes, BundleDescription importer)276 	public ImportPackageSpecification createImportPackageSpecification(String packageName, VersionRange versionRange, String bundleSymbolicName, VersionRange bundleVersionRange, Map<String, ?> directives, Map<String, ?> attributes, BundleDescription importer) {
277 		ImportPackageSpecificationImpl packageSpec = new ImportPackageSpecificationImpl();
278 		packageSpec.setName(packageName);
279 		packageSpec.setVersionRange(versionRange);
280 		packageSpec.setBundleSymbolicName(bundleSymbolicName);
281 		packageSpec.setBundleVersionRange(bundleVersionRange);
282 		packageSpec.setDirectives(directives);
283 		packageSpec.setAttributes(attributes);
284 		packageSpec.setBundle(importer);
285 		return packageSpec;
286 	}
287 
createImportPackageSpecification(ImportPackageSpecification original)288 	public ImportPackageSpecification createImportPackageSpecification(ImportPackageSpecification original) {
289 		ImportPackageSpecificationImpl packageSpec = new ImportPackageSpecificationImpl();
290 		packageSpec.setName(original.getName());
291 		packageSpec.setVersionRange(original.getVersionRange());
292 		packageSpec.setBundleSymbolicName(original.getBundleSymbolicName());
293 		packageSpec.setBundleVersionRange(original.getBundleVersionRange());
294 		packageSpec.setDirectives(original.getDirectives());
295 		packageSpec.setAttributes(original.getAttributes());
296 		if (original instanceof ImportPackageSpecificationImpl) {
297 			packageSpec.setArbitraryDirectives(((ImportPackageSpecificationImpl) original).getArbitraryDirectives());
298 		}
299 		return packageSpec;
300 	}
301 
createExportPackageDescription(ExportPackageDescription original)302 	public ExportPackageDescription createExportPackageDescription(ExportPackageDescription original) {
303 		ExportPackageDescriptionImpl exportPackage = new ExportPackageDescriptionImpl();
304 		exportPackage.setName(original.getName());
305 		exportPackage.setVersion(original.getVersion());
306 		exportPackage.setDirectives(original.getDirectives());
307 		exportPackage.setAttributes(original.getAttributes());
308 		exportPackage.setArbitraryDirectives(((ExportPackageDescriptionImpl) original).getArbitraryDirectives());
309 		return exportPackage;
310 	}
311 
createExportPackageDescription(String packageName, Version version, Map<String, ?> directives, Map<String, ?> attributes, boolean root, BundleDescription exporter)312 	public ExportPackageDescription createExportPackageDescription(String packageName, Version version, Map<String, ?> directives, Map<String, ?> attributes, boolean root, BundleDescription exporter) {
313 		ExportPackageDescriptionImpl exportPackage = new ExportPackageDescriptionImpl();
314 		exportPackage.setName(packageName);
315 		exportPackage.setVersion(version);
316 		exportPackage.setDirectives(directives);
317 		exportPackage.setAttributes(attributes);
318 		exportPackage.setExporter(exporter);
319 		return exportPackage;
320 	}
321 
322 	/**
323 	 * @deprecated
324 	 */
createGenericDescription(String name, String type, Version version, Map<String, ?> attributes)325 	public GenericDescription createGenericDescription(String name, String type, Version version, Map<String, ?> attributes) {
326 		return createGenericDescription(name, type, version, attributes, null, null);
327 	}
328 
createGenericDescription(String type, Map<String, ?> attributes, Map<String, String> directives, BundleDescription supplier)329 	public GenericDescription createGenericDescription(String type, Map<String, ?> attributes, Map<String, String> directives, BundleDescription supplier) {
330 		return createGenericDescription(null, type, null, attributes, directives, supplier);
331 	}
332 
createGenericDescription(String name, String type, Version version, Map<String, ?> attributes, Map<String, String> directives, BundleDescription supplier)333 	private GenericDescription createGenericDescription(String name, String type, Version version, Map<String, ?> attributes, Map<String, String> directives, BundleDescription supplier) {
334 		GenericDescriptionImpl result = new GenericDescriptionImpl();
335 		result.setType(type);
336 		Dictionary<String, Object> attrs = attributes == null ? new Hashtable<String, Object>() : new Hashtable<>(attributes);
337 		if (version != null) {
338 			Object versionObj = attrs.get(Constants.VERSION_ATTRIBUTE);
339 			if (!(versionObj instanceof Version) && version != null)
340 				attrs.put(Constants.VERSION_ATTRIBUTE, version);
341 		}
342 		if (name != null) {
343 			Object nameObj = attrs.get(result.getType());
344 			if (!(nameObj instanceof String))
345 				attrs.put(result.getType(), name);
346 		}
347 		result.setAttributes(attrs);
348 		result.setDirectives(directives);
349 		result.setSupplier(supplier);
350 		return result;
351 	}
352 
createGenericSpecification(String name, String type, String matchingFilter, boolean optional, boolean multiple)353 	public GenericSpecification createGenericSpecification(String name, String type, String matchingFilter, boolean optional, boolean multiple) throws InvalidSyntaxException {
354 		GenericSpecificationImpl result = new GenericSpecificationImpl();
355 		result.setName(name);
356 		result.setType(type);
357 		result.setMatchingFilter(matchingFilter, true);
358 		int resolution = 0;
359 		if (optional)
360 			resolution |= GenericSpecification.RESOLUTION_OPTIONAL;
361 		if (multiple)
362 			resolution |= GenericSpecification.RESOLUTION_MULTIPLE;
363 		result.setResolution(resolution);
364 		return result;
365 	}
366 
createNativeCodeDescription(String[] nativePaths, String[] processors, String[] osNames, VersionRange[] osVersions, String[] languages, String filter)367 	public NativeCodeDescription createNativeCodeDescription(String[] nativePaths, String[] processors, String[] osNames, VersionRange[] osVersions, String[] languages, String filter) throws InvalidSyntaxException {
368 		NativeCodeDescriptionImpl result = new NativeCodeDescriptionImpl();
369 		result.setName(Constants.BUNDLE_NATIVECODE);
370 		result.setNativePaths(nativePaths);
371 		result.setProcessors(processors);
372 		result.setOSNames(osNames);
373 		result.setOSVersions(osVersions);
374 		result.setLanguages(languages);
375 		result.setFilter(filter);
376 		return result;
377 	}
378 
createNativeCodeSpecification(NativeCodeDescription[] nativeCodeDescriptions, boolean optional)379 	public NativeCodeSpecification createNativeCodeSpecification(NativeCodeDescription[] nativeCodeDescriptions, boolean optional) {
380 		NativeCodeSpecificationImpl result = new NativeCodeSpecificationImpl();
381 		result.setName(Constants.BUNDLE_NATIVECODE);
382 		result.setOptional(optional);
383 		result.setPossibleSuppliers(nativeCodeDescriptions);
384 		return result;
385 	}
386 
387 	/**
388 	 * @deprecated
389 	 */
createState()390 	public State createState() {
391 		return internalCreateState();
392 	}
393 
createState(boolean createResolver)394 	public State createState(boolean createResolver) {
395 		State result = internalCreateState();
396 		if (createResolver)
397 			result.setResolver(new ResolverImpl(false));
398 		return result;
399 	}
400 
createState(State original)401 	public State createState(State original) {
402 		StateImpl newState = internalCreateState();
403 		newState.setTimeStamp(original.getTimeStamp());
404 		BundleDescription[] bundles = original.getBundles();
405 		for (BundleDescription bundle : bundles) {
406 			BundleDescription newBundle = createBundleDescription(bundle);
407 			newState.basicAddBundle(newBundle);
408 			DisabledInfo[] infos = original.getDisabledInfos(bundle);
409 			for (DisabledInfo info : infos) {
410 				newState.addDisabledInfo(new DisabledInfo(info.getPolicyName(), info.getMessage(), newBundle));
411 			}
412 		}
413 		newState.setResolved(false);
414 		newState.setPlatformProperties(original.getPlatformProperties());
415 		return newState;
416 	}
417 
internalCreateState()418 	private StateImpl internalCreateState() {
419 		StateImpl state = new UserState();
420 		state.setFactory(this);
421 		return state;
422 	}
423 
424 	/**
425 	 * @deprecated
426 	 */
readState(InputStream stream)427 	public State readState(InputStream stream) throws IOException {
428 		return internalReadStateDeprecated(internalCreateState(), new DataInputStream(stream), -1);
429 	}
430 
431 	/**
432 	 * @deprecated
433 	 */
readState(DataInputStream stream)434 	public State readState(DataInputStream stream) throws IOException {
435 		return internalReadStateDeprecated(internalCreateState(), stream, -1);
436 	}
437 
readState(File stateDirectory)438 	public State readState(File stateDirectory) throws IOException {
439 		return internalReadState(internalCreateState(), stateDirectory, -1);
440 	}
441 
internalReadStateDeprecated(StateImpl toRestore, DataInputStream stream, long expectedTimestamp)442 	private State internalReadStateDeprecated(StateImpl toRestore, DataInputStream stream, long expectedTimestamp) throws IOException {
443 		StateReader reader = new StateReader();
444 		if (!reader.loadStateDeprecated(toRestore, stream, expectedTimestamp))
445 			return null;
446 		return toRestore;
447 	}
448 
internalReadState(StateImpl toRestore, File stateDirectory, long expectedTimestamp)449 	private State internalReadState(StateImpl toRestore, File stateDirectory, long expectedTimestamp) throws IOException {
450 		File stateFile = new File(stateDirectory, StateReader.STATE_FILE);
451 		File lazyFile = new File(stateDirectory, StateReader.LAZY_FILE);
452 		if (!stateFile.exists() || !lazyFile.exists()) {
453 			StorageManager storageManager = new StorageManager(stateDirectory, "none", true); //$NON-NLS-1$
454 			try {
455 				// if the directory is pointing at the configuration directory then the base files will not exist
456 				storageManager.open(true);
457 				// try using the storage manager to find the managed state files (bug 143255)
458 				File managedState = storageManager.lookup(StateReader.STATE_FILE, false);
459 				File managedLazy = storageManager.lookup(StateReader.LAZY_FILE, false);
460 				if (managedState != null && managedLazy != null) {
461 					stateFile = managedState;
462 					lazyFile = managedLazy;
463 				}
464 			} finally {
465 				storageManager.close();
466 			}
467 		}
468 		StateReader reader = new StateReader(stateFile, lazyFile, false);
469 		if (!reader.loadState(toRestore, expectedTimestamp))
470 			return null;
471 		return toRestore;
472 	}
473 
474 	/**
475 	 * @deprecated
476 	 */
writeState(State state, DataOutputStream stream)477 	public void writeState(State state, DataOutputStream stream) throws IOException {
478 		internalWriteStateDeprecated(state, stream);
479 	}
480 
writeState(State state, File stateDirectory)481 	public void writeState(State state, File stateDirectory) throws IOException {
482 		if (stateDirectory == null)
483 			throw new IOException();
484 		StateWriter writer = new StateWriter();
485 		File stateFile = new File(stateDirectory, StateReader.STATE_FILE);
486 		File lazyFile = new File(stateDirectory, StateReader.LAZY_FILE);
487 		writer.saveState((StateImpl) state, stateFile, lazyFile);
488 	}
489 
490 	/**
491 	 * @deprecated
492 	 */
writeState(State state, OutputStream stream)493 	public void writeState(State state, OutputStream stream) throws IOException {
494 		internalWriteStateDeprecated(state, new DataOutputStream(stream));
495 	}
496 
writeState(State state, File stateFile, File lazyFile)497 	public void writeState(State state, File stateFile, File lazyFile) throws IOException {
498 		StateWriter writer = new StateWriter();
499 		writer.saveState((StateImpl) state, stateFile, lazyFile);
500 	}
501 
internalWriteStateDeprecated(State state, DataOutputStream stream)502 	private void internalWriteStateDeprecated(State state, DataOutputStream stream) throws IOException {
503 		if (state.getFactory() != this)
504 			throw new IllegalArgumentException();
505 		StateWriter writer = new StateWriter();
506 		writer.saveStateDeprecated((StateImpl) state, stream);
507 	}
508 
createBundleSpecifications(String declaration)509 	public List<BundleSpecification> createBundleSpecifications(String declaration) {
510 		try {
511 			ManifestElement[] elements = ManifestElement.parseHeader(Constants.REQUIRE_BUNDLE, declaration);
512 			if (elements == null)
513 				return Collections.<BundleSpecification> emptyList();
514 			List<BundleSpecification> result = new ArrayList<>(elements.length);
515 			for (ManifestElement element : elements)
516 				result.add(StateBuilder.createRequiredBundle(element));
517 			return result;
518 		} catch (BundleException e) {
519 			throw new IllegalArgumentException("Declaration is invalid: " + declaration, e); //$NON-NLS-1$
520 		}
521 	}
522 
createHostSpecifications(String declaration)523 	public List<HostSpecification> createHostSpecifications(String declaration) {
524 		try {
525 			ManifestElement[] elements = ManifestElement.parseHeader(Constants.FRAGMENT_HOST, declaration);
526 			if (elements == null)
527 				return Collections.<HostSpecification> emptyList();
528 			List<HostSpecification> result = new ArrayList<>(elements.length);
529 			for (ManifestElement element : elements)
530 				result.add(StateBuilder.createHostSpecification(element, null));
531 			return result;
532 		} catch (BundleException e) {
533 			throw new IllegalArgumentException("Declaration is invalid: " + declaration, e); //$NON-NLS-1$
534 		}
535 	}
536 
createImportPackageSpecifications(String declaration)537 	public List<ImportPackageSpecification> createImportPackageSpecifications(String declaration) {
538 		try {
539 			ManifestElement[] elements = ManifestElement.parseHeader(Constants.IMPORT_PACKAGE, declaration);
540 			if (elements == null)
541 				return Collections.<ImportPackageSpecification> emptyList();
542 			List<ImportPackageSpecification> result = new ArrayList<>(elements.length);
543 			for (ManifestElement element : elements)
544 				StateBuilder.addImportPackages(element, result, 2, false);
545 			return result;
546 		} catch (BundleException e) {
547 			throw new IllegalArgumentException("Declaration is invalid: " + declaration, e); //$NON-NLS-1$
548 		}
549 	}
550 
createGenericDescriptions(String declaration)551 	public List<GenericDescription> createGenericDescriptions(String declaration) {
552 		try {
553 			ManifestElement[] elements = ManifestElement.parseHeader(Constants.PROVIDE_CAPABILITY, declaration);
554 			if (elements == null)
555 				return Collections.<GenericDescription> emptyList();
556 			return StateBuilder.createOSGiCapabilities(elements, new ArrayList<GenericDescription>(elements.length), (Integer) null);
557 		} catch (BundleException e) {
558 			throw new IllegalArgumentException("Declaration is invalid: " + declaration, e); //$NON-NLS-1$
559 		}
560 	}
561 
createGenericSpecifications(String declaration)562 	public List<GenericSpecification> createGenericSpecifications(String declaration) {
563 		try {
564 			ManifestElement[] elements = ManifestElement.parseHeader(Constants.REQUIRE_CAPABILITY, declaration);
565 			if (elements == null)
566 				return Collections.<GenericSpecification> emptyList();
567 			return StateBuilder.createOSGiRequires(elements, new ArrayList<GenericSpecification>(elements.length));
568 		} catch (BundleException e) {
569 			throw new IllegalArgumentException("Declaration is invalid: " + declaration, e); //$NON-NLS-1$
570 		}
571 	}
572 
createExportPackageDescriptions(String declaration)573 	public List<ExportPackageDescription> createExportPackageDescriptions(String declaration) {
574 		try {
575 			ManifestElement[] elements = ManifestElement.parseHeader(Constants.IMPORT_PACKAGE, declaration);
576 			if (elements == null)
577 				return Collections.<ExportPackageDescription> emptyList();
578 			List<ExportPackageDescription> result = new ArrayList<>(elements.length);
579 			for (ManifestElement element : elements)
580 				StateBuilder.addExportPackages(element, result, false);
581 			return result;
582 		} catch (BundleException e) {
583 			throw new IllegalArgumentException("Declaration is invalid: " + declaration, e); //$NON-NLS-1$
584 		}
585 	}
586 }
587