/*******************************************************************************
* Copyright (c) 2010 Angelo Zerr 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:
* Angelo Zerr <angelo.zerr@gmail.com> - initial API and implementation
*******************************************************************************/
package org.eclipse.equinox.nonosgi.internal.registry;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;
import java.util.Enumeration;
import java.util.Map;
import java.util.ResourceBundle;
import org.eclipse.core.internal.registry.ExtensionRegistry;
import org.eclipse.core.runtime.IExtensionRegistry;
import org.eclipse.core.runtime.spi.RegistryContributor;
import org.eclipse.core.runtime.spi.RegistryStrategy;
import org.eclipse.osgi.framework.util.Headers;
/**
*
* The registry strategy that can be used in NO OSGi-env.
* <p>
* This class emulate RegistryStrategyOSGI
* </p>
*
*/
@SuppressWarnings("restriction")
public class RegistryStrategyNonOSGI extends RegistryStrategy {
private Object token;
public RegistryStrategyNonOSGI(File[] storageDirs, boolean[] cacheReadOnly,
Object token) {
super(storageDirs, cacheReadOnly);
this.token = token;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.core.runtime.spi.RegistryStrategy#onStart(org.eclipse.core
* .runtime.IExtensionRegistry, boolean)
*/
public void onStart(IExtensionRegistry registry, boolean loadedFromCache) {
// see EclipseBundleListener class (OSGi-env)
long startGlobalTime = System.currentTimeMillis();
long startTime = 0;
int pluginXMLWithNoError = 0;
int pluginXMLWithError = 0;
int pluginXMLTotal = 0;
try {
if (DebugHelper.DEBUG) {
DebugHelper.log("BEGIN RegistryStrategyNonOSGI#onStart");
}
super.onStart(registry, loadedFromCache);
if (!(registry instanceof ExtensionRegistry)) {
if (DebugHelper.DEBUG) {
DebugHelper.log(
"Impossible to load <plugin.xml>. IExtensionRegistry must be an instance of <"
+ ExtensionRegistry.class.getName() + ">",
1);
}
return;
}
ExtensionRegistry extensionRegistry = (ExtensionRegistry) registry;
// Searching <plugin.xml> URL from the ClassLoader.
if (DebugHelper.DEBUG) {
startTime = System.currentTimeMillis();
DebugHelper
.log("Start searching <plugin.xml> URLs from the ClassLoader....",
1);
}
ClassLoader cl = getClass().getClassLoader();
Enumeration<URL> pluginURLs = Utils.getPluginXMLs(cl);
if (pluginURLs == null || !pluginURLs.hasMoreElements()) {
if (DebugHelper.DEBUG) {
DebugHelper.log(
"No <plugin.xml> founded into the ClassLoader", 1);
}
return;
}
if (DebugHelper.DEBUG) {
DebugHelper.log(
"End searching <plugin.xml> URLs from the ClassLoader with time="
+ (System.currentTimeMillis() - startTime)
+ "(ms)", 1);
}
// <plugin.xml> files are present into ClassLoader.
// Searching <META-INF/MANIFEST.MF> URL from the ClassLoader.
if (DebugHelper.DEBUG) {
startTime = System.currentTimeMillis();
DebugHelper
.log("Start searching <META-INF/MANIFEST.MF> URLs from the ClassLoader....",
1);
}
Map<String /* baseDir of the files */, URL /* of the MANIFEST.MF */> manifests = Utils
.getManifestsMap(cl);
if (DebugHelper.DEBUG) {
DebugHelper.log(
"End searching <META-INF/MANIFEST.MF> URLs from the ClassLoader with time="
+ (System.currentTimeMillis() - startTime)
+ "(ms)", 1);
}
if (DebugHelper.DEBUG) {
startTime = System.currentTimeMillis();
DebugHelper.log("Start loading <plugin.xml> ....", 1);
}
// Loop for each plugin.xml URL
while (pluginURLs.hasMoreElements()) {
URL url = pluginURLs.nextElement();
pluginXMLTotal++;
try {
if (loadPluginXML(url, extensionRegistry, manifests)) {
pluginXMLWithNoError++;
} else {
pluginXMLWithError++;
}
} catch (RuntimeException e) {
pluginXMLWithError++;
if (DebugHelper.DEBUG) {
DebugHelper.logError(e);
}
}
}
if (DebugHelper.DEBUG) {
DebugHelper.log(
"End loading <plugin.xml> with time="
+ (System.currentTimeMillis() - startTime)
+ "(ms)", 1);
}
} finally {
if (DebugHelper.DEBUG) {
DebugHelper
.log("END RegistryStrategyNonOSGI#onStart: plugin.xml [OK]=<"
+ pluginXMLWithNoError
+ "/"
+ pluginXMLTotal
+ ">, plugin.xml [ERROR]=<"
+ pluginXMLWithError
+ "/"
+ pluginXMLTotal
+ ">, time="
+ (System.currentTimeMillis() - startGlobalTime)
+ "(ms).");
}
}
}
/**
* Load the plugin.xml.
*
* @param pluginManifest
* @param extensionRegistry
* @param manifests
* @return
*/
private boolean loadPluginXML(URL pluginManifest,
ExtensionRegistry extensionRegistry, Map<String, URL> manifests) {
long startTime = System.currentTimeMillis();
if (pluginManifest == null) {
return false;
}
InputStream is;
try {
is = new BufferedInputStream(pluginManifest.openStream());
} catch (IOException ex) {
is = null;
if (DebugHelper.DEBUG) {
DebugHelper.logError("<plugin.xml> [ERROR] : ("
+ pluginManifest.getPath() + "): ", 1);
DebugHelper.logError(ex);
}
return false;
}
// Search META-INF/MANIFEST.MF stored int the same plugin.xml folder.
String baseDir = Utils.getBaseDir(pluginManifest,
Constants.PLUGIN_MANIFEST);
URL manifestURL = manifests.get(baseDir);
if (manifestURL == null) {
// META-INF/MANIFEST.MF doesn't exist for the plugin.xml
// ignore it.
if (DebugHelper.DEBUG) {
DebugHelper.logError("<plugin.xml> [ERROR] : ("
+ pluginManifest.getPath() + "): ", 1);
DebugHelper.logError(
"<META-INF/MANIFEST.MF> doesn't exist for the <plugin.xml>. <"
+ baseDir
+ "META-INF/MANIFEST.MF> not founded.", 2);
}
return false;
}
// MANIFEST.MF founded for the plugin.xml, Parse MANIFEST.MF.
@SuppressWarnings("rawtypes")
Headers headers = null;
try {
headers = Headers.parseManifest(manifestURL.openStream());
} catch (Exception e) {
if (DebugHelper.DEBUG) {
DebugHelper.logError("<plugin.xml> [ERROR] : ("
+ pluginManifest.getPath() + "): ", 1);
DebugHelper.logError("Error while parsing MANIFEST.MF=<"
+ manifestURL.getPath() + ">", 2);
DebugHelper.logError(e);
}
return false;
}
// Get Bundle-SymbolicName from the MANIFEST.MF
String symbolicName = (String) headers
.get(Constants.BUNDLE_SYMBOLICNAME);
if (Utils.isEmpty(symbolicName)) {
if (DebugHelper.DEBUG) {
DebugHelper.logError("<plugin.xml> [ERROR] : ("
+ pluginManifest.getPath() + "): ", 1);
DebugHelper.logError(
"Cannot found <Bundle-SymbolicName> from the MANIFEST.MF=<"
+ manifestURL.getPath() + ">", 2);
}
return false;
}
// Remove options from the Bundle-SymbolicName declaration.
int index = symbolicName.indexOf(';');
if (index != -1) {
symbolicName = symbolicName.substring(0, index);
}
// Create IContributor
RegistryContributor contributor = ContributorFactoryNonOSGI
.createContributor(symbolicName);
// Test if IContributor doesn't already exists.
if (extensionRegistry.hasContributor(contributor)) {
if (DebugHelper.DEBUG) {
DebugHelper.logError("<plugin.xml> [ERROR] : ("
+ pluginManifest.getPath() + "): ", 1);
DebugHelper.logError(
"Contributor with id=<" + contributor.getActualId()
+ "> already exits.", 2);
}
return false;
}
ResourceBundle translationBundle = null;
long timestamp = 0;
// Parse the plugin.xml
if (!extensionRegistry.addContribution(is, contributor, true,
pluginManifest.getPath(), translationBundle, token, timestamp)) {
if (DebugHelper.DEBUG) {
DebugHelper.logError("<plugin.xml> [ERROR] : ("
+ pluginManifest.getPath() + "): ", 1);
DebugHelper.logError("Parsing problems with plugin.xml", 2);
}
return false;
}
if (DebugHelper.DEBUG) {
DebugHelper.log("<plugin.xml> [OK] loaded with time="
+ (System.currentTimeMillis() - startTime)
+ "(ms) : (" + pluginManifest.getPath()
+ ")", 1);
}
return true;
}
}