use of org.eclipse.osgi.storage.BundleInfo.Generation in project rt.equinox.framework by eclipse.
the class Storage method saveStorageHookData.
private void saveStorageHookData(DataOutputStream out, List<Generation> generations) throws IOException {
List<StorageHookFactory<?, ?, ?>> factories = getConfiguration().getHookRegistry().getStorageHookFactories();
out.writeInt(factories.size());
for (StorageHookFactory<?, ?, ?> factory : factories) {
out.writeUTF(factory.getKey());
out.writeInt(factory.getStorageVersion());
// create a temporary in memory stream so we can figure out the length
ByteArrayOutputStream tempBytes = new ByteArrayOutputStream();
DataOutputStream temp = new DataOutputStream(tempBytes);
try {
Object saveContext = factory.createSaveContext();
for (Generation generation : generations) {
if (generation.getBundleInfo().getBundleId() == 0) {
// ignore system bundle
continue;
}
@SuppressWarnings({ "rawtypes", "unchecked" }) StorageHook<Object, Object> hook = generation.getStorageHook((Class) factory.getClass());
hook.save(saveContext, temp);
}
} finally {
temp.close();
}
out.writeInt(tempBytes.size());
out.write(tempBytes.toByteArray());
}
}
use of org.eclipse.osgi.storage.BundleInfo.Generation in project rt.equinox.framework by eclipse.
the class Storage method findEntries.
public static Enumeration<URL> findEntries(List<Generation> generations, String path, String filePattern, int options) {
List<BundleFile> bundleFiles = new ArrayList<>(generations.size());
for (Generation generation : generations) bundleFiles.add(generation.getBundleFile());
// search all the bundle files
List<String> pathList = listEntryPaths(bundleFiles, path, filePattern, options);
// return null if no entries found
if (pathList.size() == 0)
return null;
// create an enumeration to enumerate the pathList
final String[] pathArray = pathList.toArray(new String[pathList.size()]);
final Generation[] generationArray = generations.toArray(new Generation[generations.size()]);
return new Enumeration<URL>() {
private int curPathIndex = 0;
private int curDataIndex = 0;
private URL nextElement = null;
public boolean hasMoreElements() {
if (nextElement != null)
return true;
getNextElement();
return nextElement != null;
}
public URL nextElement() {
if (!hasMoreElements())
throw new NoSuchElementException();
URL result = nextElement;
// force the next element search
getNextElement();
return result;
}
private void getNextElement() {
nextElement = null;
if (curPathIndex >= pathArray.length)
// reached the end of the pathArray; no more elements
return;
while (nextElement == null && curPathIndex < pathArray.length) {
String curPath = pathArray[curPathIndex];
// search the generation until we have searched them all
while (nextElement == null && curDataIndex < generationArray.length) nextElement = generationArray[curDataIndex++].getEntry(curPath);
// we have searched all datas then advance to the next path
if (curDataIndex >= generationArray.length) {
curPathIndex++;
curDataIndex = 0;
}
}
}
};
}
use of org.eclipse.osgi.storage.BundleInfo.Generation in project rt.equinox.framework by eclipse.
the class Storage method update.
public Generation update(Module module, URLConnection content) throws BundleException {
if (osgiLocation.isReadOnly()) {
// $NON-NLS-1$
throw new BundleException("The framework storage area is read only.", BundleException.INVALID_OPERATION);
}
URL sourceURL = content.getURL();
InputStream in;
try {
in = content.getInputStream();
} catch (Throwable e) {
// $NON-NLS-1$
throw new BundleException("Error reading bundle content.", e);
}
boolean isReference = in instanceof ReferenceInputStream;
File staged = stageContent(in, sourceURL);
ModuleRevision current = module.getCurrentRevision();
Generation currentGen = (Generation) current.getRevisionInfo();
BundleInfo bundleInfo = currentGen.getBundleInfo();
Generation newGen = bundleInfo.createGeneration();
try {
File contentFile = getContentFile(staged, isReference, bundleInfo.getBundleId(), newGen.getGenerationId());
newGen.setContent(contentFile, isReference);
// Check that we can open the bundle file
newGen.getBundleFile().open();
setStorageHooks(newGen);
ModuleRevisionBuilder builder = getBuilder(newGen);
moduleContainer.update(module, builder, newGen);
} catch (Throwable t) {
if (!isReference) {
try {
delete(staged);
} catch (IOException e) {
// tried our best
}
}
newGen.delete();
if (t instanceof SecurityException) {
// if the cause is a bundle exception then throw that
if (t.getCause() instanceof BundleException) {
throw (BundleException) t.getCause();
}
throw (SecurityException) t;
}
if (t instanceof BundleException) {
throw (BundleException) t;
}
// $NON-NLS-1$
throw new BundleException("Error occurred installing a bundle.", t);
} finally {
bundleInfo.unlockGeneration(newGen);
}
return newGen;
}
use of org.eclipse.osgi.storage.BundleInfo.Generation in project rt.equinox.framework by eclipse.
the class Storage method loadGenerations.
private Map<Long, Generation> loadGenerations(DataInputStream in) throws IOException {
if (in == null) {
return new HashMap<>(0);
}
int version = in.readInt();
if (version > VERSION || version < LOWEST_VERSION_SUPPORTED) {
// $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
throw new IllegalArgumentException("Found persistent version \"" + version + "\" expecting \"" + VERSION + "\"");
}
Version savedRuntimeVersion = (version >= MR_JAR_VERSION) ? Version.parseVersion(in.readUTF()) : null;
if (savedRuntimeVersion == null || !savedRuntimeVersion.equals(runtimeVersion)) {
refreshMRBundles.set(true);
}
int numCachedHeaders = in.readInt();
List<String> storedCachedHeaderKeys = new ArrayList<>(numCachedHeaders);
for (int i = 0; i < numCachedHeaders; i++) {
storedCachedHeaderKeys.add(ObjectPool.intern(in.readUTF()));
}
int numInfos = in.readInt();
Map<Long, Generation> result = new HashMap<>(numInfos);
List<Generation> generations = new ArrayList<>(numInfos);
for (int i = 0; i < numInfos; i++) {
long infoId = in.readLong();
String infoLocation = ObjectPool.intern(in.readUTF());
long nextGenId = in.readLong();
long generationId = in.readLong();
boolean isDirectory = in.readBoolean();
boolean isReference = in.readBoolean();
boolean hasPackageInfo = in.readBoolean();
String contentPath = in.readUTF();
long lastModified = in.readLong();
Map<String, String> cachedHeaders = new HashMap<>(storedCachedHeaderKeys.size());
for (String headerKey : storedCachedHeaderKeys) {
String value = in.readUTF();
if (NUL.equals(value)) {
value = null;
} else {
value = ObjectPool.intern(value);
}
cachedHeaders.put(headerKey, value);
}
boolean isMRJar = (version >= MR_JAR_VERSION) ? in.readBoolean() : false;
File content;
if (infoId == 0) {
content = getSystemContent();
isDirectory = content != null ? content.isDirectory() : false;
// Note that we do not do any checking for absolute paths with
// the system bundle. We always take the content as discovered
// by getSystemContent()
} else {
content = new File(contentPath);
if (!content.isAbsolute()) {
// make sure it has the absolute location instead
if (isReference) {
// reference installs are relative to the installPath
content = new File(installPath, contentPath);
} else {
// normal installs are relative to the storage area
content = getFile(contentPath, true);
}
}
}
BundleInfo info = new BundleInfo(this, infoId, infoLocation, nextGenId);
Generation generation = info.restoreGeneration(generationId, content, isDirectory, isReference, hasPackageInfo, cachedHeaders, lastModified, isMRJar);
result.put(infoId, generation);
generations.add(generation);
}
loadStorageHookData(generations, in);
return result;
}
use of org.eclipse.osgi.storage.BundleInfo.Generation in project rt.equinox.framework by eclipse.
the class Storage method install.
public Generation install(Module origin, String bundleLocation, URLConnection content) throws BundleException {
if (osgiLocation.isReadOnly()) {
// $NON-NLS-1$
throw new BundleException("The framework storage area is read only.", BundleException.INVALID_OPERATION);
}
URL sourceURL = content.getURL();
InputStream in;
try {
in = content.getInputStream();
} catch (Throwable e) {
// $NON-NLS-1$
throw new BundleException("Error reading bundle content.", e);
}
// Check if the bundle already exists at this location
// before doing the staging and generation creation.
// This is important since some installers seem to continually
// re-install bundles using the same location each startup
Module existingLocation = moduleContainer.getModule(bundleLocation);
if (existingLocation != null) {
// Another thread could win the location lock and install before this thread does.
try {
in.close();
} catch (IOException e) {
// ignore
}
if (origin != null) {
// Check that the existing location is visible from the origin module
Bundle bundle = origin.getBundle();
BundleContext context = bundle == null ? null : bundle.getBundleContext();
if (context != null && context.getBundle(existingLocation.getId()) == null) {
Bundle b = existingLocation.getBundle();
throw new BundleException(NLS.bind(Msg.ModuleContainer_NameCollisionWithLocation, new Object[] { b.getSymbolicName(), b.getVersion(), bundleLocation }), BundleException.REJECTED_BY_HOOK);
}
}
return (Generation) existingLocation.getCurrentRevision().getRevisionInfo();
}
boolean isReference = in instanceof ReferenceInputStream;
File staged = stageContent(in, sourceURL);
Generation generation = null;
try {
Long nextID = moduleDatabase.getAndIncrementNextId();
BundleInfo info = new BundleInfo(this, nextID, bundleLocation, 0);
generation = info.createGeneration();
File contentFile = getContentFile(staged, isReference, nextID, generation.getGenerationId());
generation.setContent(contentFile, isReference);
// Check that we can open the bundle file
generation.getBundleFile().open();
setStorageHooks(generation);
ModuleRevisionBuilder builder = getBuilder(generation);
builder.setId(nextID);
Module m = moduleContainer.install(origin, bundleLocation, builder, generation);
if (!nextID.equals(m.getId())) {
// this revision is already installed. delete the generation
generation.delete();
return (Generation) m.getCurrentRevision().getRevisionInfo();
}
return generation;
} catch (Throwable t) {
if (!isReference) {
try {
delete(staged);
} catch (IOException e) {
// tried our best
}
}
if (generation != null) {
generation.delete();
generation.getBundleInfo().delete();
}
if (t instanceof SecurityException) {
// if the cause is a bundle exception then throw that
if (t.getCause() instanceof BundleException) {
throw (BundleException) t.getCause();
}
throw (SecurityException) t;
}
if (t instanceof BundleException) {
throw (BundleException) t;
}
// $NON-NLS-1$
throw new BundleException("Error occurred installing a bundle.", t);
} finally {
if (generation != null) {
generation.getBundleInfo().unlockGeneration(generation);
}
}
}
Aggregations