| /* |
| * Copyright (c) 2014, 2015, 2018 Eike Stepper (Loehne, Germany) and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v2.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v20.html |
| * |
| * Contributors: |
| * Eike Stepper - initial API and implementation |
| */ |
| package org.eclipse.oomph.resources.impl; |
| |
| import org.eclipse.oomph.base.impl.ModelElementImpl; |
| import org.eclipse.oomph.internal.resources.ResourcesPlugin; |
| import org.eclipse.oomph.predicates.Predicate; |
| import org.eclipse.oomph.predicates.PredicatesUtil; |
| import org.eclipse.oomph.resources.ProjectFactory; |
| import org.eclipse.oomph.resources.ProjectHandler; |
| import org.eclipse.oomph.resources.ResourcesPackage; |
| import org.eclipse.oomph.resources.SourceLocator; |
| import org.eclipse.oomph.resources.backend.BackendContainer; |
| import org.eclipse.oomph.resources.backend.BackendException; |
| import org.eclipse.oomph.resources.backend.BackendResource; |
| import org.eclipse.oomph.util.OomphPlugin; |
| |
| import org.eclipse.emf.common.CommonPlugin; |
| import org.eclipse.emf.common.notify.Notification; |
| import org.eclipse.emf.common.notify.NotificationChain; |
| import org.eclipse.emf.common.util.EList; |
| import org.eclipse.emf.common.util.URI; |
| import org.eclipse.emf.ecore.EClass; |
| import org.eclipse.emf.ecore.InternalEObject; |
| import org.eclipse.emf.ecore.impl.ENotificationImpl; |
| import org.eclipse.emf.ecore.plugin.EcorePlugin; |
| import org.eclipse.emf.ecore.util.EDataTypeUniqueEList; |
| import org.eclipse.emf.ecore.util.EObjectContainmentEList; |
| import org.eclipse.emf.ecore.util.EcoreUtil; |
| import org.eclipse.emf.ecore.util.InternalEList; |
| |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.MultiStatus; |
| |
| import java.lang.reflect.InvocationTargetException; |
| import java.util.Collection; |
| import java.util.HashSet; |
| import java.util.Set; |
| |
| /** |
| * <!-- begin-user-doc --> |
| * An implementation of the model object '<em><b>Source Locator</b></em>'. |
| * <!-- end-user-doc --> |
| * <p> |
| * The following features are implemented: |
| * </p> |
| * <ul> |
| * <li>{@link org.eclipse.oomph.resources.impl.SourceLocatorImpl#getRootFolder <em>Root Folder</em>}</li> |
| * <li>{@link org.eclipse.oomph.resources.impl.SourceLocatorImpl#getExcludedPaths <em>Excluded Paths</em>}</li> |
| * <li>{@link org.eclipse.oomph.resources.impl.SourceLocatorImpl#getProjectFactories <em>Project Factories</em>}</li> |
| * <li>{@link org.eclipse.oomph.resources.impl.SourceLocatorImpl#getPredicates <em>Predicates</em>}</li> |
| * <li>{@link org.eclipse.oomph.resources.impl.SourceLocatorImpl#isLocateNestedProjects <em>Locate Nested Projects</em>}</li> |
| * </ul> |
| * |
| * @generated |
| */ |
| public class SourceLocatorImpl extends ModelElementImpl implements SourceLocator |
| { |
| /** |
| * The default value of the '{@link #getRootFolder() <em>Root Folder</em>}' attribute. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @see #getRootFolder() |
| * @generated |
| * @ordered |
| */ |
| protected static final String ROOT_FOLDER_EDEFAULT = null; |
| |
| /** |
| * The cached value of the '{@link #getRootFolder() <em>Root Folder</em>}' attribute. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @see #getRootFolder() |
| * @generated |
| * @ordered |
| */ |
| protected String rootFolder = ROOT_FOLDER_EDEFAULT; |
| |
| /** |
| * The cached value of the '{@link #getExcludedPaths() <em>Excluded Paths</em>}' attribute list. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @see #getExcludedPaths() |
| * @generated |
| * @ordered |
| */ |
| protected EList<String> excludedPaths; |
| |
| /** |
| * The cached value of the '{@link #getProjectFactories() <em>Project Factories</em>}' containment reference list. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @see #getProjectFactories() |
| * @generated |
| * @ordered |
| */ |
| protected EList<ProjectFactory> projectFactories; |
| |
| /** |
| * The cached value of the '{@link #getPredicates() <em>Predicates</em>}' containment reference list. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @see #getPredicates() |
| * @generated |
| * @ordered |
| */ |
| protected EList<Predicate> predicates; |
| |
| /** |
| * The default value of the '{@link #isLocateNestedProjects() <em>Locate Nested Projects</em>}' attribute. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @see #isLocateNestedProjects() |
| * @generated |
| * @ordered |
| */ |
| protected static final boolean LOCATE_NESTED_PROJECTS_EDEFAULT = false; |
| |
| /** |
| * The cached value of the '{@link #isLocateNestedProjects() <em>Locate Nested Projects</em>}' attribute. |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @see #isLocateNestedProjects() |
| * @generated |
| * @ordered |
| */ |
| protected boolean locateNestedProjects = LOCATE_NESTED_PROJECTS_EDEFAULT; |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| protected SourceLocatorImpl() |
| { |
| super(); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| protected EClass eStaticClass() |
| { |
| return ResourcesPackage.Literals.SOURCE_LOCATOR; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public String getRootFolder() |
| { |
| return rootFolder; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public void setRootFolder(String newRootFolder) |
| { |
| String oldRootFolder = rootFolder; |
| rootFolder = newRootFolder; |
| if (eNotificationRequired()) |
| { |
| eNotify(new ENotificationImpl(this, Notification.SET, ResourcesPackage.SOURCE_LOCATOR__ROOT_FOLDER, oldRootFolder, rootFolder)); |
| } |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public EList<String> getExcludedPaths() |
| { |
| if (excludedPaths == null) |
| { |
| excludedPaths = new EDataTypeUniqueEList<String>(String.class, this, ResourcesPackage.SOURCE_LOCATOR__EXCLUDED_PATHS); |
| } |
| return excludedPaths; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public EList<ProjectFactory> getProjectFactories() |
| { |
| if (projectFactories == null) |
| { |
| projectFactories = new EObjectContainmentEList<ProjectFactory>(ProjectFactory.class, this, ResourcesPackage.SOURCE_LOCATOR__PROJECT_FACTORIES); |
| } |
| return projectFactories; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public boolean isLocateNestedProjects() |
| { |
| return locateNestedProjects; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public void setLocateNestedProjects(boolean newLocateNestedProjects) |
| { |
| boolean oldLocateNestedProjects = locateNestedProjects; |
| locateNestedProjects = newLocateNestedProjects; |
| if (eNotificationRequired()) |
| { |
| eNotify(new ENotificationImpl(this, Notification.SET, ResourcesPackage.SOURCE_LOCATOR__LOCATE_NESTED_PROJECTS, oldLocateNestedProjects, |
| locateNestedProjects)); |
| } |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| public EList<Predicate> getPredicates() |
| { |
| if (predicates == null) |
| { |
| predicates = new EObjectContainmentEList<Predicate>(Predicate.class, this, ResourcesPackage.SOURCE_LOCATOR__PREDICATES); |
| } |
| return predicates; |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public boolean matches(IProject project) |
| { |
| return PredicatesUtil.matchesPredicates(project, predicates); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public IProject loadProject(EList<ProjectFactory> defaultProjectFactories, BackendContainer backendContainer, IProgressMonitor monitor) |
| { |
| BackendContainer rootContainer = SourceLocatorImpl.getRootContainer(this); |
| if (rootContainer == null) |
| { |
| monitor.setTaskName("Skipping root folder '" + getRootFolder() + "' because it doesn't exist"); |
| return null; |
| } |
| |
| return loadProject(this, defaultProjectFactories, rootContainer, backendContainer, monitor); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated NOT |
| */ |
| public void handleProjects(EList<ProjectFactory> defaultProjectFactories, ProjectHandler projectHandler, MultiStatus status, IProgressMonitor monitor) |
| { |
| handleProjects(this, defaultProjectFactories, projectHandler, status, monitor); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) |
| { |
| switch (featureID) |
| { |
| case ResourcesPackage.SOURCE_LOCATOR__PROJECT_FACTORIES: |
| return ((InternalEList<?>)getProjectFactories()).basicRemove(otherEnd, msgs); |
| case ResourcesPackage.SOURCE_LOCATOR__PREDICATES: |
| return ((InternalEList<?>)getPredicates()).basicRemove(otherEnd, msgs); |
| } |
| return super.eInverseRemove(otherEnd, featureID, msgs); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public Object eGet(int featureID, boolean resolve, boolean coreType) |
| { |
| switch (featureID) |
| { |
| case ResourcesPackage.SOURCE_LOCATOR__ROOT_FOLDER: |
| return getRootFolder(); |
| case ResourcesPackage.SOURCE_LOCATOR__EXCLUDED_PATHS: |
| return getExcludedPaths(); |
| case ResourcesPackage.SOURCE_LOCATOR__PROJECT_FACTORIES: |
| return getProjectFactories(); |
| case ResourcesPackage.SOURCE_LOCATOR__PREDICATES: |
| return getPredicates(); |
| case ResourcesPackage.SOURCE_LOCATOR__LOCATE_NESTED_PROJECTS: |
| return isLocateNestedProjects(); |
| } |
| return super.eGet(featureID, resolve, coreType); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @SuppressWarnings("unchecked") |
| @Override |
| public void eSet(int featureID, Object newValue) |
| { |
| switch (featureID) |
| { |
| case ResourcesPackage.SOURCE_LOCATOR__ROOT_FOLDER: |
| setRootFolder((String)newValue); |
| return; |
| case ResourcesPackage.SOURCE_LOCATOR__EXCLUDED_PATHS: |
| getExcludedPaths().clear(); |
| getExcludedPaths().addAll((Collection<? extends String>)newValue); |
| return; |
| case ResourcesPackage.SOURCE_LOCATOR__PROJECT_FACTORIES: |
| getProjectFactories().clear(); |
| getProjectFactories().addAll((Collection<? extends ProjectFactory>)newValue); |
| return; |
| case ResourcesPackage.SOURCE_LOCATOR__PREDICATES: |
| getPredicates().clear(); |
| getPredicates().addAll((Collection<? extends Predicate>)newValue); |
| return; |
| case ResourcesPackage.SOURCE_LOCATOR__LOCATE_NESTED_PROJECTS: |
| setLocateNestedProjects((Boolean)newValue); |
| return; |
| } |
| super.eSet(featureID, newValue); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public void eUnset(int featureID) |
| { |
| switch (featureID) |
| { |
| case ResourcesPackage.SOURCE_LOCATOR__ROOT_FOLDER: |
| setRootFolder(ROOT_FOLDER_EDEFAULT); |
| return; |
| case ResourcesPackage.SOURCE_LOCATOR__EXCLUDED_PATHS: |
| getExcludedPaths().clear(); |
| return; |
| case ResourcesPackage.SOURCE_LOCATOR__PROJECT_FACTORIES: |
| getProjectFactories().clear(); |
| return; |
| case ResourcesPackage.SOURCE_LOCATOR__PREDICATES: |
| getPredicates().clear(); |
| return; |
| case ResourcesPackage.SOURCE_LOCATOR__LOCATE_NESTED_PROJECTS: |
| setLocateNestedProjects(LOCATE_NESTED_PROJECTS_EDEFAULT); |
| return; |
| } |
| super.eUnset(featureID); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public boolean eIsSet(int featureID) |
| { |
| switch (featureID) |
| { |
| case ResourcesPackage.SOURCE_LOCATOR__ROOT_FOLDER: |
| return ROOT_FOLDER_EDEFAULT == null ? rootFolder != null : !ROOT_FOLDER_EDEFAULT.equals(rootFolder); |
| case ResourcesPackage.SOURCE_LOCATOR__EXCLUDED_PATHS: |
| return excludedPaths != null && !excludedPaths.isEmpty(); |
| case ResourcesPackage.SOURCE_LOCATOR__PROJECT_FACTORIES: |
| return projectFactories != null && !projectFactories.isEmpty(); |
| case ResourcesPackage.SOURCE_LOCATOR__PREDICATES: |
| return predicates != null && !predicates.isEmpty(); |
| case ResourcesPackage.SOURCE_LOCATOR__LOCATE_NESTED_PROJECTS: |
| return locateNestedProjects != LOCATE_NESTED_PROJECTS_EDEFAULT; |
| } |
| return super.eIsSet(featureID); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| @SuppressWarnings("unchecked") |
| public Object eInvoke(int operationID, EList<?> arguments) throws InvocationTargetException |
| { |
| switch (operationID) |
| { |
| case ResourcesPackage.SOURCE_LOCATOR___MATCHES__IPROJECT: |
| return matches((IProject)arguments.get(0)); |
| case ResourcesPackage.SOURCE_LOCATOR___LOAD_PROJECT__ELIST_BACKENDCONTAINER_IPROGRESSMONITOR: |
| return loadProject((EList<ProjectFactory>)arguments.get(0), (BackendContainer)arguments.get(1), (IProgressMonitor)arguments.get(2)); |
| case ResourcesPackage.SOURCE_LOCATOR___HANDLE_PROJECTS__ELIST_PROJECTHANDLER_MULTISTATUS_IPROGRESSMONITOR: |
| handleProjects((EList<ProjectFactory>)arguments.get(0), (ProjectHandler)arguments.get(1), (MultiStatus)arguments.get(2), |
| (IProgressMonitor)arguments.get(3)); |
| return null; |
| } |
| return super.eInvoke(operationID, arguments); |
| } |
| |
| /** |
| * <!-- begin-user-doc --> |
| * <!-- end-user-doc --> |
| * @generated |
| */ |
| @Override |
| public String toString() |
| { |
| if (eIsProxy()) |
| { |
| return super.toString(); |
| } |
| |
| StringBuffer result = new StringBuffer(super.toString()); |
| result.append(" (rootFolder: "); |
| result.append(rootFolder); |
| result.append(", excludedPaths: "); |
| result.append(excludedPaths); |
| result.append(", locateNestedProjects: "); |
| result.append(locateNestedProjects); |
| result.append(')'); |
| return result.toString(); |
| } |
| |
| public static void addStatus(MultiStatus status, OomphPlugin plugin, String file, Object object) |
| { |
| IStatus childStatus = plugin.getStatus(object); |
| String message = childStatus.getMessage() + " (while processing " + file + ")"; |
| |
| MultiStatus multiStatus = new MultiStatus(childStatus.getPlugin(), childStatus.getCode(), message, childStatus.getException()); |
| multiStatus.addAll(childStatus); |
| status.add(multiStatus); |
| } |
| |
| public static BackendContainer getRootContainer(SourceLocator sourceLocator) |
| { |
| String rootFolder = sourceLocator.getRootFolder(); |
| if (rootFolder != null) |
| { |
| BackendResource rootResource = BackendResource.get(rootFolder); |
| if (rootResource instanceof BackendContainer) |
| { |
| return (BackendContainer)rootResource; |
| } |
| } |
| |
| return null; |
| } |
| |
| public static IProject loadProject(SourceLocator sourceLocator, EList<ProjectFactory> defaultProjectFactories, BackendContainer rootContainer, |
| BackendContainer backendContainer, IProgressMonitor monitor) |
| { |
| try |
| { |
| EList<ProjectFactory> effectiveProjectFactories = sourceLocator.getProjectFactories(); |
| if (effectiveProjectFactories.isEmpty() && defaultProjectFactories != null) |
| { |
| effectiveProjectFactories = defaultProjectFactories; |
| } |
| |
| for (ProjectFactory projectFactory : effectiveProjectFactories) |
| { |
| IProject project = projectFactory.createProject(rootContainer, backendContainer, monitor); |
| if (project != null) |
| { |
| return project; |
| } |
| } |
| } |
| catch (RuntimeException ex) |
| { |
| throw ex; |
| } |
| catch (Exception ex) |
| { |
| throw new RuntimeException(ex); |
| } |
| |
| return null; |
| } |
| |
| public static void handleProjects(final SourceLocator sourceLocator, final EList<ProjectFactory> defaultProjectFactories, final ProjectHandler projectHandler, |
| final MultiStatus status, final IProgressMonitor monitor) |
| { |
| String rootFolder = sourceLocator.getRootFolder(); |
| if ("platform:/resource/".equals(rootFolder)) |
| { |
| for (IProject project : EcorePlugin.getWorkspaceRoot().getProjects()) |
| { |
| if (project.isAccessible() && !"External Plug-in Libraries".equals(project.getName())) |
| { |
| URI uri = CommonPlugin.resolve(URI.createPlatformResourceURI(project.getFullPath().toString(), true)); |
| if (uri.isFile()) |
| { |
| SourceLocator projectSourceLocator = EcoreUtil.copy(sourceLocator); |
| projectSourceLocator.setLocateNestedProjects(false); |
| projectSourceLocator.setRootFolder(uri.toFileString()); |
| handleProjects(projectSourceLocator, defaultProjectFactories, projectHandler, status, monitor); |
| } |
| } |
| } |
| } |
| else if (rootFolder != null && rootFolder.startsWith("platform:/resource/")) |
| { |
| URI uri = CommonPlugin.resolve(URI.createURI(rootFolder)); |
| if (uri.isFile()) |
| { |
| SourceLocator resourceSourceLocator = EcoreUtil.copy(sourceLocator); |
| resourceSourceLocator.setLocateNestedProjects(false); |
| resourceSourceLocator.setRootFolder(uri.toFileString()); |
| handleProjects(resourceSourceLocator, defaultProjectFactories, projectHandler, status, monitor); |
| } |
| } |
| else |
| { |
| doHandleProjects(sourceLocator, defaultProjectFactories, projectHandler, status, monitor); |
| } |
| } |
| |
| private static void doHandleProjects(final SourceLocator sourceLocator, final EList<ProjectFactory> defaultProjectFactories, |
| final ProjectHandler projectHandler, final MultiStatus status, final IProgressMonitor monitor) |
| { |
| final BackendContainer rootContainer = SourceLocatorImpl.getRootContainer(sourceLocator); |
| if (rootContainer == null) |
| { |
| monitor.setTaskName("Skipping root folder '" + sourceLocator.getRootFolder() + "' because it doesn't exist"); |
| return; |
| } |
| |
| final Set<URI> excludedURIs = new HashSet<URI>(); |
| for (String path : sourceLocator.getExcludedPaths()) |
| { |
| while (path.startsWith("/")) |
| { |
| path = path.substring(1); |
| } |
| |
| excludedURIs.add(URI.createURI(path)); |
| } |
| |
| rootContainer.accept(new BackendResource.Visitor.Default() |
| { |
| @Override |
| public boolean visitContainer(BackendContainer container, IProgressMonitor monitor) throws BackendException |
| { |
| ResourcesPlugin.checkCancelation(monitor); |
| |
| if (isExcludedPath(rootContainer, container)) |
| { |
| return false; |
| } |
| |
| IProject project = loadProject(sourceLocator, defaultProjectFactories, rootContainer, container, monitor); |
| if (sourceLocator.matches(project)) |
| { |
| try |
| { |
| projectHandler.handleProject(project, container); |
| } |
| catch (Exception ex) |
| { |
| SourceLocatorImpl.addStatus(status, ResourcesPlugin.INSTANCE, project.getName(), ex); |
| } |
| } |
| |
| if (project != null && !sourceLocator.isLocateNestedProjects()) |
| { |
| return false; |
| } |
| |
| return true; |
| } |
| |
| private boolean isExcludedPath(BackendContainer rootContainer, BackendContainer backendContainer) |
| { |
| URI relativeURI = backendContainer.getRelativeURI(rootContainer); |
| return relativeURI != null && excludedURIs.contains(relativeURI); |
| } |
| }, monitor); |
| } |
| |
| } // SourceLocatorImpl |