Java tutorial
/******************************************************************************* * Copyright (c) 2009, 2015 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.control; import java.io.IOException; import java.util.Collection; import java.util.Collections; import java.util.Set; import org.eclipse.core.runtime.IProgressMonitor; import org.eclipse.core.runtime.SubProgressMonitor; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.sirius.business.api.query.DAnalysisQuery; import org.eclipse.sirius.business.api.query.EObjectQuery; import org.eclipse.sirius.business.api.session.Session; import org.eclipse.sirius.business.api.session.SessionManager; import org.eclipse.sirius.business.api.session.danalysis.DAnalysisSession; import org.eclipse.sirius.business.internal.command.control.UncontrolCommand; import org.eclipse.sirius.viewpoint.DAnalysis; import org.eclipse.sirius.viewpoint.DRepresentation; import org.eclipse.sirius.viewpoint.Messages; import org.eclipse.sirius.viewpoint.SiriusPlugin; import com.google.common.collect.Iterables; import com.google.common.collect.Iterators; import com.google.common.collect.Lists; import com.google.common.collect.Sets; /** * An extension of the basic {@link UncontrolCommand} to handle both the * semantic model and the corresponding Sirius representations. Also handles * session state and modification-tracking management. * * @since 0.9.0 * * @author pcdavid */ public class SiriusUncontrolCommand extends UncontrolCommand { /** The session containing the models to modify. */ private final Session session; /** * A flag to indicate if we should uncontrol the representations in addition * to the semantic elements. */ private final boolean uncontrolRepresentations; /** * A boolean to set if the session should be save at the end of this * command. */ private final boolean shouldEndBySaving; private IProgressMonitor monitor; /** * Create a new {@link SiriusUncontrolCommand}. * * @param semanticRoot * the semantic model element to uncontrol. * @param uncontrolRepresentations * indicate if we should uncontrol the representations in * addition to the semantic elements. * @param monitor * a {@link IProgressMonitor} to show progression of uncontrol * operation * @deprecated use the other constructor instead, which requires mentioning * explicitly whether or not to save the session as part of the * command (most code should do the saving themselves outside of * the command). */ @Deprecated public SiriusUncontrolCommand(final EObject semanticRoot, final boolean uncontrolRepresentations, IProgressMonitor monitor) { this(semanticRoot, uncontrolRepresentations, true, monitor); } /** * Create a new {@link SiriusUncontrolCommand}. * * @param semanticRoot * the semantic model element to uncontrol. * @param uncontrolRepresentations * indicate if we should uncontrol the representations in * addition to the semantic elements. * @param shouldEndBySaving * A boolean to set if the session should be save at the end of * @param monitor * a {@link IProgressMonitor} to show progression of uncontrol * operation */ public SiriusUncontrolCommand(final EObject semanticRoot, final boolean uncontrolRepresentations, boolean shouldEndBySaving, IProgressMonitor monitor) { super(semanticRoot); this.uncontrolRepresentations = uncontrolRepresentations; this.session = SessionManager.INSTANCE.getSession(semanticRoot); this.shouldEndBySaving = shouldEndBySaving; this.monitor = monitor; } /** * Get root container of specified object.<br> * Default implementation consists in getting the resource container i.e the * first parent container serialized in its own resource. * * @param eObject * the current EObject. * @return should not be <code>null</code> */ protected EObject getRootContainer(EObject eObject) { return new EObjectQuery(eObject).getResourceContainer(); } /** * Execute the uncontrol action. */ @Override protected void doExecute() { try { monitor.beginTask(Messages.SiriusUncontrolCommand_label, 4); Resource childSemanticResource = semanticElementToUncontrol.eResource(); Resource childAirdResource = getChildAirdResource(); // get the parent aird resource before uncontrol. Resource parentAirdResource = getParentAirdResource(); // Uncontrol the semantic model super.doExecute(); monitor.worked(1); markContainerResourceAsModified(semanticElementToUncontrol.eContainer()); if (uncontrolRepresentations && childAirdResource != null) { moveRepresentations(childAirdResource, parentAirdResource, semanticElementToUncontrol.eResource()); } monitor.worked(1); cleanupChildrenResources(childSemanticResource, childAirdResource); monitor.worked(1); if (shouldEndBySaving) { session.save(new SubProgressMonitor(monitor, 1)); } } finally { monitor.done(); } } /** * Remove the children semantic and representation resources after * uncontrol, both from the session and from the disk, if they are empty. */ private void cleanupChildrenResources(final Resource childSemanticResource, final Resource childAirdResource) { notifySessionAboutUncontrolledResource(childSemanticResource); deleteResource(childSemanticResource); if (childAirdResource != null && uncontrolRepresentations && airdResourceHasNoRepresentations(childAirdResource)) { removeObsoleteAnalyis(childAirdResource); notifySessionAboutUncontrolledResource(childAirdResource); deleteResource(childAirdResource); } } private void removeObsoleteAnalyis(final Resource childAirdResource) { if (session instanceof DAnalysisSession) { ((DAnalysisSession) session).removeReferencedAnalysis(getDAnalysis(childAirdResource)); } } private boolean airdResourceHasNoRepresentations(final Resource childAirdResource) { return Iterators.size(Iterators.filter(EcoreUtil.getAllProperContents(childAirdResource, true), DRepresentation.class)) == 0; } private Resource getChildAirdResource() { return getAirdResourceWithAnalysisOn(semanticElementToUncontrol); } private Resource getParentAirdResource() { return getAirdResourceWithAnalysisOn(getRootContainer(semanticElementToUncontrol.eContainer())); } /** * Get the resource that contains the analysis which has the specified * object as main models references. * * @param object * The object to search. This object must be a root of a semantic * model. * @return the corresponding resource if found, false otherwise. */ protected Resource getAirdResourceWithAnalysisOn(final EObject object) { for (final Resource anResource : session.getAllSessionResources()) { for (final DAnalysis analysis : getAnalyses(anResource)) { Set<EObject> releventModels = new DAnalysisQuery(analysis).getMainModels(); if (Iterables.contains(releventModels, object)) { return anResource; } } } return null; } /** * Returns all DAnalysis among the roots of the specified resource. * * @param aird * the resource in which to search * @return list of DAnalysis of this resource */ protected Collection<DAnalysis> getAnalyses(final Resource aird) { final Collection<DAnalysis> analyses = Lists.newArrayList(); for (EObject root : aird.getContents()) { if (root instanceof DAnalysis) { analyses.add((DAnalysis) root); } } return analyses; } /** * Moves all the representations stored in <code>childResource</code> into * <code>parentResource</code>. */ private void moveRepresentations(final Resource childResource, final Resource parentResource, final Resource parentSemanticResource) { final Collection<DRepresentation> representations = collectExistingRepresentations(childResource); final DAnalysis parentAnalysis = getDAnalysis(parentResource); final DAnalysis childAnalysis = getDAnalysis(childResource); final DAnalysisSession aSession = (DAnalysisSession) session; for (final DRepresentation representation : representations) { aSession.moveRepresentation(parentAnalysis, representation); } if (childAnalysis != null) { parentAnalysis.getReferencedAnalysis().addAll(childAnalysis.getReferencedAnalysis()); } } private DAnalysis getDAnalysis(final Resource parentResource) { for (final EObject root : parentResource.getContents()) { if (root instanceof DAnalysis) { return (DAnalysis) root; } } return null; } private Collection<DRepresentation> collectExistingRepresentations(final Resource resource) { return Sets.newHashSet( Iterators.filter(EcoreUtil.getAllProperContents(resource, true), DRepresentation.class)); } private void markContainerResourceAsModified(final EObject obj) { EObject resourceContainer = getRootContainer(obj); if (obj != null && resourceContainer != null) { Resource containerResource = resourceContainer.eResource(); if (containerResource != null) { containerResource.setModified(true); } } } /** * Delete the physical workspace file underlying a resource, if any and * unload and remove this resource from its resourceSet. * * @param res * the resource to delete */ protected void deleteResource(final Resource res) { if (res != null) { try { res.save(Collections.emptyMap()); res.delete(Collections.emptyMap()); } catch (IOException e) { SiriusPlugin.getDefault().error(Messages.SiriusUncontrolCommand_resourceDeletionFailedMsg, e); } } } private void notifySessionAboutUncontrolledResource(final Resource controlledSemanticResource) { if (session instanceof DAnalysisSession) { ((DAnalysisSession) session).notifyUnControlledModel(semanticElementToUncontrol, controlledSemanticResource); } } }