/* * JBoss, Home of Professional Open Source. * * See the LEGAL.txt file distributed with this work for information regarding copyright ownership and licensing. * * See the AUTHORS.txt file distributed with this work for a full listing of individual contributors. */ package org.teiid.designer.core.refactor; import java.util.ArrayList; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import org.eclipse.core.resources.IFile; import org.eclipse.core.resources.IProject; import org.eclipse.core.resources.IResource; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Path; import org.eclipse.core.runtime.Status; 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.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.xsd.XSDImport; import org.teiid.core.designer.id.IDGenerator; import org.teiid.core.designer.id.InvalidIDException; import org.teiid.core.designer.id.ObjectID; import org.teiid.core.designer.util.CoreArgCheck; import org.teiid.designer.core.ModelerCore; import org.teiid.designer.core.container.Container; import org.teiid.designer.core.metamodel.aspect.ImportsAspect; import org.teiid.designer.core.resource.EmfResource; import org.teiid.designer.core.search.ModelWorkspaceSearch; import org.teiid.designer.core.workspace.ModelResource; import org.teiid.designer.core.workspace.ModelWorkspaceException; import org.teiid.designer.core.workspace.ModelWorkspaceManager; import org.teiid.designer.core.workspace.WorkspaceResourceFinderUtil; /** * OrganizeImportCommand * * @since 8.0 */ public class OrganizeImportCommandFinderHelper { private Resource resource; private Collection<PathPair> refactoredPaths; protected OrganizeImportCommandFinderHelper() { this.refactoredPaths = new ArrayList<PathPair>(); } /** * @param pathPairs * @since 4.3 */ protected void setRefactoredPaths( Collection<PathPair> pathPairs ) { if (pathPairs != null) { this.refactoredPaths = pathPairs; } else { this.refactoredPaths = new ArrayList<PathPair>(); } } /** * @param resource * @since 4.3 */ protected void setResource( final Resource resource ) { this.resource = resource; } /** * Obtain the URI to an existing model, given the supplied URI and the supplied Resource. * * @param uri * @param resource * @return the URI for an existing IResource, or null if there is no existing IResource */ protected URI findModelUri( final URI uri, final Resource resource ) { CoreArgCheck.isNotNull(uri); String path = URI.decode(uri.toString()); if (resource != null) { return getModelUri(resource, path); } return getModelUri(uri); } /** * @param resource * @return URI * @since 4.3 */ private URI getModelUri( final Resource resource, String path ) { String resourcePath = WorkspaceResourceFinderUtil.getWorkspaceUri(resource); if (resourcePath != null) { path = resourcePath; } else { /** * MyCode : 18565 Check if the same resource UUID also exists in the Model container */ if (resource instanceof EmfResource) { try { ObjectID objectID = ((EmfResource)resource).getUuid(); resourcePath = findResourcePathByUUID(objectID); if (resourcePath != null) { path = resourcePath; } else { return null; } } catch (Exception e) { ModelerCore.Util.log(e); } } } return URI.createURI(path); } /** * @param objectID * @return String * @throws CoreException * @since 4.3 */ protected String findResourcePathByUUID( ObjectID objectID ) throws CoreException { String path = null; if (objectID != null) { final Resource systemModels = ModelerCore.getModelContainer().getResourceFinder().findByUUID(objectID, false); path = WorkspaceResourceFinderUtil.getWorkspaceUri(systemModels); } return path; } /** * @param uri * @return URI * @since 4.3 */ private URI getModelUri( final URI uri ) { String path = null; IResource iResource = WorkspaceResourceFinderUtil.findIResource(uri); if (iResource != null) { path = iResource.getFullPath().toString(); } else { /** * MyCode : 17647 Added the following code to find a valid resource even the uri path is pointing to wrong location. */ iResource = findResourceInProjectByName(uri.lastSegment()); if (iResource == null) { return null; } path = iResource.getFullPath().toString(); } return URI.createURI(path); } /** * @param name * @return IResource * @since 4.3 */ protected IResource findResourceInProjectByName( final String name ) { if (name == null) { return null; } IResource iResource = null; Collection<IFile> iResources = WorkspaceResourceFinderUtil.findIResourceByName(name); if (iResources.size() == 0) { return null; } else if (iResources.size() == 1) { iResource = iResources.iterator().next(); } else { // Find the IResource with this name in the same IProject as the IResource being operated on IResource iRes = WorkspaceResourceFinderUtil.findIResource(this.resource.getURI()); IProject project = iRes.getProject(); for (IFile fileResource : iResources) { if (fileResource.getProject().equals(project)) { iResource = fileResource; break; } } // If no IResource exists in this project then pick the first on in the array if (iResource == null) { iResource = iResources.iterator().next(); } } return iResource; } /** * @param refs * @param problems * @param handler * @return Resource * @since 4.3 */ protected Resource findResourceWithObject( final Collection refs, final List problems, OrganizeImportHandler handler ) { final ModelWorkspaceSearch search = new ModelWorkspaceSearch(); final ModelWorkspaceManager workspaceManager = ModelWorkspaceManager.getModelWorkspaceManager(); final List modelReferences = new LinkedList(); HashSet searchedFragments = new HashSet(); HashSet searchedIDs = new HashSet(); if (refs.size() != 0) { final Iterator iter = refs.iterator(); while (iter.hasNext()) { final EObject reference = (EObject)iter.next(); final InternalEObject internalEObject = (InternalEObject)reference; final URI proxyUri = internalEObject.eProxyURI(); final String fragment = proxyUri.fragment(); if (fragment != null) { // Convert to an object ID ... ObjectID id = null; try { id = IDGenerator.getInstance().stringToObject(fragment); } catch (InvalidIDException e) { // not an ID; } if (id == null && searchedFragments.contains(fragment)) { continue; } else if (searchedIDs.contains(id)) { continue; } // Search the workspace for a model resources containing this identifier IPath[] modelPaths = (id == null ? search.getResourcesContainingObjectId(fragment) : search.getResourcesContainingObjectId(id)); if (modelPaths != null && modelPaths.length > 0) { for (int i = 0; i < modelPaths.length; ++i) { final IPath resourcePath = modelPaths[i]; final ModelResource mResource = (ModelResource)workspaceManager.findModelWorkspaceItem(resourcePath, IResource.FILE); if (mResource != null) { if (!modelReferences.contains(mResource)) { modelReferences.add(mResource); } } } } if (id != null) { searchedIDs.add(id); } else { searchedFragments.add(fragment); } } } } // Try to get the EMF Resource from the ModelResource... Resource result = null; if (!modelReferences.isEmpty()) { ModelResource mResource = null; if (modelReferences.size() == 1) { mResource = (ModelResource)modelReferences.get(0); } else { final OrganizeImportHandler theHandler = handler; if (theHandler != null) { final Object choice = handler.choose(modelReferences); if (choice instanceof ModelResource) { mResource = (ModelResource)choice; } else if (choice != null) { // Not null, and not the expected type ... final Object[] params = new Object[] {choice.getClass().getName(), ModelResource.class.getName()}; final String msg = ModelerCore.Util.getString("OrganizeImportCommand.Unexpected_choice", params); //$NON-NLS-1$ throw new AssertionError(msg); } } } if (mResource != null) { try { result = mResource.getEmfResource(); } catch (ModelWorkspaceException e1) { final int code = OrganizeImportCommandHelper.ERROR_GETTING_RESOURCE; final Object[] params = new Object[] {mResource}; final String msg = ModelerCore.Util.getString("OrganizeImportCommand.error_getting_resource", params); //$NON-NLS-1$ problems.add(new Status(IStatus.ERROR, OrganizeImportCommandHelper.PLUGINID, code, msg, null)); } } } return result; } /** * @param uri * @param monitor * @param problems * @return Resource * @since 4.3 */ protected Resource findRefactoredResource( final Resource eResource, final URI externalResourceURI, final IProgressMonitor monitor, final List problems ) { ResourceSet eResourceSet = eResource.getResourceSet(); Resource externalResource = eResourceSet.getResource(externalResourceURI, false); if (externalResource == null) { Container cntr = ModelerCore.getContainer(eResource); if (cntr != null) { // Search for the resource by name Resource[] eResources = cntr.getResourceFinder().findByName(externalResourceURI.lastSegment(), false, true); if (eResources.length == 0) { return null; } else if (eResources.length == 1) { return eResources[0]; } else { // Find best match to the resource containing the external reference List matches = new ArrayList(eResources.length); String parentUriString = eResource.getURI().trimSegments(1).toString(); for (int i = 0; i != eResources.length; ++i) { Resource r = eResources[i]; String uriString = r.getURI().trimSegments(1).toString(); if (parentUriString.startsWith(uriString) || uriString.startsWith(parentUriString)) { matches.add(r); } } if (matches.size() == 0) { externalResource = eResources[0]; } else if (matches.size() == 1) { externalResource = (Resource)matches.get(0); } else { externalResource = eResources[0]; } } } } return externalResource; // /** // Try to reconstruct the new resource path by matching the path // to that of the runtime workspace location. This logic will not // work if the actual location of the resource is in a project // outside of the workspace folder. // */ // IPath tmpResPath = new Path (uri.path()); // if (!uri.isRelative()) { // IPath workspacePath = ModelerCore.getWorkspace().getRoot().getLocation(); // int matchingSegments = tmpResPath.matchingFirstSegments(workspacePath); // if( matchingSegments != 0 ) { // tmpResPath = tmpResPath.removeFirstSegments(matchingSegments).makeAbsolute(); // }else { // // MyDefect : 17647 Added to find path from refactored resource map. // tmpResPath = findFromRefactoredPaths(tmpResPath.toString()); // } // } // // final IPath resourcePath = getNewResourcePath(tmpResPath.toString()); // ModelResource mResource = null; // Resource result = null; // if (resourcePath != null) { // try { // IFile tmpFile = (IFile) WorkspaceResourceFinderUtil.findIResourceByPath(resourcePath); // if(tmpFile == null && resourcePath != null) { // tmpFile = (IFile)findResourceInProjectByName(resourcePath.lastSegment()); // } // // mResource = ModelerCore.getModelEditor().findModelResource(tmpFile); // if (mResource == null) { // mResource = ModelerCore.create(tmpFile); // mResource.save(monitor, true); // } // // if (mResource != null) { // result = mResource.getEmfResource(); // } // } catch (ModelWorkspaceException e1) { // final int code = OrganizeImportCommandHelper.ERROR_GETTING_RESOURCE; // final Object[] params = new Object[]{resourcePath}; // final String msg = ModelerCore.Util.getString("OrganizeImportCommand.Error_while_finding_resource_for_path_1",params); //$NON-NLS-1$ // problems.add( new Status(IStatus.ERROR,OrganizeImportCommandHelper.PLUGINID,code,msg,null) ); // } // } // return result; } // /** // * // * @param oldPath // * @return IPath // * @since 4.3 // */ // private IPath getNewResourcePath(String oldPath) { // if (this.refactoredPaths != null) { // String newPath = (String)refactoredPaths.get(oldPath); // if (newPath != null) { // return new Path(newPath); // } // } // // if((this.refactoredPaths == null || this.refactoredPaths.isEmpty()) && oldPath != null) { // return new Path(oldPath); // } // // return null; // } /** * @param uriPath * @return IPath * @since 4.3 */ protected IPath findFromRefactoredPaths( String uriPath ) { if (this.refactoredPaths != null) { for (PathPair pathPair : refactoredPaths) { String oldPath = pathPair.getSourcePath(); if (uriPath.endsWith(oldPath)) { return new Path(oldPath); } } } return new Path(uriPath); } /** * @param eobject * @param importsAspect * @return IPath * @since 4.3 */ protected IPath findPath( EObject eobject, ImportsAspect importsAspect ) { IPath importPath = importsAspect.getModelPath(eobject); if (importPath == null) { return createPath(eobject); } return importPath; } /** * @param eobject * @return IPath * @since 4.3 */ private IPath createPath( EObject eobject ) { if (eobject instanceof XSDImport) { String schemaLocation = ((XSDImport)eobject).getSchemaLocation(); return getNewPathInfo(schemaLocation); } return null; } /** * @param schemaLocation * @return IPath * @since 4.3 */ private IPath getNewPathInfo( String schemaLocation ) { if (schemaLocation == null) return null; IPath currentPath = new Path(schemaLocation); for (PathPair pathPair : refactoredPaths) { IPath oldPathRef = new Path(pathPair.getSourcePath()); if (oldPathRef.lastSegment().equals(currentPath.lastSegment())) { return new Path(pathPair.getTargetPath()); } } return null; } }