blob: 1de68d866ee2a8f34834869db532ced113000c40 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2004 IBM Corporation and others.
* 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:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.wst.common.internal.emfworkbench.operation;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.MultiStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.SubProgressMonitor;
import org.eclipse.emf.codegen.ecore.genmodel.GenModel;
import org.eclipse.emf.codegen.ecore.genmodel.GenModelFactory;
import org.eclipse.emf.codegen.ecore.genmodel.GenPackage;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.Resource;
import org.eclipse.emf.ecore.util.EcoreUtil;
import org.eclipse.emf.importer.java.builder.JavaEcoreBuilder;
import org.eclipse.jem.util.emf.workbench.WorkbenchResourceHelperBase;
import org.eclipse.jem.util.logger.proxy.Logger;
import org.eclipse.wst.common.frameworks.internal.operations.WTPOperation;
import org.eclipse.xsd.XSDPackage;
import org.eclipse.xsd.XSDSchema;
import org.eclipse.xsd.ecore.XSDEcoreBuilder;
/**
* @author delfinoj
*
* Generates SDO DataObject classes.
*
*/
public class DataObjectGenerator extends WTPOperation {
protected IProject project;
protected List xmiPackages;
protected List javaModels;
protected XSDEcoreBuilder xsdECoreBuilder;
protected List ePackages;
/**
* @param operationDataModel
*/
public DataObjectGenerator(DataObjectGeneratorModel operationDataModel) {
super(operationDataModel);
}
/**
* Set the nsURI of the <code>ePackage</code> to be in the form
* "java://{fullyQualifiedPackageInterfaceName}. When this format is used, EMF will attempt to
* register the static package by loading the interface and calling the eINSTANCE field.
*
* @param ePackage
* @param fullyQualifiedPackageInterfaceName
*/
public static void setStaticPackageNsURI(EPackage ePackage, String fullyQualifiedPackageInterfaceName) {
if (ePackage != null && fullyQualifiedPackageInterfaceName != null)
ePackage.setNsURI("java://" + fullyQualifiedPackageInterfaceName);//$NON-NLS-1$
}
protected IProject getProject() {
if (project == null)
project = (IProject) operationDataModel.getProperty(DataObjectGeneratorModel.PROJECT);
return project;
}
protected XSDEcoreBuilder getXSDEcoreBuilder() {
if (xsdECoreBuilder == null)
xsdECoreBuilder = new XSDEcoreBuilder();
return xsdECoreBuilder;
}
/**
* @see com.ibm.etools.ctc.ant.task.util.BaseProjectBuilder#generate(org.eclipse.core.runtime.IProgressMonitor)
*/
protected boolean prepareGenerate() {
// Collect all generated EPackages
ePackages = new ArrayList();
// Packages generated from XSDs
if (xsdECoreBuilder != null)
ePackages.addAll(xsdECoreBuilder.getTargetNamespaceToEPackageMap().values());
// Packages loaded from XMI files
if (xmiPackages != null)
ePackages.addAll(xmiPackages);
if (javaModels != null)
prepareEPackagesFromJavaModels();
if (ePackages.isEmpty())
return false;
return true;
}
protected void prepareEPackagesFromJavaModels() {
// Generate packages from annotated java model files
JavaEcoreBuilder javaEcoreBuilder = new JavaEcoreBuilder(getProject().getFile(new Path("sdo.genmodel"))) { //$NON-NLS-1$
public void getAllGenModelFiles(Collection result, IFile file) throws CoreException {
// Ignore .genmodel files on the buildpath
return;
}
};
//TODO - Ecore builder api has changed....
//javaEcoreBuilder.run(new NullProgressMonitor(), false);
IStatus localStatus = javaEcoreBuilder.getStatus();
if (localStatus.getSeverity() != IStatus.ERROR) {
List genPackages = javaEcoreBuilder.getGenModel().getGenPackages();
processGenPackagesFromJavaModels(genPackages);
} else
logProblems(localStatus);
}
/**
* @param statusArg
*/
private void logProblems(IStatus statusArg) {
Logger logger = Logger.getLogger();
logger.logError("Problems detected generating SDO objects."); //$NON-NLS-1$
log(statusArg, logger);
}
private void log(IStatus statusArg, Logger logger) {
doLog(statusArg, logger);
if (statusArg.isMultiStatus()) {
MultiStatus mStatus = (MultiStatus) statusArg;
IStatus[] children = mStatus.getChildren();
for (int i = 0; i < children.length; i++) {
log(children[i], logger);
}
}
}
private void doLog(IStatus statusArg, Logger logger) {
switch (statusArg.getSeverity()) {
case IStatus.ERROR :
logger.logError(statusArg.getMessage());
break;
case IStatus.WARNING :
logger.logWarning(statusArg.getMessage());
break;
case IStatus.INFO :
logger.log(statusArg.getMessage());
break;
}
}
/**
* @param genPackages
*/
protected void processGenPackagesFromJavaModels(List genPackages) {
if (genPackages.isEmpty())
return;
for (Iterator i = genPackages.iterator(); i.hasNext();) {
GenPackage genPackage = (GenPackage) i.next();
EPackage ePackage = genPackage.getEcorePackage();
updateEPackageFromJavaModel(ePackage, genPackage);
ePackages.add(ePackage);
}
}
protected void updateEPackageFromJavaModel(EPackage ePackage, GenPackage genPackage) {
// Fix the ePackage name
ePackage.setName(ePackage.getNsPrefix());
setStaticPackageNsURI(ePackage, genPackage);
}
/**
* Since we are generating static Packages we need to set the nsURI of each EPackage to be in
* the form "java://{fully qualified package interface name}. When this format is used, EMF will
* attempt to register the static package by loading the interface and calling the eINSTANCE
* field.
*
* @param ePackage
* @param genPackage
*/
protected void setStaticPackageNsURI(EPackage ePackage, GenPackage genPackage) {
String interfaceName = genPackage.getPackageInterfaceName();
if (interfaceName != null) {
StringBuffer b = new StringBuffer();
b.append(genPackage.getPackageName()).append('.').append(interfaceName);
setStaticPackageNsURI(ePackage, b.toString());
}
}
/**
* @see com.ibm.etools.ctc.ant.task.util.BaseProjectBuilder#generate(org.eclipse.core.runtime.IProgressMonitor)
*/
protected void generate(IProgressMonitor progressMonitor) throws CoreException {
try {
progressMonitor.beginTask(getProject().getFullPath().toString(), 100);
// Create a GenModel
GenModel genModel = GenModelFactory.eINSTANCE.createGenModel();
initializeGenModel(genModel);
setPackagesOnGenModel(genModel);
// Validate the GenModel
IStatus localStatus = genModel.validate();
if (!localStatus.isOK())
throw new CoreException(localStatus);
doGenerate(progressMonitor, genModel);
progressMonitor.worked(100);
} finally {
progressMonitor.done();
}
}
/*
* Generate static code.
*/
protected void doGenerate(IProgressMonitor progressMonitor, GenModel genModel) {
try {
genModel.generate(new SubProgressMonitor(progressMonitor, 50));
} catch (Throwable e) {
e.printStackTrace();
}
}
/*
* Initialize the GenModel from the EPackages
*/
protected void setPackagesOnGenModel(GenModel genModel) {
genModel.initialize(ePackages);
for (Iterator i = genModel.getGenPackages().iterator(); i.hasNext();) {
GenPackage genPackage = (GenPackage) i.next();
genPackage.setLoadInitialization(false);
String prefix = genPackage.getInterfacePackageName();
prefix = prefix.substring(prefix.lastIndexOf('.') + 1);
if (prefix.length() > 1)
prefix = prefix.substring(0, 1).toUpperCase() + prefix.substring(1);
else
prefix = prefix.toUpperCase();
genPackage.setPrefix(prefix);
}
}
/**
* @param genModel
*/
protected void initializeGenModel(GenModel genModel) {
setSDODefaults(genModel);
genModel.setDynamicTemplates(operationDataModel.getBooleanProperty(DataObjectGeneratorModel.DYNAMIC_TEMPLATES));
genModel.setForceOverwrite(operationDataModel.getBooleanProperty(DataObjectGeneratorModel.FORCE_OVERWRITE));
genModel.setCanGenerate(operationDataModel.getBooleanProperty(DataObjectGeneratorModel.CAN_GENERATE));
genModel.setUpdateClasspath(operationDataModel.getBooleanProperty(DataObjectGeneratorModel.UPDATE_CLASSPATH));
genModel.setGenerateSchema(operationDataModel.getBooleanProperty(DataObjectGeneratorModel.GENERATE_SCHEMA));
genModel.setNonNLSMarkers(operationDataModel.getBooleanProperty(DataObjectGeneratorModel.NON_NLS_MARKERS));
IFolder modelDir = (IFolder) operationDataModel.getProperty(DataObjectGeneratorModel.MODEL_DIR);
genModel.setModelDirectory(modelDir.getFullPath().toOSString());
}
/*
* Options from SetDefaultSDOOptions, recommended by Ed
*/
protected void setSDODefaults(GenModel genModel) {
genModel.setRootExtendsInterface(""); //$NON-NLS-1$
//TODO why would you expose this internal interface in the generated code, instead of
// commonj.sdo.DataObject
genModel.setRootImplementsInterface("org.eclipse.emf.ecore.sdo.InternalEDataObject"); //$NON-NLS-1$
genModel.setRootExtendsClass("org.eclipse.emf.ecore.sdo.impl.EDataObjectImpl"); //$NON-NLS-1$
genModel.setFeatureMapWrapperInterface("commonj.sdo.Sequence"); //$NON-NLS-1$
genModel.setFeatureMapWrapperInternalInterface("org.eclipse.emf.ecore.sdo.util.ESequence"); //$NON-NLS-1$
genModel.setFeatureMapWrapperClass("org.eclipse.emf.ecore.sdo.util.BasicESequence"); //$NON-NLS-1$
genModel.setSuppressEMFTypes(true);
}
/*
* (non-Javadoc)
*
* @see org.eclipse.wst.common.frameworks.internal.operation.WTPOperation#execute(org.eclipse.core.runtime.IProgressMonitor)
*/
protected void execute(IProgressMonitor monitor) throws CoreException, InvocationTargetException, InterruptedException {
loadModelFiles(monitor);
if (prepareGenerate())
generate(monitor);
}
/**
* @param monitor
*/
protected void loadModelFiles(IProgressMonitor monitor) {
loadXSDFiles(monitor);
loadEcoreFiles(monitor);
//loadWSDLFiles(monitor);
loadJavaFiles(monitor);
}
/**
* Load an XSD and generate the eCore packages for each tracked XSD file.
*
* @param monitor
*/
protected void loadXSDFiles(IProgressMonitor monitor) {
if (operationDataModel.isSet(DataObjectGeneratorModel.XSD_FILES)) {
List files = (List) operationDataModel.getProperty(DataObjectGeneratorModel.XSD_FILES);
IFile file;
for (int i = 0; i < files.size(); i++) {
file = (IFile) files.get(i);
Resource resource = WorkbenchResourceHelperBase.load(file);
Collection xsdSchemas = EcoreUtil.getObjectsByType(resource.getContents(), XSDPackage.eINSTANCE.getXSDSchema());
for (Iterator j = xsdSchemas.iterator(); j.hasNext();) {
getXSDEcoreBuilder().generate((XSDSchema) j.next());
}
}
}
}
/**
* Load an Ecore model file and generate the eCore packages for each tracked Ecore file.
*
* @param monitor
*/
protected void loadEcoreFiles(IProgressMonitor monitor) {
if (operationDataModel.isSet(DataObjectGeneratorModel.ECORE_FILES)) {
List files = (List) operationDataModel.getProperty(DataObjectGeneratorModel.ECORE_FILES);
IFile file;
for (int i = 0; i < files.size(); i++) {
file = (IFile) files.get(i);
Resource resource = WorkbenchResourceHelperBase.getResource(file, true);
addXmiPackages(resource.getContents());
}
}
}
protected void addXmiPackages(List packages) {
if (xmiPackages == null)
xmiPackages = new ArrayList();
xmiPackages.addAll(packages);
}
/**
* Load the XSD files and generate the eCore packages for each tracked WSDL file.
*
* @param monitor
*/
protected void loadWSDLFiles(IProgressMonitor monitor) {
// if (operationDataModel.isSet(DataObjectGeneratorModel.WSDL_FILES)) {
// List files = (List) operationDataModel.getProperty(DataObjectGeneratorModel.WSDL_FILES);
// IFile file;
// for (int i = 0; i < files.size(); i++) {
// file = (IFile) files.get(i);
// //TODO We can't handle WSDL in WSAD 5.1 as the WSDL model is not an EMF 2.0 model
// // Re-activate this function when we move to 6.0
// // // Load a WSDL file and collect all the references XSD schemas
// // Set xsdSchemas=new HashSet();
// // URI uri = URI.createFileURI(file.getLocation().toString());
// // Resource resource = WorkbenchResourceHelper.getResource(uri);
// // for (Iterator i=resource.getAllContents(); i.hasNext(); ) {
// // Object object=i.next();
// // if (object instanceof XSDSchemaExtensibilityElement) {
// // XSDSchemaExtensibilityElement
// // extensibilityElement=(XSDSchemaExtensibilityElement)object;
// // XSDSchema xsdSchema=extensibilityElement.getEXSDSchema();
// // if (xsdSchema!=null)
// // xsdSchemas.add(xsdSchema);
// // } else if (object instanceof Part) {
// // Part part=(Part)object;
// // XSDNamedComponent xsdComponent=part.getEXSDType();
// // if (xsdComponent==null)
// // xsdComponent=part.getEXSDElement();
// // if (xsdComponent!=null) {
// // XSDSchema xsdSchema=xsdComponent.getSchema();
// // if (xsdSchema!=null &&
// // !XSDUtil.isSchemaForSchemaNamespace(xsdSchema.getTargetNamespace())) {
// // xsdSchemas.add(xsdSchema);
// // }
// // }
// // }
// // }
// //
// // // Generate Ecore packages from XSDs
// // for (Iterator i=xsdSchemas.iterator(); i.hasNext(); )
// // xsdECoreBuilder.generate((XSDSchema)i.next());
// // }
// }
// }
}
/**
* Load an Ecore model file and generate the eCore packages for each tracked Ecore file.
*
* @param monitor
*/
protected void loadJavaFiles(IProgressMonitor monitor) {
javaModels = (List) operationDataModel.getProperty(DataObjectGeneratorModel.JAVA_FILES);
}
}