blob: cadbd2ca176d2e4bd4d715f1aaeb8779769ed4a0 [file] [log] [blame]
/******************************************************************************
* Copyright (c) 2002, 2009 IBM Corporation 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:
* IBM Corporation - initial API and implementation
****************************************************************************/
package org.eclipse.gmf.runtime.emf.core.internal.resources;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.WeakHashMap;
import java.util.Map.Entry;
import org.eclipse.core.resources.IContainer;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IPathVariableChangeEvent;
import org.eclipse.core.resources.IPathVariableChangeListener;
import org.eclipse.core.resources.IPathVariableManager;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.core.runtime.IConfigurationElement;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Platform;
import org.eclipse.core.runtime.Status;
import org.eclipse.core.runtime.preferences.IEclipsePreferences;
import org.eclipse.core.runtime.preferences.IScopeContext;
import org.eclipse.core.runtime.preferences.InstanceScope;
import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.Notifier;
import org.eclipse.emf.common.notify.impl.AdapterImpl;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.resource.URIConverter;
import org.eclipse.gmf.runtime.common.core.util.Trace;
import org.eclipse.gmf.runtime.emf.core.internal.plugin.EMFCoreDebugOptions;
import org.eclipse.gmf.runtime.emf.core.internal.plugin.EMFCorePlugin;
import org.eclipse.gmf.runtime.emf.core.internal.util.EMFCoreConstants;
import org.eclipse.gmf.runtime.emf.core.resources.GMFResource;
import org.eclipse.gmf.runtime.emf.core.resources.IPathmapManager;
import org.eclipse.gmf.runtime.emf.core.resources.IPathmapManager2;
import org.eclipse.gmf.runtime.emf.core.util.EMFCoreUtil;
import org.osgi.framework.Bundle;
import org.osgi.service.prefs.BackingStoreException;
/**
* This class manages GMF path mappings for URI conversion.
*
* @author rafikj
*/
public class PathmapManager extends AdapterImpl implements IPathmapManager, IPathmapManager2 {
// path maps can be defined using an extension point: Pathmaps
// or by referencing an eclipse path variable
// or by adding a pathmap manually
// The variable name.
private static final String NAME = "name"; //$NON-NLS-1$
//The plugin containing the path.
private static final String PLUGIN = "plugin"; //$NON-NLS-1$
// The path.
private static final String PATH = "path"; //$NON-NLS-1$
private static final String NODE_QUALIFIER = EMFCorePlugin.getDefault().getBundle().getSymbolicName();
private static final String PREFERENCE_KEY = "referenced.path.variables"; //$NON-NLS-1$
// The path map as defined by the extensions and the referenced path variables and the manually
// added pathmaps.
private static final Map PATH_MAP = Collections.synchronizedMap(configure());
private static final Set FILE_VARIABLES = Collections.synchronizedSet(new HashSet());
private static final Map instances = Collections.synchronizedMap(new WeakHashMap());
// The list of eclipse path variables that are being used in this path map manager
private static Set referencedPathVariablesList;
private static IEclipsePreferences preferenceStore = null;
static {
IPathVariableManager pathManager = ResourcesPlugin.getWorkspace().getPathVariableManager();
// We will get the initial list of referenced path variables from our preference store
IEclipsePreferences preferences = getPreferenceStore();
String referencedPathVariables = preferences.get(PREFERENCE_KEY, ""); //$NON-NLS-1$
StringTokenizer tokenizer = new StringTokenizer(referencedPathVariables, " "); //$NON-NLS-1$
referencedPathVariablesList = new HashSet(tokenizer.countTokens());
for (;tokenizer.hasMoreTokens();) {
String pathVariable = tokenizer.nextToken();
addPathVariableReference(pathVariable);
}
// Update the preference store in case some path variables have been deleted since the
// last time we saved the store.
updatePreferenceStore();
// Register this listener to keep up-to-date with the eclipse path variables and update our
// referenced path variables appropriately.
pathManager.addChangeListener(new IPathVariableChangeListener() {
public void pathVariableChanged(IPathVariableChangeEvent event) {
switch (event.getType()) {
case IPathVariableChangeEvent.VARIABLE_DELETED:
removePathVariableReference(event.getVariableName());
updatePreferenceStore();
break;
case IPathVariableChangeEvent.VARIABLE_CHANGED:
// We only care about variables that we are referencing that
// have changed.
if (referencedPathVariablesList.contains(event.getVariableName())) {
// Check to see if it has become incompatible
if (!isDirectory(event.getValue())) {
removePathVariableReference(event.getVariableName());
} else {
setPathVariable(event.getVariableName(), URI.createFileURI(event.getValue().toString()).toString());
}
updatePreferenceStore();
}
break;
}
}
});
}
private static IEclipsePreferences getPreferenceStore() {
if (preferenceStore == null) {
IScopeContext ctx = new InstanceScope();
preferenceStore = ctx.getNode(NODE_QUALIFIER);
}
return preferenceStore;
}
/**
* Adds a new reference to a path variable defined in eclipse
* to be used by this pathmap manager. It is assumed that this
* path variable is declared in the eclipes path variable manager
* and that it is a valid path variable for our purposes.
* See {@link #isCompatiblePathVariable(String)} for more details.
*
* @param pathVariable A valid path variable that has been defined in the
* eclipse {@link IPathVariableManager} and is compatible with our path maps.
*/
public static void addPathVariableReference(String pathVariable) {
if (getAllPathVariables().contains(pathVariable)) {
// We already reference this path variable so we can assume that it is added
// and is compatible.
return;
}
if (!isCompatiblePathVariable(pathVariable)) {
return;
}
IPathVariableManager pathManager = ResourcesPlugin.getWorkspace().getPathVariableManager();
IPath value = pathManager.getValue(pathVariable);
if (value != null) {
referencedPathVariablesList.add(pathVariable);
setPathVariable(pathVariable, URI.createFileURI(value.toString()).toString());
}
}
/**
* Updates the preference store with the current set of path variables that this manager
* is currently referencing from the eclipse {@link IPathVariableManager}.
*/
public static void updatePreferenceStore() {
StringBuffer referencedPathVariables = new StringBuffer();
for (Iterator i = referencedPathVariablesList.iterator(); i.hasNext();) {
referencedPathVariables.append((String)i.next());
referencedPathVariables.append(' ');
}
getPreferenceStore().put(PREFERENCE_KEY, referencedPathVariables.toString());
try {
getPreferenceStore().flush();
} catch (BackingStoreException e) {
EMFCorePlugin.getDefault().getLog().log(new Status(IStatus.ERROR, EMFCorePlugin.getPluginId(), IStatus.ERROR, e.getMessage(), e));
}
}
/**
* Removes a reference to a path variable defined in eclipse that was being
* used by this pathmap manager.
*
* @param pathVariable A path variable that was once referenced by this pathmap
* manager pointing to a variable declared in the eclipse {@link IPathVariableManager}.
*/
public static void removePathVariableReference(String pathVariable) {
if (referencedPathVariablesList.contains(pathVariable)) {
referencedPathVariablesList.remove(pathVariable);
unsetPathVariable(pathVariable);
}
}
public static Set getPathVariableReferences() {
return Collections.unmodifiableSet(referencedPathVariablesList);
}
/**
* Obtains a set of all path variable names, registered on the extension
* point and referenced from Eclipse Platform path variables.
*
* @return the set of all mapped path variables
*/
public static Set getAllPathVariables() {
return Collections.unmodifiableSet(PATH_MAP.keySet());
}
/**
* Queries whether the specified path variable name is registered on the
* extension point (versus selected by the user from the platform variables).
*
* @param variable the variable name
*
* @return <code>true</code> if this variable name is registered on the
* path maps extension point; <code>false</code>, otherwise
*/
public static boolean isRegisteredPathVariable(String variable) {
return PATH_MAP.containsKey(variable)
&& !referencedPathVariablesList.contains(variable);
}
/**
* If the specified <code>variable</code> is registered on the extension
* point, then retrieve its value.
*
* @param variable the registered variable to retrieve
* @return the registered variable's value or <code>null</code> if
* it is not registered
*/
public static String getRegisteredValue(String variable) {
return (String) PATH_MAP.get(variable);
}
public static boolean isCompatiblePathVariable(String variable) {
if (referencedPathVariablesList.contains(variable)) {
// We assume that if this variable is already referenced then it is valid.
return true;
}
IPathVariableManager pathManager = ResourcesPlugin.getWorkspace().getPathVariableManager();
IPath value = pathManager.getValue(variable);
if (value == null)
return false;
// Check to see if it is a directory first.
// EMF will not correctly handle extension parsing
// of a pathmap URI if we point directly to a file. This
// means that the wrong resource factory could be called.
// This could possibly change in the future.
return isDirectory(value);
}
private static boolean isDirectory(IPath value) {
File f = new File(value.toString());
return (f.isDirectory());
}
/**
* Constructor.
*/
public PathmapManager() {
super();
instances.put(this, Boolean.TRUE);
}
/**
* Obtains all of the instances of this class.
*
* @return my instances
*/
private static Set allInstances() {
return instances.keySet();
}
/**
* Obtains the pathmap manager attached to the specified resource set, if any.
*
* @param rset a resource set
* @return the attached pathmap manager, or <code>null</code> if none
*/
public static PathmapManager getExistingPathmapManager(ResourceSet rset) {
PathmapManager result = null;
List adapters = rset.eAdapters();
for (int i = 0, size = adapters.size(); (result == null) && (i < size); i++) {
Object next = adapters.get(i);
if (next instanceof PathmapManager) {
result = (PathmapManager) next;
}
}
return result;
}
/**
* Set the value of a pathmap variable. Dirties any resources
* that have HREF's that need to be changed.
*
* @param var the path map variable name
* @param val the path map variable value (must be an encoded URI)
*/
public static void setPathVariable(String var, String val) {
setPathVariable(var, val, true);
}
/**
* Sets the value of a pathmap variable (a folder). The provided flag
* determines if resources should be dirtied if they have HREF's that
* should be changed.
*
* @param var the path map variable name
* @param val the path map variable value (must be an encoded URI)
* @param dirtyResources true, if resources should be dirtied so that
* their modified HREF's are saved. false, otherwise.
*/
public static void setPathVariable(String var, String val, boolean dirtyResources) {
internalSetPathVariable(var, val);
for (Iterator i = allInstances().iterator(); i.hasNext();) {
((PathmapManager) i.next()).resyncEntries(true, dirtyResources);
}
}
private static void internalSetPathVariable(String var, String val) {
// We must try to determine if this pathmap resides in the workspace as some container
// so that we store into the pathmap a substitution that is a platform:/resource
// type of substitution. This is required because otherwise, pathmap URIs normalize
// to file URIs while platform URIs do not normalize, they remain as platform URIs.
// This will break some comparisons that might occur when trying to load a resource
// that is already loaded because the normalized version of the platform URI to be loaded
// will not match the normalized version of the pathmap URI causing two instances of
// the same resource to be loaded.
java.net.URI valURI = java.net.URI.create(val);
IContainer[] containers = ResourcesPlugin.getWorkspace().getRoot().findContainersForLocationURI(valURI);
if (containers.length == 1) {
val = URI.createPlatformResourceURI(containers[0].getFullPath().toString(),true).toString();
}
IFile[] files = ResourcesPlugin.getWorkspace().getRoot().findFilesForLocationURI(valURI);
if (files.length == 1) {
val = URI.createPlatformResourceURI(files[0].getFullPath().toString(),true).toString();
}
PATH_MAP.put(var, val);
}
/**
* Set the value of a pathmap variable to point to a specific file (not a folder). The
* provided flag determines whether resource should be dirtied if their HREF's need to
* be changed.
*
* @param var the path map variable name
* @param val the path map variable value (must be an encoded URI pointing to a file, not a folder)
* @param dirtyResources true, if resources should be dirtied so that their HREF's can be
* changed. false, otherwise.
*/
public static void setFilePathVariable(String var, String val, boolean dirtyResources) {
FILE_VARIABLES.add(var);
internalSetPathVariable(var, val);
for (Iterator i = allInstances().iterator(); i.hasNext();) {
((PathmapManager) i.next()).resyncEntries(true, dirtyResources);
}
}
/**
* Sets the value of a map of pathmap variables to point to specific files (not folders)
* The provided flag determines whether resource should be dirtied if their HREF's need to
* be changed.
*
* @param settings A map of new variables(Strings) to their values(Strings).
* @param dirtyResource true, if resources should be dirtied so that their HREF's can
* be changed. false, otherwise.
*/
public static void setFilePathVariables(Map settings, boolean dirtyResources) {
FILE_VARIABLES.addAll(settings.keySet());
for (Iterator i = settings.entrySet().iterator(); i.hasNext();) {
Map.Entry entry = (Map.Entry)i.next();
internalSetPathVariable((String)entry.getKey(), (String)entry.getValue());
}
for (Iterator i = allInstances().iterator(); i.hasNext();) {
((PathmapManager) i.next()).resyncEntries(true, dirtyResources);
}
}
/**
* Sets the value of a map of pathmap variables to point specific folders (not files).
* The provided flag determines whether resource should be dirtied if their HREF's need
* to be changed.
*
* @param settings A map of new variables(Strings) to their values(Strings).
* @param dirtyResource ture, if resources should be dirtied so that their HREF's can
* be changed. false, otherwise.
*/
public static void setPathVariables(Map settings, boolean dirtyResources) {
for (Iterator i = settings.entrySet().iterator(); i.hasNext();) {
Map.Entry entry = (Map.Entry)i.next();
internalSetPathVariable((String)entry.getKey(), (String)entry.getValue());
}
for (Iterator i = allInstances().iterator(); i.hasNext();) {
((PathmapManager) i.next()).resyncEntries(true, dirtyResources);
}
}
public IStatus addPathVariable(String name, String value) {
setPathVariable(name, value);
return Status.OK_STATUS; // TODO: report accurate status
}
public IStatus addFilePathVariable(String name, String value, boolean dirtyResources) {
setFilePathVariable(name, value, dirtyResources);
return Status.OK_STATUS; // TODO: report accurate status
}
public IStatus addFilePathVariables(Map settings, boolean dirtyResources) {
setFilePathVariables(settings, dirtyResources);
return Status.OK_STATUS; // TODO: report accurate status
}
public IStatus addFolderPathVariable(String name, String value, boolean dirtyResources) {
setPathVariable(name, value, dirtyResources);
return Status.OK_STATUS;
}
public IStatus addFolderPathVariables(Map settings, boolean dirtyResources) {
setPathVariables(settings, dirtyResources);
return Status.OK_STATUS;
}
/**
* Remove a pathmap variable.
*/
public static void unsetPathVariable(String var) {
PATH_MAP.remove(var);
for (Iterator i = allInstances().iterator(); i.hasNext();) {
((PathmapManager) i.next()).resyncEntries(true, true);
}
}
public IStatus removePathVariable(String name) {
unsetPathVariable(name);
return Status.OK_STATUS; // TODO: report accurate status
}
/**
* Obtains the resource set for which I manage the path mappings.
*
* @return my resource set
*/
private ResourceSet getResourceSet() {
return (ResourceSet) getTarget();
}
/**
* Get the value of a pathmap variable.
*
* @param var the path map variable name
* @return the path map variable value (a URI) or an empty string if
* the specified variable is undefined
*/
public String getPathVariable(String var) {
URI varURI = makeURI(var);
if (varURI != null) {
URI valURI = (URI) getURIMap().get(varURI);
if (valURI != null) {
String val = valURI.toString();
if (val != null) {
int len = val.length();
if (len != 0) {
if (val.charAt(len - 1) == EMFCoreConstants.PATH_SEPARATOR)
val = val.substring(0, len - 1);
return val;
}
}
}
}
return EMFCoreConstants.EMPTY_STRING;
}
/**
* Configure the Pathmaps extension point.
*/
private static Map configure() {
Map paths = new HashMap();
IConfigurationElement[] configs = Platform.getExtensionRegistry()
.getExtensionPoint(EMFCorePlugin.getPluginId(), "Pathmaps") //$NON-NLS-1$
.getConfigurationElements();
for (int i = 0; i < configs.length; ++i) {
IConfigurationElement element = configs[i];
String var = element.getAttribute(NAME);
if ((var == null) || (var.length() == 0))
continue;
String path = element.getAttribute(PATH);
if (path == null)
path = EMFCoreConstants.EMPTY_STRING;
String plugin = element.getAttribute(PLUGIN);
if ((plugin == null) || (plugin.length() == 0))
plugin = element.getDeclaringExtension().getNamespaceIdentifier();
Bundle bundle = Platform.getBundle(plugin);
if (bundle == null)
continue;
URL url = bundle.getEntry(path);
if (url == null)
continue;
try {
url = FileLocator.resolve(url);
if (url == null)
continue;
// We must encode here because everything that is placed into the path
// map must be encoded to match the encoded URI's on each resource
// in the resource set.
paths.put(var, URI.createURI(url.toString(),true).toString());
} catch (IOException e) {
Trace.catching(EMFCorePlugin.getDefault(),
EMFCoreDebugOptions.EXCEPTIONS_CATCHING, PathmapManager.class,
"configure", e); //$NON-NLS-1$
}
}
return paths;
}
public void notifyChanged(Notification msg) {
if (msg.getFeatureID(ResourceSet.class) == ResourceSet.RESOURCE_SET__RESOURCES) {
switch (msg.getEventType()) {
case Notification.ADD:
denormalize((Resource) msg.getNewValue(), getResourceSet().getURIConverter());
break;
case Notification.ADD_MANY:
List resources = (List)msg.getNewValue();
if (resources == null)
break;
for (Iterator i = resources.iterator(); i.hasNext();) {
denormalize((Resource)msg.getNewValue(), getResourceSet().getURIConverter());
}
break;
case Notification.REMOVE:
normalize((Resource)msg.getOldValue(), getResourceSet().getURIConverter());
break;
case Notification.REMOVE_MANY:
resources = (List)msg.getNewValue();
if (resources == null)
break;
for (Iterator i = resources.iterator(); i.hasNext();) {
normalize((Resource)msg.getNewValue(), getResourceSet().getURIConverter());
}
break;
}
}
}
public void setTarget(Notifier newTarget) {
// get the old resource set
ResourceSet rset = getResourceSet();
if (rset != null) {
// remove all path mappings from existing resources
resyncEntries(false, true);
}
super.setTarget(newTarget);
// get the new resource set
rset = getResourceSet();
if (rset != null) {
// denormalize all resources using the path mappings
resyncEntries(true, true);
}
}
/**
* Add all entries.
*/
private void resyncEntries(boolean resync, boolean dirtyResources) {
// save URIs of all resources.
Map savedURIs = new HashMap();
ResourceSet rset = getResourceSet();
if (rset == null)
return;
for (Iterator i = rset.getResources().iterator(); i.hasNext();) {
Resource resource = (Resource) i.next();
URI uri = resource.getURI();
savedURIs.put(resource, uri);
}
// normalize all resource URIs before clearing the map.
normalizeAll();
// get the URI Map.
Map uriMap = getURIMap();
// save the URI Map.
Map savedURIMap = new HashMap();
Set<Entry<?,?>> uriMapEntrySet = uriMap.entrySet();
for (Entry<?, ?> uriMapEntry : uriMapEntrySet) {
URI key = (URI) uriMapEntry.getKey();
if ((key != null)
&& (!EMFCoreConstants.PATH_MAP_SCHEME.equals(key.scheme())))
savedURIMap.put(key, uriMapEntry.getValue());
}
// clear the map.
getURIMap().clear();
if (resync) {
synchronized(PATH_MAP) {
// rebuild the map.
for (Iterator i = PATH_MAP.entrySet().iterator(); i.hasNext();) {
Map.Entry entry = (Entry) i.next();
addEntry((String) entry.getKey(), (String) entry.getValue());
}
}
}
// restore the map.
Set<Entry<?, ?>> savedURIEntrySet = savedURIMap.entrySet();
for (Entry<?, ?> savedURIEntry : savedURIEntrySet) {
URI key = (URI) savedURIEntry.getKey();
if(key != null){
uriMap.put(key, savedURIEntry.getValue());
}
}
if (resync) {
// denormalize all.
denormalizeAll();
}
// if some resources have changed their URI, ensure their exports are
// dirtied.
if (dirtyResources) {
for (Iterator i = rset.getResources().iterator(); i.hasNext();) {
Resource resource = (Resource) i.next();
URI uri = resource.getURI();
URI savedURI = (URI) savedURIs.get(resource);
if (uri != savedURI) {
if ((uri != null) && (!uri.equals(savedURI))) {
Collection exports = EMFCoreUtil.getExports(resource);
for (Iterator j = exports.iterator(); j.hasNext();) {
Resource export = (Resource) j.next();
if (!export.isModified())
export.setModified(true);
}
}
}
}
}
}
/**
* Add entry to map.
*/
private void addEntry(String var, String val) {
URI varURI = makeURI(var);
if (varURI != null) {
int len = val.length();
if (len == 0)
return;
StringBuffer uri = new StringBuffer();
uri.append(val);
// TODO
if (!FILE_VARIABLES.contains(var) && val.charAt(len - 1) != EMFCoreConstants.PATH_SEPARATOR)
uri.append(EMFCoreConstants.PATH_SEPARATOR);
URI valURI = URI.createURI(uri.toString());
getURIMap().put(varURI, valURI);
}
}
/**
* Normalize the URI of a set of resources.
*/
private void normalizeAll() {
ResourceSet rset = getResourceSet();
URIConverter converter = rset.getURIConverter();
if (converter != null) {
for (Iterator i = rset.getResources().iterator(); i
.hasNext();) {
Resource resource = (Resource) i.next();
normalize(resource, converter);
}
}
}
private void normalize(Resource resource, URIConverter converter) {
URI uri = resource.getURI();
if (uri == null)
return;
if ((EMFCoreConstants.PATH_MAP_SCHEME.equals(uri.scheme()))
&& (resource instanceof GMFResource)) {
((GMFResource) resource)
.setRawURI(converter.normalize(uri));
}
}
/**
* Denormalize the URI of a set of resources.
*/
private void denormalizeAll() {
ResourceSet rset = getResourceSet();
URIConverter converter = rset.getURIConverter();
if (converter != null) {
for (Iterator i = rset.getResources().iterator(); i
.hasNext();) {
Resource resource = (Resource) i.next();
denormalize(resource, converter);
}
}
}
private void denormalize(Resource resource, URIConverter converter) {
URI uri = resource.getURI();
if (uri == null)
return;
if (resource instanceof GMFResource)
((GMFResource) resource).setURI(converter.normalize(uri));
}
/**
* Make a pathmap uri from a pathmap variable name.
*/
private static URI makeURI(String var) {
int len = var.length();
if (len == 0)
return null;
StringBuffer uri = new StringBuffer();
uri.append(EMFCoreConstants.PATH_MAP_SCHEME);
uri.append(EMFCoreConstants.SCHEME_SEPARATOR);
uri.append(EMFCoreConstants.PATH_SEPARATOR);
uri.append(EMFCoreConstants.PATH_SEPARATOR);
uri.append(var);
//TODO
if (!FILE_VARIABLES.contains(var) && var.charAt(len - 1) != EMFCoreConstants.PATH_SEPARATOR)
uri.append(EMFCoreConstants.PATH_SEPARATOR);
return URI.createURI(uri.toString());
}
/**
* Get EMF's URI map.
*/
private Map getURIMap() {
return getResourceSet().getURIConverter().getURIMap();
}
/**
* Denormalizes a given resource's URI to a pathmap URI if it is possible.
*
* @param uri A file or platform URI that has been denormalized as much
* possible.
*
* @return The original URI if it could not be denormalized any further
* or a new pathmap URI otherwise.
*/
public static URI denormalizeURI(URI uri) {
String uriAsString = uri.toString();
String maxValueString = null;
String maxKey = null;
synchronized(PATH_MAP) {
for (Iterator i = PATH_MAP.entrySet().iterator(); i.hasNext();) {
Map.Entry entry = (Map.Entry)i.next();
String valueString = (String)entry.getValue();
// Wipe out the trailing separator from the value if necessary
if (valueString.endsWith("/")) { //$NON-NLS-1$
valueString = valueString.substring(0,valueString.length()-1);
}
if ((uriAsString.startsWith(valueString) &&
(valueString.length() == uriAsString.length() ||
uriAsString.charAt(valueString.length()) == EMFCoreConstants.PATH_SEPARATOR))
&& (maxValueString == null || maxValueString.length() < valueString.length())) {
maxValueString = valueString;
maxKey = (String)entry.getKey();
}
}
}
if (maxKey != null) {
URI valueURI = URI.createURI(maxValueString);
URI pathmapURI = makeURI(maxKey);
int segmentStart = valueURI.segmentCount();
int segmentCount = uri.segmentCount();
for (int j=segmentStart; j < segmentCount; j++) {
pathmapURI = pathmapURI.appendSegment(uri.segment(j));
}
return pathmapURI;
}
return uri;
}
}