/******************************************************************************* | |
* Copyright (c) 2005, 2012 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: | |
* Oracle Corporation | |
*******************************************************************************/ | |
package org.eclipse.bpel.ui.details.providers; | |
import java.util.Iterator; | |
import java.util.LinkedList; | |
import java.util.List; | |
import org.eclipse.bpel.ui.BPELUIPlugin; | |
import org.eclipse.core.resources.IContainer; | |
import org.eclipse.core.resources.IResource; | |
import org.eclipse.core.resources.IWorkspaceRoot; | |
import org.eclipse.core.runtime.CoreException; | |
import org.eclipse.emf.common.util.URI; | |
import org.eclipse.emf.ecore.resource.Resource; | |
import org.eclipse.emf.ecore.resource.ResourceSet; | |
/** | |
* Content provider for EMF objects that can be read from the Workspace | |
* | |
* @author Michal Chmielewski (michal.chmielewski@oracle.com) | |
*/ | |
public abstract class AbstractResourceContentProvider extends AbstractContentProvider { | |
static private final String SLASH = "/"; //$NON-NLS-1$ | |
/** | |
* Append the schemas that are present in the object passed to the list | |
* indicated. | |
* | |
* @param input an object that has or is schema definitions. | |
* @param list the list where the schemas are put. | |
*/ | |
ResourceSet fResourceSet; | |
public AbstractResourceContentProvider ( ResourceSet set ) { | |
fResourceSet = set; | |
} | |
protected void doCollectElements ( Object input, List list) throws CoreException { | |
if (input == null) { | |
return ; | |
} | |
if (input instanceof IContainer) { | |
findCandidates((IContainer) input,list, getKindClass() ); | |
return; | |
} | |
if (isAcceptableKind(input)) { | |
list.add(input); | |
return; | |
} | |
Object[] arr = null; | |
if (input.getClass().isArray()) { | |
arr = (Object[]) input; | |
} else if (input instanceof List) { | |
arr = ((List)input).toArray(); | |
} | |
if (arr == null) { | |
return; | |
} | |
for(int i=0; i < arr.length; i++) { | |
doCollectElements ( arr[i], list ); | |
} | |
} | |
@Override | |
public void collectElements (Object input, List list) { | |
try { | |
doCollectElements ( input, list ); | |
} catch (CoreException e) { | |
BPELUIPlugin.log(e); | |
} | |
} | |
/** | |
* Check of the object passed is of the acceptable kind. This simply | |
* checks to see if the the result returned by {@link #getKindClass()} | |
* matches the object passed. | |
* | |
* @param obj the object to test. | |
* @return true/false, depending on outcomee. | |
*/ | |
protected boolean isAcceptableKind ( Object obj ) { | |
Class [] kind = getKindClass(); | |
if (kind == null) { | |
return true; | |
} | |
for(int i=0; i < kind.length; i++) { | |
if (kind[i].isInstance(obj)) { | |
return true; | |
} | |
} | |
return false; | |
} | |
/** | |
* Find the candidate objects to load. | |
* | |
* @param container | |
* @param list | |
* @param the kind of EMF objects that we want back | |
* @return | |
* @throws CoreException | |
*/ | |
protected List findCandidates ( IContainer container, List list, Class [] kind ) throws CoreException { | |
if (list == null) { | |
list = new LinkedList(); | |
} | |
Iterator i = findCandidates( container ).iterator(); | |
while (i.hasNext()) { | |
IResource r = (IResource) i.next(); | |
try { | |
Object obj = load(r); | |
if ( isAcceptableKind (obj) ) { | |
list.add(obj); | |
} | |
} catch (Exception ex) { | |
BPELUIPlugin.log(ex); | |
} | |
} | |
return list; | |
} | |
/** | |
* Load the EMF model from the resource indicated. Return the top EMF object for the model. | |
* | |
* @param r | |
* @return | |
*/ | |
protected Object load ( IResource r ) | |
{ | |
// Format: /Project/path | |
String uri = SLASH + r.getProject().getName() + SLASH + r.getProjectRelativePath(); | |
URI locationURI = URI.createPlatformResourceURI( uri ); | |
Resource resource = fResourceSet.getResource(locationURI, true); | |
return resource.getContents().get(0); | |
} | |
protected abstract String[] getKind () ; | |
/** | |
* Return the kind of objects that we as a provider are interested in | |
* | |
* @return an array of kind of objects that we are interested in | |
*/ | |
protected Class[] getKindClass () { | |
return null; | |
} | |
/** | |
* Return the depth at which discover for new resources will abort if none is found | |
* at the current level and the level below. | |
* | |
* @return the max depth to search, including current level | |
*/ | |
protected int getDepth ( ) { | |
return 2; | |
} | |
/** | |
* Find candidate resourcesin the container passed. The container is searched | |
* up to a certain depth. If resources are found in that container then the next | |
* level is searched. Otherwise the search at that level stops. So not exactly a full | |
* workspace scan. | |
* | |
* @param container the container to search (project, folder, workspace root) | |
* @return the list of schemas found | |
* @throws CoreException | |
*/ | |
protected List findCandidates ( IContainer container ) throws CoreException { | |
LinkedList list = new LinkedList(); | |
// Workspace root contains Projects ... | |
if (container instanceof IWorkspaceRoot) { | |
return findCandidates( container, list, getKind(), getDepth() + 1 ); | |
} | |
return findCandidates( container, list, getKind(), getDepth() ); | |
} | |
protected List findCandidates ( IContainer container, List list, String [] kind , int depth ) throws CoreException { | |
if (depth <= 0 || container.isAccessible() == false) { | |
return list; | |
} | |
depth -= 1; | |
boolean bFound = false; | |
IResource [] rlist = container.members(); | |
for(int i=0; i< rlist.length; i++) { | |
IResource r = rlist[i]; | |
if ( r.getType() != IResource.FILE) { | |
continue; | |
} | |
String name = r.getFileExtension(); | |
for(int j=0; j < kind.length; j++) { | |
if (name != null && name.equalsIgnoreCase(kind[j])) { | |
bFound = true; | |
list.add( r ); | |
break; | |
} | |
} | |
} | |
// if found some candidates at this level, look only in the next level (and | |
// so on). Eventually, not all levels are searched, just the ones that contain | |
// xsd resources and their descendant folders | |
if (bFound) { | |
depth = 1; | |
} | |
for(int i=0; i < rlist.length; i++) { | |
IResource r = rlist[i]; | |
if (r instanceof IContainer) { | |
findCandidates((IContainer) r, list, kind, depth); | |
} | |
} | |
return list; | |
} | |
} |