/******************************************************************************* * Copyright (c) 2010-2012, Abel Hegedus, Istvan Rath and Daniel Varro * 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: * Abel Hegedus - initial API and implementation *******************************************************************************/ package org.eclipse.viatra2.emf.incquery.testing.ui.handlers; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.apache.log4j.Logger; import org.eclipse.core.commands.AbstractHandler; import org.eclipse.core.commands.ExecutionEvent; import org.eclipse.core.commands.ExecutionException; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.NullProgressMonitor; import org.eclipse.emf.common.notify.Notifier; import org.eclipse.emf.common.ui.dialogs.WorkspaceResourceDialog; 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.incquery.testing.core.ModelLoadHelper; import org.eclipse.incquery.testing.core.SnapshotHelper; import org.eclipse.incquery.runtime.api.IPatternMatch; import org.eclipse.incquery.runtime.api.IncQueryEngine; import org.eclipse.incquery.runtime.api.IncQueryMatcher; import org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher.ObservablePatternMatcher; import org.eclipse.incquery.tooling.ui.queryexplorer.content.matcher.ObservablePatternMatcherRoot; import org.eclipse.jface.viewers.IStructuredSelection; import org.eclipse.jface.viewers.TreeSelection; import org.eclipse.ui.IEditorPart; import org.eclipse.ui.handlers.HandlerUtil; import org.eclipse.incquery.snapshot.EIQSnapshot.EIQSnapshotFactory; import org.eclipse.incquery.snapshot.EIQSnapshot.IncQuerySnapshot; import com.google.inject.Inject; /** * @author Abel Hegedus * */ public class SaveSnapshotHandler extends AbstractHandler { @Inject SnapshotHelper helper; @Inject ModelLoadHelper loader; @Inject private Logger logger; /* (non-Javadoc) * @see org.eclipse.core.commands.IHandler#execute(org.eclipse.core.commands.ExecutionEvent) */ @Override public Object execute(ExecutionEvent event) throws ExecutionException { IStructuredSelection selection = (IStructuredSelection) HandlerUtil.getCurrentSelection(event); if (selection instanceof TreeSelection) { saveSnapshot((TreeSelection) selection, event); } return null; } private void saveSnapshot(TreeSelection selection, ExecutionEvent event) { Object obj = selection.getFirstElement(); IEditorPart editor = null; List<ObservablePatternMatcher> matchers = new ArrayList<ObservablePatternMatcher>(); IncQueryEngine engine = null; if(obj instanceof ObservablePatternMatcher) { ObservablePatternMatcher observablePatternMatcher = (ObservablePatternMatcher) obj; editor = observablePatternMatcher.getParent().getEditorPart(); matchers.add(observablePatternMatcher); IncQueryMatcher<?> matcher = observablePatternMatcher.getMatcher(); if(matcher != null) { engine = matcher.getEngine(); } } else if(obj instanceof ObservablePatternMatcherRoot) { ObservablePatternMatcherRoot matcherRoot = (ObservablePatternMatcherRoot) obj; editor = matcherRoot.getEditorPart(); if(matcherRoot.getMatchers().size() > 0) { matchers.addAll(matcherRoot.getMatchers()); for (ObservablePatternMatcher obsMatcher : matcherRoot.getMatchers()) { IncQueryMatcher<?> matcher = obsMatcher.getMatcher(); if(matcher != null && matcher.getEngine() != null) { engine = matcher.getEngine(); break; } } } } if(engine == null) { logger.error("Cannot save snapshot without IncQueryEngine!"); return; } ResourceSet resourceSet = getResourceSetForNotifier(engine.getEmfRoot()); if(resourceSet == null) { engine.getLogger().error("Cannot save snapshot, models not in ResourceSet!"); return; } IFile snapshotFile = null; IFile[] files = WorkspaceResourceDialog.openFileSelection(HandlerUtil.getActiveShell(event), "Existing snapshot", "Select existing EMF-IncQuery snapshot file (Cancel for new file)", false, null, null); IncQuerySnapshot snapshot = null; if(files.length == 0) { snapshotFile = WorkspaceResourceDialog.openNewFile(HandlerUtil.getActiveShell(event), "New snapshot", "Select EMF-IncQuery snapshot target file (.eiqsnapshot extension)", null, null); if(snapshotFile != null && !snapshotFile.exists()) { snapshot = EIQSnapshotFactory.eINSTANCE.createIncQuerySnapshot(); Resource res = resourceSet.createResource(URI.createPlatformResourceURI(snapshotFile.getFullPath().toString(),true)); res.getContents().add(snapshot); } else { engine.getLogger().error("Selected file name must use .eiqsnapshot extension!"); return; } } else { snapshotFile = files[0]; if(snapshotFile != null && snapshotFile.getFileExtension().equals("eiqsnapshot")) { snapshot = loader.loadExpectedResultsFromFile(resourceSet,snapshotFile); if(snapshot != null) { if(!validateInputSpecification(engine, snapshot)) { return; } } else { engine.getLogger().error("Selected file does not contain snapshot!"); return; } } else { engine.getLogger().error("Selected file not .eiqsnapshot!"); return; } } for (ObservablePatternMatcher matcher : matchers) { IPatternMatch filter = matcher.getMatcher().arrayToMatch(matcher.getFilter()); if(matcher.getMatcher() != null) { helper.saveMatchesToSnapshot(matcher.getMatcher(), filter, snapshot); } } if(editor != null) { editor.doSave(new NullProgressMonitor()); } else { try { snapshot.eResource().save(null); } catch(IOException e) { engine.getLogger().error("Error during saving snapshot into file!",e); } } } /** * @param engine * @param snapshot */ private boolean validateInputSpecification(IncQueryEngine engine, IncQuerySnapshot snapshot) { if(snapshot.getInputSpecification() != null) { Notifier root = helper.getEMFRootForSnapshot(snapshot); Notifier matcherRoot = engine.getEmfRoot(); if(matcherRoot != root) { engine.getLogger().error("Existing snapshot model root (" + root + ") not equal to selected input (" + matcherRoot + ")!"); return false; } return true; /*switch(snapshot.getInputSpecification()) { case EOBJECT: if(matcherRoot instanceof EObject && root instanceof EObject) { if(matcherRoot != root) { engine.getLogger().logError("Existing snapshot model root (" + root + ") not equal to selected input (" + matcherRoot + ")!"); } } break; case RESOURCE: if(matcherRoot instanceof Resource && root instanceof Resource) { Resource res = (Resource) matcherRoot; for (EObject eobj : res.getContents()) { if(!snapshot.getModelRoots().contains(eobj)) { engine.getLogger().logError("Existing snapshot model root not equal to selected input! Missing model root: " + eobj); } } for(EObject eobj : snapshot.getModelRoots()) { if(!res.getContents().contains(eobj)) { engine.getLogger().logError("Existing snapshot model root not equal to selected input! Missing snapshot root: " + eobj); } } } break; case RESOURCE_SET: if(matcherRoot instanceof ResourceSet && root instanceof ResourceSet) { ResourceSet set = (ResourceSet) matcherRoot; for (Resource res : set.getResources()) { for (EObject eobj : res.getContents()) { if(!snapshot.getModelRoots().contains(eobj)) { engine.getLogger().logError("Existing snapshot model root not equal to selected input!"); } } } } break; }*/ } return true; } private ResourceSet getResourceSetForNotifier(Notifier notifier) { if(notifier instanceof EObject) { Resource resource = ((EObject) notifier).eResource(); if(resource != null) { return resource.getResourceSet(); } } else if(notifier instanceof Resource) { return ((Resource) notifier).getResourceSet(); } else if(notifier instanceof ResourceSet) { return (ResourceSet) notifier; } return null; } }