/*******************************************************************************
* Copyright (c) 2006-2012
* Software Technology Group, Dresden University of Technology
* DevBoost GmbH, Berlin, Amtsgericht Charlottenburg, HRB 140026
*
* 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:
* Software Technology Group - TU Dresden, Germany;
* DevBoost GmbH - Berlin, Germany
* - initial API and implementation
******************************************************************************/
package org.reuseware.sokan.index.util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.Path;
import org.eclipse.emf.common.util.URI;
import org.reuseware.sokan.ID;
import org.reuseware.sokan.IndexRow;
import org.reuseware.sokan.SokanFactory;
/**
* Utility methods to work with resources and their identifiers.
*/
public final class ResourceUtil {
private ResourceUtil() { }
/**
* Converts the given URI to an Eclipse file handle.
*
* @param uri the URI
* @return the file handle
*/
public static IFile fileFor(URI uri) {
if (uri == null || !uri.isPlatform()) {
return null;
}
String pathStr = uri.toPlatformString(true);
IPath path = new Path(pathStr);
IFile file = ResourcesPlugin.getWorkspace().getRoot().getFile(path);
return file;
}
/**
* Given a list of <code>IResource</code> this method tries to find the
* resource in the list that can be represented by the given artifactID. The
* desired resource doesn't need to be indexed yet, but it needs to be
* located in a store.
*
* @param resourceList
* a list of resources.
* @param artifactID
* The artifact identifier of the needed resource.
* @return A resource from the list, that matches the given artifact
* identifier. <code>Null</code> is retrieved if there is no
* resource matching in the list or the resource is not located in a
* store.
*/
public static IResource findResource(List<IResource> resourceList,
ID artifactID) {
if (resourceList == null || artifactID == null) {
return null;
}
ID myID;
for (IResource iRes : resourceList) {
myID = idFrom(iRes);
if (artifactID.equals(myID)) {
return iRes;
}
}
return null;
}
/**
* Retrieves an artifact identifier defined by a string or <code>null</code>
* if no or an empty String is given. It is not checked, whether the
* artifact is in the store. In fact, the idString is simply parsed to a
* list and then given as segments to the new <code>ID</code> instance.
*
* @param idString
* A string representing an <code>ID</code>.
* @see ResourceUtil#idString(ID)
* @return A new <code>ID</code> instance.
*/
public static ID idFrom(String idString) {
if (idString == null || idString.equals("")
|| idString.equals(SokanConst.SEPERATOR)) {
return null;
}
String idStr;
if (idString.startsWith(SokanConst.SEPERATOR)) {
idStr = idString.substring(1);
} else {
idStr = idString;
}
ID id = SokanFactory.eINSTANCE.createID();
id.getSegments().addAll(CoreUtil.toList(idStr, SokanConst.SEPERATOR));
return id;
}
/**
* Retrieves an artifact identifier defined by a string array or
* <code>null</code> if no or an empty String array is given. It is not
* checked, whether the artifact is in the store. In fact, the string array
* is given as segments to the new <code>ID</code> instance.
*
* @param idStringArray
* A string array representing an <code>ID</code>.
* @see ResourceUtil#idString(ID)
* @return A new <code>ID</code> instance.
*/
public static ID idFrom(String[] idStringArray) {
if (idStringArray == null || idStringArray.length == 0) {
return null;
}
ID id = SokanFactory.eINSTANCE.createID();
id.getSegments().addAll(Arrays.asList(idStringArray));
return id;
}
/**
* Retrieves an artifact identifier defined by a string list or
* <code>null</code> if no or an empty list is given. It is not
* checked, whether the artifact is in the store. In fact, the string list
* is given as segments to the new <code>ID</code> instance.
*
* @param idStringList
* A string list representing an <code>ID</code>.
* @see ResourceUtil#idString(ID)
* @return A new <code>ID</code> instance.
*/
public static ID idFrom(List<String> idStringList) {
if (idStringList == null || idStringList.size() == 0) {
return null;
}
ID id = SokanFactory.eINSTANCE.createID();
id.getSegments().addAll(idStringList);
return id;
}
/**
* Retrieves an artifact identifier for the given resource or
* <code>null</code> if no resource is given. This resource doesn't need to
* be indexed yet, but it must be contained in a store.
*
* @param resource
* The resource associated with the artifact.
* @return A new <code>ID</code> instance.
*/
public static ID idFrom(IResource resource) {
if (resource == null) {
return null;
}
return idFrom(uriFrom(resource));
}
/**
* Retrieves an artifact identifier defined by the given <code>URI</code>.
* This artifact doesn't need to be indexed yet, but the resource
* representing the artifact must be contained in a store. Hence, this
* method will return <code>null</code> if the given <code>URI</code> is
* <code>null</code> or doesn't point into a store.
*
* @param uri
* The unique resource identifier.
* @return A new <code>ID</code> instance.
*/
public static ID idFrom(URI uri) {
if (uri == null) {
return null;
}
String physicalURIString = uri.toString();
for (URI aBase : getStoreURIList()) {
if (physicalURIString.startsWith(aBase.toString())
&& !StoreUtil.INSTANCE.isStore(uri)) {
return buildIDFromURI(uri.deresolve(aBase));
}
}
return null;
}
/**
* Retrieves the artifact identifiers for the given resources.
* <code>Null</code> is retrieved if the requested list of resources is
* <code>null</code>. In addition, the resources doesn't need to be indexed
* yet, but they must be contained in a store.
*
* @param uris
* The resource associated with the artifact.
* @return A list of artifact identifiers.
*/
public static List<ID> idListFromURIs(Collection<URI> uris) {
if (uris == null) {
return Collections.emptyList();
}
List<ID> idList = new ArrayList<ID>(uris.size());
for (URI uri : uris) {
ID id = idFrom(uri);
if (id != null) {
idList.add(idFrom(uri));
}
}
return idList;
}
/**
* Builds a string out of a given ID.
*
* @param id
* The artifact's identifier.
* @see ResourceUtil#idFrom(String)
* @return A <code>String</code> representing an <code>ID</code>.
*/
public static String idString(ID id) {
if (id == null) {
return null;
}
return SokanConst.SEPERATOR
+ CoreUtil.toListString(id.getSegments(), SokanConst.SEPERATOR);
}
/**
* Builds a string out of a given String list that represents an ID.
*
* @param idList
* The artifact's identifier as String list.
* @see ResourceUtil#idFrom(String)
* @return A <code>String</code> list representing an <code>ID</code>.
*/
public static String idString(List<String> idList) {
if (idList == null) {
return null;
}
return SokanConst.SEPERATOR
+ CoreUtil.toListString(idList, SokanConst.SEPERATOR);
}
/**
* Retrieves the artifact's physical <code>URI</code> of a given artifact
* identifier. Retrieves <code>null</code> if artifactID is
* <code>null</code>.<br>
* <b>Attention!</b> <br>
* This method leads to an index query!
*
* @param artifactID
* The artifact's identifier.
* @return The artifact's physical <code>URI</code>.
*/
public static URI uriFrom(ID artifactID) {
if (artifactID == null) {
return null;
}
IndexRow row = IndexUtil.INSTANCE.getIndex(artifactID);
if (row == null) {
return null;
}
return uriFrom(row.getPhyURI());
}
/**
* Retrieves the <code>URI</code> of a given path or <code>null</code> if
* this path is <code>null</code>.
*
* @param path
* A path in the Eclipse workspace.
* @return A platform resource <code>URI</code>.
*/
public static URI uriFrom(IPath path) {
if (path == null) {
return null;
}
return URI.createPlatformResourceURI(path.toString(), true);
}
/**
* Retrieves the physical <code>URI</code> of a given resource. It is not
* checked, whether this resource is indexed as artifact.
*
* @param resource
* A resource in the Eclipse workspace.
* @return A platform resource <code>URI</code>.
*/
public static URI uriFrom(IResource resource) {
if (resource == null) {
return null;
}
return uriFrom(resource.getFullPath());
}
/**
* Retrieves the u<code>URI</code> defined by a uriString or
* <code>null</code> if this string is <code>null</code> or empty.
*
* @param uriString
* A string defining a <code>URI</code>.
* @see ResourceUtil#uriString(URI)
* @return A platform resource <code>URI</code>.
*/
public static URI uriFrom(String uriString) {
if (uriString == null || uriString.equals("")) {
return null;
}
return URI.createURI(uriString, true);
}
/**
* Retrieves a string representing a <code>URI</code> or null if the given
* <code>URI</code> is <code>null</code>.
*
* @param uri
* The <code>URI</code> to get a string representation from.
* @return A string defining a <code>URI</code>.
*/
public static String uriString(URI uri) {
if (uri == null) {
return null;
}
return uri.toString();
}
/**
* Retrieves a string representing the <code>URI</code> of a resource or
* null if the given resource is <code>null</code>.
*
* @param resource
* The <code>Resource</code> to get a <code>URI</code>
* representation from.
* @return A string defining a <code>URI</code>.
*/
public static String uriString(IResource resource) {
if (resource == null) {
return null;
}
return uriString(uriFrom(resource));
}
private static List<URI> getStoreURIList() {
List<URI> uris = new ArrayList<URI>();
uris.addAll(StoreUtil.INSTANCE.getAllStoreURIs());
uris.addAll(StoreUtil.INSTANCE.getAllDeletedStoreURIs());
return uris;
}
private static ID buildIDFromURI(URI uri) {
if (uri == null) {
return null;
}
List<String> segments = uri.segmentsList();
if (segments.size() < 1) {
return null;
}
segments = segments.subList(1, segments.size());
ID id = SokanFactory.eINSTANCE.createID();
id.getSegments().addAll(segments);
return id;
}
}