/** * Optimus, framework for Model Transformation * * Copyright (C) 2013 Worldline or third-party contributors as * indicated by the @author tags or express copyright attribution * statements applied by the authors. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ package net.atos.optimus.m2t.merger.java.core; import static org.eclipse.jdt.core.dom.TypeDeclaration.BODY_DECLARATIONS_PROPERTY; import static org.eclipse.jdt.core.dom.TypeDeclaration.JAVADOC_PROPERTY; import static org.eclipse.jdt.core.dom.TypeDeclaration.MODIFIERS2_PROPERTY; import static org.eclipse.jdt.core.dom.TypeDeclaration.SUPERCLASS_TYPE_PROPERTY; import static org.eclipse.jdt.core.dom.TypeDeclaration.SUPER_INTERFACE_TYPES_PROPERTY; import java.util.List; import java.util.Set; import net.atos.optimus.common.tools.jdt.JavaCodeHelper; import net.atos.optimus.m2t.merger.java.core.internal.MergerLogger; import net.atos.optimus.m2t.merger.java.core.internal.MergerLoggerMessages; import org.eclipse.jdt.core.dom.AbstractTypeDeclaration; import org.eclipse.jdt.core.dom.BodyDeclaration; import org.eclipse.jdt.core.dom.ChildListPropertyDescriptor; import org.eclipse.jdt.core.dom.ChildPropertyDescriptor; import org.eclipse.jdt.core.dom.FieldDeclaration; import org.eclipse.jdt.core.dom.MethodDeclaration; import org.eclipse.jdt.core.dom.Type; import org.eclipse.jdt.core.dom.TypeDeclaration; import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; import org.eclipse.jface.text.Document; /** * Merge two types. A type is composed by a TypeDeclartion, a set of fields, * methods and inner types. * * @author Maxence Vanbésien (mvaawl@gmail.com) * @since 1.0 */ class TypeMerger extends EnumMerger { /** * TypeMerger constructor * * @param jcm * A JavaCodeMerger instance * @param astr * An ASTRewrite instance * @param log * A Merger Logger instance */ public TypeMerger(JavaCodeMerger jcm, ASTRewrite astr) { super(jcm, astr); } @Override protected ChildPropertyDescriptor getJavadocPropertyDescriptor() { return JAVADOC_PROPERTY; } @Override protected ChildListPropertyDescriptor getModifiersPropertyDescriptor() { return MODIFIERS2_PROPERTY; } @Override protected ChildListPropertyDescriptor getBodyDeclarationsPropertyDescriptor() { return BODY_DECLARATIONS_PROPERTY; } @Override protected ChildListPropertyDescriptor getSuperInterfacesPropertyDescriptor() { return SUPER_INTERFACE_TYPES_PROPERTY; } /** * Return super interfaces types defines on {@code atd} Abstract * TypeDeclaration. * * @param atd * An Abstract Type Declaration instance * @return A super interfaces types defines on {@code atd} Abstract * TypeDeclaration. */ @SuppressWarnings("unchecked") @Override protected List<Type> getSuperInterfacesTypes(AbstractTypeDeclaration atd) { return ((TypeDeclaration) atd).superInterfaceTypes(); } /** * This method launch merge process on sub fragments. * * @param existing * The first code fragment containing sub fragments to merge * @param generated * The second code fragment containing sub fragments to merge */ @Override public void mergeSubFragments(BodyDeclaration existing, BodyDeclaration generated, Document generatedDoc) { AbstractTypeDeclaration existingType = (AbstractTypeDeclaration) existing; AbstractTypeDeclaration generatedType = (AbstractTypeDeclaration) generated; /* * Merge fields, methods and inner types. */ mergeBodyDeclarationsChildren(existingType, generatedType, generatedDoc, FieldDeclaration.class); mergeBodyDeclarationsChildren(existingType, generatedType, generatedDoc, MethodDeclaration.class); mergeBodyDeclarationsChildren(existingType, generatedType, generatedDoc, AbstractTypeDeclaration.class); } /** * Merge type declaration */ @Override protected void mergeDeclaration(AbstractTypeDeclaration existingType, AbstractTypeDeclaration generatedType, Set<String> generatedAnnotations) { super.mergeDeclaration(existingType, generatedType, generatedAnnotations); // Extension is merged mergeExtension((TypeDeclaration) existingType, (TypeDeclaration) generatedType); } /** * Merge extension from existingType {@code et} and generatedType {@code gt} * to an AST Rewrite object instance. * * @param et * The existing type * @param generatedType * The generated type */ protected void mergeExtension(TypeDeclaration et, TypeDeclaration gt) { if (et.getSuperclassType() != null && gt.getSuperclassType() != null) { if (MergerLogger.enabled()) MergerLogger.log(MergerLoggerMessages.TYPE_REPLACESUPERCLASS.value(JavaCodeHelper.getName(et.getSuperclassType()), JavaCodeHelper.getName(gt.getSuperclassType()), JavaCodeHelper.getName(et), JavaCodeHelper.getDescription(et))); astr.replace(et.getSuperclassType(), gt.getSuperclassType(), null); } else if (et.getSuperclassType() != null) { /* Nothing to do */ } else if (gt.getSuperclassType() != null) { if (MergerLogger.enabled()) MergerLogger.log(MergerLoggerMessages.TYPE_ADDSUPERCLASS.value(JavaCodeHelper.getName(gt.getSuperclassType()), JavaCodeHelper.getName(et), JavaCodeHelper.getDescription(et))); astr.set(et, SUPERCLASS_TYPE_PROPERTY, gt.getSuperclassType(), null); } } }