/** * <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: ModelAnnotator.java,v 1.10 2011/08/25 12:34:30 mtaal Exp $ */ package org.eclipse.emf.texo.generator; import java.util.Iterator; import java.util.List; import org.eclipse.emf.ecore.EClass; import org.eclipse.emf.ecore.ENamedElement; import org.eclipse.emf.ecore.EObject; import org.eclipse.emf.ecore.EPackage; import org.eclipse.emf.texo.annotations.annotationsmodel.ENamedElementAnnotation; /** * Each annotation model (jpa, jaxb, model) should implement a ModelAnnotator. The ModelAnnotator takes care of fully * annotating all model elements in a domain model. * * @author <a href="mtaal@elver.org">Martin Taal</a> */ public abstract class ModelAnnotator { private static ModelAnnotator codeGenAnnotator = null; public static ModelAnnotator getCodeGenAnnotator() { return codeGenAnnotator; } public static void setCodeGenAnnotator(ModelAnnotator codeGenAnnotator) { ModelAnnotator.codeGenAnnotator = codeGenAnnotator; } /** * The annotation model suffix is used to read additional annotations from files stored in the project. The annotation * suffix is for example orm or code-gen. * * @return the annotation suffix for this annotator. */ public abstract String getAnnotationModelSuffix(); /** * Iterates over all model elements of the EPackages ({@link #getEPackages()}), including the EPackages themselves. * * Calls {@link AnnotationManager#getAnnotation(ENamedElement, EClass)} for each model element. This ensures that an * annotation is created for each model element. The {@link #getAnnotationEClass(ENamedElement)} method is used to * determine which type of annotation to created for a model element. * * The annotate method is the first step in the annotation process. The next method called is the * {@link #postAnnotate()} method. * * @param ePackages * the EPackage instances to annotate * @param annotationManager * the annotationManager is responsible for managing manual and automatically created annotations * * @see ModelController#annotate() * @see #postAnnotate() */ public void annotate(List<EPackage> ePackages, AnnotationManager annotationManager) { ExtensionPointUtils.readAnnotationsModelsFromExtensions(); for (EPackage ePackage : ePackages) { // annotate the epackage itself { final EClass annotationEClass = getAnnotationEClass(ePackage); if (annotationEClass != null) { annotationManager.getAnnotation(ePackage, annotationEClass); } } // and then its content final Iterator<EObject> iterator = ePackage.eAllContents(); while (iterator.hasNext()) { final Object object = iterator.next(); if (object instanceof ENamedElement) { final ENamedElement eNamedElement = (ENamedElement) object; final EClass annotationEClass = getAnnotationEClass(eNamedElement); if (annotationEClass != null) { annotationManager.getAnnotation(eNamedElement, annotationEClass); } } } } } /** * This method is called after all ModelAnnotators have created annotations and have fully annotated the model. * * This method calls the {@link Annotator#postAnnotating(EModelElementAnnotation)} method for each model element * annotation. * * @param ePackages * the EPackage instances to annotate * @param annotationManager * the annotationManager is responsible for managing manual and automatically created annotations */ public void postAnnotate(List<EPackage> ePackages, AnnotationManager annotationManager) { // and then do the second step for (EPackage ePackage : ePackages) { // post annotate the epackage itself { final EClass annotationEClass = getAnnotationEClass(ePackage); if (annotationEClass != null) { final Annotator<ENamedElementAnnotation> annotator = annotationManager.getAnnotator(annotationEClass); final ENamedElementAnnotation annotation = annotationManager.getAnnotation(ePackage, annotationEClass); if (annotator != null) { annotator.postAnnotating(annotation); } } } // and then its content final Iterator<EObject> iterator = ePackage.eAllContents(); while (iterator.hasNext()) { final Object object = iterator.next(); if (object instanceof ENamedElement) { final ENamedElement eNamedElement = (ENamedElement) object; final EClass annotationEClass = getAnnotationEClass(eNamedElement); if (annotationEClass != null) { final Annotator<ENamedElementAnnotation> annotator = annotationManager.getAnnotator(annotationEClass); final ENamedElementAnnotation annotation = annotationManager.getAnnotation(eNamedElement, annotationEClass); if (annotator != null) { annotator.postAnnotating(annotation); } } } } } } /** * @param eNamedElement * the model element from the domain model * @return the annotation EClass, instances of this EClass are used to annotate the model element. Note null may be * returned, in which the model element is not annotated by this Model Annotator. */ protected abstract EClass getAnnotationEClass(ENamedElement eNamedElement); /** * Returns the list of Annotator instances which take care of annotating the domain model. Normally there will be one * annotator for the EPackages, one for the EClasses, one for the EDataTypes, etc. * * @return the list of Annotators */ protected abstract List<Annotator<? extends ENamedElementAnnotation>> getAnnotators(); }