| /******************************************************************************* |
| * Copyright (c) 2007 Cisco Systems, Inc. |
| * 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: |
| * E. Dillon (Cisco Systems, Inc.) - reformat for Code Open-Sourcing |
| *******************************************************************************/ |
| package org.eclipse.tigerstripe.workbench.internal.api.impl; |
| |
| import java.io.File; |
| import java.io.StringReader; |
| import java.net.URI; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| |
| import org.apache.commons.lang.StringUtils; |
| import org.eclipse.core.resources.IContainer; |
| import org.eclipse.core.resources.IMarker; |
| import org.eclipse.core.resources.IProject; |
| import org.eclipse.core.resources.IResource; |
| import org.eclipse.core.resources.IWorkspaceRoot; |
| import org.eclipse.core.resources.IWorkspaceRunnable; |
| import org.eclipse.core.resources.ResourcesPlugin; |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IPath; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.ISafeRunnable; |
| import org.eclipse.core.runtime.ListenerList; |
| import org.eclipse.core.runtime.NullProgressMonitor; |
| import org.eclipse.core.runtime.Path; |
| import org.eclipse.core.runtime.SafeRunner; |
| import org.eclipse.jdt.core.IJavaProject; |
| import org.eclipse.jdt.core.JavaCore; |
| import org.eclipse.tigerstripe.workbench.TigerstripeException; |
| import org.eclipse.tigerstripe.workbench.WorkingCopyException; |
| import org.eclipse.tigerstripe.workbench.generation.IM1Generator; |
| import org.eclipse.tigerstripe.workbench.generation.IM1RunConfig; |
| import org.eclipse.tigerstripe.workbench.internal.BasePlugin; |
| import org.eclipse.tigerstripe.workbench.internal.api.contract.segment.IFacetReference; |
| import org.eclipse.tigerstripe.workbench.internal.api.contract.useCase.IUseCaseReference; |
| import org.eclipse.tigerstripe.workbench.internal.api.project.IImportCheckpoint; |
| import org.eclipse.tigerstripe.workbench.internal.api.project.INameProvider; |
| import org.eclipse.tigerstripe.workbench.internal.contract.segment.FacetReference; |
| import org.eclipse.tigerstripe.workbench.internal.contract.useCase.UseCaseReference; |
| import org.eclipse.tigerstripe.workbench.internal.core.TigerstripeRuntime; |
| import org.eclipse.tigerstripe.workbench.internal.core.generation.M1Generator; |
| import org.eclipse.tigerstripe.workbench.internal.core.model.ArtifactManager; |
| import org.eclipse.tigerstripe.workbench.internal.core.model.ArtifactManagerImpl; |
| import org.eclipse.tigerstripe.workbench.internal.core.model.importing.AbstractImportCheckpointHelper; |
| import org.eclipse.tigerstripe.workbench.internal.core.project.Dependency; |
| import org.eclipse.tigerstripe.workbench.internal.core.project.InternalTigerstripeProject; |
| import org.eclipse.tigerstripe.workbench.internal.core.project.ModelReferenceInternal; |
| import org.eclipse.tigerstripe.workbench.internal.core.project.ProjectDetails; |
| import org.eclipse.tigerstripe.workbench.model.deprecated_.IArtifactManagerSession; |
| import org.eclipse.tigerstripe.workbench.project.IDependency; |
| import org.eclipse.tigerstripe.workbench.project.IModelReference; |
| import org.eclipse.tigerstripe.workbench.project.IPluginConfig; |
| import org.eclipse.tigerstripe.workbench.project.IProjectDependencyChangeListener; |
| import org.eclipse.tigerstripe.workbench.project.IProjectDependencyDelta; |
| import org.eclipse.tigerstripe.workbench.project.IProjectDetails; |
| import org.eclipse.tigerstripe.workbench.project.ITigerstripeModelProject; |
| import org.eclipse.tigerstripe.workbench.project.ITigerstripeModelProjectInternal; |
| |
| public abstract class TigerstripeProjectHandle extends |
| BaseTigerstripeModelProject implements ITigerstripeModelProjectInternal { |
| |
| private ListenerList projectChangeListeners = new ListenerList(); |
| |
| private INameProvider nameProvider; |
| |
| private ArtifactManager manager; |
| |
| private boolean dependenciesCacheNeedsRefresh = false; |
| |
| public static final String DESCRIPTOR_FILENAME = ITigerstripeConstants.PROJECT_DESCRIPTOR; |
| |
| private boolean wasDisposed = false; |
| |
| public String getDescriptorFilename() { |
| return DESCRIPTOR_FILENAME; |
| } |
| |
| private InternalTigerstripeProject tsProject; |
| |
| public TigerstripeProjectHandle(URI projectContainerURI) { |
| super(TigerstripeRuntime.getDefaultInstance(),projectContainerURI); |
| } |
| |
| @Override |
| protected IM1Generator getGenerator(ITigerstripeModelProject project,IM1RunConfig config) { |
| return new M1Generator(this, config); |
| } |
| |
| |
| public void setProjectDetails(IProjectDetails projectDetails) |
| throws WorkingCopyException, TigerstripeException { |
| assertSet(); |
| getTSProject().setProjectDetails((ProjectDetails) projectDetails); |
| } |
| |
| public INameProvider getNameProvider() { |
| if (nameProvider == null) { |
| nameProvider = new NameProviderImpl(this); |
| } |
| |
| return nameProvider; |
| } |
| |
| public String getBaseRepository() throws TigerstripeException { |
| if (getTSProject() != null) |
| return getTSProject().getBaseRepository(); |
| throw new TigerstripeException("Invalid project handle."); |
| } |
| |
| |
| public synchronized IArtifactManagerSession getArtifactManagerSession() |
| throws TigerstripeException { |
| if (artifactMgrSession == null) { |
| if (manager == null) { |
| ArtifactManagerImpl impl = new ArtifactManagerImpl(getTSProject()); |
| impl.registerListeners(); |
| manager = impl; |
| } |
| setArtifactManagerSession(new ArtifactManagerSessionImpl(manager)); |
| } |
| |
| return artifactMgrSession; |
| } |
| |
| public boolean wasDisposed() { |
| if (isWorkingCopy()) { |
| return super.wasDisposed() && wasDisposed; |
| } |
| return wasDisposed; |
| } |
| |
| protected void setTSProject(InternalTigerstripeProject tsProject) { |
| this.tsProject = tsProject; |
| } |
| |
| public InternalTigerstripeProject getTSProject() throws TigerstripeException { |
| if (tsProject == null) { |
| // try and create a project for the URI |
| File baseDir = new File(this.getProjectContainerURI()); |
| if (baseDir.isDirectory()) { |
| tsProject = new InternalTigerstripeProject(baseDir, this); |
| } else |
| throw new TigerstripeException("Invalid project " |
| + baseDir.toString()); |
| } |
| |
| tsProject.reload(false); |
| return this.tsProject; |
| } |
| |
| @Override |
| public boolean exists() { |
| boolean result = false; |
| // check that a descriptor can be found and that it is valid |
| if (findProjectDescriptor()) { |
| try { |
| getTSProject(); |
| result = true; |
| } catch (TigerstripeException e) { |
| result = false; |
| } |
| } |
| return result; |
| } |
| |
| |
| public void addPluginConfig(IPluginConfig ref) throws TigerstripeException { |
| assertSet(); |
| getTSProject().addPluginConfig(ref); |
| } |
| |
| public void removePluginConfig(IPluginConfig ref) |
| throws TigerstripeException { |
| assertSet(); |
| getTSProject().removePluginConfig(ref); |
| } |
| |
| |
| public IDependency makeDependency(String relativePath) |
| throws TigerstripeException { |
| return new Dependency(runtime, getTSProject(), relativePath); |
| } |
| |
| |
| public void addDependency(IDependency dependency, IProgressMonitor monitor) |
| throws TigerstripeException { |
| assertSet(); |
| dependenciesCacheNeedsRefresh = true; |
| getTSProject().addDependency(dependency); |
| ProjectDependencyChangeDelta delta = new ProjectDependencyChangeDelta( |
| this, IProjectDependencyDelta.PROJECT_DEPENDENCY_ADDED, dependency); |
| broadcastProjectDependencyChange(delta); |
| } |
| |
| public void addDependencies(IDependency[] dependencies, |
| IProgressMonitor monitor) throws WorkingCopyException, |
| TigerstripeException { |
| assertSet(); |
| dependenciesCacheNeedsRefresh = true; |
| getTSProject().addDependencies(dependencies); |
| for (IDependency dep : dependencies) { |
| ProjectDependencyChangeDelta delta = new ProjectDependencyChangeDelta( |
| this, IProjectDependencyDelta.PROJECT_DEPENDENCY_ADDED, |
| dep); |
| broadcastProjectDependencyChange(delta); |
| } |
| } |
| |
| public void removeDependency(IDependency dependency, |
| IProgressMonitor monitor) throws WorkingCopyException, |
| TigerstripeException { |
| assertSet(); |
| dependenciesCacheNeedsRefresh = true; |
| getTSProject().removeDependency(dependency); |
| ProjectDependencyChangeDelta delta = new ProjectDependencyChangeDelta( |
| this, IProjectDependencyDelta.PROJECT_DEPENDENCY_REMOVED, dependency); |
| broadcastProjectDependencyChange(delta); |
| } |
| |
| public void removeDependencies(IDependency[] dependencies, |
| IProgressMonitor monitor) throws WorkingCopyException, |
| TigerstripeException { |
| assertSet(); |
| dependenciesCacheNeedsRefresh = true; |
| getTSProject().removeDependencies(dependencies); |
| for (IDependency dep : dependencies) { |
| ProjectDependencyChangeDelta delta = new ProjectDependencyChangeDelta( |
| this, IProjectDependencyDelta.PROJECT_DEPENDENCY_REMOVED, |
| dep); |
| broadcastProjectDependencyChange(delta); |
| } |
| } |
| |
| public void removeModelReference(String modelRefId) |
| throws TigerstripeException { |
| assertSet(); |
| dependenciesCacheNeedsRefresh = true; |
| IModelReference modelRef = clearReference(modelRefId); |
| // This could happen if reference was not loaded, simply create a dummy |
| // instance to pass to the base project, otherwise it won't be removed |
| // correctly. |
| if (modelRef == null) { |
| modelRef = new ModelReferenceInternal(modelRefId); |
| } |
| getTSProject().removeModelReference(modelRef); |
| ProjectDependencyChangeDelta delta = new ProjectDependencyChangeDelta( |
| this, IProjectDependencyDelta.PROJECT_REFERENCE_REMOVED, |
| modelRef); |
| broadcastProjectDependencyChange(delta); |
| } |
| |
| public void removeModelReferences(String[] modelRefs) |
| throws TigerstripeException { |
| for (String modelId : modelRefs) { |
| removeModelReference(modelId); |
| } |
| } |
| |
| public IModelReference addModelReference(String modelId) |
| throws TigerstripeException { |
| assertSet(); |
| dependenciesCacheNeedsRefresh = true; |
| IModelReference modelRef = makeReference(modelId); |
| modelRef.setEnabled(true); |
| getTSProject().addModelReference(modelRef); |
| if (modelRef.isResolved()) { |
| ProjectDependencyChangeDelta delta = new ProjectDependencyChangeDelta( |
| this, IProjectDependencyDelta.PROJECT_REFERENCE_ADDED, |
| modelRef); |
| broadcastProjectDependencyChange(delta); |
| } |
| return modelRef; |
| } |
| |
| public IModelReference[] addModelReferences(String[] modelRefIds) |
| throws TigerstripeException { |
| Collection<IModelReference> modelRefs = new ArrayList<>(); |
| for (String modelId : modelRefIds) { |
| modelRefs.add(addModelReference(modelId)); |
| } |
| return modelRefs.stream().toArray(IModelReference[]::new); |
| } |
| |
| |
| public void setAdvancedProperty(String property, String value) |
| throws TigerstripeException { |
| assertSet(); |
| getTSProject().setAdvancedProperty(property, value); |
| } |
| |
| public boolean requiresDescriptorUpgrade() throws TigerstripeException { |
| return getTSProject().requiresDescriptorUpgrade(); |
| } |
| |
| /** |
| * Returns the IImportCheckpoint for this project |
| * |
| */ |
| public IImportCheckpoint getImportCheckpoint() throws TigerstripeException { |
| |
| AbstractImportCheckpointHelper cpHelper = new AbstractImportCheckpointHelper( |
| this); |
| IImportCheckpoint result = cpHelper.readCheckpoint(); |
| return result; |
| } |
| |
| public IArtifactManagerSession getIArtifactManagerSession() |
| throws TigerstripeException { |
| return getArtifactManagerSession(); |
| } |
| |
| public void doSave() throws TigerstripeException { |
| try { |
| InternalTigerstripeProject project = getTSProject(); |
| if (project != null) { |
| project.doSave(null); |
| project.clearDirty(); |
| return; |
| } |
| } catch (TigerstripeException e) { |
| if (tsProject != null) { |
| // This means we are saving on an empty directory, and the |
| // descriptor needs to be created now |
| tsProject.doSave(null); |
| return; |
| } |
| } |
| |
| throw new TigerstripeException("Invalid project, cannot save."); |
| } |
| |
| public IFacetReference makeFacetReference(URI facetURI) |
| throws TigerstripeException { |
| return new FacetReference(facetURI, this); |
| } |
| |
| public IFacetReference makeFacetReference(String projectRelativePath) |
| throws TigerstripeException { |
| return new FacetReference(projectRelativePath, |
| getTSProject()); |
| } |
| |
| public IUseCaseReference makeIUseCaseReference(URI useCaseURI) |
| throws TigerstripeException { |
| return new UseCaseReference(useCaseURI, this); |
| } |
| |
| public void addFacetReference(IFacetReference facetRef) |
| throws TigerstripeException { |
| assertSet(); |
| getTSProject().addFacetReference(facetRef); |
| } |
| |
| public void removeFacetReference(IFacetReference facetRef) |
| throws TigerstripeException { |
| assertSet(); |
| getTSProject().removeFacetReference(facetRef); |
| } |
| |
| |
| public ITigerstripeModelProject[] getIReferencedProjects() |
| throws TigerstripeException { |
| return getReferencedProjects(); |
| } |
| |
| // ========================================================================== |
| // ==== |
| // WorkingCopy stuff |
| @Override |
| public void doCommit(IProgressMonitor monitor) throws TigerstripeException { |
| |
| TigerstripeProjectHandle original = (TigerstripeProjectHandle) getOriginal(); |
| original.reloadFrom(getTSProject(), dependenciesCacheNeedsRefresh, |
| monitor); |
| original.doSave(); |
| try { |
| original.getIProject().refreshLocal(1, monitor); |
| } catch (CoreException e) { |
| throw new TigerstripeException("Error saving descriptor", e); |
| } |
| |
| getTSProject().clearDirty(); |
| dependenciesCacheNeedsRefresh = false; |
| } |
| |
| // ======================================== |
| // Project dependency change listeners stuff |
| public void addProjectDependencyChangeListener( |
| IProjectDependencyChangeListener listener) { |
| if (isWorkingCopy()) { |
| TigerstripeProjectHandle original = (TigerstripeProjectHandle) getOriginal(); |
| original.addProjectDependencyChangeListener(listener); |
| } else { |
| projectChangeListeners.add(listener); |
| } |
| } |
| |
| public void removeProjectDependencyChangeListener( |
| IProjectDependencyChangeListener listener) { |
| if (isWorkingCopy()) { |
| TigerstripeProjectHandle original = (TigerstripeProjectHandle) getOriginal(); |
| if (original != null) { |
| original.removeProjectDependencyChangeListener(listener); |
| } |
| } else { |
| projectChangeListeners.remove(listener); |
| } |
| } |
| |
| public void broadcastProjectDependencyChange( |
| final IProjectDependencyDelta delta) { |
| |
| if (isWorkingCopy()) { |
| TigerstripeProjectHandle original = (TigerstripeProjectHandle) getOriginal(); |
| original.broadcastProjectDependencyChange(delta); |
| } else { |
| |
| Object[] objects = projectChangeListeners.getListeners(); |
| for (Object obj : objects) { |
| final IProjectDependencyChangeListener listener = (IProjectDependencyChangeListener) obj; |
| SafeRunner.run(new ISafeRunnable() { |
| public void handleException(Throwable exception) { |
| BasePlugin.log(exception); |
| } |
| |
| public void run() throws Exception { |
| listener.projectDependenciesChanged(delta); |
| } |
| }); |
| } |
| } |
| } |
| |
| public void reloadFrom(InternalTigerstripeProject descriptor, |
| boolean dependenciesCacheNeedsRefresh, IProgressMonitor monitor) |
| throws TigerstripeException { |
| StringReader reader = new StringReader(descriptor.asText()); |
| getTSProject().reloadFrom(reader); |
| |
| if (dependenciesCacheNeedsRefresh) { |
| // Rebuild the cache if dependencies were added |
| ((ArtifactManagerSessionImpl) getArtifactManagerSession()) |
| .getArtifactManager().updateDependenciesContentCache( |
| monitor); |
| } |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.tigerstripe.workbench.project.ITigerstripeModelProject#getModelId |
| * () |
| */ |
| public String getModelId() throws TigerstripeException { |
| return StringUtils.defaultIfEmpty(getProjectDetails().getModelId(), getName()); |
| } |
| |
| /* |
| * (non-Javadoc) |
| * |
| * @see |
| * org.eclipse.tigerstripe.workbench.project.ITigerstripeModelProject#setModelId |
| * (java.lang.String) |
| */ |
| public void setModelId(String modelId) throws WorkingCopyException, |
| TigerstripeException { |
| IProjectDetails details = getProjectDetails(); |
| details.setModelId(modelId); |
| setProjectDetails(details); |
| } |
| |
| @Override |
| public void dispose() { |
| super.dispose(); |
| if (manager != null) { |
| manager.dispose(); |
| } |
| if (tsProject != null) { |
| tsProject.dispose(); |
| } |
| wasDisposed = true; |
| } |
| |
| // NM: Marks the cache as dirty so it'll refresh it next time |
| public void markCacheAsDirty() { |
| dependenciesCacheNeedsRefresh = true; |
| } |
| |
| |
| public boolean containsErrors() { |
| IProject project = (IProject) this.getAdapter(IProject.class); |
| try { |
| IMarker[] markers = project.findMarkers(IMarker.PROBLEM, true, |
| IResource.DEPTH_INFINITE); |
| for (int i = 0; i < markers.length; i++) { |
| if (IMarker.SEVERITY_ERROR == markers[i].getAttribute( |
| IMarker.SEVERITY, IMarker.SEVERITY_INFO)) { |
| return true; |
| } |
| } |
| } catch (CoreException e) { |
| BasePlugin.log(e); |
| } |
| return false; |
| } |
| |
| public Object getAdapter(@SuppressWarnings("rawtypes") Class adapter) { |
| if (adapter == IProject.class) { |
| try { |
| return getIProject(); |
| } catch (TigerstripeException e) { |
| return null; |
| } |
| } else if (adapter == IJavaProject.class) { |
| try { |
| IProject project = getIProject(); |
| |
| // Note that this will be null for the PhantomProject |
| if (project != null) { |
| return JavaCore.create(project); |
| } |
| } catch (TigerstripeException e) { |
| return null; |
| } |
| } |
| return null; |
| } |
| |
| private IProject getIProject() |
| throws TigerstripeException { |
| |
| IContainer container = getIContainer(); |
| |
| if (container instanceof IProject) { |
| return (IProject) container; |
| } |
| |
| /** |
| * Project also can be child folder in other project. In this case this |
| * container will be IFolder instead of IProject |
| */ |
| |
| if (container != null) { |
| IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); |
| for (IProject project : root.getProjects()) { |
| if (project.getLocation().equals(container.getLocation())) { |
| return project; |
| } |
| } |
| } |
| |
| throw new TigerstripeException("Can't resolve " + this.getLocation() |
| + " as Eclipse IProject"); |
| } |
| |
| private IContainer container; |
| |
| // Introduced as a result of Bugzilla 319896 |
| private IContainer getIContainer() { |
| if (container == null) { |
| IWorkspaceRoot root = ResourcesPlugin.getWorkspace().getRoot(); |
| File file = new File(this.getLocation().toOSString()); |
| IPath path = new Path(file.getAbsolutePath()); |
| container = root.getContainerForLocation(path); |
| } |
| return container; |
| } |
| |
| public void delete(final boolean force, IProgressMonitor monitor) |
| throws TigerstripeException { |
| |
| if (monitor == null) |
| monitor = new NullProgressMonitor(); |
| |
| final IProject project = (IProject) getAdapter(IProject.class); |
| if (project != null) { |
| try { |
| ResourcesPlugin.getWorkspace().run(new IWorkspaceRunnable() { |
| @Override |
| public void run(IProgressMonitor monitor) |
| throws CoreException { |
| project.delete(force, monitor); |
| } |
| }, project, IResource.NONE, monitor); |
| } catch (CoreException e) { |
| throw new TigerstripeException("An error occured while trying to delete project:" + e.getMessage(), e); |
| } |
| } |
| } |
| |
| @Override |
| public IPath getFullPath() { |
| String name = getName(); |
| if (name == null) { |
| return null; |
| } |
| IResource member = ResourcesPlugin.getWorkspace().getRoot() |
| .findMember(name); |
| if (member == null) { |
| return null; |
| } |
| return member.getFullPath(); |
| } |
| |
| @Override |
| protected IModelReference newRef(String modelId) { |
| return new ModelReferenceInternal(getRuntime(), this, modelId); |
| } |
| |
| } |