blob: f2f9e4d40423dc7d92afc061f9062379974791da [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2018 THALES GLOBAL SERVICES.
* 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:
* Obeo - initial API and implementation
*******************************************************************************/
package org.eclipse.sirius.business.api.modelingproject;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IProjectNature;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.sirius.business.api.session.Session;
import org.eclipse.sirius.business.api.session.SessionManager;
import org.eclipse.sirius.business.internal.query.ModelingProjectQuery;
import org.eclipse.sirius.ext.base.Option;
import org.eclipse.sirius.ext.base.Options;
import org.eclipse.sirius.viewpoint.Messages;
/**
* A modeling project nature is used to know which projects should be handled in project mode by the modeling explorer.
*
* @author mchauvin
*/
public class ModelingProject implements IProjectNature, IModelingElement {
/** The nature id. */
public static final String NATURE_ID = "org.eclipse.sirius.nature.modelingproject"; //$NON-NLS-1$
/** The default name for the representations file of a modeling project. */
public static final String DEFAULT_REPRESENTATIONS_FILE_NAME = "representations.aird"; //$NON-NLS-1$
/** the project on which the nature is applied. */
private IProject project;
/**
* The URI of the main session file of this project.
*/
private URI mainRepresentationsFileURI;
/**
* A modeling project is not valid if its main representations file has not be loaded correctly.
*/
private boolean valid = true;
/**
* Default constructor necessary for reflection instantiation.
*/
public ModelingProject() {
}
/**
* {@inheritDoc}
*
* @see org.eclipse.core.resources.IProjectNature#configure()
*/
@Override
public void configure() throws CoreException {
/* do nothing */
}
/**
* {@inheritDoc}
*
* @see org.eclipse.core.resources.IProjectNature#deconfigure()
*/
@Override
public void deconfigure() throws CoreException {
/* do nothing */
}
/**
* {@inheritDoc}
*
* @see org.eclipse.core.resources.IProjectNature#getProject()
*/
@Override
public IProject getProject() {
return project;
}
/**
* {@inheritDoc}
*
* @see org.eclipse.core.resources.IProjectNature#setProject(org.eclipse.core.resources.IProject)
*/
@Override
public void setProject(IProject project) {
this.project = project;
}
/**
* Check if the given project is accessible and it has a modeling project nature.
*
* @param project
* the project to check
* @return <code>true</code> if it has, <code>false</code> otherwise
*/
public static boolean hasModelingProjectNature(IProject project) {
try {
return project.exists() && project.hasNature(ModelingProject.NATURE_ID);
} catch (CoreException e) {
// project does not exist or is not open
}
return false;
}
/**
* Get the corresponding Modeling project.
*
* @param project
* The original project
* @return an optional ModelingProject (none if this project is not a modeling project).
*/
public static Option<ModelingProject> asModelingProject(IProject project) {
IProjectNature nature = null;
if (project != null) {
try {
nature = project.getNature(ModelingProject.NATURE_ID);
} catch (CoreException e) {
/* does nothing */
}
}
if (nature instanceof ModelingProject) {
return Options.newSome((ModelingProject) nature);
}
return Options.newNone();
}
/**
* Retrieve the opened session in this project.
*
* @return the opened session associated to this project, <code>null</code> if it can not be found or if session is
* not yet opened
*/
public Session getSession() {
/*
* this method should remain fastest as possible : - the number of aird file for a a project should be very low,
* most often there will be only one.
*/
final Option<URI> optionalUri = getMainRepresentationsFileURI(new NullProgressMonitor());
if (optionalUri.some()) {
for (Session session : SessionManager.INSTANCE.getSessions()) {
if (session.getSessionResource() != null && optionalUri.get().equals(session.getSessionResource().getURI())) {
return session;
}
}
}
return null;
}
/**
* Return an optional URI corresponding to the main representations file of this project. If the main
* representations file is not known, it will be computed by a specific SaxParser that analyzes representations
* files of this project to determine which is never referenced.
*
* @param monitor
* the monitor to be used for reporting progress and responding to cancellation. The monitor is never
* <code>null</code>
* @return an optional URI corresponding to the main session file of this project.
* @throws IllegalArgumentException
* In case of multiples main aird in the references.
*/
public Option<URI> getMainRepresentationsFileURI(IProgressMonitor monitor) throws IllegalArgumentException {
return getMainRepresentationsFileURI(monitor, false, false);
}
/**
* Return an optional URI corresponding to the main representations file of this project. If the main
* representations file is not known, it will be computed by a specific SaxParser that analyzes representations
* files of this project to determine which is never referenced.<BR>
* This method marks this project as invalid.
*
* @param monitor
* the monitor to be used for reporting progress and responding to cancellation. The monitor is never
* <code>null</code>
* @param force
* true if the main representations file must be compute even if it is already known.
* @param throwException
* true if you want to throw exception in case of problem or only have an None option result.
* @return an optional URI corresponding to the main session file of this project.
* @throws IllegalArgumentException
* In case of problem during computing the main representations file.
*/
public synchronized Option<URI> getMainRepresentationsFileURI(IProgressMonitor monitor, boolean force, boolean throwException) throws IllegalArgumentException {
Option<URI> mainRepresentationsFileURIOption = Options.newNone();
try {
monitor.beginTask(Messages.ModelingProject_getMainRepFileURIMsg, 1);
if (force) {
setValid(true);
mainRepresentationsFileURI = null;
}
if (valid && mainRepresentationsFileURI == null) {
// The main representations file is not known (or is known but
// must be recomputed). We must compute it.
try {
mainRepresentationsFileURI = new ModelingProjectQuery(this).computeMainRepresentationsFileURI(new SubProgressMonitor(monitor, 1));
} catch (IllegalArgumentException e) {
// Set this project in invalid state
setValid(false);
// Throw exception if asked
if (throwException) {
throw e;
}
}
}
} finally {
monitor.done();
}
if (mainRepresentationsFileURI != null) {
mainRepresentationsFileURIOption = Options.newSome(mainRepresentationsFileURI);
}
return mainRepresentationsFileURIOption;
}
/**
* Check if this representations file is the main representations file of this project.
*
* @param representationsFile
* the file to check
* @return true if this file is the main representations file, false otherwise
*/
public boolean isMainRepresentationsFile(IFile representationsFile) {
boolean result = false;
Option<URI> optionalMainRepresentationsFile = getMainRepresentationsFileURI(new NullProgressMonitor());
if (optionalMainRepresentationsFile.some()) {
result = optionalMainRepresentationsFile.get().equals(URI.createPlatformResourceURI(representationsFile.getFullPath().toString(), true));
}
return result;
}
/**
* Get the valid status of this project.A modeling project is not valid if its main representations file has not be
* loaded correctly.
*
* @return true is the Modeling project is valid, false otherwise.
*/
public synchronized boolean isValid() {
return this.valid;
}
/**
* Set the valid status of a modeling project. A modeling project is not valid if its main representations file has
* not be loaded correctly.
*
* @param valid
* The new valid state
*/
public synchronized void setValid(boolean valid) {
this.valid = valid;
}
}