/*******************************************************************************
* Copyright (c) 2012 Google, Inc.
* 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:
* Google, Inc. - initial API and implementation
*******************************************************************************/
package com.windowtester.codegen;
import java.util.Iterator;
import org.eclipse.jdt.core.ToolFactory;
import org.eclipse.jdt.core.formatter.CodeFormatter;
import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.Document;
import org.eclipse.text.edits.TextEdit;
import com.windowtester.codegen.assembly.unit.ClassUnit;
import com.windowtester.codegen.assembly.unit.FieldUnit;
import com.windowtester.codegen.assembly.unit.ImportUnit;
import com.windowtester.codegen.assembly.unit.MethodUnit;
import com.windowtester.codegen.assembly.unit.ModifierList;
import com.windowtester.internal.debug.Logger;
import com.windowtester.runtime.swt.internal.preferences.ICodeGenConstants;
/**
* A builder that produces a source string, given a test case builder.
*/
public class SourceStringBuilder {
//TODO[author=pq] newlines should be properly handled universally
protected String NEW_LINE = ICodeGenConstants.NEW_LINE;
/** The test case under construction */
private final ITestCaseBuilder testcase;
/**
* Create an instance.
* @param testcase - the testcase under construction
*/
public SourceStringBuilder(ITestCaseBuilder testcase) {
this.testcase = testcase;
}
/**
* Build a String representation of the test case under construction.
* @return a String representation of the test case
*/
public String build() {
StringBuffer sb = new StringBuffer();
addPackage(sb);
addImports(sb);
addClassDecl(sb);
addFields(sb);
addClasses(sb);
addMethods(sb);
close(sb);
String formatted = sb.toString();
formatted = format(sb.toString());
return formatted;
}
/**
* Format the given source String
* @param source - the source to format
* @return the source formatted
*/
public String format(String source) {
TextEdit textEdit = null;
try {
textEdit = ToolFactory.createCodeFormatter(null).format(
CodeFormatter.K_COMPILATION_UNIT, source, 0,
source.length(), 0, System.getProperty("line.separator"));
} catch(Throwable e) {
Logger.log("An error occured in formatting a source string.", e);
//this happens when run outside the platform (during testing)
//in this case we just return the unformatted original String
return source;
}
String formattedContent;
if (textEdit != null) {
Document document = new Document(source);
try {
textEdit.apply(document);
} catch (BadLocationException e) {
Logger.log("An error occured in formatting a source string.", e);
}
formattedContent = document.get();
} else {
formattedContent = source;
}
return formattedContent;
}
/**
* Add the test case's methods to the given buffer
* @param sb - the buffer
*/
private void addMethods(StringBuffer sb) {
for (Iterator iter = testcase.getMethods().iterator(); iter.hasNext();) {
MethodUnit method = (MethodUnit) iter.next();
sb.append(method.getBody()).append(NEW_LINE);
}
}
private void addClasses(StringBuffer sb) {
for (Iterator iter = testcase.getClasses().iterator(); iter.hasNext();) {
ClassUnit cls = (ClassUnit) iter.next();
sb.append(cls.getBody()).append(NEW_LINE);
}
}
/**
* Add the test case's fields to the given buffer
* @param sb - the buffer
*/
private void addFields(StringBuffer sb) {
for (Iterator iter = testcase.getFields().iterator(); iter.hasNext();) {
FieldUnit field = (FieldUnit) iter.next();
sb.append(field.getBody()).append(NEW_LINE);
}
}
/**
* Add the test case's class decl to the given buffer
* @param sb - the buffer
*/
private void addClassDecl(StringBuffer sb) {
sb.append("public class ").append(testcase.getName());
String sc = testcase.getExtends();
if (sc != null && !sc.equals(""))
sb.append(" extends ").append(sc).append(' ');
sb.append("{").append(NEW_LINE).append(NEW_LINE);
}
/**
* Add the test case's pacage declaration to the given buffer
* @param sb - the buffer
*/
private void addPackage(StringBuffer sb) {
String pkg = testcase.getPackage();
if (pkg != null && !pkg.trim().equals(""))
sb.append("package ").append(pkg).append(';')
.append(NEW_LINE).append(NEW_LINE);
}
/**
* Add the test case's imports to the given buffer
* @param sb - the buffer
*/
private void addImports(StringBuffer sb) {
for (Iterator iter = testcase.getImports().iterator(); iter.hasNext();) {
ImportUnit element = (ImportUnit) iter.next();
addImport(sb, element);
sb.append(
NEW_LINE);
}
sb.append(NEW_LINE).append(NEW_LINE);
}
public void addImport(StringBuffer sb, ImportUnit element) {
sb.append("import ");
ModifierList modifiers = element.getModifiers();
sb.append(modifiers.toString());
if (!modifiers.isEmpty())
sb.append(' '); //mods to have a trailing space
sb.append(element.getName()).append(';');
}
/**
* Close the given test case.
* @param sb - the buffer
*/
private void close(StringBuffer sb) {
sb.append('}');
}
}