SiriusUtil.java
/**
* Copyright (c) 2004-2025 Carnegie Mellon University and others. (see Contributors file).
* All Rights Reserved.
*
* NO WARRANTY. ALL MATERIAL IS FURNISHED ON AN "AS-IS" BASIS. CARNEGIE MELLON UNIVERSITY MAKES NO WARRANTIES OF ANY
* KIND, EITHER EXPRESSED OR IMPLIED, AS TO ANY MATTER INCLUDING, BUT NOT LIMITED TO, WARRANTY OF FITNESS FOR PURPOSE
* OR MERCHANTABILITY, EXCLUSIVITY, OR RESULTS OBTAINED FROM USE OF THE MATERIAL. CARNEGIE MELLON UNIVERSITY DOES NOT
* MAKE ANY WARRANTY OF ANY KIND WITH RESPECT TO FREEDOM FROM PATENT, TRADEMARK, OR COPYRIGHT INFRINGEMENT.
*
* This program and the accompanying materials are made available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
* SPDX-License-Identifier: EPL-2.0
*
* Created, in part, with funding and support from the United States Government. (see Acknowledgments file).
*
* This program includes and/or can make use of certain third party source code, object code, documentation and other
* files ("Third Party Software"). The Third Party Software that is used by this program is dependent upon your system
* configuration. By using this program, You agree to comply with any and all relevant Third Party Software terms and
* conditions contained in any such Third Party Software or separate license file distributed with such Third Party
* Software. The parties who own the Third Party Software ("Third Party Licensors") are intended third party benefici-
* aries to this license with respect to the terms applicable to their Third Party Software. Third Party Software li-
* censes only apply to the Third Party Software and not any other portion of this program or this program as a whole.
*/
package org.osate.aadl2.errormodel.faulttree.util;
import java.util.Collection;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.jobs.Job;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.transaction.RecordingCommand;
import org.eclipse.emf.transaction.TransactionalEditingDomain;
import org.eclipse.sirius.business.api.componentization.ViewpointRegistry;
import org.eclipse.sirius.business.api.modelingproject.AbstractRepresentationsFileJob;
import org.eclipse.sirius.business.api.modelingproject.ModelingProject;
import org.eclipse.sirius.business.api.query.DViewQuery;
import org.eclipse.sirius.business.api.query.ViewpointQuery;
import org.eclipse.sirius.business.api.session.Session;
import org.eclipse.sirius.business.api.session.SessionManager;
import org.eclipse.sirius.business.api.session.SessionStatus;
import org.eclipse.sirius.ext.base.Option;
import org.eclipse.sirius.ui.business.api.dialect.DialectUIManager;
import org.eclipse.sirius.ui.business.api.session.IEditingSession;
import org.eclipse.sirius.ui.business.api.session.SessionUIManager;
import org.eclipse.sirius.ui.business.api.viewpoint.ViewpointSelectionCallback;
import org.eclipse.sirius.ui.tools.api.project.ModelingProjectManager;
import org.eclipse.sirius.ui.tools.api.views.ViewHelper;
import org.eclipse.sirius.ui.tools.internal.actions.creation.CreateRepresentationAction;
import org.eclipse.sirius.ui.tools.internal.views.common.SessionLabelProvider;
import org.eclipse.sirius.ui.tools.internal.views.common.modelingproject.OpenRepresentationsFileJob;
import org.eclipse.sirius.viewpoint.DAnalysis;
import org.eclipse.sirius.viewpoint.DRepresentation;
import org.eclipse.sirius.viewpoint.DView;
import org.eclipse.sirius.viewpoint.description.RepresentationDescription;
import org.eclipse.sirius.viewpoint.description.Viewpoint;
import org.eclipse.swt.widgets.Display;
/**
* Utilities around Sirius, sessions and representations
*
* @author St?phane Thibaudeau <stephane.thibaudeau@obeo.fr>
*
*/
@SuppressWarnings("restriction")
public class SiriusUtil {
public static SiriusUtil INSTANCE = new SiriusUtil();
private SiriusUtil() {
super();
}
/**
*
* @param session
* @param monitor
*/
public void saveSession(Session session, IProgressMonitor monitor) {
if (SessionStatus.DIRTY.equals(session.getStatus())) {
session.save(monitor);
}
}
public Viewpoint getViewpoint(final Session session, URI viewpointURI, final IProgressMonitor monitor) {
Viewpoint result = getViewpointFromSession(session, viewpointURI);
if (result != null) {
return result;
}
ViewpointRegistry registry = ViewpointRegistry.getInstance();
try {
final Viewpoint regViewpoint = registry.getViewpoint(viewpointURI);
// make sure it is selected
if (regViewpoint != null) {
IEditingSession uiSession = SessionUIManager.INSTANCE.getOrCreateUISession(session);
uiSession.open();
// Ensure the viewpoint is selected for the session
session.getTransactionalEditingDomain().getCommandStack()
.execute(new RecordingCommand(session.getTransactionalEditingDomain()) {
@Override
protected void doExecute() {
// Check if already selected
if (!session.getSelectedViewpoints(false).contains(regViewpoint)) {
ViewpointSelectionCallback selection = new ViewpointSelectionCallback();
selection.selectViewpoint(regViewpoint, session, monitor);
}
}
});
}
} catch (Exception e) {
// Unable to retrieve viewpoint
}
return getViewpointFromSession(session, viewpointURI);
}
public Viewpoint getViewpointFromSession(Session session, URI viewpointURI) {
String viewpointName = viewpointURI.lastSegment();
Collection<Viewpoint> viewpoints = session.getSelectedViewpoints(false);
for (Viewpoint viewpoint : viewpoints) {
if (viewpointName.endsWith(viewpoint.getName())) {
return viewpoint;
}
}
return null;
}
/**
* Retrieves a viewpoint from its URI
* @param viewpointURI
* @return Viewpoint from the viewpoints registry
*/
public Viewpoint getViewpointFromRegistry(URI viewpointURI) {
ViewpointRegistry registry = ViewpointRegistry.getInstance();
try {
return registry.getViewpoint(viewpointURI);
} catch (Exception e) {
// Unable to retrieve viewpoint
}
return null;
}
/**
* Retrieves a representation description
* @param viewpoint
* @param id Id of the representation description (the id is set in the odesign model)
* @return
*/
public RepresentationDescription getRepresentationDescription(Viewpoint viewpoint, String id) {
for (RepresentationDescription description : new ViewpointQuery(viewpoint).getAllRepresentationDescriptions()) {
if (id.equals(description.getName())) {
return description;
}
}
return null;
}
public DRepresentation findRepresentation(final Session existingSession, final Viewpoint viewpoint,
final RepresentationDescription description, final String representationName) {
// Step 2: get the DRepresentation to open
DAnalysis root = (DAnalysis) existingSession.getSessionResource().getContents().get(0);
for (DView dView : root.getOwnedViews()) {
if (dView.getViewpoint().getName().equals(viewpoint.getName())) {
DViewQuery q = new DViewQuery(dView);
List<DRepresentation> myRepresentations = q.getLoadedRepresentations();
for (DRepresentation dRepresentation : myRepresentations) {
if (representationName.equalsIgnoreCase(dRepresentation.getName())) {
return dRepresentation;
}
}
}
}
return null;
}
/**
* Creates and opens a representation on the specified object
* @param existingSession Sirius session
* @param viewpoint Viewpoint containing the representation description
* @param description Representation description used to indicate which kind of representation to create
* @param representationName Name of the new representation
* @param object Semantic object
* @param monitor Progress monitor
*/
public void createAndOpenRepresentation(final Session existingSession, final Viewpoint viewpoint,
final RepresentationDescription description, final String representationName, final EObject object,
final IProgressMonitor monitor) {
// Create and open the representation
Display.getDefault().syncExec(() -> {
CreateRepresentationAction action = new CreateRepresentationAction(existingSession, object, description,
new SessionLabelProvider(ViewHelper.INSTANCE.createAdapterFactory())) {
@Override
protected String getRepresentationName() {
return representationName;
}
};
action.run();
});
}
/**
* Returns a session for the project. The session is loaded and references the URI as a semantid resource
* @param project
* @param semanticResourceURI
* @param monitor
* @return loaded session or null
*/
public Session getSessionForProjectAndResource(IProject project, URI semanticResourceURI,
IProgressMonitor monitor) {
// find existing session for semantic resource URI
Session existingSession = getSessionForSemanticURI(semanticResourceURI);
if (existingSession != null) {
return existingSession;
}
final Option<ModelingProject> prj = ModelingProject.asModelingProject(project);
if (prj.some()) {
// get session from modeling project
ModelingProject modelingProject = prj.get();
existingSession = modelingProject.getSession();
// make sure it is loaded
if (existingSession == null) {
loadSession(modelingProject, monitor);
waitWhileSessionLoads(monitor);
existingSession = modelingProject.getSession();
}
if (existingSession != null) {
// add semantic resource URI
addSemanticResource(existingSession, semanticResourceURI, monitor);
return existingSession;
}
}
// search through all sessions in the workspace
for (Session session : SessionManager.INSTANCE.getSessions()) {
ResourceSet set = session.getTransactionalEditingDomain().getResourceSet();
for (Resource res : set.getResources()) {
if (res.getURI() != null) {
if (set.getURIConverter().normalize(res.getURI())
.equals(set.getURIConverter().normalize(semanticResourceURI))) {
existingSession = session;
}
}
}
}
if (existingSession != null) {
addSemanticResource(existingSession, semanticResourceURI, monitor);
return existingSession;
}
return existingSession;
}
/**
* Adds a resource as a semantic resource for the session
* @param session
* @param semanticResourceURI
* @param monitor
*/
private void addSemanticResource(final Session session, final URI semanticResourceURI,
final IProgressMonitor monitor) {
Resource resource = getResourceFromSession(session, semanticResourceURI);
if (resource == null) {
TransactionalEditingDomain ted = session.getTransactionalEditingDomain();
ted.getCommandStack().execute(new RecordingCommand(ted) {
@Override
protected void doExecute() {
session.addSemanticResource(semanticResourceURI, monitor);
}
});
}
}
/**
* Retrieves the Sirius session referencing the URI as a semantic resource
*
* @param uri URI of the potential semantic resource
* @return the Sirius session or null if no corresponding session was found
*/
public Session getSessionForSemanticURI(URI uri) {
for (Session session : SessionManager.INSTANCE.getSessions()) {
ResourceSet set = session.getTransactionalEditingDomain().getResourceSet();
// Loop on resources to check if the URI matches one of the semantic resources
for (Resource res : set.getResources()) {
if (res.getURI() != null) {
if (set.getURIConverter().normalize(res.getURI()).equals(uri)) {
return session;
}
}
}
}
return null;
}
/**
* Loads a Sirius session for a modeling project
* @param project
* @param monitor
*/
private void loadSession(ModelingProject project, IProgressMonitor monitor) {
Option<URI> optionalMainSessionFileURI = project.getMainRepresentationsFileURI(monitor, false, false);
if (optionalMainSessionFileURI.some()) {
// Load the main representations file of this modeling
// project if it's not already loaded or during loading.
ModelingProjectManager.INSTANCE.loadAndOpenRepresentationsFile(optionalMainSessionFileURI.get());
}
}
/**
* Waits until all sessions are loaded
* @param monitor
*/
private void waitWhileSessionLoads(IProgressMonitor monitor) {
if (OpenRepresentationsFileJob.shouldWaitOtherJobs()) {
// We are loading session(s), wait loading is finished
// before continuing.
try {
Job.getJobManager().join(AbstractRepresentationsFileJob.FAMILY, monitor);
} catch (InterruptedException e) {
// Do nothing
}
}
}
/**
* Returns a session's semantic resource from its URI
* @param session
* @param uri
* @return the semantic resource or null if the session references no resource with the specified URI
*/
public Resource getResourceFromSession(Session session, URI uri) {
ResourceSet set = session.getTransactionalEditingDomain().getResourceSet();
URI normalizeduri = set.getURIConverter().normalize(uri);
for (Resource resource : session.getSemanticResources()) {
if (resource.getURI() != null) {
if (set.getURIConverter().normalize(resource.getURI()).equals(normalizeduri)) {
return resource;
}
}
}
return null;
}
public String getPrintName(EObject obj) {
Object res = obj.eGet(obj.eClass().getEStructuralFeature("name"));
if (res != null) {
return (String) res;
}
return obj.eResource().getURI().trimFileExtension().toString();
}
/**
* Opens a model targetroot with the specified viewpoint and representation. Creates representation if necessary
* * @param targetroot root of EMF based model
* @param project
* @param viewpoint
* @param representation
* @param monitor
*/
public void autoOpenModel(final EObject targetroot, final IProject project, final String viewPoint,
final String representation, final String jobName) {
IProgressMonitor monitor = new NullProgressMonitor();
URI viewpointURI = URI.createURI(viewPoint);
URI semanticResourceURI = targetroot.eResource().getURI();
// enable Modeling Nature
if (!ModelingProject.hasModelingProjectNature(project)) {
try {
ModelingProjectManager.INSTANCE.convertToModelingProject(project, monitor);
} catch (Exception e) {
}
}
Session existingSession = getSessionForProjectAndResource(project, semanticResourceURI, monitor);
if (existingSession != null) {
EObject model = getModelFromSession(existingSession, semanticResourceURI);
// XXX this next piece of code tries to compensate for a bug in Sirius where it cannot find the model
// It should be there since the getSessionForProjectandResource would have put it there.
if (model == null) {
model = targetroot;
}
final Viewpoint vPoint = getViewpoint(existingSession, viewpointURI, monitor);
final RepresentationDescription description = getRepresentationDescription(vPoint, representation);
String modelRootName = getPrintName(model);
String representationName = modelRootName + " " + representation;
DRepresentation rep = findRepresentation(existingSession, vPoint, description, representationName);
if (rep == null) {
try {
createAndOpenRepresentation(existingSession, vPoint, description, representationName, model,
monitor);
saveSession(existingSession, monitor);
project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
} catch (Exception e) {
}
} else {
try {
DialectUIManager.INSTANCE.openEditor(existingSession, rep, monitor);
saveSession(existingSession, monitor);
project.refreshLocal(IResource.DEPTH_INFINITE, monitor);
} catch (Exception e) {
}
}
}
if (ModelingProject.hasModelingProjectNature(project)) {
try {
ModelingProjectManager.INSTANCE.removeModelingNature(project, monitor);
} catch (Exception e) {
}
}
}
/**
* Retrieves a Model instance from a semantic resource
* The model element must be one of the root objects in the specified semantic resource
* @param session
* @param uri
* @return
*/
private EObject getModelFromSession(Session session, URI uri) {
Resource resource = SiriusUtil.INSTANCE.getResourceFromSession(session, uri);
if (resource != null && !resource.getContents().isEmpty()) {
return resource.getContents().get(0);
}
return null;
}
}