blob: f4a69b6b46ecc3739f3d6d79b42015927e1d1304 [file] [log] [blame]
/**
* Copyright (c) 2005-2007 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v2.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v20.html
*
* Contributors:
* IBM - Initial API and implementation
*/
package org.eclipse.emf.importer;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.eclipse.core.resources.IWorkspaceRunnable;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.NullProgressMonitor;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.emf.codegen.ecore.Generator;
import org.eclipse.emf.codegen.ecore.genmodel.GenJDKLevel;
import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
import org.eclipse.emf.codegen.ecore.genmodel.GenPackage;
import org.eclipse.emf.codegen.ecore.genmodel.util.GenModelUtil;
import org.eclipse.emf.codegen.util.CodeGenUtil;
import org.eclipse.emf.codegen.util.CodeGenUtil.EclipseUtil.StreamProgressMonitor;
import org.eclipse.emf.common.util.BasicMonitor;
import org.eclipse.emf.common.util.DiagnosticException;
import org.eclipse.emf.common.util.Monitor;
import org.eclipse.emf.common.util.URI;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.EcorePackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.importer.util.ImporterUtil;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
/**
* @since 2.1.0
*/
public abstract class ModelImporterApplication implements IApplication
{
protected ModelImporter modelImporter;
protected String modelLocations;
protected IPath genModelFullPath;
protected boolean reload = false;
protected IPath modelProjectLocationPath;
protected IPath modelFragmentPath;
protected IPath editProjectLocationPath;
protected IPath editFragmentPath;
protected IPath editorProjectLocationPath;
protected IPath editorFragmentPath;
protected IPath testsProjectLocationPath;
protected IPath testsFragmentPath;
protected String templatePath;
protected String copyright;
protected boolean sdo = false;
protected String modelPluginID;
protected String validateModel;
protected GenJDKLevel genJDKLevel;
protected boolean importOrganizing;
protected List<EPackage> referencedEPackages;
protected Map<URI, Set<String>> referencedGenModelURIToEPackageNSURIs;
protected boolean quiet = false;
public ModelImporter getModelImporter()
{
if (modelImporter == null)
{
modelImporter = createModelImporter();
}
return modelImporter;
}
protected abstract ModelImporter createModelImporter();
public Object start(IApplicationContext context) throws Exception
{
String [] args = (String[])context.getArguments().get(IApplicationContext.APPLICATION_ARGS);
return run(args == null ? new String [0] : args);
}
public void stop()
{
// Subclasses may override
}
public Object run(final Object args) throws Exception
{
try
{
IWorkspaceRunnable runnable = new IWorkspaceRunnable()
{
public void run(IProgressMonitor progressMonitor) throws CoreException
{
try
{
ModelImporterApplication.this.run(progressMonitor, (String[])args);
}
catch (Exception exception)
{
throw new CoreException(new Status(
IStatus.ERROR,
ImporterPlugin.ID,
0,
"Error",
exception));
}
finally
{
progressMonitor.done();
}
}
};
ResourcesPlugin.getWorkspace().run(runnable, getProgressMonitor());
return 0;
}
catch (Exception exception)
{
if (!quiet)
{
exception.printStackTrace();
}
ImporterPlugin.INSTANCE.log(exception);
return 1;
}
}
protected IProgressMonitor getProgressMonitor()
{
return quiet ? new NullProgressMonitor() : new StreamProgressMonitor(System.out);
}
public void run(IProgressMonitor progressMonitor, String[] arguments) throws Exception
{
run(BasicMonitor.toMonitor(progressMonitor), arguments);
}
public void run(Monitor monitor, String[] arguments) throws Exception
{
try
{
monitor.beginTask("", 1);
if (arguments.length == 0 || "-help".equalsIgnoreCase(arguments[0].toString()))
{
printUsage();
}
else
{
processArguments(arguments, "-pdelaunch".equals(arguments[0]) ? 1 : 0);
execute(CodeGenUtil.createMonitor(monitor, 1));
}
}
finally
{
monitor.done();
}
}
public void printUsage()
{
System.out.println(getUsage());
}
protected abstract StringBuffer getUsage();
protected static final String NL = System.getProperties().getProperty("line.separator");
protected StringBuffer appendLine(StringBuffer buffer, String line)
{
if (line != null)
{
buffer.append(line);
}
buffer.append(NL);
return buffer;
}
public void execute(Monitor monitor) throws Exception
{
try
{
monitor.beginTask("", 6);
adjustAttributes(CodeGenUtil.createMonitor(monitor, 1));
adjustModelImporter(CodeGenUtil.createMonitor(monitor, 1));
computeEPackages(CodeGenUtil.createMonitor(monitor, 1));
adjustEPackages(CodeGenUtil.createMonitor(monitor, 1));
adjustGenModel(CodeGenUtil.createMonitor(monitor, 1));
doExecute(CodeGenUtil.createMonitor(monitor, 1));
}
finally
{
monitor.done();
}
}
protected void processArguments(String[] arguments, int index)
{
index = processModelAndGenModelLocationArguments(arguments, index);
while (index < arguments.length)
{
index = processArgument(arguments, index);
}
}
protected int processModelAndGenModelLocationArguments(String[] arguments, int index)
{
StringBuffer locations = new StringBuffer();
URI firstModelURI = null;
while (arguments.length > index && arguments[index] != null && !arguments[index].startsWith("-"))
{
String location = arguments[index++];
if (location.endsWith(".genmodel"))
{
genModelFullPath = new Path(new File(location).getAbsolutePath());
break;
}
else
{
File file = new File(location);
if (file.isFile())
{
try
{
location = URI.createFileURI(file.getCanonicalPath()).toString();
}
catch (IOException e)
{
location = URI.createFileURI(file.getAbsolutePath()).toString();
}
}
if (firstModelURI == null)
{
firstModelURI = URI.createURI(location);
}
locations.append(" ").append(location);
}
}
if (firstModelURI != null)
{
modelLocations = locations.deleteCharAt(0).toString(); // removing the first space
if (genModelFullPath == null)
{
genModelFullPath =
new Path(new File(firstModelURI.trimFileExtension().appendFileExtension("genmodel").lastSegment()).getAbsolutePath());
}
}
return index;
}
protected int processModelProjectArguments(String[] arguments, int index)
{
modelProjectLocationPath = new Path(new File(arguments[++index]).getAbsolutePath());
modelFragmentPath = new Path(arguments[++index]);
return index;
}
protected int processArgument(String[] arguments, int index)
{
if (arguments[index].equalsIgnoreCase("-reload"))
{
reload = true;
}
else if (arguments[index].equalsIgnoreCase("-modelProject"))
{
index = processModelProjectArguments(arguments, index);
}
else if (arguments[index].equalsIgnoreCase("-editProject"))
{
editProjectLocationPath = new Path(new File(arguments[++index]).getAbsolutePath());
editFragmentPath = new Path(arguments[++index]);
}
else if (arguments[index].equalsIgnoreCase("-editorProject"))
{
editorProjectLocationPath = new Path(new File(arguments[++index]).getAbsolutePath());
editorFragmentPath = new Path(arguments[++index]);
}
else if (arguments[index].equalsIgnoreCase("-testsProject"))
{
testsProjectLocationPath = new Path(new File(arguments[++index]).getAbsolutePath());
testsFragmentPath = new Path(arguments[++index]);
}
else if (arguments[index].equalsIgnoreCase("-modelPluginID"))
{
modelPluginID = arguments[++index];
}
else if (arguments[index].equalsIgnoreCase("-copyright"))
{
copyright = arguments[++index];
}
else if (arguments[index].equalsIgnoreCase("-sdo"))
{
sdo = true;
}
else if (arguments[index].equalsIgnoreCase("-quiet"))
{
quiet = true;
}
else if (arguments[index].equalsIgnoreCase("-templatePath"))
{
templatePath = URI.createFileURI(new File(arguments[++index]).getAbsolutePath()).toString();
}
else if (arguments[index].equalsIgnoreCase("-jdkLevel"))
{
genJDKLevel = GenJDKLevel.get(arguments[++index]);
}
else if (arguments[index].equalsIgnoreCase("-importOrganizing"))
{
importOrganizing = true;
}
else if (arguments[index].equalsIgnoreCase("-validateModel"))
{
validateModel = arguments[++index];
}
else if (arguments[index].equalsIgnoreCase("-refGenModel"))
{
if (referencedGenModelURIToEPackageNSURIs == null)
{
referencedGenModelURIToEPackageNSURIs = new HashMap<URI, Set<String>>();
}
URI genModelURI = URI.createURI(arguments[++index]);
Set<String> ePackageNSURIs = referencedGenModelURIToEPackageNSURIs.get(genModelURI);
if (ePackageNSURIs == null)
{
ePackageNSURIs = new HashSet<String>();
referencedGenModelURIToEPackageNSURIs.put(genModelURI, ePackageNSURIs);
}
do
{
ePackageNSURIs.add(arguments[++index]);
}
while (index + 1 < arguments.length && !arguments[index + 1].startsWith("-"));
}
else
{
handleUnrecognizedArgument(arguments[index]);
}
return index + 1;
}
protected void handleUnrecognizedArgument(String argument)
{
throw new IllegalArgumentException("Unrecognized argument: '" + argument + "'");
}
protected void adjustAttributes(Monitor monitor)
{
if (!reload)
{
try
{
monitor.beginTask("", 1);
if (modelProjectLocationPath == null)
{
modelProjectLocationPath = new Path(new File(".").getAbsolutePath());
}
if (modelFragmentPath == null)
{
modelFragmentPath = new Path(".");
}
}
finally
{
monitor.done();
}
}
}
protected boolean usePlatformURI()
{
return false;
}
protected void adjustModelImporter(Monitor monitor)
{
try
{
monitor.beginTask("", 1);
ModelImporter modelImporter = getModelImporter();
modelImporter.setUsePlatformURI(usePlatformURI());
modelImporter.setGenModelProjectLocation(modelProjectLocationPath);
if (modelPluginID != null)
{
modelImporter.setModelPluginID(modelPluginID);
}
if (modelProjectLocationPath != null && modelFragmentPath != null)
{
modelImporter.setModelPluginDirectory(modelProjectLocationPath + "/./" + modelFragmentPath + "/.");
}
handleGenModelPath(genModelFullPath);
modelImporter.setModelLocation(modelLocations);
}
finally
{
monitor.done();
}
}
protected void handleGenModelPath(IPath genModelFullPath)
{
ModelImporter modelImporter = getModelImporter();
if (reload)
{
try
{
modelImporter.defineOriginalGenModelPath(genModelFullPath);
}
catch (DiagnosticException exception)
{
throw new RuntimeException(exception);
}
}
else
{
modelImporter.setGenModelContainerPath(genModelFullPath.removeLastSegments(1));
modelImporter.setGenModelFileName(genModelFullPath.lastSegment());
}
}
protected final void computeEPackages(Monitor monitor) throws Exception
{
try
{
monitor.beginTask("", 1);
getModelImporter().computeEPackages(CodeGenUtil.createMonitor(monitor, 1));
}
finally
{
monitor.done();
}
}
protected void adjustEPackages(Monitor monitor)
{
try
{
monitor.beginTask("", 1);
if (referencedGenModelURIToEPackageNSURIs != null)
{
ResourceSet resourceSet = getModelImporter().createResourceSet();
for (Map.Entry<URI, Set<String>> entry : referencedGenModelURIToEPackageNSURIs.entrySet())
{
URI genModelURI = entry.getKey();
Set<String> ePackageNSURIs = entry.getValue();
File genModelFile = new File(genModelURI.toString());
if (genModelFile.isFile())
{
IPath genModelPath = new Path(genModelFile.getAbsolutePath());
genModelURI = URI.createFileURI(genModelPath.toOSString());
}
Resource resource = resourceSet.getResource(genModelURI, true);
GenModel referencedGenModel = GenModelUtil.getGenModel(resource);
for (GenPackage genPackage : referencedGenModel.getGenPackages())
{
if (ePackageNSURIs.contains(genPackage.getEcorePackage().getNsURI()))
{
getModelImporter().getReferencedGenPackages().add(genPackage);
}
}
}
}
}
finally
{
monitor.done();
}
}
protected void handleQualifiedEPackageName(EPackage ePackage)
{
String packageName = ePackage.getName();
int index = packageName.lastIndexOf(".");
if (index != -1)
{
getModelImporter().getEPackageImportInfo(ePackage).setBasePackage(packageName.substring(0, index));
ePackage.setName(packageName.substring(index + 1));
}
}
protected void handleEPackage(EPackage ePackage, boolean generate)
{
getModelImporter().getEPackageImportInfo(ePackage).setConvert(generate);
if (!generate)
{
// The referencedEPackages list is used to track the packages for
// which is necessary to create the stub GenModel. So if the ePackage
// is referenced by an existing GenPackage, it doesn't need to be added to
// referencedEPackages.
for (GenPackage genPackage : getModelImporter().getReferencedGenPackages())
{
if (genPackage.getEcorePackage() == ePackage || (genPackage.getNSURI() != null && genPackage.getNSURI().equals(ePackage.getNsURI())))
{
return;
}
}
if (referencedEPackages == null)
{
referencedEPackages = new ArrayList<EPackage>();
}
referencedEPackages.add(ePackage);
}
}
protected void adjustGenModel(Monitor monitor)
{
try
{
monitor.beginTask("", 1);
GenModel genModel = getModelImporter().getGenModel();
if (editProjectLocationPath != null)
{
genModel.setEditDirectory(editProjectLocationPath + "/./" + editFragmentPath + "/.");
}
if (editorProjectLocationPath != null)
{
genModel.setEditorDirectory(editorProjectLocationPath + "/./" + editorFragmentPath + "/.");
}
if (testsProjectLocationPath != null)
{
genModel.setTestsDirectory(testsProjectLocationPath + "/./" + testsFragmentPath + "/.");
}
if (templatePath != null)
{
genModel.setTemplateDirectory(templatePath);
genModel.setDynamicTemplates(true);
}
if (copyright != null)
{
genModel.setCopyrightText(copyright);
}
if (sdo)
{
setSDODefaults(genModel);
}
if (genJDKLevel != null)
{
genModel.setComplianceLevel(genJDKLevel);
}
if (importOrganizing)
{
genModel.setImportOrganizing(true);
}
if (validateModel != null)
{
genModel.setValidateModel(Boolean.parseBoolean(validateModel));
}
}
finally
{
monitor.done();
}
}
protected void setSDODefaults(GenModel genModel)
{
Generator.setSDODefaults(genModel);
}
protected void doExecute(Monitor monitor) throws Exception
{
try
{
monitor.beginTask("", 3);
getModelImporter().prepareGenModelAndEPackages(CodeGenUtil.createMonitor(monitor, 1));
adjustModelImporterAfterPrepare();
handleReferencedEPackages();
getModelImporter().saveGenModelAndEPackages(CodeGenUtil.createMonitor(monitor, 1));
}
finally
{
monitor.done();
}
}
protected void adjustModelImporterAfterPrepare()
{
GenModel genModel = getModelImporter().getGenModel();
if (genJDKLevel != null)
{
genModel.setComplianceLevel(genJDKLevel);
}
genModel.setImportOrganizing(importOrganizing);
if (!reload)
{
genModel.setOperationReflection(false);
genModel.setRootExtendsClass("org.eclipse.emf.ecore.impl.EObjectImpl");
}
// Subclasses may overwrite
}
/**
* Handles the referencedEPackages contributed by the -refPackage argument option.
*/
protected void handleReferencedEPackages()
{
// Add a dummy GenModel for referenced packages.
//
if (referencedEPackages != null && !referencedEPackages.isEmpty())
{
ModelImporter modelImporter = getModelImporter();
GenModel genModel = modelImporter.getGenModel();
Resource genModelResource = genModel.eResource();
GenModel referencedGenModel = (GenModel)EcoreUtil.create(genModel.eClass());
genModelResource.getContents().add(referencedGenModel);
referencedGenModel.initialize(referencedEPackages);
ImporterUtil.addUniqueGenPackages(genModel.getUsedGenPackages(), referencedGenModel.getGenPackages());
referencedGenModel.getForeignModel().addAll(genModel.getForeignModel());
modelImporter.traverseGenPackages(referencedGenModel.getGenPackages());
for (Iterator<GenPackage> i = referencedGenModel.getGenPackages().iterator(); i.hasNext();)
{
GenPackage genPackage = i.next();
EPackage ePackage = genPackage.getEcorePackage();
if (ePackage.eResource() == null)
{
modelImporter.addToResource(ePackage, genModelResource.getResourceSet());
}
// Special case for a reference to Ecore to ensure that flag settings are respected and are set only for Ecore itself.
//
if (EcorePackage.eNS_URI.equals(ePackage.getNsURI()))
{
if (referencedGenModel.getGenPackages().size() == 1)
{
referencedGenModel.setModelName("ecore");
referencedGenModel.setBooleanFlagsField("eFlags");
referencedGenModel.setBooleanFlagsReservedBits(8);
}
else
{
i.remove();
ImporterUtil.addUniqueGenPackages(referencedGenModel.getUsedGenPackages(), Collections.singletonList(genPackage));
GenModel ecoreGenModel = (GenModel)EcoreUtil.create(genModel.eClass());
genModel.eResource().getContents().add(ecoreGenModel);
ecoreGenModel.getGenPackages().add(genPackage);
ecoreGenModel.setBooleanFlagsField("eFlags");
ecoreGenModel.setBooleanFlagsReservedBits(8);
ecoreGenModel.getForeignModel().addAll(genModel.getForeignModel());
ecoreGenModel.setModelName("ecore");
}
}
else if (referencedGenModel.getModelName() == null)
{
referencedGenModel.setModelName(genPackage.getPackageName());
}
}
}
}
}