diff options
Diffstat (limited to 'bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateWriter.java')
-rw-r--r-- | bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateWriter.java | 164 |
1 files changed, 164 insertions, 0 deletions
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 new file mode 100644 index 000000000..b068453fe --- /dev/null +++ b/bundles/org.eclipse.osgi/resolver/src/org/eclipse/osgi/internal/resolver/StateWriter.java @@ -0,0 +1,164 @@ +/******************************************************************************* + * Copyright (c) 2003 IBM Corporation and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Common Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/cpl-v10.html + * + * Contributors: + * IBM Corporation - initial API and implementation + *******************************************************************************/ +package org.eclipse.osgi.internal.resolver; + +import java.io.DataOutputStream; +import java.io.IOException; +import java.util.HashMap; +import java.util.Map; + +import org.eclipse.osgi.service.resolver.*; + +public class StateWriter { + + // objectTable will be a hashmap of objects. The objects will be things + // like a plugin descriptor, extension, extension point, etc. The integer + // index value will be used in the cache to allow cross-references in the + // cached registry. + protected Map objectTable = new HashMap(); + + public static final byte STATE_CACHE_VERSION = 3; + public static final byte NULL = 0; + public static final byte OBJECT = 1; + public static final byte INDEX = 2; + + private int addToObjectTable(Object object) { + objectTable.put(object, new Integer(objectTable.size())); + // return the index of the object just added (i.e. size - 1) + return (objectTable.size() - 1); + } + private int getFromObjectTable(Object object) { + if (objectTable != null) { + Object objectResult = objectTable.get(object); + if (objectResult != null) { + return ((Integer) objectResult).intValue(); + } + } + return -1; + } + private boolean writePrefix(Object object, DataOutputStream out) throws IOException { + if (writeIndex(object, out)) + return true; + // add this object to the object table first + addToObjectTable(object); + out.writeByte(OBJECT); + return false; + } + private void writeState(StateImpl state, DataOutputStream out) throws IOException { + out.write(STATE_CACHE_VERSION); + if (writePrefix(state, out)) + return; + BundleDescription[] bundles = state.getBundles(); + out.writeInt(bundles.length); + if (bundles.length == 0) + return; + for (int i = 0; i < bundles.length; i++) + writeBundleDescription((BundleDescriptionImpl) bundles[i], out); + out.writeLong(state.getTimeStamp()); + out.writeBoolean(state.isResolved()); + if (!state.isResolved()) + return; + BundleDescription[] resolvedBundles = state.getResolvedBundles(); + out.writeInt(resolvedBundles.length); + for (int i = 0; i < resolvedBundles.length; i++) + writeBundleDescription((BundleDescriptionImpl) resolvedBundles[i], out); + } + private void writeBundleDescription(BundleDescriptionImpl bundle, DataOutputStream out) throws IOException { + if (writePrefix(bundle, out)) + return; + out.writeLong(bundle.getBundleId()); + writeStringOrNull(bundle.getUniqueId(), out); + writeStringOrNull(bundle.getLocation(), out); + out.writeInt(bundle.getState()); + writeVersion(bundle.getVersion(), out); + writeHostSpec((HostSpecificationImpl) bundle.getHost(), out); + + PackageSpecification[] packages = bundle.getPackages(); + out.writeInt(packages.length); + for (int i = 0; i < packages.length; i++) + writePackageSpec((PackageSpecificationImpl) packages[i], out); + + String[] providedPackages = bundle.getProvidedPackages(); + out.writeInt(providedPackages.length); + for (int i = 0; i < providedPackages.length; i++) + out.writeUTF(providedPackages[i]); + + BundleSpecification[] requiredBundles = bundle.getRequiredBundles(); + out.writeInt(requiredBundles.length); + for (int i = 0; i < requiredBundles.length; i++) + writeBundleSpec((BundleSpecificationImpl) requiredBundles[i], out); + } + private void writeBundleSpec(BundleSpecificationImpl bundle, DataOutputStream out) throws IOException { + writeVersionConstraint(bundle, out); + out.writeBoolean(bundle.isExported()); + out.writeBoolean(bundle.isOptional()); + } + private void writePackageSpec(PackageSpecificationImpl packageSpec, DataOutputStream out) throws IOException { + writeVersionConstraint(packageSpec, out); + out.writeBoolean(packageSpec.isExported()); + } + private void writeProvidedPackage(PackageSpecificationImpl packageSpec, DataOutputStream out) throws IOException { + out.writeUTF(packageSpec.getName()); + } + private void writeHostSpec(HostSpecificationImpl host, DataOutputStream out) throws IOException { + if (host == null) { + out.writeByte(NULL); + return; + } + out.writeByte(OBJECT); + writeVersionConstraint(host, out); + out.writeBoolean(host.reloadHost()); + } + // called by writers for VersionConstraintImpl subclasses + private void writeVersionConstraint(VersionConstraintImpl version, DataOutputStream out) throws IOException { + writeStringOrNull(version.getName(), out); + writeVersion(version.getVersionSpecification(), out); + out.writeByte(version.getMatchingRule()); + writeVersion(version.getActualVersion(), out); + writeBundleDescription((BundleDescriptionImpl) version.getSupplier(), out); + } + private void writeVersion(Version version, DataOutputStream out) throws IOException { + // TODO: should assess whether avoiding sharing versions would be good + if (writePrefix(version, out)) + return; + out.writeInt(version.getMajorComponent()); + out.writeInt(version.getMinorComponent()); + out.writeInt(version.getServiceComponent()); + writeStringOrNull(version.getQualifierComponent(), out); + } + private boolean writeIndex(Object object, DataOutputStream out) throws IOException { + if (object == null) { + out.writeByte(NULL); + return true; + } + int index = getFromObjectTable(object); + if (index == -1) + return false; + out.writeByte(INDEX); + out.writeInt(index); + return true; + } + public void saveState(StateImpl state, DataOutputStream output) throws IOException { + try { + writeState(state, output); + } finally { + output.close(); + } + } + private void writeStringOrNull(String string, DataOutputStream out) throws IOException { + if (string == null) + out.writeByte(NULL); + else { + out.writeByte(OBJECT); + out.writeUTF(string); + } + } +}
\ No newline at end of file |