blob: ec323b54b01915900f20db1778bbcea06338e929 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2005 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
*******************************************************************************/
/*
* $$RCSfile: WorkbenchURIConverterImpl.java,v $$
* $$Revision: 1.4 $$ $$Date: 2005/05/11 16:11:09 $$
*/
package org.eclipse.jem.util.emf.workbench;
import java.io.*;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.*;
import org.eclipse.core.runtime.*;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.impl.URIConverterImpl;
import org.eclipse.jem.util.plugin.JEMUtilPlugin;
/**
* A default implementation of the WorkbenchURIConverter interface.
*
* @since 1.0.0
*/
public class WorkbenchURIConverterImpl extends URIConverterImpl implements WorkbenchURIConverter {
private final static IWorkspaceRoot WORKSPACE_ROOT = URIConverterImpl.workspaceRoot;
private final static String WORKSPACE_ROOT_LOCATION = WORKSPACE_ROOT.getLocation().toString();
private static final String FILE_PROTOCOL = "file"; //$NON-NLS-1$
private static final IPath INVALID_PATH = new Path("!!!!~!!!!"); //$NON-NLS-1$
private static final IFile INVALID_FILE = WORKSPACE_ROOT.getFile(INVALID_PATH.append(INVALID_PATH));
//Used to avoid trying to fixup the URI when getting the
//OutputStream
protected boolean forceSaveRelative = false;
protected List inputContainers;
protected IContainer outputContainer;
protected ResourceSetWorkbenchSynchronizer resourceSetSynchronizer;
/*
* KLUDGE: We need to know the meta data area. This is so that any uri that starts with the metadata directory
* is considered a file uri and NOT a workspace uri. The metadata is where plugin's store their working data.
* It is not part of the workspace root.
*
* There is no request for simply the metadata area. The log file is in the metadata directory. So we will
* get the log file location and just remove the log file name. That should leave us with the metadata directory
* only. If Eclipse ever decides to move it from here, this will no longer work. But it hasn't moved in three
* versions.
*
* @since 1.1.0
*/
static protected final String METADATA_LOCATION = Platform.getLogFileLocation().removeLastSegments(1).toString();
/**
* Default converter constructor, no containers.
*
*
* @since 1.0.0
*/
public WorkbenchURIConverterImpl() {
super();
}
/**
* Construct with an input container.
*
* @param anInputContainer
*
* @since 1.0.0
*/
public WorkbenchURIConverterImpl(IContainer anInputContainer) {
this(anInputContainer, (ResourceSetWorkbenchSynchronizer) null);
}
/**
* Construct with an input container and a synchronzier.
*
* @param aContainer
* @param aSynchronizer
*
* @since 1.0.0
*/
public WorkbenchURIConverterImpl(IContainer aContainer, ResourceSetWorkbenchSynchronizer aSynchronizer) {
this(aContainer, null, aSynchronizer);
}
/**
* Construct with an input container and an output container.
*
* @param anInputContainer
* @param anOutputContainer
*
* @since 1.0.0
*/
public WorkbenchURIConverterImpl(IContainer anInputContainer, IContainer anOutputContainer) {
this(anInputContainer, anOutputContainer, null);
}
/**
* Construct with an input container, output container, and a synchronizer.
*
* @param anInputContainer
* @param anOutputContainer
* @param aSynchronizer
*
* @since 1.0.0
*/
public WorkbenchURIConverterImpl(IContainer anInputContainer, IContainer anOutputContainer, ResourceSetWorkbenchSynchronizer aSynchronizer) {
addInputContainer(anInputContainer);
setOutputContainer(anOutputContainer);
resourceSetSynchronizer = aSynchronizer;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jem.util.emf.workbench.WorkbenchURIConverter#addInputContainer(org.eclipse.core.resources.IContainer)
*/
public void addInputContainer(IContainer aContainer) {
if (aContainer != null && !getInputContainers().contains(aContainer))
getInputContainers().add(aContainer);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jem.util.emf.workbench.WorkbenchURIConverter#addInputContainers(java.util.List)
*/
public void addInputContainers(List containers) {
for (int i = 0; i < containers.size(); i++) {
addInputContainer((IContainer) containers.get(i));
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jem.util.emf.workbench.WorkbenchURIConverter#removeInputContainer(org.eclipse.core.resources.IContainer)
*/
public boolean removeInputContainer(IContainer aContainer) {
return getInputContainers().remove(aContainer);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jem.util.emf.workbench.WorkbenchURIConverter#getInputContainers()
*/
public List getInputContainers() {
if (inputContainers == null)
inputContainers = new ArrayList();
return inputContainers;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jem.util.emf.workbench.WorkbenchURIConverter#getInputContainer()
*/
public IContainer getInputContainer() {
if (!getInputContainers().isEmpty())
return (IContainer) getInputContainers().get(0);
else
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jem.util.emf.workbench.WorkbenchURIConverter#getOutputContainer()
*/
public IContainer getOutputContainer() {
if (outputContainer == null)
outputContainer = getInputContainer();
return outputContainer;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jem.util.emf.workbench.WorkbenchURIConverter#setOutputContainer(org.eclipse.core.resources.IContainer)
*/
public void setOutputContainer(IContainer newOutputContainer) {
outputContainer = newOutputContainer;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jem.util.emf.workbench.WorkbenchURIConverter#getOutputFile(org.eclipse.core.runtime.IPath)
*/
public IFile getOutputFile(IPath aPath) {
IFile file = null;
if (getOutputContainer() != null) {
if (forceSaveRelative)
return primGetOutputFile(aPath);
file = getOutputFileForPathWithContainerSegments(aPath);
if (file != null)
return file;
else
return primGetOutputFile(aPath);
}
return file;
}
protected IFile primGetOutputFile(IPath aPath) {
return primGetFile(getOutputContainer(), aPath);
}
protected IFile getOutputFileForPathWithContainerSegments(IPath aPath) {
IContainer out = getOutputContainer();
return getFileForPathWithContainerSegments(aPath, out, false);
}
protected IFile getFileForPathWithContainerSegments(IPath aPath, IContainer container, boolean testExists) {
IPath containerPath = null;
IFile file = null;
if (testExists) {
containerPath = container.getProjectRelativePath();
if (!containerPath.isEmpty()) {
file = getFileForMatchingPath(aPath, containerPath, container);
if (file != null && file.exists())
return file;
}
}
containerPath = container.getFullPath();
file = getFileForMatchingPath(aPath, containerPath, container);
return file;
}
protected IFile getFileForMatchingPath(IPath containerPath, IPath sourcePath, IContainer container) {
int matches = 0;
matches = containerPath.matchingFirstSegments(sourcePath);
if (matches > 0 && matches == sourcePath.segmentCount()) {
IPath loadPath = containerPath.removeFirstSegments(matches);
return primGetFile(container, loadPath);
}
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jem.util.emf.workbench.WorkbenchURIConverter#getFile(java.lang.String)
*/
public IFile getFile(String uri) {
return getFile(new Path(uri));
}
/**
* Get the file from the path.
*
* @param path
* @return
* @see WorkbenchURIConverter#getFile(String)
* @since 1.0.0
*/
public IFile getFile(IPath path) {
IFile file = null;
if (getInputContainer() != null) {
path = path.makeRelative();
java.util.Iterator it = getInputContainers().iterator();
while (it.hasNext()) {
IContainer con = (IContainer) it.next();
file = getInputFile(con, path);
if (file != null && file.exists())
return file;
}
}
if (file == null)
return INVALID_FILE;
return file;
}
/**
* Get output file from string path.
*
* @param uri
* @return
*
* @see WorkbenchURIConverter#getOutputFile(IPath)
* @since 1.0.0
*/
public IFile getOutputFile(String uri) {
return getOutputFile(new Path(uri));
}
/**
* Get the input file from the container and path.
*
* @param con
* @param path
* @return
*
* @since 1.0.0
*/
public IFile getInputFile(IContainer con, IPath path) {
IFile file = null;
if (WORKSPACE_ROOT.equals(con) && path.segmentCount() < 2)
path = INVALID_PATH.append(path);
file = primGetFile(con, path);
if (file == null || !file.exists())
file = getFileForPathWithContainerSegments(path, con, true);
return file;
}
protected IFile primGetFile(IContainer container, IPath path) {
try {
return container.getFile(path);
} catch (IllegalArgumentException ex) {
}
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jem.util.emf.workbench.WorkbenchURIConverter#canGetUnderlyingResource(java.lang.String)
*/
public boolean canGetUnderlyingResource(String aFileName) {
IFile file = getFile(aFileName);
return file != null && file.exists();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jem.util.emf.workbench.WorkbenchURIConverter#isForceSaveRelative()
*/
public boolean isForceSaveRelative() {
return forceSaveRelative;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jem.util.emf.workbench.WorkbenchURIConverter#setForceSaveRelative(boolean)
*/
public void setForceSaveRelative(boolean forceSaveRelative) {
this.forceSaveRelative = forceSaveRelative;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.ecore.resource.URIConverter#normalize(org.eclipse.emf.common.util.URI)
*/public URI normalize(URI uri) {
URI result = uri;
String fragment = null;
if (uri.hasFragment()) {
fragment = uri.fragment();
result = uri.trimFragment();
}
result = getInternalURIMap().getURI(result);
if (WorkbenchResourceHelperBase.isPlatformResourceURI(result))
return appendFragment(result, fragment);
if (WorkbenchResourceHelperBase.isPlatformPluginResourceURI(result)) {
URI normalized = normalizePluginURI(result, fragment);
return (normalized != null) ? normalized : uri;
}
String protocol = result.scheme();
URI fileSearchURI = null;
if (protocol == null) {
fileSearchURI = normalizeEmptyProtocol(result, fragment);
if (fileSearchURI != null)
return fileSearchURI;
} else if (FILE_PROTOCOL.equals(protocol)) {
fileSearchURI = normalizeFileProtocol(result, fragment);
if (fileSearchURI != null)
return fileSearchURI;
} else if (JEMUtilPlugin.WORKSPACE_PROTOCOL.equals(protocol))
return normalizeWorkspaceProtocol(result, fragment);
return super.normalize(uri);
}
/*
* Resolves a plugin format into the actual.
*/
protected URI normalizePluginURI(URI uri, String fragment) {
if (uri.segmentCount() < 2)
return uri; // Invalid, just let it go on.
// See if already normalized.
int u_scoreNdx = uri.segment(1).lastIndexOf('_');
if (u_scoreNdx != -1) {
// Not normalized. Remove the version to make it normalized.
String[] segments = uri.segments();
segments[1] = segments[1].substring(0, u_scoreNdx);
return URI.createHierarchicalURI(uri.scheme(), uri.authority(), uri.device(), segments, uri.query(), fragment);
} else
return uri;
}
protected URI normalizeWorkspaceProtocol(URI aWorkspaceURI, String fragment) {
URI result;
String uriString = aWorkspaceURI.toString();
uriString = uriString.substring(JEMUtilPlugin.WORKSPACE_PROTOCOL.length() + 1);
result = URI.createPlatformResourceURI(uriString);
if (fragment != null)
result = appendFragment(aWorkspaceURI, fragment);
return result;
}
protected URI normalizeEmptyProtocol(URI aFileUri, String fragment) {
//Make the relative path absolute and return a platform URI.
IPath path = new Path(aFileUri.toString());
return normalizeToWorkspaceURI(path, fragment);
}
private URI normalizeToWorkspaceURI(IPath path, String fragment) {
URI result = null;
IFile file = getFile(path);
if (file == null || !file.exists())
file = getOutputFile(path);
if (file != null) {
result = URI.createPlatformResourceURI(file.getFullPath().toString());
result = appendFragment(result, fragment);
}
return result;
}
protected URI normalizeFileProtocol(URI aFileUri, String fragment) {
URI result = null;
//Make the relative path absolute and return a platform URI.
String devicePath = aFileUri.devicePath();
//Test for workspace location.
if (!devicePath.startsWith(METADATA_LOCATION) &&
devicePath.startsWith(WORKSPACE_ROOT_LOCATION) && devicePath.length() > WORKSPACE_ROOT_LOCATION.length()) {
//test for workspace location
result = normalizeToWorkspaceURI(new Path(devicePath.substring(WORKSPACE_ROOT_LOCATION.length())), fragment);
} else if (aFileUri.isRelative()) {
result = normalizeToWorkspaceURI(new Path(aFileUri.toString()), fragment);
} else {
result = aFileUri;
}
return result;
}
protected URI appendFragment(URI result, String fragment) {
if (fragment != null)
return result.appendFragment(fragment);
else
return result;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.jem.util.emf.workbench.WorkbenchURIConverter#getOutputFileWithMappingApplied(java.lang.String)
*/
public IFile getOutputFileWithMappingApplied(String uri) {
URI converted = getInternalURIMap().getURI(URI.createURI(uri));
return getOutputFile(new Path(converted.toString()));
}
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.ecore.resource.impl.URIConverterImpl#createPlatformResourceOutputStream(java.lang.String)
*/
public OutputStream createPlatformResourceOutputStream(String platformResourcePath) throws IOException {
IFile file = WORKSPACE_ROOT.getFile(new Path(platformResourcePath));
ProjectUtilities.ensureContainerNotReadOnly(file);
return new WorkbenchByteArrayOutputStream(file, resourceSetSynchronizer);
}
protected URI getContainerRelativeURI(IFile aFile) {
IPath path = WorkbenchResourceHelperBase.getPathFromContainers(inputContainers, aFile.getFullPath());
if (path != null)
return URI.createURI(path.toString());
return null;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.emf.ecore.resource.impl.URIConverterImpl#createPlatformResourceInputStream(java.lang.String)
*/
public InputStream createPlatformResourceInputStream(String platformResourcePath) throws IOException {
IFile file = WORKSPACE_ROOT.getFile(new Path(platformResourcePath));
try {
if (!file.isLocal(IResource.DEPTH_ONE) || !file.isSynchronized(IResource.DEPTH_ONE)) {
try {
File iofile = file.getFullPath().toFile();
if (iofile.exists() || file.exists())
file.refreshLocal(IResource.DEPTH_ONE, null);
} catch (CoreException ce) {
if (ce.getStatus().getCode() != IResourceStatus.WORKSPACE_LOCKED)
throw ce;
}
}
// CHANGED from <no-args> to <true> [94015]
return file.getContents(true);
} catch (CoreException exception) {
throw new Resource.IOWrappedException(exception);
}
}
}