/******************************************************************************* * 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; } }