/**
* <copyright>
*
* Copyright (c) 2009, 2010 Springsite BV (The Netherlands) 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:
* Martin Taal - Initial API and implementation
*
* </copyright>
*
* $Id: EclipseModelGeneratorTest.java,v 1.24 2011/10/25 13:19:13 mtaal Exp $
*/
package org.eclipse.emf.texo.modelgenerator.test;
import java.net.URI;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import junit.framework.TestCase;
import org.eclipse.core.resources.IProject;
import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.EClassifier;
import org.eclipse.emf.ecore.EPackage;
import org.eclipse.emf.ecore.resource.ResourceSet;
import org.eclipse.emf.ecore.xcore.XcoreStandaloneSetup;
import org.eclipse.emf.texo.component.ComponentProvider;
import org.eclipse.emf.texo.generator.AnnotationManager;
import org.eclipse.emf.texo.generator.ArtifactGenerator;
import org.eclipse.emf.texo.generator.EclipseGeneratorUtils;
import org.eclipse.emf.texo.generator.GeneratorUtils;
import org.eclipse.emf.texo.generator.ModelAnnotator;
import org.eclipse.emf.texo.generator.ModelAnnotatorRegistry;
import org.eclipse.emf.texo.generator.ModelController;
import org.eclipse.emf.texo.generator.TexoResourceManager;
import org.eclipse.emf.texo.modelgenerator.modelannotations.EPackageModelGenAnnotation;
import org.eclipse.emf.texo.modelgenerator.xtend.ModelTemplate;
import org.eclipse.emf.texo.orm.annotator.ORMMappingOptions;
import org.eclipse.emf.texo.provider.IdProvider;
import org.eclipse.emf.texo.provider.TitleProvider;
import org.eclipse.emf.texo.utils.ModelUtils;
import org.eclipse.xtext.EcoreUtil2;
import org.eclipse.xtext.util.CancelIndicator;
/**
* Test the generation of model code through the Eclipse plugin. Needs to be run as a junit plugin test.
*
* Generates all models present in the test model project in the org.eclipse.emf.texo.test.model package in the src
* directory.
*
* @see TestModel
* @author <a href="mailto:mtaal@elver.org">Martin Taal</a>
* @version $Revision: 1.24 $
*/
public class EclipseModelGeneratorTest extends TestCase {
private static final String IDENTIFIABLE_NSURI = "http://www.eclipse.org/emf/texo/test/model/base/identifiable"; //$NON-NLS-1$
private static final String IDENTIFIABLE_ECLASS_NAME = "Identifiable"; //$NON-NLS-1$
private static final String DEFAULT_EXTENDS = "org.eclipse.emf.texo.test.model.base.identifiable.Identifiable"; //$NON-NLS-1$
private static final String TEST_MODEL_PROJECT = "org.eclipse.emf.texo.test.model"; //$NON-NLS-1$
private static final EPackage.Registry SHARED_REGISTRY = GeneratorUtils.createEPackageRegistry();
private boolean generateTexoModels = false;
private ORMMappingOptions testORMOptions = new ORMMappingOptions();
private ORMMappingOptions safeORMOptions = new ORMMappingOptions();
private XcoreStandaloneSetup xcoreStandaloneSetup = new XcoreStandaloneSetup();
public EclipseModelGeneratorTest() {
// do some initialization
xcoreStandaloneSetup.createInjectorAndDoEMFRegistration();
}
public void testGenerateModels() throws Exception {
final IProject testProject = EclipseGeneratorUtils.getProject(TEST_MODEL_PROJECT);
// testProject.refreshLocal(100, new NullProgressMonitor());
// testProject.build(IncrementalProjectBuilder.CLEAN_BUILD, "org.eclipse.xtext.ui.shared.xtextBuilder",
// Collections.EMPTY_MAP, new NullProgressMonitor());
// testProject.build(IncrementalProjectBuilder.FULL_BUILD, new NullProgressMonitor());
testORMOptions.setAddOrderColumnToListMappings(true);
testORMOptions.setEnforceUniqueNames(true);
testORMOptions.setTestRun(true);
safeORMOptions.setAddOrderColumnToListMappings(true);
safeORMOptions.setRenameSQLReservedNames(true);
safeORMOptions.setEnforceUniqueNames(true);
safeORMOptions.setGenerateFullDbSchemaNames(true);
safeORMOptions.setTestRun(true);
// force initialization
ModelAnnotatorRegistry.getInstance().getModelAnnotators();
// let everyone have orm annotations..
if (!isGenerateTexoModels()) {
AnnotationManager.enableAnnotationSystem(AnnotationManager.JPA_ANNOTATION_SYSTEM_ID);
}
for (String modelFile : getModelFileRelativePaths()) {
System.err.println("Generating modelfile " + modelFile); //$NON-NLS-1$
if (modelFile.contains("employee.xsd")) { //$NON-NLS-1$
testProject.setPersistentProperty(TexoResourceManager.TEMPLATE_FOLDER_PROPERTY, "templates"); //$NON-NLS-1$
} else {
testProject.setPersistentProperty(TexoResourceManager.TEMPLATE_FOLDER_PROPERTY, null);
}
generate(new String[] { modelFile });
}
}
protected boolean useSharedEPackageRegistry() {
return false;
}
private void generate(final String[] ecoreFileNames) throws Exception {
try {
ORMMappingOptions.setDefaultOptions(testORMOptions);
final List<String> safelyMappedModels = TestModel.getSafelyMappedModels();
for (String ecoreFileName : ecoreFileNames) {
if (safelyMappedModels.contains(ecoreFileName)) {
ORMMappingOptions.setDefaultOptions(safeORMOptions);
break;
}
}
final EPackage.Registry packageRegistry = useSharedEPackageRegistry() ? SHARED_REGISTRY : GeneratorUtils
.createEPackageRegistry();
final ResourceSet resourceSet = GeneratorUtils.createGenerationResourceSet(packageRegistry);
final List<URI> uris = new ArrayList<URI>();
for (final String ecoreFileName : ecoreFileNames) {
final URI uri = TestModel.getModelPlatformUri(ecoreFileName);
uris.add(uri);
// read the deps
final List<String> deps = TestModel.getModelDependencies(ecoreFileName);
if (deps.size() > 0) {
final List<URI> depUris = new ArrayList<URI>();
for (String dep : deps) {
depUris.add(TestModel.getModelPlatformUri(dep));
}
// register all the dependent epackages also using the resource uri and the platform uri, this is needed in
// case of xcore which resolves using platform uris
final List<EPackage> depEPackages = GeneratorUtils
.readEPackages(depUris, resourceSet, packageRegistry, false);
for (EPackage depEPackage : depEPackages) {
if (depEPackage.eResource() != null && depEPackage.eResource().getURI() != null) {
final String uriStr = depEPackage.eResource().getURI().toString();
packageRegistry.put(uriStr, depEPackage);
packageRegistry.put(org.eclipse.emf.common.util.URI.createPlatformResourceURI(uriStr, true).toString(),
depEPackage);
}
}
}
}
// and read the epackages we are generating for
final List<EPackage> ePackages = GeneratorUtils.readEPackages(uris, resourceSet, packageRegistry, false);
// for (String key : packageRegistry.keySet()) {
// System.err.println(key + " --> " + ((EPackage) packageRegistry.get(key)).getName());
// }
if (true || !isGenerateTexoModels()) {
// also reads the identifiable.xcore in memory
addSuperType(resourceSet, ePackages, packageRegistry);
boolean dontSetDefaultExtends = false;
boolean hasIdentifiable = false;
for (EPackage ePackage : ePackages) {
hasIdentifiable = hasIdentifiable
|| ePackage.getNsURI().equals("http://www.eclipse.org/emf/texo/test/model/base/identifiable"); //$NON-NLS-1$
if (ePackage.eResource() != null) {
EcoreUtil2.resolveLazyCrossReferences(ePackage.eResource(), CancelIndicator.NullImpl);
}
dontSetDefaultExtends |= hasIdentifiable
|| ePackage.getNsURI().equals("http://www.eclipse.org/emf/texo/test/model/issues/bz423155");
}
// give everyone the identifiable as super, except the identifiable
// package and some other packages
if (dontSetDefaultExtends) {
EPackageModelGenAnnotation.setDefaultExtends(null);
} else {
EPackageModelGenAnnotation.setDefaultExtends(DEFAULT_EXTENDS);
}
}
try {
final ModelController modelController = new ModelController();
modelController.setEPackages(ePackages);
modelController.getAnnotationManager().getAnnotatedModel().setGeneratingSources(true);
modelController.annotate(new ArrayList<ModelAnnotator>());
final ArtifactGenerator artifactGenerator = new ArtifactGenerator();
artifactGenerator.setModelController(modelController);
artifactGenerator.setOutputFolder("src-test-gen"); //$NON-NLS-1$
artifactGenerator.setProjectName(TEST_MODEL_PROJECT);
artifactGenerator.setTemplateProjectName(TEST_MODEL_PROJECT);
if (!isGenerateTexoModels()) {
artifactGenerator.setDoDao(true);
}
artifactGenerator.setXTendTemplate(new ModelTemplate());
artifactGenerator.run();
} finally {
EPackageModelGenAnnotation.setDefaultExtends(null);
}
} catch (final Exception e) {
throw new IllegalStateException(e);
} finally {
ORMMappingOptions.setDefaultOptions(null);
}
}
protected void addSuperType(final ResourceSet resourceSet, final List<EPackage> ePackages,
final EPackage.Registry packageRegistry) throws Exception {
// first check if there is already an identifiable, if so use that one
EClass identifiableEClass = getIdentifiableSuperEClass(ePackages);
// read it from the package registry
if (identifiableEClass == null) {
EPackage identifiableEPackage = packageRegistry.getEPackage(IDENTIFIABLE_NSURI);
if (identifiableEPackage != null) {
identifiableEClass = getIdentifiableSuperEClass(Collections.singletonList(identifiableEPackage));
}
}
// not found then read it
if (identifiableEClass == null) {
final List<EPackage> identifiableEPackages = GeneratorUtils
.readEPackages(
Collections.singletonList(TestModel.getModelPlatformUri("base/identifiable.ecore")), resourceSet, packageRegistry, false); //$NON-NLS-1$
for (EPackage ePackage : identifiableEPackages) {
if (ePackage.getNsURI().equals(IDENTIFIABLE_NSURI)) {
identifiableEClass = (EClass) ePackage.getEClassifier(IDENTIFIABLE_ECLASS_NAME);
break;
}
}
}
for (EPackage ePackage : ePackages) {
addSuperType(ePackage, identifiableEClass);
}
// reset the id and title providers
IdProvider.setInstance(ComponentProvider.getInstance().newInstance(IdProvider.class));
TitleProvider.setInstance(ComponentProvider.getInstance().newInstance(TitleProvider.class));
}
protected EClass getIdentifiableSuperEClass(final List<EPackage> ePackages) {
for (EPackage ePackage : ePackages) {
for (EClassifier eClassifier : ePackage.getEClassifiers()) {
if (eClassifier instanceof EClass) {
final EClass eClass = (EClass) eClassifier;
final EClass identifiableEClass = getIdentifiableSuperEClass(eClass);
if (identifiableEClass != null) {
return identifiableEClass;
}
}
}
}
return null;
}
protected EClass getIdentifiableSuperEClass(final EClass eClass) {
if (eClass.getEPackage().getNsURI().equals(IDENTIFIABLE_NSURI) && eClass.getName().equals(IDENTIFIABLE_ECLASS_NAME)) {
return eClass;
}
for (EClass eSuperClass : eClass.getESuperTypes()) {
final EClass identifiableEClass = getIdentifiableSuperEClass(eSuperClass);
if (identifiableEClass != null) {
return identifiableEClass;
}
}
return null;
}
// add the identifiable super type to each ecore
protected void addSuperType(final EPackage ePackage, final EClass identifiableEClass) {
if (identifiableEClass.getEPackage() == ePackage) {
return;
}
for (EClassifier eClassifier : ePackage.getEClassifiers()) {
if (eClassifier instanceof EClass) {
final EClass eClass = (EClass) eClassifier;
if (eClass.isInterface() || ModelUtils.isEMap(eClass) || eClass.getName().contains("Embedded")) { //$NON-NLS-1$
continue;
}
addSuperType(eClass, identifiableEClass);
}
}
for (EPackage subEPackage : ePackage.getESubpackages()) {
addSuperType(subEPackage, identifiableEClass);
}
}
protected void addSuperType(final EClass eClass, final EClass identifiableEClass) {
if (eClass == identifiableEClass) {
return;
}
if (eClass.getEPackage().getNsURI().equals(IDENTIFIABLE_NSURI)) {
return;
}
for (EClass eSuperClass : eClass.getESuperTypes()) {
if (!eSuperClass.isInterface()) {
addSuperType(eSuperClass, identifiableEClass);
return;
}
}
eClass.getESuperTypes().add(0, identifiableEClass);
}
protected List<String> getModelFileRelativePaths() {
return TestModel.getAllSpecifiedModelRelativePaths();
}
protected boolean isGenerateTexoModels() {
return generateTexoModels;
}
protected void setGenerateTexoModels(final boolean generateTexoModels) {
this.generateTexoModels = generateTexoModels;
}
}