/** * <copyright> * * Copyright (c) 2005, 2006, 2007, 2008 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: AnnotationGenerator.java,v 1.5 2008/02/28 07:08:32 mtaal Exp $ */ package org.eclipse.emf.teneo.annotations.mapper; import java.util.List; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.EClassifier; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.ecore.EStructuralFeature; import org.eclipse.emf.ecore.EcorePackage; import org.eclipse.emf.ecore.util.EcoreUtil; import org.eclipse.emf.teneo.PersistenceOptions; import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEClass; import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEDataType; import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedEPackage; import org.eclipse.emf.teneo.annotations.pamodel.PAnnotatedModel; import org.eclipse.emf.teneo.annotations.pannotation.PannotationFactory; import org.eclipse.emf.teneo.ecore.EModelResolver; import org.eclipse.emf.teneo.extension.ExtensionManager; import org.eclipse.emf.teneo.extension.ExtensionManagerAware; import org.eclipse.emf.teneo.extension.ExtensionPoint; import org.eclipse.emf.teneo.mapping.strategy.EntityNameStrategy; import org.eclipse.emf.teneo.mapping.strategy.SQLNameStrategy; /** * Adds default annotations to an existing pamodel. Default annotations are added on the basis of * the emf type information. It sets the default annotations according to the ejb3 spec. * * @author <a href="mailto:mtaal@elver.org">Martin Taal</a> * @version $Revision: 1.5 $ */ public class AnnotationGenerator implements ExtensionPoint, ExtensionManagerAware { // The logger protected static final Log log = LogFactory.getLog(AnnotationGenerator.class); protected PersistenceOptions persistenceOptions; // the extension manager private ExtensionManager extensionManager; // Convenience link to pamodel factory private final PannotationFactory aFactory = PannotationFactory.eINSTANCE; // The annotated model which is being processed private PAnnotatedModel annotatedModel; // The annotators private EClassAnnotator eClassAnnotator; private EDataTypeAnnotator eDataTypeAnnotator; /** * Adds default annotations to a pamodel, the method is synchronized because globals are set. * Not necessary because this class should always be used single threaded but okay. */ public synchronized void map(PAnnotatedModel annotatedModel, PersistenceOptions po) { persistenceOptions = po; final List<PAnnotatedEPackage> apacks = annotatedModel.getPaEPackages(); final EPackage[] epacks = new EPackage[apacks.size()]; int cnt = 0; for (PAnnotatedEPackage apack : apacks) { epacks[cnt++] = apack.getModelEPackage(); } final EModelResolver eModelResolver = EModelResolver.instance(); log.debug("Registering epackages in model resolver, modelresolver instance is: " + eModelResolver.getClass().getName()); eModelResolver.register(epacks); // if force fully classify typename then use the EModelResolver/ERuntime if (persistenceOptions.isAlsoMapAsClass()) { log.debug("Class names are to be fully classified, registering all the " + "epackages"); // and now set the map as entity for each eclass for (PAnnotatedEPackage apack : annotatedModel.getPaEPackages()) { for (PAnnotatedEClass aclass : apack.getPaEClasses()) { aclass.setOnlyMapAsEntity(!eModelResolver.hasImplementationClass(aclass.getModelEClass())); } } } // solve a specific case of the EcorePackage going wrong for the eSuperTypes // see bugzilla: https://bugs.eclipse.org/bugs/show_bug.cgi?id=205790 for (EPackage epack : epacks) { if (epack.getNsURI() != null && epack.getNsURI().compareTo(EcorePackage.eINSTANCE.getNsURI()) == 0) { // now find the for (EClassifier eClassifier : epack.getEClassifiers()) { if (eClassifier.eClass() == EcorePackage.eINSTANCE.getEClass()) { final EClass eClass = (EClass) eClassifier; for (EStructuralFeature eFeature : eClass.getEAllStructuralFeatures()) { if (eFeature.getName().compareTo("eSuperTypes") == 0) { if (eFeature.getEAnnotation("teneo.jpa") == null) { EcoreUtil.setAnnotation(eFeature, "teneo.jpa", "value", "@ManyToMany"); break; } } } } } } } annotatedModel.setInitialized(true); this.annotatedModel = annotatedModel; // initialize the strategies so they have the correct information // TODO this should be handled in aware like interfaces final EntityNameStrategy entityNameStrategy = extensionManager.getExtension(EntityNameStrategy.class); entityNameStrategy.setPaModel(annotatedModel); // is maybe already set? final SQLNameStrategy sqlNameStrategy = extensionManager.getExtension(SQLNameStrategy.class); sqlNameStrategy.setPersistenceOptions(po); setAnnotators(); for (PAnnotatedEPackage pae : annotatedModel.getPaEPackages()) { processPackage(pae); } } /** Set the annotators */ protected void setAnnotators() { eClassAnnotator = createAnnotator(EClassAnnotator.class); eDataTypeAnnotator = createAnnotator(EDataTypeAnnotator.class); } /** Creates an annotator and sets all kinds of default info */ private <T extends AbstractAnnotator> T createAnnotator(Class<T> clz) { final T annotator = extensionManager.getExtension(clz); annotator.setAnnotatedModel(annotatedModel); annotator.setExtensionManager(extensionManager); annotator.setPersistenceOptions(persistenceOptions); annotator.setFactory(aFactory); annotator.initialize(); return annotator; } /** Maps one epackage */ protected void processPackage(PAnnotatedEPackage aPackage) { log.debug(">>>> Adding default annotations for EPackage " + aPackage.getModelElement().getName()); log.debug("Processing EDataTypes"); for (PAnnotatedEDataType annotatedEDataType : aPackage.getPaEDataTypes()) { eDataTypeAnnotator.annotate(annotatedEDataType); } log.debug("Processing EClasses"); for (PAnnotatedEClass annotatedEClass : aPackage.getPaEClasses()) { eClassAnnotator.annotate(annotatedEClass); } } /** * @param extensionManager * the extensionManager to set */ public void setExtensionManager(ExtensionManager extensionManager) { this.extensionManager = extensionManager; } }