Skip to main content
aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
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.java164
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

Back to the top