/******************************************************************************* * Copyright © 2011, 2013 IBM Corporation 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: * IBM Corporation - initial API and implementation * *******************************************************************************/ package org.eclipse.edt.mof.codegen.java; import java.util.HashSet; import java.util.List; import java.util.Set; import org.eclipse.edt.mof.EClass; import org.eclipse.edt.mof.EClassifier; import org.eclipse.edt.mof.EField; import org.eclipse.edt.mof.EFunction; import org.eclipse.edt.mof.EParameter; import org.eclipse.edt.mof.EType; import org.eclipse.edt.mof.codegen.api.TabbedWriter; import org.eclipse.edt.mof.codegen.api.Template; import org.eclipse.edt.mof.codegen.api.TemplateContext; import org.eclipse.edt.mof.codegen.api.TemplateException; public class EClassTemplate extends MofImplTemplate { public void genImpl(EClass eClass, TemplateContext ctx, TabbedWriter out) throws TemplateException { genImplPackageDecl(eClass, ctx, out); genImplImports(eClass, ctx, out); genImplClassHeader(eClass, ctx, out); genBaseClassBody(eClass, ctx, out); Template fieldTemplate; for (EField field : eClass.getEFields()) { fieldTemplate = ctx.getTemplateFor(field.getEClass()); fieldTemplate.gen("genImplSetGet", field, ctx, out); } Template functionTemplate; for (EFunction function : eClass.getEFunctions()) { functionTemplate = ctx.getTemplateFor(function.getEClass()); functionTemplate.gen("genImpl", function, ctx, out); } out.popIndent(); out.print('}'); } /** * Generate only the fields as part of a Base class that can regenerated. * See <code>genImplExtendBase</code> which would extend the base class * to contain functions that are intended to be written. The extended class * is not intended to be regenerated. * @param eClass * @param ctx * @param out * @throws TemplateException */ public void genImplBase(EClass eClass, TemplateContext ctx, TabbedWriter out) throws TemplateException { genImplPackageDecl(eClass, ctx, out); genImplImports(eClass, ctx, out); genBaseClassHeader(eClass, ctx, out); genBaseClassBody(eClass, ctx, out); Template fieldTemplate; for (EField field : eClass.getEFields()) { fieldTemplate = ctx.getTemplateFor(field.getEClass()); fieldTemplate.gen("genImplSetGet", field, ctx, out); } out.popIndent(); out.print('}'); } public void genImplExtendsBase(EClass eClass, TemplateContext ctx, TabbedWriter out) throws TemplateException { genImplPackageDecl(eClass, ctx, out); Set<EClassifier> imports = new HashSet<EClassifier>(); imports.add(eClass); for (EFunction function : eClass.getEFunctions()) { EType type = function.getEType(); if (type != null && needsImport(type.getEClassifier())) { imports.add((EClassifier)type.getEClassifier()); } for (EParameter parm : function.getEParameters()) { type = parm.getEType().getEClassifier(); if (type != null && needsImport((EClassifier)type)) { imports.add((EClassifier)type); } } } for (EClassifier classifier : imports) { out.print("import "); out.print(classifier.getETypeSignature()); out.println(";"); } out.println(); genImplExtendsBaseClassHeader(eClass, ctx, out); Template functionTemplate; for (EFunction function : eClass.getEFunctions()) { functionTemplate = ctx.getTemplateFor(function.getEClass()); functionTemplate.gen("genImpl", function, ctx, out); } out.popIndent(); out.print('}'); } public void genInterface(EClass eClass, TemplateContext ctx, TabbedWriter out) throws TemplateException { genPackageDecl(eClass, ctx, out); genImports(eClass, ctx, out); genClassHeader(eClass, ctx, out); Template fieldTemplate; for (EField field : eClass.getEFields()) { fieldTemplate = ctx.getTemplateFor(field.getEClass()); fieldTemplate.gen("genInterfaceSetGet", field, ctx, out); } Template functionTemplate; for (EFunction function : eClass.getEFunctions()) { functionTemplate = ctx.getTemplateFor(function.getEClass()); functionTemplate.gen("genInterface", function, ctx, out); } out.popIndent(); out.print('}'); } public void genImplPackageDecl(EClass eClass, TemplateContext ctx, TabbedWriter out) { out.print("package "); out.print(getPackageName(eClass, ctx)); out.println(".impl;"); out.println(); } public void genImplImports(EClass eClass, TemplateContext ctx, TabbedWriter out) { for (EClassifier type : GenUtils.getImportTypes(eClass, true)) { genImplImport(eClass, type, ctx, out); } out.println(); } public void genImplImport(EClass eClass, EClassifier importType, TemplateContext ctx, TabbedWriter out) { if (!eClass.getSuperTypes().isEmpty() && eClass.getSuperTypes().get(0) == importType) { out.print("import "); out.print(getPackageName(importType, ctx)); out.print(".impl."); out.print(importType.getEClassifier().getName()); out.print("Impl"); out.println(";"); } out.print("import "); out.print(getETypeSignature(importType, ctx)); out.println(';'); } public void genBaseClassHeader(EClass eClass, TemplateContext ctx, TabbedWriter out) { boolean noSuperType = getSuperType(eClass) == null; out.print("public abstract "); out.print("class "); out.print(eClass.getName()); out.print("ImplBase"); out.print(noSuperType ? " " : " extends " + getSuperType(eClass).getName() + "Impl"); out.print(" implements "); out.print(eClass.getName()); out.println(" {"); out.pushIndent(); } public void genImplExtendsBaseClassHeader(EClass eClass, TemplateContext ctx, TabbedWriter out) { out.print("public"); out.print(eClass.isAbstract() ? " abstract " : " "); out.print("class "); out.print(eClass.getName()); out.print("Impl"); out.print(" extends " + eClass.getName() + "ImplBase"); out.print(" implements "); out.print(eClass.getName()); out.println(" {"); out.pushIndent(); } public void genImplClassHeader(EClass eClass, TemplateContext ctx, TabbedWriter out) { boolean noSuperType = getSuperType(eClass) == null; out.print("public"); out.print(eClass.isAbstract() ? " abstract " : " "); out.print("class "); out.print(eClass.getName()); out.print("Impl"); out.print(noSuperType ? " " : " extends " + getSuperType(eClass).getName() + "Impl"); out.print(" implements "); out.print(eClass.getName()); out.println(" {"); out.pushIndent(); } public void genBaseClassBody(EClass eClass, TemplateContext ctx, TabbedWriter out) { boolean noSuperType = getSuperType(eClass) == null; if (!eClass.getEFields().isEmpty()) { for (int i=0; i<eClass.getEFields().size(); i++) { out.println("private static int Slot_" + eClass.getEFields().get(i).getName() + "=" + i + ";"); } out.println("private static int totalSlots = " + eClass.getEFields().size() + ";"); out.println(); out.println("public static int totalSlots() {"); out.pushIndent(); if (noSuperType) { out.println("return totalSlots;"); } else { out.println("return totalSlots + " + GenUtils.getSuperType(eClass).getName() + "Impl.totalSlots();"); } out.popIndent(); out.println('}'); out.println(); if (!noSuperType) { out.println("static {"); out.pushIndent(); out.print("int offset = "); out.print(GenUtils.getSuperType(eClass).getName()); out.println("Impl.totalSlots();"); for (int i=0; i<eClass.getEFields().size(); i++) { out.println("Slot_" + eClass.getEFields().get(i).getName() + " += offset;"); } out.popIndent(); out.println('}'); } } } public void genPackageDecl(EClass eClass, TemplateContext ctx, TabbedWriter out) { out.print("package "); out.print(getPackageName(eClass, ctx)); out.println(';'); out.println(); } public void genImports(EClass eClass, TemplateContext ctx, TabbedWriter out) { for (EClassifier type : getImportTypes(eClass, false)) { genImport(type, ctx, out); } out.println(); } public void genImport(EClassifier type, TemplateContext ctx, TabbedWriter out) { out.print("import "); out.print(getETypeSignature(type, ctx)); out.println(';'); } public void genClassHeader(EClass eClass, TemplateContext ctx, TabbedWriter out) { boolean noSuperType = getSuperType(eClass) == null; out.print("public interface "); out.print(eClass.getName()); if (!noSuperType) { out.print(" extends "); List<EClass> types = eClass.getSuperTypes(); for(int i = 0; i< types.size(); i++) { out.print(types.get(i).getName()); if (i < types.size() - 1) { out.print(", "); } } } out.println(" {"); out.pushIndent(); } }