/** * 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.FieldDeclaration.JAVADOC_PROPERTY; import static org.eclipse.jdt.core.dom.FieldDeclaration.MODIFIERS2_PROPERTY; import static org.eclipse.jdt.core.dom.VariableDeclarationFragment.INITIALIZER_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.ASTNode; 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.VariableDeclarationFragment; import org.eclipse.jdt.core.dom.rewrite.ASTRewrite; import org.eclipse.jdt.core.dom.rewrite.ListRewrite; /** * Merge two FieldDeclaration instance. A FieldDeclaration is composed by a * javadoc, modifiers, type and initialization. * * @author Maxence Vanbésien (mvaawl@gmail.com) * @since 1.0 */ class FieldDeclarationMerger extends BodyDeclarationMerger { /** * Simple constructor with a logger as first parameter, An ASTRewrite * instance as second one. * * @param log * A Merger Logger instance * @param astr * An ASTRewrite object instance */ public FieldDeclarationMerger(ASTRewrite astr) { super(astr); } @Override protected ChildPropertyDescriptor getJavadocPropertyDescriptor() { return JAVADOC_PROPERTY; } @Override protected ChildListPropertyDescriptor getModifiersPropertyDescriptor() { return MODIFIERS2_PROPERTY; } @Override public void insert(ASTNode parent, BodyDeclaration fragmentToInsert) { super.insert(parent, fragmentToInsert); FieldDeclaration lastField = null; AbstractTypeDeclaration parentType = (AbstractTypeDeclaration) parent; /* * Read all fields of the type declaration (used to insert this field at * the right place) */ List<FieldDeclaration> existingFields = JavaCodeHelper.getTypedChildren(parentType, FieldDeclaration.class); // Save the last field if a field already exist if (existingFields.size() > 0) { lastField = existingFields.get(existingFields.size() - 1); } ListRewrite lw = this.astr.getListRewrite(parentType, JavaCodeHelper.getBodyDeclarationProperty(parentType.getClass())); // Insert this field... if (lastField == null) { /* * ... at the beginning of the type if this is the first field */ lw.insertFirst(fragmentToInsert, null); } else { // ... after the previous field if a field already exist lw.insertAfter(fragmentToInsert, lastField, null); } } @Override public void merge(BodyDeclaration existing, BodyDeclaration generated, Set<String> generatedAnnotations) { super.merge(existing, generated, generatedAnnotations); FieldDeclaration existingField = (FieldDeclaration) existing; FieldDeclaration generatedField = (FieldDeclaration) generated; // Merge types this.mergeTypes(existingField.getType(), generatedField.getType()); // Merge initializations this.mergeInitialization(existingField, generatedField); // Rename in case of REFACTORING mergeFieldNames(existingField, generatedField); } private void mergeFieldNames(FieldDeclaration existingField, FieldDeclaration generatedField) { // Updates the name in case of refactoring: astr.replace((VariableDeclarationFragment) existingField.fragments().get(0), (VariableDeclarationFragment) generatedField.fragments().get(0), null); } /** * Merge initialization from existingField and generatedField to an AST * Rewrite object instance. */ private void mergeInitialization(FieldDeclaration existingField, FieldDeclaration generatedField) { VariableDeclarationFragment evdf = null; VariableDeclarationFragment gvdf = null; /* * Initializing expression is replaced. WARNING : This code is only able * to work with one field in a FieldDeclaration instance, several fields * in one FieldDeclaration is not supported by this implementation. */ evdf = (VariableDeclarationFragment) existingField.fragments().get(0); gvdf = (VariableDeclarationFragment) generatedField.fragments().get(0); if (evdf.getInitializer() == null && gvdf.getInitializer() == null) { /* * If existing initializer is null and generated initializer is * null, nothing to do */ return; } if (evdf.getInitializer() != null && gvdf.getInitializer() != null) { /* * If existing and generated initializers are not null, replace * existing by generated */ if (MergerLogger.enabled()) MergerLogger.log(MergerLoggerMessages.FIELDDECL_INITIALIZER.value(evdf.getInitializer().toString(), gvdf .getInitializer().toString(), JavaCodeHelper.getName(existingField), JavaCodeHelper .getDescription(existingField))); this.astr.replace(evdf.getInitializer(), gvdf.getInitializer(), null); } else if (evdf.getInitializer() != null) { /* * If existing initializer is not null and generated initializer is * null, nothing to do */ } else { /* * If existing initializer is null and generated initializer is not * null, add generated in result */ if (MergerLogger.enabled()) MergerLogger.log(MergerLoggerMessages.FIELDDECL_INITIALIZERADD.value(gvdf.getInitializer().toString(), JavaCodeHelper.getName(existingField), JavaCodeHelper.getDescription(existingField))); this.astr.set(evdf, INITIALIZER_PROPERTY, gvdf.getInitializer(), null); } } }