| /** |
| * 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()); |
| } |
| } |
| } |
| } |
| } |