blob: 9e71c438f7529b29acc1d1be4036693c4470084a [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2004 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.*;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.osgi.service.resolver.*;
class StateReader {
// 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 List objectTable = new ArrayList();
public static final byte STATE_CACHE_VERSION = 5;
public static final byte NULL = 0;
public static final byte OBJECT = 1;
public static final byte INDEX = 2;
private int addToObjectTable(Object object) {
objectTable.add(object);
// return the index of the object just added (i.e. size - 1)
return (objectTable.size() - 1);
}
private boolean readState(StateImpl state, DataInputStream in, long expectedTimestamp) throws IOException {
if (in.readByte() != STATE_CACHE_VERSION)
return false;
byte tag = readTag(in);
if (tag != OBJECT)
return false;
long timestampRead = in.readLong();
if (expectedTimestamp >= 0 && timestampRead != expectedTimestamp)
return false;
addToObjectTable(state);
int length = in.readInt();
if (length == 0)
return true;
for (int i = 0; i < length; i++)
state.basicAddBundle(readBundleDescription(in));
state.setTimeStamp(timestampRead);
state.setResolved(in.readBoolean());
if (!state.isResolved())
return true;
int resolvedLength = in.readInt();
for(int i = 0;i < resolvedLength;i++)
state.addResolvedBundle(readBundleDescription(in));
return true;
}
private BundleDescriptionImpl readBundleDescription(DataInputStream in) throws IOException {
byte tag = readTag(in);
if (tag == NULL)
return null;
if (tag == INDEX)
return (BundleDescriptionImpl) objectTable.get(in.readInt());
BundleDescriptionImpl result = new BundleDescriptionImpl();
addToObjectTable(result);
result.setBundleId(in.readLong());
result.setUniqueId(readString(in, false));
result.setLocation(readString(in, false));
result.setState(in.readInt());
result.setVersion(readVersion(in));
result.setHost(readHostSpec(in));
int packageCount = in.readInt();
if (packageCount > 0) {
PackageSpecification[] packages = new PackageSpecification[packageCount];
for (int i = 0; i < packages.length; i++)
packages[i] = readPackageSpec(in);
result.setPackages(packages);
}
int providedPackageCount = in.readInt();
if (providedPackageCount > 0) {
String[] providedPackages = new String[providedPackageCount];
for (int i = 0; i < providedPackages.length; i++)
providedPackages[i] = in.readUTF();
result.setProvidedPackages(providedPackages);
}
int requiredBundleCount = in.readInt();
if (requiredBundleCount > 0) {
BundleSpecification[] requiredBundles = new BundleSpecification[requiredBundleCount];
for (int i = 0; i < requiredBundles.length; i++)
requiredBundles[i] = readBundleSpec(in);
result.setRequiredBundles(requiredBundles);
}
result.setSingleton(in.readBoolean());
return result;
}
private BundleSpecificationImpl readBundleSpec(DataInputStream in) throws IOException {
BundleSpecificationImpl result = new BundleSpecificationImpl();
readVersionConstraint(result, in);
result.setExported(in.readBoolean());
result.setOptional(in.readBoolean());
return result;
}
private PackageSpecificationImpl readPackageSpec(DataInputStream in) throws IOException {
PackageSpecificationImpl result = new PackageSpecificationImpl();
readVersionConstraint(result, in);
result.setExport(in.readBoolean());
return result;
}
private HostSpecificationImpl readHostSpec(DataInputStream in) throws IOException {
byte tag = readTag(in);
if (tag == NULL)
return null;
HostSpecificationImpl result = new HostSpecificationImpl();
readVersionConstraint(result, in);
result.setReloadHost(in.readBoolean());
return result;
}
// called by readers for VersionConstraintImpl subclasses
private void readVersionConstraint(VersionConstraintImpl version, DataInputStream in) throws IOException {
version.setName(readString(in, false));
version.setVersionSpecification(readVersion(in));
version.setMatchingRule(in.readByte());
version.setActualVersion(readVersion(in));
version.setSupplier(readBundleDescription(in));
}
private Version readVersion(DataInputStream in) throws IOException {
byte tag = readTag(in);
if (tag == NULL)
return null;
if (tag == INDEX)
return (Version) objectTable.get(in.readInt());
int majorComponent = in.readInt();
int minorComponent = in.readInt();
int serviceComponent = in.readInt();
String qualifierComponent = readString(in, false);
Version result = new Version(majorComponent, minorComponent, serviceComponent, qualifierComponent);
addToObjectTable(result);
return result;
}
public final boolean loadState(StateImpl state, DataInputStream input, long expectedTimestamp) throws IOException {
try {
return readState(state, input, expectedTimestamp);
} finally {
input.close();
}
}
public final boolean loadState(StateImpl state, DataInputStream input) throws IOException {
return loadState(state, input, -1);
}
private String readString(DataInputStream in, boolean intern) throws IOException {
byte type = in.readByte();
if (type == NULL)
return null;
if (intern)
return in.readUTF().intern();
else
return in.readUTF();
}
private byte readTag(DataInputStream in) throws IOException {
return in.readByte();
}
}