blob: 9ef4292df2d871ef8684baa49cc183d951c72c8a [file] [log] [blame]
//------------------------------------------------------------------------------
// Copyright (c) 2005, 2006 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 implementation
//------------------------------------------------------------------------------
package org.eclipse.epf.persistence;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import org.eclipse.emf.common.util.AbstractTreeIterator;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.InternalEObject;
import org.eclipse.emf.ecore.resource.impl.URIConverterImpl;
import org.eclipse.epf.resourcemanager.ResourceDescriptor;
import org.eclipse.epf.resourcemanager.ResourceManager;
import org.eclipse.epf.uma.MethodElement;
import org.eclipse.epf.uma.MethodLibrary;
/**
* URI converter that converts a file-based URI to a UMA-based URI and vice
* versa using the mapping information stored in ResourceDescriptors of
* ResourceManager. A UMA-based URI has the following format:
* uma://GUID1#GUID2 where GUID1 is the GUID of the file and GUID2 is the
* object's GUID.
*
* @author Phong Nguyen Le
* @since 1.0
*/
public class MultiFileURIConverter extends URIConverterImpl {
public static final String SCHEME = "uma"; //$NON-NLS-1$
private static final HashSet lockedGUIDs = new HashSet();
protected ResourceManager resMgr;
private URI libraryURI;
private URI libraryUmaURI;
private MultiFileResourceSetImpl resourceSet;
private boolean resolveProxy;
public MultiFileURIConverter(MultiFileResourceSetImpl resourceSet) {
this.resourceSet = resourceSet;
}
void setResolveProxy(boolean resolveProxy) {
this.resolveProxy = resolveProxy;
}
void setLibraryURIs(MethodLibrary library) {
libraryURI = library.eResource().getURI();
libraryUmaURI = URI.createURI(new StringBuffer(SCHEME)
.append("://").append(library.getGuid()).toString()); //$NON-NLS-1$
}
private static void lockGUID(String guid) {
synchronized (lockedGUIDs) {
lockedGUIDs.add(guid);
}
}
private static boolean isLockedGUID(String guid) {
synchronized (lockedGUIDs) {
return lockedGUIDs.contains(guid);
}
}
private static boolean unlockGUID(String guid) {
synchronized (lockedGUIDs) {
return lockedGUIDs.remove(guid);
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.ecore.resource.impl.URIConverterImpl#normalize(org.eclipse.emf.common.util.URI)
*/
public URI normalize(URI uri) {
return normalize(uri, null);
}
public URI normalize(URI uri, EObject resolver) {
if (SCHEME.equalsIgnoreCase(uri.scheme())) {
String guid = uri.authority();
if (isLockedGUID(guid)) {
return null;
}
try {
lockGUID(guid);
ResourceDescriptor desc = null;
HashSet excludedResManagers = null;
if (resolver != null && resolver.eResource() != null) {
ResourceManager resMgr = MultiFileSaveUtil
.getResourceManager(resolver.eResource());
if (resMgr != null) {
desc = MultiFileSaveUtil.findResourceDescriptor(resMgr,
guid, null, resolveProxy);
if (desc == null) {
// add this ResourceManager and its submanagers to
// excludedResManagers
// so the next search for ResourceDescriptor will
// ignore them
//
excludedResManagers = new HashSet();
Iterator iter = new AbstractTreeIterator(resMgr) {
protected Iterator getChildren(Object object) {
return ((ResourceManager) object)
.getSubManagers().iterator();
}
};
while (iter.hasNext()) {
excludedResManagers.add(iter.next());
}
}
}
}
if (desc == null && getResourceManager() != null) {
desc = MultiFileSaveUtil.findResourceDescriptor(
getResourceManager(), guid, excludedResManagers,
resolveProxy);
}
if (desc != null) {
URI normalized = desc.getResolvedURI();
// check if the resource with this normalized URI has
// temporary URI
//
URI tempURI = (URI) resourceSet.getURIToTempURIMap().get(
normalized);
if (tempURI != null) {
normalized = tempURI;
}
if (uri.hasFragment()) {
normalized = normalized.appendFragment(uri.fragment());
}
return normalized;
}
return null;
} finally {
unlockGUID(guid);
}
}
return super.normalize(uri);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.ecore.resource.impl.URIConverterImpl#createInputStream(org.eclipse.emf.common.util.URI)
*/
public InputStream createInputStream(URI uri) throws IOException {
if (uri == null)
return null;
return super.createInputStream(uri);
}
public static URI createURI(String guid) {
return URI.createURI(new StringBuffer(SCHEME)
.append("://").append(guid).toString()); //$NON-NLS-1$
}
public static URI createURI(MethodElement e) {
return URI.createURI(createUriString(e));
}
public static String createUriString(Object e) {
InternalEObject o = (InternalEObject) e;
URI objectURI = o.eProxyURI();
if (objectURI != null && SCHEME.equals(objectURI.scheme())) {
return objectURI.toString();
}
String guid = MultiFileSaveUtil.getGuid(e);
if (guid == null) {
return null;
}
return new StringBuffer(SCHEME).append("://").append(guid).toString(); //$NON-NLS-1$
}
// public URI toUmaUri(URI uri) {
// // System.out.println("MultiFileURIConverter.toUmaUri(): uri="+uri);
// if(uri.scheme().equals("uma") || uriDescMap == null) return uri;
// if(libraryURI.equals(uri)) return libraryUmaURI;
// ResourceDescriptor desc = (ResourceDescriptor)
// uriDescMap.get(uri.trimFragment().toString());
// return desc == null ? uri : URI.createURI("uma://" +
// desc.getId()).appendFragment(uri.fragment());
// }
// public void setResourceManager(ResourceManager resMgr) {
// this.resMgr = resMgr;
// }
public ResourceManager getResourceManager() {
if (resMgr == null) {
resMgr = resourceSet.getRootResourceManager();
}
return resMgr;
}
/**
* Finds ResourceDescriptor for the given GUID from root ResourceManager
*
* @param guid
* @return
*/
public ResourceDescriptor findResourceDescriptor(String guid) {
return MultiFileSaveUtil.findResourceDescriptor(getResourceManager(),
guid, null, resolveProxy);
}
public void dispose() {
if (resMgr != null) {
resMgr.dispose();
resMgr = null;
}
}
/**
*
* @param e
* @param uri
* @param modifiedResources
* output of resources that have been changed after this call.
*/
public void setURIMapping(EObject e, URI uri, Set modifiedResources) {
setURIMapping(e, uri, modifiedResources, true);
}
public void setURIMapping(EObject e, URI uri, Set modifiedResources,
boolean afterMove) {
String guid = MultiFileSaveUtil.getGuid(e);
ResourceManager resMgr = MultiFileSaveUtil.getResourceManagerFor(e,
modifiedResources);
ResourceDescriptor resDesc = resMgr.getResourceDescriptor(guid);
if (resDesc != null) {
if (afterMove) {
resDesc.setResolvedURI(uri);
} else {
// preserve the current resolved URI
resDesc.getResolvedURI();
// set new URI string for the upcoming move
resDesc.setUri(uri.deresolve(
MultiFileSaveUtil.getFinalURI(resDesc.eResource()))
.toString());
}
if (modifiedResources != null)
modifiedResources.add(resDesc.eResource());
} else {
// find the ResourceDescriptor in other ResourceManagers
//
MultiFileResourceSetImpl resourceSet = (MultiFileResourceSetImpl) e
.eResource().getResourceSet();
ResourceManager libResMgr = resourceSet.getRootResourceManager();
resDesc = MultiFileSaveUtil.findResourceDescriptor(libResMgr, guid,
Collections.singletonList(resMgr), resolveProxy);
if (resDesc != null) {
// ResourceDescriptor already exists
// change its uri, move it and its sub manager, if there is any,
// to new ResourceManager
//
// find sub manager
ResourceManager currentResMgr = (ResourceManager) resDesc
.eContainer();
ResourceManager subMgr = null;
for (Iterator iter = currentResMgr.getSubManagers().iterator(); iter
.hasNext();) {
ResourceManager mgr = (ResourceManager) iter.next();
URI mgrURI = ((MultiFileXMIResourceImpl) mgr.eResource())
.getFinalURI();
if (mgrURI.equals(uri)) {
subMgr = mgr;
break;
}
}
// move ResourceDescriptor
resMgr.getResourceDescriptors().add(resDesc);
if (modifiedResources != null) {
modifiedResources.add(currentResMgr.eResource());
modifiedResources.add(resMgr.eResource());
}
// move sub ResourceManager
if (subMgr != null) {
resMgr.getSubManagers().add(subMgr);
}
// set new URI
if (afterMove) {
resDesc.setResolvedURI(uri);
} else {
// preserve the current resolved URI
resDesc.getResolvedURI();
// set new URI string for the upcoming move
resDesc.setUri(uri.deresolve(resDesc.eResource().getURI())
.toString());
}
if (modifiedResources != null)
modifiedResources.add(resDesc.eResource());
} else {
MultiFileSaveUtil.registerWithResourceManager(resMgr, e, uri);
if (modifiedResources != null)
modifiedResources.add(resMgr.eResource());
}
}
}
public static void main(String[] args) {
URI uri = URI
.createURI("uma://_LPzdAGZ7EdmAm_xSX2EdUA#//@breakdownElements.0"); //$NON-NLS-1$
System.out.println(uri);
System.out
.println("deresolved URI: " + uri.deresolve(URI.createURI("uma://_LPzdAGZ7EdmAm_xSX2EdUA"))); //$NON-NLS-1$ //$NON-NLS-2$
}
}