blob: 4c9cab8e6dc45e90c0f17aa22a655b5e3a9f4510 [file] [log] [blame]
/**
* <copyright>
*
* Copyright (c) 2009-2010 Thales Corporate Services S.A.S.
* 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:
* Thales Corporate Services S.A.S - initial API and implementation
*
* </copyright>
*/
package org.eclipse.egf.pattern.jet.engine;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
import org.eclipse.egf.common.constant.EGFCommonConstants;
import org.eclipse.egf.core.fcore.IPlatformFcore;
import org.eclipse.egf.model.pattern.Pattern;
import org.eclipse.egf.model.pattern.PatternException;
import org.eclipse.egf.model.pattern.PatternParameter;
import org.eclipse.egf.model.pattern.PatternVariable;
import org.eclipse.egf.pattern.common.java.AbstractJavaEngine;
import org.eclipse.egf.pattern.engine.AssemblyHelper;
import org.eclipse.egf.pattern.engine.PatternHelper;
import org.eclipse.egf.pattern.jet.JetPreferences;
import org.eclipse.egf.pattern.jet.Messages;
import org.eclipse.egf.pattern.utils.FileHelper;
import org.eclipse.egf.pattern.utils.JavaMethodGenerationHelper;
import org.eclipse.egf.pattern.utils.ParameterTypeHelper;
/**
* @author Thomas Guiu
*
*/
public class JetEngine extends AbstractJavaEngine {
public JetEngine(Pattern pattern) throws PatternException {
super(pattern);
}
public void translate() throws PatternException {
Pattern pattern = getPattern();
// **************************************************************************
// 1 - put together all pt files
AssemblyHelper helper = new JetAssemblyHelper(getPattern(), new JetAssemblyContentProvider(getPattern()));
String templatecontent = helper.visit();
// 2 - compile the result
String templateURI = "Pattern_" + pattern.getName() + " (" + pattern.getID() + ")";
try {
SkeletonJETCompiler compiler = new SkeletonJETCompiler(templateURI, new ByteArrayInputStream(templatecontent.getBytes()), JetPreferences.getEncoding());
compiler.parse();
if (pattern.getSuperPattern() != null) {
Pattern parentPattern = pattern.getSuperPattern();
((SkeletonJETCompiler.CustomJETSkeleton) compiler.getSkeleton()).setParentClass(JetNatureHelper.getTemplateClassName(parentPattern));
}
ByteArrayOutputStream outStream = new ByteArrayOutputStream();
compiler.generate(outStream);
String targetClassName = JetNatureHelper.getTemplateClassName(pattern);
IPath outputPath = computeFilePath(targetClassName);
IPlatformFcore platformFcore = PatternHelper.getPlatformFcore(getPattern());
if (platformFcore == null)
throw new PatternException(Messages.bind(Messages.assembly_error4, pattern.getName(), pattern.getID()));
IProject project = platformFcore.getPlatformBundle().getProject();
if (project == null)
throw new PatternException(Messages.bind(Messages.assembly_error5, pattern.getName(), pattern.getID()));
FileHelper.setContent(project.getFile(outputPath), getContent(new String(outStream.toByteArray())));
} catch (PatternException e) {
throw e;
} catch (Exception e) {
throw new PatternException(e);
}
}
private String getContent(String content) {
StringBuilder builder = new StringBuilder(content.length() + 500);
int startIndex = content.indexOf(JetAssemblyHelper.START_LOOP_MARKER);
int endIndex = content.indexOf(JetAssemblyHelper.END_LOOP_MARKER);
int insertionIndex = content.lastIndexOf('}');
if (startIndex == -1 || endIndex == -1 || insertionIndex == -1)
return content;
// add start of class code
builder.append(content.substring(0, startIndex));
Pattern pattern = getPattern();
// add new method call
builder.append(AssemblyHelper.ORCHESTRATION_METHOD).append("(ctx);");
// add end of class code
int startMethodIndex = content.indexOf(JetAssemblyHelper.START_METHOD_DECLARATION_MARKER, endIndex);
int endMethodIndex = content.indexOf(JetAssemblyHelper.END_METHOD_DECLARATION_MARKER, endIndex);
if (startMethodIndex != -1 && endMethodIndex != -1) {
builder.append(content.substring(endIndex + JetAssemblyHelper.END_LOOP_MARKER.length(), startMethodIndex));
builder.append(content.substring(endMethodIndex + JetAssemblyHelper.END_METHOD_DECLARATION_MARKER.length(), insertionIndex));
} else
builder.append(content.substring(endIndex + JetAssemblyHelper.END_LOOP_MARKER.length(), insertionIndex));
// add pattern reporter stuff
builder.append("public String ").append(AssemblyHelper.ORCHESTRATION_METHOD).append("(PatternContext ctx) throws Exception {").append(EGFCommonConstants.LINE_SEPARATOR);
builder.append("InternalPatternContext ictx = (InternalPatternContext)ctx;").append(EGFCommonConstants.LINE_SEPARATOR);
builder.append("int index = 0, executionIndex = ictx.getExecutionBuffer().length();").append(EGFCommonConstants.LINE_SEPARATOR);
// add orchestration statements
builder.append(content.substring(startIndex + JetAssemblyHelper.START_LOOP_MARKER.length(), endIndex));
builder.append(EGFCommonConstants.LINE_SEPARATOR);
builder.append("String loop = ictx.getBuffer().toString();").append(EGFCommonConstants.LINE_SEPARATOR);
if (!getPattern().getAllParameters().isEmpty()) {
builder.append("if (ictx.useReporter()){").append(EGFCommonConstants.LINE_SEPARATOR);
builder.append(" ictx.getExecutionBuffer().append(ictx.getBuffer().substring(index));").append(EGFCommonConstants.LINE_SEPARATOR);
builder.append(" Map<String, Object> parameterValues = new HashMap<String, Object>();").append(EGFCommonConstants.LINE_SEPARATOR);
for (org.eclipse.egf.model.pattern.PatternParameter parameter : pattern.getAllParameters()) {
String name = parameter.getName();
// String type =
// ParameterTypeHelper.INSTANCE.getTypeLiteral(parameter.getType());
// builder.append(type).append(" ").append(parameter.getName()).append(" = (").append(type).append(")").append(local).append(";").append(EGFCommonConstants.LINE_SEPARATOR);
builder.append(" parameterValues.put(\"").append(name).append("\", this.").append(name).append(");").append(EGFCommonConstants.LINE_SEPARATOR);
}
builder.append(" ictx.getReporter().loopFinished(loop, ictx, parameterValues);").append(EGFCommonConstants.LINE_SEPARATOR);
builder.append(" ictx.clearBuffer();}").append(EGFCommonConstants.LINE_SEPARATOR);
}
builder.append("return loop;").append(EGFCommonConstants.LINE_SEPARATOR);
builder.append("} ").append(EGFCommonConstants.LINE_SEPARATOR);
builder.append("").append(EGFCommonConstants.LINE_SEPARATOR);
// Handle variable initialization and fields
int startVariable = content.indexOf(JetAssemblyHelper.START_INIT_VARIABLE_MARKER);
int endVariable = content.indexOf(JetAssemblyHelper.END_INIT_VARIABLE_MARKER);
if (startVariable != -1 && endVariable != -1) {
int indexOf = builder.indexOf(JetAssemblyHelper.CONSTRUCTOR_MARKER);
if (indexOf != -1) {
CharSequence sequence = content.subSequence(startVariable + JetAssemblyHelper.START_INIT_VARIABLE_MARKER.length(), endVariable);
indexOf += JetAssemblyHelper.CONSTRUCTOR_MARKER.length();
builder.insert(indexOf, sequence);
// TODO filter sequence instead of using a workaround...
builder.insert(indexOf, "\nStringBuffer stringBuffer = new StringBuffer();\n");
startVariable = builder.indexOf(JetAssemblyHelper.START_INIT_VARIABLE_MARKER);
endVariable = builder.indexOf(JetAssemblyHelper.END_INIT_VARIABLE_MARKER);
if (startVariable != -1 && endVariable != -1) {
builder.delete(startVariable, endVariable + JetAssemblyHelper.END_INIT_VARIABLE_MARKER.length());
}
}
}
// handle variable declarations
for (PatternVariable var : pattern.getVariables()) {
builder.append("protected ").append(ParameterTypeHelper.INSTANCE.getTypeLiteral(var.getType())).append(" ").append(var.getName()).append(" = null;").append(EGFCommonConstants.LINE_SEPARATOR);
}
for (PatternParameter var : pattern.getParameters()) {
String type = ParameterTypeHelper.INSTANCE.getTypeLiteral(var.getType());
builder.append("protected ").append(type).append(" ").append(var.getName()).append(" = null;").append(EGFCommonConstants.LINE_SEPARATOR);
builder.append("public void ").append(JavaMethodGenerationHelper.getSetterMethod(var)).append("(").append(type).append(" object) {").append(EGFCommonConstants.LINE_SEPARATOR);
builder.append("this.").append(var.getName()).append(" = object;").append(EGFCommonConstants.LINE_SEPARATOR);
builder.append("}").append(EGFCommonConstants.LINE_SEPARATOR);
}
// handle methods declarations
if (startMethodIndex != -1 && endMethodIndex != -1) {
builder.append(content.substring(startMethodIndex + JetAssemblyHelper.START_METHOD_DECLARATION_MARKER.length(), endMethodIndex));
}
builder.append(content.substring(insertionIndex));
return builder.toString();
}
@Override
protected String getPatternClassname() throws PatternException {
return JetNatureHelper.getTemplateClassName(getPattern());
}
}