/* * Copyright (c) 2006, 2007 Borland Software Corporation * * 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: * Artem Tikhomirov (Borland) - initial API and implementation * Alexander Fedorov (Borland) - #148836 - transform action as wizard */ package org.eclipse.gmf.internal.bridge.transform; import java.io.IOException; import java.util.Collection; import java.util.HashSet; import java.util.Iterator; import org.eclipse.core.resources.IFile; import org.eclipse.core.runtime.CoreException; import org.eclipse.core.runtime.IPath; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.Status; import org.eclipse.emf.codegen.ecore.genmodel.GenModel; import org.eclipse.emf.common.util.URI; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.resource.ContentHandler; import org.eclipse.emf.ecore.resource.Resource; import org.eclipse.emf.ecore.resource.ResourceSet; import org.eclipse.emf.ecore.resource.impl.ResourceSetImpl; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.gmf.internal.bridge.genmodel.BasicGenModelAccess; import org.eclipse.gmf.internal.bridge.genmodel.DummyGenModel; import org.eclipse.gmf.internal.bridge.genmodel.FileGenModelAccess; import org.eclipse.gmf.internal.bridge.genmodel.GenModelAccess; import org.eclipse.gmf.internal.bridge.ui.Plugin; import org.eclipse.gmf.mappings.Mapping; /** * Interact with user to retrieve genmodel for the domain model. XXX detect * stale genmodels and reconcile them based on user's decision * * @author artem */ public class GenModelDetector { private final Mapping myMapping; private GenModelAccess myGMAccess; private Collection<EPackage> myPackages; public GenModelDetector(Mapping mapping) { if (mapping == null) { throw new IllegalArgumentException("Could not detect with null Mapping"); } myMapping = mapping; } public IStatus detect() { myPackages = findEPackages(myMapping); if (myPackages.isEmpty()) { myGMAccess = new GenModelAccess.Adapter(null); return Status.OK_STATUS; } else if (myPackages.size() == 1) { final EPackage solePack = myPackages.iterator().next(); BasicGenModelAccess gma = new BasicGenModelAccess(solePack); gma.initDefault(); return apply(gma); } else { return Plugin.createError(Messages.GenModelDetector_e_not_found, null); } } public IStatus advise(URI genModelURI) { if (genModelURI == null) { throw new IllegalArgumentException("Null GenModel URI"); } GenModelAccess gma = new FileGenModelAccess(genModelURI); return apply(gma); } public IStatus advise(IFile workspaceFile) { if (workspaceFile == null) { throw new IllegalArgumentException("Null GenModel file"); } GenModelAccess gma = new FileGenModelAccess(workspaceFile); return apply(gma); } private Collection<EPackage> findEPackages(Mapping mapping) { Collection<EPackage> packages = new HashSet<EPackage>(); for (EObject next : EcoreUtil.ExternalCrossReferencer.find(mapping).keySet()) { if (next instanceof EClass) { packages.add(((EClass) next).getEPackage()); } } for (Iterator<EPackage> it = packages.iterator(); it.hasNext();) { EPackage next = it.next(); if (next.getESuperPackage() != null && EcoreUtil.isAncestor(packages, next.getESuperPackage())) { it.remove(); } } return packages; } private IStatus apply(GenModelAccess gma) { IStatus load = gma.load(new ResourceSetImpl()); if (load.isOK()) { gma.unload(); myGMAccess = gma; return Status.OK_STATUS; } else { return load; } } private EPackage getPrimaryPackage() { if (myPackages == null || myPackages.size() == 0) { return null; } return myPackages.iterator().next(); } public boolean canCreateDefault() { return myPackages != null && myPackages.size() == 1; } public URI createDefault(String pluginID, IFile patternResource) throws CoreException { DummyGenModel gma = new DummyGenModel(getPrimaryPackage(), null); gma.setPluginID(pluginID); GenModel model = gma.create(); IPath path = patternResource.getFullPath().removeFileExtension().addFileExtension("genmodel"); //$NON-NLS-1$ URI uri = URI.createPlatformResourceURI(path.toString(), true); Resource res = new ResourceSetImpl().createResource(uri, ContentHandler.UNSPECIFIED_CONTENT_TYPE); res.getContents().add(model); try { res.save(null); return uri; } catch (IOException ex) { IStatus error = Plugin.createError(Messages.GenModelDetector_e_save, ex); throw new CoreException(error); } } public GenModel get(ResourceSet resSet) { if (myGMAccess == null) { throw new IllegalStateException(Messages.GenModelDetector_e_no_genmodelaccess); } IStatus s = myGMAccess.load(resSet); if (!s.isOK()) { throw new IllegalStateException(s.getMessage()); } return myGMAccess.model(); } }