blob: 1e0243831d74d73cefe49411892db9ac330bb2ba [file] [log] [blame]
/**
* Copyright (c) 2002-2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* IBM - Initial API and implementation
*/
package org.eclipse.emf.common;
import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.text.Collator;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import java.util.TreeMap;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Platform;
import org.eclipse.emf.common.util.ResourceLocator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.osgi.service.resolver.BundleDescription;
import org.osgi.framework.Bundle;
import org.osgi.framework.BundleActivator;
import org.osgi.resource.Capability;
/**
* The <b>Plugin</b> for the model EMF.Common library.
* EMF must run
* within an Eclipse workbench,
* within a headless Eclipse workspace,
* or just stand-alone as part of some other application.
* To support this, all resource access should be directed to the resource locator,
* which can redirect the service as appropriate to the runtime.
* During stand-alone invocation no plugin initialization takes place.
* In this case, common.resources.jar must be on the CLASSPATH.
* @see #INSTANCE
*/
public final class CommonPlugin extends EMFPlugin
{
/**
* The singleton instance of the plugin.
*/
public static final CommonPlugin INSTANCE = new CommonPlugin();
/**
* The one instance of this class.
*/
private static Implementation plugin;
/**
* Creates the singleton instance.
*/
private CommonPlugin()
{
super(new ResourceLocator[] {});
}
@Override
public ResourceLocator getPluginResourceLocator()
{
return plugin;
}
/**
* Returns the singleton instance of the Eclipse plugin.
* @return the singleton instance.
*/
public static Implementation getPlugin()
{
return plugin;
}
/**
* Use the platform, if available, to convert to a local URI.
*/
public static URI asLocalURI(URI uri)
{
return plugin == null ? uri : Implementation.asLocalURI(uri);
}
/**
* Use the platform, if available, to resolve the URI.
*/
public static URI resolve(URI uri)
{
return plugin == null ? uri : Implementation.resolve(uri);
}
/**
* Use the platform, if available, to load the named class using the right class loader.
*/
public static Class<?> loadClass(String pluginID, String className) throws ClassNotFoundException
{
return plugin == null ? Class.forName(className) : Implementation.loadClass(pluginID, className);
}
/**
* Computes a list of {@link ElementRecord element records} for each requested extension point.
* Each key in the map is extension point ID.
* <p>
* The corresponding value is a list of the extension point element records associated with that extension point.
* </p>
* <p>
* Each root element record has synthetic attributes derived from the extension point:
* </p>
* <dl style="text-index: 1em;">
* <dt>{@code point}</dt>
* <dd>The extension point ID itself.</dd>
* <dt>{@code symbolicName}</dt>
* <dd>The symbolic name of the bundle that contains the extension point.</dd>
* <dt>{@code location}</dt>
* <dd>
* The root location URI the bundle containing the extension point.
* For example, {@code platform:/resource/org.example.plugin} for an extension point in the workspace,
* {@code file:/folder/org.eclipse.plugin} for folder bundle in the target platform,
* or {@code archive:file:/file/folder/org.example.plugin.jar!/} for a jarred bundle in the target platform.
* This is useful for resolving a relative path in attribute value to its absolute path in the bundle.
* </dd>
* </dl>
* <p>
* This method uses the Plug-in Development Environment (PDE) to compute the results.
* It will include results for plug-ins in the workspace as well as for plug-ins in the target platform.
* If PDE is not available, this information cannot be computed.
* </p>
*
* @param extensionPoints a set of extension points to query; if it's {@code null} or empty, all extension points will be queried.
* @return a map of extension point data, or {@code null} if PDE is not available.
* @since 2.14
*/
public static Map<String, List<ElementRecord>> getTargetPlatformExtensionPoints(Set<String> extensionPoints)
{
if (IS_ECLIPSE_RUNNING && PDEHelper.IS_PDE_BUNDLE_AVAILABLE)
{
return PDEHelper.computeModels(extensionPoints);
}
else
{
return null;
}
}
/**
* Computes a map from bundle symbolic name to the bundle's location URI.
* <p>
* This method uses the Plug-in Development Environment (PDE) to compute the results.
* It will include results for plug-ins in the workspace as well as for plug-ins in the target platform.
* If PDE is not available, this information cannot be computed.
* </p>
*
* @return a map from bundle symbolic name to the bundle's location URI, or {@code null} if PDE is not available.
* @since 2.14
*/
public static Map<String, URI> getTargetPlatformBundleMappings()
{
if (IS_ECLIPSE_RUNNING && PDEHelper.IS_PDE_BUNDLE_AVAILABLE)
{
return PDEHelper.computeTargetPlatformBundleMappings();
}
else
{
return null;
}
}
private static volatile Method collatorGetInstanceMethod;
private static volatile boolean collatorGetInstanceMethodInitialized;
private static Method getCollatorGetInstanceMethod()
{
if (!collatorGetInstanceMethodInitialized)
{
try
{
Class<?> collatorClass = loadClass("com.ibm.icu", "com.ibm.icu.text.Collator");
collatorGetInstanceMethod = collatorClass.getMethod("getInstance", Locale.class);
}
catch (Throwable throwable)
{
// Assume the class is not available.
}
collatorGetInstanceMethodInitialized = true;
}
return collatorGetInstanceMethod;
}
/**
* Returns a string comparator appropriate for collating strings for the {@link Locale#getDefault() current locale}.
* @return a string comparator appropriate for collating strings for the {@link Locale#getDefault() current locale}.
*/
public Comparator<String> getComparator()
{
return getComparator(Locale.getDefault());
}
/**
* Returns a string comparator appropriate for collating strings for the give locale.
* This will use ICU, when available that plug-in is available, or {@link Collator} otherwise.
* @param locale the locale for which a comparator is needed.
* @return a string comparator appropriate for collating strings for the give locale.
*/
@SuppressWarnings("unchecked")
public Comparator<String> getComparator(Locale locale)
{
Method collatorGetInstanceMethod = getCollatorGetInstanceMethod();
if (collatorGetInstanceMethod != null)
{
try
{
return (Comparator<String>)collatorGetInstanceMethod.invoke(null, locale);
}
catch (Throwable eception)
{
// Just return the default.
}
}
return (Comparator<String>)(Comparator<?>)Collator.getInstance(locale);
}
/**
* The actual implementation of the Eclipse <b>Plugin</b>.
*/
public static class Implementation extends EclipsePlugin
{
/**
* Creates an instance.
*/
public Implementation()
{
super();
// Remember the static instance.
//
plugin = this;
}
/**
* Use the platform to convert to a local URI.
*/
protected static URI asLocalURI(URI uri)
{
try
{
String fragment = uri.fragment();
URL url = FileLocator.toFileURL(new URL(uri.trimFragment().toString()));
return fix(url, fragment);
}
catch (IOException exception)
{
// Ignore the exception and return the original URI.
}
return uri;
}
/**
* Use the platform to convert to a local URI.
*/
protected static URI resolve(URI uri)
{
String fragment = uri.fragment();
URI uriWithoutFragment = uri.trimFragment();
String uriWithoutFragmentToString = uriWithoutFragment.toString();
URL url = null;
try
{
url = FileLocator.resolve(new URL(uriWithoutFragmentToString));
}
catch (IOException exception1)
{
// Platform.resolve() doesn't work if the project is encoded.
//
try
{
uriWithoutFragmentToString = URI.decode(uriWithoutFragmentToString);
url = FileLocator.resolve(new URL(uriWithoutFragmentToString));
}
catch (IOException exception2)
{
// Continue with the unresolved URI.
}
}
if (url != null)
{
try
{
return fix(url, fragment);
}
catch (IOException exception)
{
// Return the original URI.
}
}
return uri;
}
protected static URI fix(URL url, String fragment) throws IOException
{
// Only file-scheme URIs will be re-encoded. If a URI was decoded in the workaround
// above, and Platform.resolve() didn't return a file-scheme URI, then this will return
// an decoded URI.
//
URI result =
"file".equalsIgnoreCase(url.getProtocol()) ?
URI.createFileURI(URI.decode(url.getFile())) :
URI.createURI(url.toString());
if (fragment != null)
{
result = result.appendFragment(fragment);
}
return result;
}
/**
* Use the platform to load the named class using the right class loader.
*/
public static Class<?> loadClass(String pluginID, String className) throws ClassNotFoundException
{
Bundle bundle = Platform.getBundle(pluginID);
if (bundle == null)
{
throw new ClassNotFoundException(className + " cannot be loaded because because bundle " + pluginID + " cannot be resolved");
}
else
{
return bundle.loadClass(className);
}
}
/**
* @since 2.10
*/
public static class Activator extends EMFPlugin.OSGiDelegatingBundleActivator
{
@Override
protected BundleActivator createBundle()
{
return new Implementation();
}
}
}
/**
* A specialized {@link HashMap} map that supports {@link #getTargetPlatformValues(String,String) computing} information from the target platform, if the PDE is available.
* It is abstract because the {@link #createKey(String)} method must be specialized to convert each attribute's string value to a value of the map's key type.
*
* @param <K> the type of the key.
* @param <V> the type of the value.
*
* @since 2.14
*/
public static abstract class SimpleTargetPlatformRegistryImpl<K, V> extends HashMap<K, V>
{
private static final long serialVersionUID = 1L;
/**
* Creates an instance.
*/
public SimpleTargetPlatformRegistryImpl()
{
}
/**
* Returns the set of values computed by {@link CommonPlugin#getTargetPlatformExtensionPoints(Set) fetching} all the given extension points
* and {@link ElementRecord#getAttributes() looking up} the given attribute name in each {@link ElementRecord#getChildren() element} of that extension point.
* Each attribute value is {@link #createKey(String) converted} to a value of the map's key type.
* @param extensionPoint the qualified extension point name.
* @param attributeName the attribute name to query.
* @return the values computed from the target platform, if the Plug-in Development Environment is available, or a copy of the {@link #keySet()} otherwise.
* @see #createKey(String)
*/
protected Set<K> getTargetPlatformValues(String extensionPoint, String attributeName)
{
Map<String, List<CommonPlugin.ElementRecord>> targetPlatformExtensionPoints = getTargetPlatformExtensionPoints(Collections.singleton(extensionPoint));
if (targetPlatformExtensionPoints != null)
{
Set<K> result = new LinkedHashSet<K>();
List<CommonPlugin.ElementRecord> extensionPointElementRecords = targetPlatformExtensionPoints.get(extensionPoint);
if (extensionPointElementRecords != null)
{
for (CommonPlugin.ElementRecord extensionPointRecord : extensionPointElementRecords)
{
for (ElementRecord elementRecord : extensionPointRecord.getChildren())
{
String attribute = elementRecord.getAttributes().get(attributeName);
if (attribute != null)
{
result.add(createKey(attribute));
}
}
}
}
return result;
}
else
{
return new LinkedHashSet<K>(keySet());
}
}
/**
* Returns the attribute value converted to a value of the key type.
* @param attribute the attribute value.
* @return the attribute value converted to a value of the key type.
*/
protected abstract K createKey(String attribute);
}
/**
* A simple representation of an element in a {@code plugin.xml}.
* It has the obvious things you'd expect of an element, i.e., a name, attributes, and children.
*
* @since 2.14
*/
public static final class ElementRecord
{
/**
* The element name.
*/
private final String name;
/**
* The attributes of the element.
*/
private final Map<String, String> attributes = new TreeMap<String, String>();
/**
* The children of the element.
*/
private final List<ElementRecord> children = new ArrayList<ElementRecord>();
/**
* Creates an element with the given name.
*
* @param name the name of the element.
*/
private ElementRecord(String name)
{
this.name = name;
}
/**
* Returns the name of the element.
* @return the name of the element.
*/
public String getName()
{
return name;
}
/**
* Returns the attributes of the element.
* @return the attributes of the element.
*/
public Map<String, String> getAttributes()
{
return Collections.unmodifiableMap(attributes);
}
/**
* Returns the children elements.
* @return the children elements.
*/
public List<ElementRecord> getChildren()
{
return Collections.unmodifiableList(children);
}
/**
* A helpful override for debugging.
*/
@Override
public String toString()
{
return "" + name + " attributes= " + attributes + " children=" + children;
}
}
private static class PDEHelper
{
private static final String ECORE_GENERATED_PACKAGE = "org.eclipse.emf.ecore.generated_package";
private static final Method PLUGIN_MODEL_BASE_GET_BUNDLE_DESCRIPTION_METHOD;
private static final Method PLUGIN_MODEL_BASE_GET_UNDERLYING_RESOURCE_METHOD;
private static final Method RESOURCE_GET_PROJECT_METHOD;
private static final Method RESOURCE_GET_FULL_PATH_METHOD;
private static final Method PLUGIN_MODEL_BASE_GET_INSTALL_LOCATION_METHOD;
private static final Method PLUGIN_MODEL_BASE_GET_EXTENSIONS_METHOD;
private static final Method PLUGIN_REGISTRY_GET_ACTIVE_MODELS_METHOD;
private static final Method EXTENSIONS_GET_EXTENSIONS_METHOD;
private static final Method PLUGIN_EXTENSION_GET_POINT_METHOD;
private static final Method PLUGIN_EXTENSION_GET_CHILDREN_METHOD;
private static final Class<?> PLUGIN_ELEMENT_CLASS;
private static final Method PLUGIN_ELEMENT_GET_ATTRIBUTES_METHOD;
private static final Method PLUGIN_OBJECT_GET_NAME_METHOD;
private static final Method PLUGIN_ATTRIBUTE_GET_VALUE_METHOD;
private static final boolean IS_PDE_BUNDLE_AVAILABLE;
static
{
Method pluginModelBaseGetBundleDescriptionMethod = null;
Method pluginModelBaseGetUnderlyingResourceMethod = null;
Method resourceGetProjectMethod = null;
Method resourceGetFullPathtMethod = null;
Method pluginModelBaseGetInstallLocationMethod = null;
Method pluginModelBaseGetExtensionsMethod = null;
Method pluginRegistryGetActiveModelsMethod = null;
Method extensionsGetExtensionsMethod = null;
Method pluginExtensionGetPointMethod = null;
Method pluginExtensionGetChildrenMethod = null;
Class<?> pluginElementClass = null;
Method pluginElementGetAttributesMethod = null;
Method pluginObjectGetNameMethod = null;
Method pluginAttributeGetValueMethod = null;
boolean isPDEBundleAvailable = false;
try
{
Class<?> pluginModelBaseClass = CommonPlugin.loadClass("org.eclipse.pde.core", "org.eclipse.pde.core.plugin.IPluginModelBase");
pluginModelBaseGetBundleDescriptionMethod = pluginModelBaseClass.getMethod("getBundleDescription");
pluginModelBaseGetUnderlyingResourceMethod = pluginModelBaseClass.getMethod("getUnderlyingResource");
resourceGetProjectMethod = pluginModelBaseGetUnderlyingResourceMethod.getReturnType().getMethod("getProject");
resourceGetFullPathtMethod = resourceGetProjectMethod.getReturnType().getMethod("getFullPath");
pluginModelBaseGetInstallLocationMethod = pluginModelBaseClass.getMethod("getInstallLocation");
pluginModelBaseGetExtensionsMethod = pluginModelBaseClass.getMethod("getExtensions");
Class<?> pluginRegistryClass = CommonPlugin.loadClass("org.eclipse.pde.core", "org.eclipse.pde.core.plugin.PluginRegistry");
pluginRegistryGetActiveModelsMethod = pluginRegistryClass.getMethod("getActiveModels", boolean.class);
Class<?> extensionsClass = CommonPlugin.loadClass("org.eclipse.pde.core", "org.eclipse.pde.core.plugin.IExtensions");
extensionsGetExtensionsMethod = extensionsClass.getMethod("getExtensions");
Class<?> pluginExtensionClass = CommonPlugin.loadClass("org.eclipse.pde.core", "org.eclipse.pde.core.plugin.IPluginExtension");
pluginExtensionGetPointMethod = pluginExtensionClass.getMethod("getPoint");
pluginExtensionGetChildrenMethod = pluginExtensionClass.getMethod("getChildren");
pluginElementClass = CommonPlugin.loadClass("org.eclipse.pde.core", "org.eclipse.pde.core.plugin.IPluginElement");
pluginObjectGetNameMethod = pluginElementClass.getMethod("getName");
pluginElementGetAttributesMethod = pluginElementClass.getMethod("getAttributes");
Class<?> pluginAttributeClass = CommonPlugin.loadClass("org.eclipse.pde.core", "org.eclipse.pde.core.plugin.IPluginAttribute");
pluginAttributeGetValueMethod = pluginAttributeClass.getMethod("getValue");
isPDEBundleAvailable = true;
}
catch (Throwable exception)
{
// Ignore.
}
PLUGIN_MODEL_BASE_GET_BUNDLE_DESCRIPTION_METHOD = pluginModelBaseGetBundleDescriptionMethod;
PLUGIN_MODEL_BASE_GET_UNDERLYING_RESOURCE_METHOD = pluginModelBaseGetUnderlyingResourceMethod;
RESOURCE_GET_PROJECT_METHOD = resourceGetProjectMethod;
RESOURCE_GET_FULL_PATH_METHOD = resourceGetFullPathtMethod;
PLUGIN_MODEL_BASE_GET_INSTALL_LOCATION_METHOD = pluginModelBaseGetInstallLocationMethod;
PLUGIN_MODEL_BASE_GET_EXTENSIONS_METHOD = pluginModelBaseGetExtensionsMethod;
PLUGIN_REGISTRY_GET_ACTIVE_MODELS_METHOD = pluginRegistryGetActiveModelsMethod;
EXTENSIONS_GET_EXTENSIONS_METHOD = extensionsGetExtensionsMethod;
PLUGIN_EXTENSION_GET_POINT_METHOD = pluginExtensionGetPointMethod;
PLUGIN_EXTENSION_GET_CHILDREN_METHOD = pluginExtensionGetChildrenMethod;
PLUGIN_ELEMENT_CLASS = pluginElementClass;
PLUGIN_OBJECT_GET_NAME_METHOD = pluginObjectGetNameMethod;
PLUGIN_ELEMENT_GET_ATTRIBUTES_METHOD = pluginElementGetAttributesMethod;
PLUGIN_ATTRIBUTE_GET_VALUE_METHOD = pluginAttributeGetValueMethod;
IS_PDE_BUNDLE_AVAILABLE = isPDEBundleAvailable && !"true".equals(System.getProperty("org.eclipse.emf.common.CommonPlugin.doNotUsePDE"));
}
@SuppressWarnings("unchecked")
private static <T> T invoke(Object object, Method method, Object... arguments)
{
try
{
return (T)method.invoke(object, arguments);
}
catch (Exception exception)
{
return null;
}
}
private static Map<String, URI> computeTargetPlatformBundleMappings()
{
final Map<String, URI> result = new TreeMap<String, URI>();
new ActiveModelVisitor()
{
@Override
void visitActiveModel(Object activeModel, BundleDescription bundleDescription, URI location)
{
String symbolicName = bundleDescription.getSymbolicName();
if (symbolicName != null && location != null)
{
result.put(symbolicName, location);
}
}
};
return result;
}
private static Map<String, List<ElementRecord>> computeModels(final Set<String> extensionPoints)
{
final Map<String, List<ElementRecord>> result = new TreeMap<String, List<ElementRecord>>();
new ActiveModelVisitor()
{
@Override
void visitActiveModel(Object activeModel, BundleDescription bundleDescription, URI location)
{
String symbolicName = bundleDescription.getSymbolicName();
// Iterate over the plugin's extensions...
//
// IExtensions extensions = activeModel.getExtensions();
// IPluginExtension[] pluginExtensions = extensions.getExtensions();
//
Object extensions = invoke(activeModel, PLUGIN_MODEL_BASE_GET_EXTENSIONS_METHOD);
Object[] pluginExtensions = invoke(extensions, EXTENSIONS_GET_EXTENSIONS_METHOD);
if (pluginExtensions.length == 0)
{
if (extensionPoints != null && extensionPoints.contains(ECORE_GENERATED_PACKAGE))
{
List<Capability> capabilities = bundleDescription.getCapabilities(ECORE_GENERATED_PACKAGE);
if (!capabilities.isEmpty())
{
ElementRecord extensionRecord = new ElementRecord("extension");
recordExtensionAttributes(extensionRecord, ECORE_GENERATED_PACKAGE, symbolicName, location);
for (Capability capability : capabilities)
{
ElementRecord elementRecord = new ElementRecord("package");
Map<String, Object> attributes = capability.getAttributes();
elementRecord.attributes.put("uri", "" + attributes.get("uri"));
elementRecord.attributes.put("class", "" + attributes.get("class"));
elementRecord.attributes.put("genModel", "" + attributes.get("genModel"));
extensionRecord.children.add(elementRecord);
}
List<ElementRecord> elementRecords = getElementRecords(ECORE_GENERATED_PACKAGE);
elementRecords.add(extensionRecord);
}
}
}
else
{
for (Object pluginExtension : pluginExtensions)
{
// String point = pluginExtension.getPoint();
//
String point = invoke(pluginExtension, PLUGIN_EXTENSION_GET_POINT_METHOD);
// Process all or the specified extension points.
//
if (extensionPoints == null || extensionPoints.isEmpty() || extensionPoints.contains(point))
{
ElementRecord elementRecord = visitElement(pluginExtension);
recordExtensionAttributes(elementRecord, point, symbolicName, location);
List<ElementRecord> elementRecords = getElementRecords(point);
elementRecords.add(elementRecord);
}
}
}
}
private void recordExtensionAttributes(ElementRecord elementRecord, String point, String symbolicName, URI location)
{
if (location != null)
{
elementRecord.attributes.put("point", point);
elementRecord.attributes.put("symbolicName", symbolicName);
elementRecord.attributes.put("location", location.toString());
}
}
private List<ElementRecord> getElementRecords(String point)
{
List<ElementRecord> elementRecords = result.get(point);
if (elementRecords == null)
{
elementRecords = new ArrayList<ElementRecord>();
result.put(point, elementRecords);
}
return elementRecords;
}
};
// dump(result);
return result;
}
private static void visitElement(Object[] children, List<ElementRecord> elementRecords)
{
// Visit the children.
//
for (Object child : children)
{
// if (child instanceof IPluginElement)
//
if (PLUGIN_ELEMENT_CLASS.isInstance(child))
{
elementRecords.add(visitElement(child));
}
}
}
private static ElementRecord visitElement(Object child)
{
ElementRecord elementRecord;
if (PLUGIN_ELEMENT_CLASS.isInstance(child))
{
// child.getName();
//
String elementName = invoke(child, PLUGIN_OBJECT_GET_NAME_METHOD);
// Record it by name.
//
elementRecord = new ElementRecord(elementName);
// child.getAttributes()
Object[] attributes = invoke(child, PLUGIN_ELEMENT_GET_ATTRIBUTES_METHOD);
for (Object attribute : attributes)
{
// attribute.getName() and attribute.getValue()
//
String attributeName = invoke(attribute, PLUGIN_OBJECT_GET_NAME_METHOD);
String attributeValue = invoke(attribute, PLUGIN_ATTRIBUTE_GET_VALUE_METHOD);
// Record in the map.
//
elementRecord.attributes.put(attributeName, attributeValue);
}
}
else
{
elementRecord = new ElementRecord("extension");
}
// Visit the child elements recursively.
//
Object[] elements = invoke(child, PLUGIN_EXTENSION_GET_CHILDREN_METHOD);
if (elements.length != 0)
{
visitElement(elements, elementRecord.children);
}
return elementRecord;
}
private static abstract class ActiveModelVisitor
{
public ActiveModelVisitor() {
// Iterate over all the active models in the workspace and target platform.
//
// IPluginModelBase[] activeModels = PluginRegistry.getActiveModels(false);
//
Object[] activeModels = invoke(null, PLUGIN_REGISTRY_GET_ACTIVE_MODELS_METHOD, Boolean.FALSE);
for (Object activeModel : activeModels)
{
// Determine the symbolic name, underlying resource, if any, and the install location.
//
// BundleDescription bundleDescription = activeModel.getBundleDescription();
// IResource underlyingResource = activeModel.getUnderlyingResource();
// String installLocation = activeModel.getInstallLocation();
//
BundleDescription bundleDescription = invoke(activeModel, PLUGIN_MODEL_BASE_GET_BUNDLE_DESCRIPTION_METHOD);
Object underlyingResource = invoke(activeModel, PLUGIN_MODEL_BASE_GET_UNDERLYING_RESOURCE_METHOD);
String installLocation = (String)invoke(activeModel, PLUGIN_MODEL_BASE_GET_INSTALL_LOCATION_METHOD);
// The URI for the location is determined from the underlying resource or the install location, with preference to the former if available.
//
URI location;
if (underlyingResource != null)
{
// If there is an underlying resource, use the platform resource URI referencing the project in the workspace as the location.
// underlyingResource.getProject()
//
Object project = invoke(underlyingResource, RESOURCE_GET_PROJECT_METHOD);
IPath fullPath = invoke(project, RESOURCE_GET_FULL_PATH_METHOD);
location = URI.createPlatformResourceURI(fullPath.toString(), true);
}
else if (installLocation != null)
{
// Otherwise, the install location in the file system is used...
//
File file = new File(installLocation);
if (file.isDirectory())
{
// If the file is a directory, create a file URI for that directory.
//
location = URI.createFileURI(installLocation);
}
else
{
// Otherwise, the location must be an archive, create an archive URI for the file URI of the jar.
//
location = URI.createURI("archive:" + URI.createFileURI(installLocation) + "!/");
}
}
else
{
location = null;
}
visitActiveModel(activeModel, bundleDescription, location);
}
}
abstract void visitActiveModel(Object activeModel, BundleDescription bundleDescription, URI location);
}
// private static void dump(Map<String, List<ElementRecord>> data)
// {
// for (Map.Entry<String, List<ElementRecord>> entry : data.entrySet())
// {
// System.out.println(entry.getKey());
// dump(entry.getValue(), " ");
// }
// }
//
// private static void dump(List<ElementRecord> data, String indent)
// {
// for (ElementRecord elementRecord : data)
// {
// System.out.print(indent + "<" + elementRecord.getName());
// for (Map.Entry<String, String> attribute : elementRecord.getAttributes().entrySet())
// {
// System.out.println();
// System.out.print(indent + " " + attribute.getKey() + "='" + attribute.getValue() + "'");
// }
// List<ElementRecord> children = elementRecord.getChildren();
// if (children.isEmpty())
// {
// System.out.println("/>");
// }
// else
// {
// System.out.println(">");
// dump(children, indent + " ");
// System.out.print(indent + "</" + elementRecord.getName() + ">");
// }
// }
// }
}
}