//------------------------------------------------------------------------------ // 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$ } }