Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Watson2007-09-05 18:28:58 +0000
committerThomas Watson2007-09-05 18:28:58 +0000
commitdd53c9a33ca09f6e6383173891f190cfef2ed5f7 (patch)
tree4d2c131f2ea8ac4d587b2dd26867e2f9116e9796 /bundles/org.eclipse.osgi/resolver
parent01a1e8cdf381f2cb19e3d19100d5c5550d7d2ec9 (diff)
downloadrt.equinox.framework-dd53c9a33ca09f6e6383173891f190cfef2ed5f7.tar.gz
rt.equinox.framework-dd53c9a33ca09f6e6383173891f190cfef2ed5f7.tar.xz
rt.equinox.framework-dd53c9a33ca09f6e6383173891f190cfef2ed5f7.zip
Bug 165964 Process Bundle-NativeCode at resolve time
Diffstat (limited to 'bundles/org.eclipse.osgi/resolver')
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java22
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java23
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/NativeCodeDescriptionImpl.java190
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/NativeCodeSpecificationImpl.java136
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ReadOnlyState.java5
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ResolverErrorImpl.java7
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateBuilder.java48
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java30
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateMessages.properties4
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateMsg.java4
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateObjectFactoryImpl.java76
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateReader.java62
-rw-r--r--bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateWriter.java57
13 files changed, 648 insertions, 16 deletions
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java
index 5badacb6a..d84d1421e 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/module/ResolverImpl.java
@@ -265,6 +265,28 @@ public class ResolverImpl implements org.eclipse.osgi.service.resolver.Resolver
return false;
}
+ // check the native code specification
+ NativeCodeSpecification nativeCode = bundle.getNativeCodeSpecification();
+ if (nativeCode != null) {
+ NativeCodeDescription[] nativeCodeSuppliers = nativeCode.getPossibleSuppliers();
+ NativeCodeDescription highestRanked = null;
+ for (int i = 0; i < nativeCodeSuppliers.length; i++)
+ if (nativeCode.isSatisfiedBy(nativeCodeSuppliers[i]) && (highestRanked == null || highestRanked.compareTo(nativeCodeSuppliers[i]) < 0))
+ highestRanked = nativeCodeSuppliers[i];
+ if (highestRanked == null) {
+ if (!nativeCode.isOptional()) {
+ state.addResolverError(bundle, ResolverError.NO_NATIVECODE_MATCH, nativeCode.toString(), nativeCode);
+ return false;
+ }
+ } else {
+ if (highestRanked.hasInvalidNativePaths()) {
+ state.addResolverError(bundle, ResolverError.INVALID_NATIVECODE_PATHS, highestRanked.toString(), nativeCode);
+ return false;
+ }
+ }
+ state.resolveConstraint(nativeCode, highestRanked);
+ }
+
// check the platform filter
String platformFilter = bundle.getPlatformFilter();
if (platformFilter == null)
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java
index 1ae157cbb..1f0987f5e 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/BundleDescriptionImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2006 IBM Corporation and others.
+ * Copyright (c) 2003, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -113,6 +113,11 @@ public class BundleDescriptionImpl extends BaseDescriptionImpl implements Bundle
return lazyData.genericCapabilities;
}
+ public NativeCodeSpecification getNativeCodeSpecification() {
+ fullyLoad();
+ return lazyData.nativeCode;
+ }
+
public ExportPackageDescription[] getExportPackages() {
fullyLoad();
return lazyData.exportPackages == null ? EMPTY_EXPORTS : lazyData.exportPackages;
@@ -251,6 +256,19 @@ public class BundleDescriptionImpl extends BaseDescriptionImpl implements Bundle
((VersionConstraintImpl) genericRequires[i]).setBundle(this);
}
+ protected void setNativeCodeSpecification(NativeCodeSpecification nativeCode) {
+ checkLazyData();
+ lazyData.nativeCode = nativeCode;
+ if (nativeCode != null) {
+ ((NativeCodeSpecificationImpl) nativeCode).setBundle(this);
+ NativeCodeDescription[] suppliers = nativeCode.getPossibleSuppliers();
+ if (suppliers != null)
+ for (int i = 0; i < suppliers.length; i++)
+ ((NativeCodeDescriptionImpl) suppliers[i]).setSupplier(this);
+ }
+
+ }
+
protected int getStateBits() {
return stateBits;
}
@@ -450,7 +468,7 @@ public class BundleDescriptionImpl extends BaseDescriptionImpl implements Bundle
synchronized (reader) {
if (isFullyLoaded()) {
reader.setAccessedFlag(true); // set reader accessed flag
- return;
+ return;
}
try {
reader.fullyLoad(this);
@@ -543,6 +561,7 @@ public class BundleDescriptionImpl extends BaseDescriptionImpl implements Bundle
ImportPackageSpecification[] importPackages;
GenericDescription[] genericCapabilities;
GenericSpecification[] genericRequires;
+ NativeCodeSpecification nativeCode;
ExportPackageDescription[] selectedExports;
BundleDescription[] resolvedRequires;
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/NativeCodeDescriptionImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/NativeCodeDescriptionImpl.java
new file mode 100644
index 000000000..75ae9cc8b
--- /dev/null
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/NativeCodeDescriptionImpl.java
@@ -0,0 +1,190 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.internal.resolver;
+
+import java.util.Dictionary;
+import org.eclipse.osgi.framework.internal.core.Constants;
+import org.eclipse.osgi.service.resolver.*;
+import org.osgi.framework.*;
+
+public class NativeCodeDescriptionImpl extends BaseDescriptionImpl implements NativeCodeDescription {
+ private static final VersionRange[] EMPTY_VERSIONRANGES = new VersionRange[0];
+
+ private Filter filter;
+ private String[] languages;
+ private String[] nativePaths;
+ private String[] osNames;
+ private VersionRange[] osVersions;
+ private String[] processors;
+ private BundleDescription supplier;
+ private boolean invalidNativePaths = false;
+
+ public Filter getFilter() {
+ return filter;
+ }
+
+ public String[] getLanguages() {
+ if (languages == null)
+ return BundleDescriptionImpl.EMPTY_STRING;
+ return languages;
+ }
+
+ public String[] getNativePaths() {
+ if (nativePaths == null)
+ return BundleDescriptionImpl.EMPTY_STRING;
+ return nativePaths;
+ }
+
+ public String[] getOSNames() {
+ if (osNames == null)
+ return BundleDescriptionImpl.EMPTY_STRING;
+ return osNames;
+ }
+
+ public VersionRange[] getOSVersions() {
+ if (osVersions == null)
+ return EMPTY_VERSIONRANGES;
+ return osVersions;
+ }
+
+ public String[] getProcessors() {
+ if (processors == null)
+ return BundleDescriptionImpl.EMPTY_STRING;
+ return processors;
+ }
+
+ public BundleDescription getSupplier() {
+ return supplier;
+ }
+
+ public int compareTo(Object other) {
+ if (!(other instanceof NativeCodeDescription))
+ return 1;
+ State containingState = getSupplier().getContainingState();
+ if (containingState == null)
+ return 0;
+ Dictionary[] platformProps = containingState.getPlatformProperties();
+ Version osversion;
+ try {
+ osversion = Version.parseVersion((String) platformProps[0].get(Constants.FRAMEWORK_OS_VERSION));
+ } catch (Exception e) {
+ osversion = Version.emptyVersion;
+ }
+ NativeCodeDescription otherDesc = (NativeCodeDescription) other;
+ VersionRange[] thisRanges = getOSVersions();
+ VersionRange[] otherRanges = otherDesc.getOSVersions();
+ Version thisHighest = getHighestVersionMatch(osversion, thisRanges);
+ Version otherHighest = getHighestVersionMatch(osversion, otherRanges);
+ if (thisHighest.compareTo(otherHighest) < 0)
+ return -1;
+ return (getLanguages().length == 0 ? 0 : 1) - (otherDesc.getLanguages().length == 0 ? 0 : 1);
+ }
+
+ public boolean hasInvalidNativePaths() {
+ return invalidNativePaths;
+ }
+
+ private Version getHighestVersionMatch(Version version, VersionRange[] ranges) {
+ Version highest = Version.emptyVersion;
+ for (int i = 0; i < ranges.length; i++) {
+ if (ranges[i].isIncluded(version) && highest.compareTo(ranges[i].getMinimum()) < 0)
+ highest = ranges[i].getMinimum();
+ }
+ return highest;
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+
+ String[] paths = getNativePaths();
+ for (int i = 0; i < paths.length; i++) {
+ if (i > 0) {
+ sb.append("; "); //$NON-NLS-1$
+ }
+ sb.append(paths[i]);
+ }
+
+ String[] procs = getProcessors();
+ for (int i = 0; i < procs.length; i++) {
+ sb.append("; "); //$NON-NLS-1$
+ sb.append(Constants.BUNDLE_NATIVECODE_PROCESSOR);
+ sb.append('=');
+ sb.append(procs[i]);
+ }
+
+ String[] oses = getOSNames();
+ for (int i = 0; i < oses.length; i++) {
+ sb.append("; "); //$NON-NLS-1$
+ sb.append(Constants.BUNDLE_NATIVECODE_OSNAME);
+ sb.append('=');
+ sb.append(oses[i]);
+ }
+
+ VersionRange[] osRanges = getOSVersions();
+ for (int i = 0; i < osRanges.length; i++) {
+ sb.append("; "); //$NON-NLS-1$
+ sb.append(Constants.BUNDLE_NATIVECODE_OSVERSION);
+ sb.append("=\""); //$NON-NLS-1$
+ sb.append(osRanges[i].toString());
+ sb.append('"');
+ }
+
+ String[] langs = getLanguages();
+ for (int i = 0; i < langs.length; i++) {
+ sb.append("; "); //$NON-NLS-1$
+ sb.append(Constants.BUNDLE_NATIVECODE_LANGUAGE);
+ sb.append('=');
+ sb.append(langs[i]);
+ }
+
+ Filter f = getFilter();
+ if (f != null) {
+ sb.append("; "); //$NON-NLS-1$
+ sb.append(Constants.SELECTION_FILTER_ATTRIBUTE);
+ sb.append("=\""); //$NON-NLS-1$
+ sb.append(f.toString());
+ sb.append('"');
+ }
+ return (sb.toString());
+ }
+
+ void setInvalidNativePaths(boolean invalidNativePaths) {
+ this.invalidNativePaths = invalidNativePaths;
+ }
+
+ void setOSNames(String[] osNames) {
+ this.osNames = osNames;
+ }
+
+ void setOSVersions(VersionRange[] osVersions) {
+ this.osVersions = osVersions;
+ }
+
+ void setFilter(String filter) throws InvalidSyntaxException {
+ this.filter = filter == null ? null : FrameworkUtil.createFilter(filter);
+ }
+
+ void setLanguages(String[] languages) {
+ this.languages = languages;
+ }
+
+ void setNativePaths(String[] nativePaths) {
+ this.nativePaths = nativePaths;
+ }
+
+ void setProcessors(String[] processors) {
+ this.processors = processors;
+ }
+
+ void setSupplier(BundleDescription supplier) {
+ this.supplier = supplier;
+ }
+}
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/NativeCodeSpecificationImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/NativeCodeSpecificationImpl.java
new file mode 100644
index 000000000..578b401e9
--- /dev/null
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/NativeCodeSpecificationImpl.java
@@ -0,0 +1,136 @@
+/*******************************************************************************
+ * Copyright (c) 2007 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.osgi.internal.resolver;
+
+import java.util.Collection;
+import java.util.Dictionary;
+import org.eclipse.osgi.framework.internal.core.AliasMapper;
+import org.eclipse.osgi.framework.internal.core.Constants;
+import org.eclipse.osgi.service.resolver.*;
+import org.osgi.framework.Filter;
+import org.osgi.framework.Version;
+
+public class NativeCodeSpecificationImpl extends VersionConstraintImpl implements NativeCodeSpecification {
+ private static final NativeCodeDescription[] EMPTY_NATIVECODEDESCRIPTIONS = new NativeCodeDescription[0];
+ private static AliasMapper aliasMapper = new AliasMapper();
+ private NativeCodeDescription[] possibleSuppliers;
+ private boolean optional;
+
+ public NativeCodeDescription[] getPossibleSuppliers() {
+ if (possibleSuppliers == null)
+ return EMPTY_NATIVECODEDESCRIPTIONS;
+ return possibleSuppliers;
+ }
+
+ void setPossibleSuppliers(NativeCodeDescription[] possibleSuppliers) {
+ this.possibleSuppliers = possibleSuppliers;
+ }
+
+ public boolean isOptional() {
+ return optional;
+ }
+
+ void setOptional(boolean optional) {
+ this.optional = optional;
+ }
+
+ public boolean isSatisfiedBy(BaseDescription supplier) {
+ if (!(supplier instanceof NativeCodeDescription))
+ return false;
+ State containingState = getBundle().getContainingState();
+ if (containingState == null)
+ return false;
+ Dictionary[] platformProps = containingState.getPlatformProperties();
+ NativeCodeDescription nativeSupplier = (NativeCodeDescription) supplier;
+ Filter filter = nativeSupplier.getFilter();
+ boolean match = false;
+ for (int i = 0; i < platformProps.length && !match; i++) {
+ if (filter != null && !filter.matchCase(platformProps[i]))
+ continue;
+ String[] osNames = nativeSupplier.getOSNames();
+ if (osNames.length == 0)
+ match = true;
+ else {
+ String platformOS = (String) platformProps[i].get(Constants.FRAMEWORK_OS_NAME);
+ for (int j = 0; j < osNames.length && !match; j++) {
+ Object aliasedName = aliasMapper.aliasOSName(osNames[j]);
+ if (aliasedName instanceof String) {
+ if (aliasedName.equals(platformOS))
+ match = true;
+ } else if (platformOS != null && ((Collection) aliasedName).contains(platformOS)) {
+ match = true;
+ }
+ }
+ }
+ if (!match)
+ continue;
+ match = false;
+
+ String[] processors = nativeSupplier.getProcessors();
+ if (processors.length == 0)
+ match = true;
+ else {
+ String platformProcessor = (String) platformProps[i].get(Constants.FRAMEWORK_PROCESSOR);
+ for (int j = 0; j < processors.length && !match; j++) {
+ String aliasedProcessor = aliasMapper.aliasProcessor(processors[j]);
+ if (aliasedProcessor.equals(platformProcessor))
+ match = true;
+ }
+ }
+ if (!match)
+ return false;
+ match = false;
+
+ String[] languages = nativeSupplier.getLanguages();
+ if (languages.length == 0l)
+ match = true;
+ else {
+ String platformLanguage = (String) platformProps[i].get(Constants.FRAMEWORK_LANGUAGE);
+ for (int j = 0; j < languages.length && !match; j++) {
+ if (languages[j].equalsIgnoreCase(platformLanguage))
+ match = true;
+ }
+ }
+ if (!match)
+ return false;
+ match = false;
+
+ VersionRange[] osVersions = nativeSupplier.getOSVersions();
+ if (osVersions.length == 0)
+ match = true;
+ else {
+ Version osversion;
+ try {
+ osversion = Version.parseVersion((String) platformProps[i].get(Constants.FRAMEWORK_OS_VERSION));
+ } catch (Exception e) {
+ osversion = Version.emptyVersion;
+ }
+ for (int j = 0; j < osVersions.length && !match; j++) {
+ if (osVersions[j].isIncluded(osversion))
+ match = true;
+ }
+ }
+ }
+ return match;
+ }
+
+ public String toString() {
+ StringBuffer sb = new StringBuffer();
+ NativeCodeDescription[] suppliers = getPossibleSuppliers();
+ for (int i = 0; i < suppliers.length; i++) {
+ if (i > 0)
+ sb.append(", "); //$NON-NLS-1$
+ sb.append(suppliers[i].toString());
+ }
+
+ return sb.toString();
+ }
+}
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ReadOnlyState.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ReadOnlyState.java
index 46dcd7950..c3988e1f3 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ReadOnlyState.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ReadOnlyState.java
@@ -170,4 +170,9 @@ public class ReadOnlyState implements State {
public long getHighestBundleId() {
return target.getHighestBundleId();
}
+
+ public void setNativePathsInvalid(NativeCodeDescription nativeCodeDescription, boolean hasInvalidPaths) {
+ throw new UnsupportedOperationException();
+ }
+
}
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ResolverErrorImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ResolverErrorImpl.java
index 69b6dadf2..95c04c138 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ResolverErrorImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/ResolverErrorImpl.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2006 IBM Corporation and others.
+ * Copyright (c) 2006, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -18,6 +18,7 @@ public class ResolverErrorImpl implements ResolverError {
private int type;
private String data;
private VersionConstraint unsatisfied;
+
public ResolverErrorImpl(BundleDescriptionImpl bundle, int type, String data, VersionConstraint unsatisfied) {
this.bundle = bundle;
this.data = data;
@@ -65,6 +66,10 @@ public class ResolverErrorImpl implements ResolverError {
return NLS.bind(StateMsg.RES_ERROR_SINGLETON_CONFLICT, getData());
case ResolverError.PLATFORM_FILTER :
return NLS.bind(StateMsg.RES_ERROR_PLATFORM_FILTER, getData());
+ case ResolverError.NO_NATIVECODE_MATCH :
+ return NLS.bind(StateMsg.RES_ERROR_NO_NATIVECODE_MATCH, getData());
+ case ResolverError.INVALID_NATIVECODE_PATHS :
+ return NLS.bind(StateMsg.RES_ERROR_NATIVECODE_PATH_INVALID, getData());
default :
return StateMsg.RES_ERROR_UNKNOWN;
}
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateBuilder.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateBuilder.java
index 25ddf3dfe..6ccaaaf91 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateBuilder.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateBuilder.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2006 IBM Corporation and others.
+ * Copyright (c) 2003, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -101,6 +101,8 @@ class StateBuilder {
result.setGenericRequires(createGenericRequires(genericRequires));
ManifestElement[] genericCapabilities = getGenericCapabilities(manifest, genericAliases);
result.setGenericCapabilities(createGenericCapabilities(genericCapabilities));
+ ManifestElement[] nativeCode = ManifestElement.parseHeader(Constants.BUNDLE_NATIVECODE, (String) manifest.get(Constants.BUNDLE_NATIVECODE));
+ result.setNativeCodeSpecification(createNativeCode(nativeCode));
return result;
}
@@ -476,6 +478,50 @@ class StateBuilder {
return (GenericDescription[]) results.toArray(new GenericDescription[results.size()]);
}
+ private static NativeCodeSpecification createNativeCode(ManifestElement[] nativeCode) throws BundleException {
+ if (nativeCode == null)
+ return null;
+ NativeCodeSpecificationImpl result = new NativeCodeSpecificationImpl();
+ result.setName(Constants.BUNDLE_NATIVECODE);
+ int length = nativeCode.length;
+ boolean optional = false;
+ if (length > 0 && nativeCode[length - 1].getValue().equals("*")) { //$NON-NLS-1$
+ result.setOptional(true);
+ length--;
+ }
+ NativeCodeDescriptionImpl[] suppliers = new NativeCodeDescriptionImpl[length];
+ for (int i = 0; i < length; i++) {
+ suppliers[i] = createNativeCodeDescription(nativeCode[i]);
+ }
+ result.setPossibleSuppliers(suppliers);
+ return result;
+ }
+
+ private static NativeCodeDescriptionImpl createNativeCodeDescription(ManifestElement manifestElement) throws BundleException {
+ NativeCodeDescriptionImpl result = new NativeCodeDescriptionImpl();
+ result.setName(Constants.BUNDLE_NATIVECODE);
+ result.setNativePaths(manifestElement.getValueComponents());
+ result.setOSNames(manifestElement.getAttributes(Constants.BUNDLE_NATIVECODE_OSNAME));
+ result.setProcessors(manifestElement.getAttributes(Constants.BUNDLE_NATIVECODE_PROCESSOR));
+ result.setOSVersions(createVersionRanges(manifestElement.getAttributes(Constants.BUNDLE_NATIVECODE_OSVERSION)));
+ result.setLanguages(manifestElement.getAttributes(Constants.BUNDLE_NATIVECODE_LANGUAGE));
+ try {
+ result.setFilter(manifestElement.getAttribute(Constants.SELECTION_FILTER_ATTRIBUTE));
+ } catch (InvalidSyntaxException e) {
+ throw new BundleException(Constants.SELECTION_FILTER_ATTRIBUTE, e);
+ }
+ return result;
+ }
+
+ private static VersionRange[] createVersionRanges(String[] ranges) {
+ if (ranges == null)
+ return null;
+ VersionRange[] result = new VersionRange[ranges.length];
+ for (int i = 0; i < result.length; i++)
+ result[i] = new VersionRange(ranges[i]);
+ return result;
+ }
+
private static VersionRange getVersionRange(String versionRange) {
if (versionRange == null)
return null;
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java
index c5f7007cf..86e5743c1 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateImpl.java
@@ -23,7 +23,7 @@ import org.eclipse.osgi.util.ManifestElement;
import org.osgi.framework.*;
public abstract class StateImpl implements State {
- public static final String[] PROPS = {"osgi.os", "osgi.ws", "osgi.nl", "osgi.arch", Constants.OSGI_FRAMEWORK_SYSTEM_PACKAGES, Constants.OSGI_RESOLVER_MODE, Constants.FRAMEWORK_EXECUTIONENVIRONMENT, "osgi.resolveOptional", "osgi.genericAliases"}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
+ public static final String[] PROPS = {"osgi.os", "osgi.ws", "osgi.nl", "osgi.arch", Constants.OSGI_FRAMEWORK_SYSTEM_PACKAGES, Constants.OSGI_RESOLVER_MODE, Constants.FRAMEWORK_EXECUTIONENVIRONMENT, "osgi.resolveOptional", "osgi.genericAliases", Constants.FRAMEWORK_OS_NAME, Constants.FRAMEWORK_OS_VERSION, Constants.FRAMEWORK_PROCESSOR, Constants.FRAMEWORK_LANGUAGE}; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$ //$NON-NLS-6$
transient private Resolver resolver;
transient private StateDeltaImpl changes;
transient private boolean resolving = false;
@@ -63,6 +63,15 @@ public abstract class StateImpl implements State {
// ignore this is handled in another place
}
}
+ NativeCodeSpecification nativeCode = description.getNativeCodeSpecification();
+ if (nativeCode != null) {
+ NativeCodeDescription[] suppliers = nativeCode.getPossibleSuppliers();
+ for (int i = 0; i < suppliers.length; i++) {
+ FilterImpl filter = (FilterImpl) suppliers[i].getFilter();
+ if (filter != null)
+ addPlatformPropertyKeys(filter.getAttributes());
+ }
+ }
resolved = false;
getDelta().recordBundleAdded((BundleDescriptionImpl) description);
if (Constants.getInternalSymbolicName().equals(description.getSymbolicName()))
@@ -548,29 +557,37 @@ public abstract class StateImpl implements State {
synchronized boolean setPlatformProperties(Dictionary[] platformProperties, boolean resetSystemExports) {
if (platformProperties.length == 0)
throw new IllegalArgumentException();
- // copy the properties for our use internally
+ // copy the properties for our use internally;
+ // only copy String and String[] values
Dictionary[] newPlatformProperties = new Dictionary[platformProperties.length];
for (int i = 0; i < platformProperties.length; i++) {
newPlatformProperties[i] = new Hashtable(platformProperties[i].size());
synchronized (platformProperties[i]) {
for (Enumeration keys = platformProperties[i].keys(); keys.hasMoreElements();) {
Object key = keys.nextElement();
- newPlatformProperties[i].put(key, platformProperties[i].get(key));
+ Object value = platformProperties[i].get(key);
+ if (value instanceof String || value instanceof String[])
+ newPlatformProperties[i].put(key, value);
}
}
}
boolean result = false;
+ boolean performResetSystemExports = false;
if (this.platformProperties.length != newPlatformProperties.length) {
result = true;
+ performResetSystemExports = true;
} else {
// we need to see if any of the existing filter prop keys have changed
String[] keys = getPlatformPropertyKeys();
- for (int i = 0; i < newPlatformProperties.length && !result; i++)
+ for (int i = 0; i < newPlatformProperties.length && !result; i++) {
result |= changedProps(this.platformProperties[i], newPlatformProperties[i], keys);
+ if (resetSystemExports)
+ performResetSystemExports |= checkProp(this.platformProperties[i].get(Constants.FRAMEWORK_SYSTEMPACKAGES), newPlatformProperties[i].get(Constants.FRAMEWORK_SYSTEMPACKAGES));
+ }
}
// always do a complete replacement of the properties in case new bundles are added that uses new filter props
this.platformProperties = newPlatformProperties;
- if (resetSystemExports && result)
+ if (performResetSystemExports)
resetSystemExports();
return result;
}
@@ -775,4 +792,7 @@ public abstract class StateImpl implements State {
return highestBundleId;
}
+ public void setNativePathsInvalid(NativeCodeDescription nativeCodeDescription, boolean hasInvalidNativePaths) {
+ ((NativeCodeDescriptionImpl) nativeCodeDescription).setInvalidNativePaths(hasInvalidNativePaths);
+ }
}
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateMessages.properties b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateMessages.properties
index 6a68499f6..b61289c04 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateMessages.properties
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateMessages.properties
@@ -1,5 +1,5 @@
###############################################################################
-# Copyright (c) 2004, 2005 IBM Corporation and others.
+# Copyright (c) 2004, 2007 IBM Corporation and others.
# All rights reserved. This program and the accompanying materials
# are made available under the terms of the Eclipse Public License v1.0
# which accompanies this distribution, and is available at
@@ -27,4 +27,6 @@ RES_ERROR_FRAGMENT_CONFLICT=Constraints from the fragment conflict with the host
RES_ERROR_USES_CONFLICT=Package uses conflict: {0}
RES_ERROR_SINGLETON_CONFLICT=Another singleton version selected: {0}
RES_ERROR_PLATFORM_FILTER=Platform filter did not match: {0}
+RES_ERROR_NO_NATIVECODE_MATCH=No match found for native code: {0}
+RES_ERROR_NATIVECODE_PATH_INVALID=The native code paths cannot be found: {0}
RES_ERROR_UNKNOWN=Unknown resolution error
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateMsg.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateMsg.java
index b67b81286..5223f5fc8 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateMsg.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateMsg.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2004, 2005 IBM Corporation and others.
+ * Copyright (c) 2004, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -31,6 +31,8 @@ public class StateMsg extends NLS {
public static String RES_ERROR_USES_CONFLICT;
public static String RES_ERROR_SINGLETON_CONFLICT;
public static String RES_ERROR_PLATFORM_FILTER;
+ public static String RES_ERROR_NO_NATIVECODE_MATCH;
+ public static String RES_ERROR_NATIVECODE_PATH_INVALID;
public static String RES_ERROR_UNKNOWN;
static {
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateObjectFactoryImpl.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateObjectFactoryImpl.java
index 0ccf63e6a..c15239491 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateObjectFactoryImpl.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateObjectFactoryImpl.java
@@ -21,6 +21,9 @@ import org.osgi.framework.*;
public class StateObjectFactoryImpl implements StateObjectFactory {
+ /**
+ * @deprecated
+ */
public BundleDescription createBundleDescription(Dictionary manifest, String location, long id) throws BundleException {
return createBundleDescription(null, manifest, location, id);
}
@@ -31,16 +34,26 @@ public class StateObjectFactoryImpl implements StateObjectFactory {
return result;
}
+ /**
+ * @deprecated
+ */
public BundleDescription createBundleDescription(long id, String symbolicName, Version version, String location, BundleSpecification[] required, HostSpecification host, ImportPackageSpecification[] imports, ExportPackageDescription[] exports, String[] providedPackages, boolean singleton) {
return createBundleDescription(id, symbolicName, version, location, required, host, imports, exports, providedPackages, singleton, true, true, null, null, null, null);
}
+ /**
+ * @deprecated
+ */
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) {
// bug 154137 we need to parse the executionEnvironment param; no need to check for null, ManifestElement does that for us.
return createBundleDescription(id, symbolicName, version, location, required, host, imports, exports, singleton, attachFragments, dynamicFragments, platformFilter, ManifestElement.getArrayFromList(executionEnvironment), genericRequires, genericCapabilities);
}
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) {
+ return createBundleDescription(id, symbolicName, version, location, required, host, imports, exports, singleton, attachFragments, dynamicFragments, platformFilter, executionEnvironments, genericRequires, genericCapabilities, null);
+ }
+
+ 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) {
BundleDescriptionImpl bundle = new BundleDescriptionImpl();
bundle.setBundleId(id);
bundle.setSymbolicName(symbolicName);
@@ -57,6 +70,7 @@ public class StateObjectFactoryImpl implements StateObjectFactory {
bundle.setExecutionEnvironments(executionEnvironments);
bundle.setGenericRequires(genericRequires);
bundle.setGenericCapabilities(genericCapabilities);
+ bundle.setNativeCodeSpecification(nativeCode);
return bundle;
}
@@ -91,9 +105,36 @@ public class StateObjectFactoryImpl implements StateObjectFactory {
bundle.setExecutionEnvironments(original.getExecutionEnvironments());
bundle.setGenericCapabilities(createGenericCapabilities(original.getGenericCapabilities()));
bundle.setGenericRequires(createGenericRequires(original.getGenericRequires()));
+ bundle.setNativeCodeSpecification(createNativeCodeSpecification(original.getNativeCodeSpecification()));
return bundle;
}
+ private NativeCodeSpecification createNativeCodeSpecification(NativeCodeSpecification original) {
+ if (original == null)
+ return null;
+ NativeCodeSpecificationImpl result = new NativeCodeSpecificationImpl();
+ result.setName(original.getName());
+ result.setOptional(original.isOptional());
+ NativeCodeDescription[] originalDescriptions = original.getPossibleSuppliers();
+ NativeCodeDescriptionImpl[] newDescriptions = new NativeCodeDescriptionImpl[originalDescriptions.length];
+ for (int i = 0; i < originalDescriptions.length; i++) {
+ newDescriptions[i] = new NativeCodeDescriptionImpl();
+ newDescriptions[i].setName(originalDescriptions[i].getName());
+ newDescriptions[i].setNativePaths(originalDescriptions[i].getNativePaths());
+ newDescriptions[i].setProcessors(originalDescriptions[i].getProcessors());
+ newDescriptions[i].setOSNames(originalDescriptions[i].getOSNames());
+ newDescriptions[i].setOSVersions(originalDescriptions[i].getOSVersions());
+ newDescriptions[i].setLanguages(originalDescriptions[i].getLanguages());
+ try {
+ newDescriptions[i].setFilter(originalDescriptions[i].getFilter().toString());
+ } catch (InvalidSyntaxException e) {
+ // this is already tested from the orginal filter
+ }
+ }
+ result.setPossibleSuppliers(newDescriptions);
+ return result;
+ }
+
private GenericDescription[] createGenericCapabilities(GenericDescription[] genericCapabilities) {
if (genericCapabilities == null || genericCapabilities.length == 0)
return null;
@@ -227,12 +268,35 @@ public class StateObjectFactoryImpl implements StateObjectFactory {
return result;
}
+ public NativeCodeDescription createNativeCodeDescription(String[] nativePaths, String[] processors, String[] osNames, VersionRange[] osVersions, String[] languages, String filter) throws InvalidSyntaxException {
+ NativeCodeDescriptionImpl result = new NativeCodeDescriptionImpl();
+ result.setName(Constants.BUNDLE_NATIVECODE);
+ result.setNativePaths(nativePaths);
+ result.setProcessors(processors);
+ result.setOSNames(osNames);
+ result.setOSVersions(osVersions);
+ result.setLanguages(languages);
+ result.setFilter(filter);
+ return result;
+ }
+
+ public NativeCodeSpecification createNativeCodeSpecification(NativeCodeDescription[] nativeCodeDescriptions, boolean optional) {
+ NativeCodeSpecificationImpl result = new NativeCodeSpecificationImpl();
+ result.setName(Constants.BUNDLE_NATIVECODE);
+ result.setOptional(optional);
+ result.setPossibleSuppliers(nativeCodeDescriptions);
+ return result;
+ }
+
public SystemState createSystemState() {
SystemState state = new SystemState();
state.setFactory(this);
return state;
}
+ /**
+ * @deprecated
+ */
public State createState() {
return internalCreateState();
}
@@ -271,10 +335,16 @@ public class StateObjectFactoryImpl implements StateObjectFactory {
return restoredState;
}
+ /**
+ * @deprecated
+ */
public State readState(InputStream stream) throws IOException {
return internalReadStateDeprecated(internalCreateState(), new DataInputStream(stream), -1);
}
+ /**
+ * @deprecated
+ */
public State readState(DataInputStream stream) throws IOException {
return internalReadStateDeprecated(internalCreateState(), stream, -1);
}
@@ -315,6 +385,9 @@ public class StateObjectFactoryImpl implements StateObjectFactory {
return toRestore;
}
+ /**
+ * @deprecated
+ */
public void writeState(State state, DataOutputStream stream) throws IOException {
internalWriteStateDeprecated(state, stream);
}
@@ -328,6 +401,9 @@ public class StateObjectFactoryImpl implements StateObjectFactory {
writer.saveState((StateImpl) state, stateFile, lazyFile);
}
+ /**
+ * @deprecated
+ */
public void writeState(State state, OutputStream stream) throws IOException {
internalWriteStateDeprecated(state, new DataOutputStream(stream));
}
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateReader.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateReader.java
index 089a84673..86a43a2b5 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateReader.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateReader.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2006 IBM Corporation and others.
+ * Copyright (c) 2003, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -40,7 +40,7 @@ class StateReader {
private int numBundles;
private boolean accessedFlag = false;
- public static final byte STATE_CACHE_VERSION = 26;
+ public static final byte STATE_CACHE_VERSION = 27;
public static final byte NULL = 0;
public static final byte OBJECT = 1;
public static final byte INDEX = 2;
@@ -330,6 +330,8 @@ class StateReader {
result.setGenericRequires(reqs);
}
+ result.setNativeCodeSpecification(readNativeCode(in));
+
result.setFullyLoaded(true); // set fully loaded before setting the dependencies
// No need to add bundle dependencies for hosts, imports or requires;
// This is done by readBundleDescription
@@ -356,6 +358,7 @@ class StateReader {
addToObjectTable(exportPackageDesc, tableIndex);
exportPackageDesc.setTableIndex(tableIndex);
readBaseDescription(exportPackageDesc, in);
+ exportPackageDesc.setExporter(readBundleDescription(in));
exportPackageDesc.setRoot(in.readBoolean());
exportPackageDesc.setAttributes(readMap(in));
exportPackageDesc.setDirectives(readMap(in));
@@ -456,6 +459,7 @@ class StateReader {
GenericDescriptionImpl result = new GenericDescriptionImpl();
addToObjectTable(result, tableIndex);
readBaseDescription(result, in);
+ result.setSupplier(readBundleDescription(in));
result.setType(readString(in, false));
Map mapAttrs = readMap(in);
Dictionary attrs = new Hashtable();
@@ -487,6 +491,60 @@ class StateReader {
return result;
}
+ private NativeCodeSpecification readNativeCode(DataInputStream in) throws IOException {
+ if (!in.readBoolean())
+ return null;
+ NativeCodeSpecificationImpl result = new NativeCodeSpecificationImpl();
+ result.setOptional(in.readBoolean());
+ int numNativeDesc = in.readInt();
+ NativeCodeDescriptionImpl[] nativeDescs = new NativeCodeDescriptionImpl[numNativeDesc];
+ for (int i = 0; i < numNativeDesc; i++)
+ nativeDescs[i] = readNativeCodeDescription(in);
+ result.setPossibleSuppliers(nativeDescs);
+ int supplierIndex = in.readInt();
+ if (supplierIndex >= 0)
+ result.setSupplier(nativeDescs[supplierIndex]);
+ return result;
+ }
+
+ private NativeCodeDescriptionImpl readNativeCodeDescription(DataInputStream in) throws IOException {
+ NativeCodeDescriptionImpl result = new NativeCodeDescriptionImpl();
+ readBaseDescription(result, in);
+ result.setSupplier(readBundleDescription(in));
+ try {
+ result.setFilter(readString(in, false));
+ } catch (InvalidSyntaxException e) {
+ // do nothing, this filter was tested before
+ }
+ result.setLanguages(readStringArray(in));
+ result.setNativePaths(readStringArray(in));
+ result.setOSNames(readStringArray(in));
+ result.setOSVersions(readVersionRanges(in));
+ result.setProcessors(readStringArray(in));
+ result.setInvalidNativePaths(in.readBoolean());
+ return result;
+ }
+
+ private VersionRange[] readVersionRanges(DataInputStream in) throws IOException {
+ int num = in.readInt();
+ if (num == 0)
+ return null;
+ VersionRange[] result = new VersionRange[num];
+ for (int i = 0; i < num; i++)
+ result[i] = readVersionRange(in);
+ return result;
+ }
+
+ private String[] readStringArray(DataInputStream in) throws IOException {
+ int num = in.readInt();
+ if (num == 0)
+ return null;
+ String[] result = new String[num];
+ for (int i = 0; i < num; i++)
+ result[i] = readString(in, false);
+ return result;
+ }
+
// called by readers for VersionConstraintImpl subclasses
private void readVersionConstraint(VersionConstraintImpl version, DataInputStream in) throws IOException {
version.setName(readString(in, false));
diff --git a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateWriter.java b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateWriter.java
index f5178d5ea..bc9273c5a 100644
--- a/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateWriter.java
+++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateWriter.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2003, 2006 IBM Corporation and others.
+ * Copyright (c) 2003, 2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
@@ -13,8 +13,7 @@ package org.eclipse.osgi.internal.resolver;
import java.io.*;
import java.util.*;
import org.eclipse.osgi.service.resolver.*;
-import org.osgi.framework.Constants;
-import org.osgi.framework.Version;
+import org.osgi.framework.*;
class StateWriter {
@@ -297,6 +296,8 @@ class StateWriter {
writeGenericSpecification(genericRequires[i], out);
}
+ writeNativeCode(bundle.getNativeCodeSpecification(), out);
+
// save the size of the lazy data
((BundleDescriptionImpl) bundle).setLazyDataSize(out.size() - dataStart);
}
@@ -312,6 +313,7 @@ class StateWriter {
if (writePrefix(exportPackageDesc, out))
return;
writeBaseDescription(exportPackageDesc, out);
+ writeBundleDescription(exportPackageDesc.getExporter(), out, false);
out.writeBoolean(exportPackageDesc.isRoot());
writeMap(out, exportPackageDesc.getAttributes());
writeMap(out, exportPackageDesc.getDirectives());
@@ -321,6 +323,7 @@ class StateWriter {
if (writePrefix(description, out))
return;
writeBaseDescription(description, out);
+ writeBundleDescription(description.getSupplier(), out, false);
writeStringOrNull(description.getType() == GenericDescription.DEFAULT_TYPE ? null : description.getType(), out);
Dictionary attrs = description.getAttributes();
Map mapAttrs = new HashMap(attrs.size());
@@ -344,6 +347,54 @@ class StateWriter {
writeStringOrNull(specification.getMatchingFilter(), out);
}
+ private void writeNativeCode(NativeCodeSpecification nativeCodeSpecification, DataOutputStream out) throws IOException {
+ if (nativeCodeSpecification == null) {
+ out.writeBoolean(false);
+ return;
+ }
+ out.writeBoolean(true);
+ out.writeBoolean(nativeCodeSpecification.isOptional());
+ NativeCodeDescription[] nativeDescs = nativeCodeSpecification.getPossibleSuppliers();
+ int numDescs = nativeDescs == null ? 0 : nativeDescs.length;
+ out.writeInt(numDescs);
+ int supplierIndex = -1;
+ for (int i = 0; i < numDescs; i++) {
+ if (nativeDescs[i] == nativeCodeSpecification.getSupplier())
+ supplierIndex = i;
+ writeNativeCodeDescription(nativeDescs[i], out);
+ }
+ out.writeInt(supplierIndex);
+ }
+
+ private void writeNativeCodeDescription(NativeCodeDescription nativeCodeDescription, DataOutputStream out) throws IOException {
+ writeBaseDescription(nativeCodeDescription, out);
+ writeBundleDescription(nativeCodeDescription.getSupplier(), out, false);
+ Filter filter = nativeCodeDescription.getFilter();
+ writeStringOrNull(filter == null ? null : filter.toString(), out);
+ writeStringArray(nativeCodeDescription.getLanguages(), out);
+ writeStringArray(nativeCodeDescription.getNativePaths(), out);
+ writeStringArray(nativeCodeDescription.getOSNames(), out);
+ writeVersionRanges(nativeCodeDescription.getOSVersions(), out);
+ writeStringArray(nativeCodeDescription.getProcessors(), out);
+ out.writeBoolean(nativeCodeDescription.hasInvalidNativePaths());
+ }
+
+ private void writeVersionRanges(VersionRange[] ranges, DataOutputStream out) throws IOException {
+ out.writeInt(ranges == null ? 0 : ranges.length);
+ if (ranges == null)
+ return;
+ for (int i = 0; i < ranges.length; i++)
+ writeVersionRange(ranges[i], out);
+ }
+
+ private void writeStringArray(String[] strings, DataOutputStream out) throws IOException {
+ out.writeInt(strings == null ? 0 : strings.length);
+ if (strings == null)
+ return;
+ for (int i = 0; i < strings.length; i++)
+ writeStringOrNull(strings[i], out);
+ }
+
private void writeMap(DataOutputStream out, Map source) throws IOException {
if (source == null) {
out.writeInt(0);

Back to the top