blob: 0de254f9ab6283c3ed012aeb677d1b6128a0c07e [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2003, 2004 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.jst.j2ee.internal.codegen;
import java.util.Iterator;
import java.util.List;
/**
* This implementation of the interface wraps a StringBuffer.
* <p>
* Need preferences tie-ins for some of this.
*/
public class GenerationBuffer implements IGenerationBuffer {
private StringBuffer fBuffer = null;
private StringBuffer fCurrentMargin = null;
private String fIndentString = IBaseGenConstants.DEFAULT_INDENT;
private int fIndentCount = 0;
private char fFormatParmMarker = IBaseGenConstants.DEFAULT_FORMAT_PARM_MARKER;
/**
* GenerationBuffer default constructor.
*/
public GenerationBuffer() {
super();
}
/**
* @see org.eclipse.jst.j2ee.internal.internal.internal.codegen.api.IGenerationBuffer
*/
public void append(String[] strings) {
if ((strings != null) && (strings.length > 0)) {
for (int i = 0; i < strings.length; i++) {
append(strings[i]);
if (i < (strings.length - 1))
append(IBaseGenConstants.COMMA_SEPARATOR);
}
}
}
/**
* @see org.eclipse.jst.j2ee.internal.internal.internal.codegen.api.IGenerationBuffer
*/
public void append(String aString) {
if ((aString != null) && (aString.length() > 0))
getBuffer().append(aString);
}
/**
* @see org.eclipse.jst.j2ee.internal.internal.internal.codegen.api.IGenerationBuffer
*/
public void append(List strings) {
if (strings != null) {
Iterator stringsIter = strings.iterator();
while (stringsIter.hasNext()) {
append(stringsIter.next().toString());
if (stringsIter.hasNext())
append(IBaseGenConstants.COMMA_SEPARATOR);
}
}
}
/**
* @see org.eclipse.jst.j2ee.internal.internal.internal.codegen.api.IGenerationBuffer
*/
public void appendWithMargin(String aString) {
appendWithMargin(aString, true);
}
/**
* @see org.eclipse.jst.j2ee.internal.internal.internal.codegen.api.IGenerationBuffer
*/
public void appendWithMargin(String aString, boolean startMargin) {
if ((aString != null) && (aString.length() > 0)) {
StringBuffer buffer = getBuffer();
buffer.ensureCapacity(buffer.length() + aString.length() + 50);
if (startMargin)
margin();
int sourceLength = aString.length();
char current;
boolean inLineBreak = false;
for (int i = 0; i < sourceLength; i++) {
current = aString.charAt(i);
// if (Character.getType(current) == Character.LINE_SEPARATOR) { This should work,
// but getType is broken.
if ((current == '\r') || (current == '\n')) {
inLineBreak = true;
} else {
if (inLineBreak) {
margin();
inLineBreak = false;
}
}
buffer.append(current);
}
}
}
/**
* @see org.eclipse.jst.j2ee.internal.internal.internal.codegen.api.IGenerationBuffer
*/
public void appendWithMarginAndPrefix(String aString, String prefix) {
appendWithMarginAndPrefix(aString, prefix, true);
}
/**
* @see org.eclipse.jst.j2ee.internal.internal.internal.codegen.api.IGenerationBuffer
*/
public void appendWithMarginAndPrefix(String aString, String prefix, boolean startMargin) {
if ((aString != null) && (aString.length() > 0)) {
StringBuffer buffer = getBuffer();
buffer.ensureCapacity(buffer.length() + aString.length() + 50);
if (startMargin) {
margin();
append(prefix);
}
int sourceLength = aString.length();
char current;
boolean inLineBreak = false;
for (int i = 0; i < sourceLength; i++) {
current = aString.charAt(i);
// if (Character.getType(current) == Character.LINE_SEPARATOR) { This should work,
// but getType is broken.
if ((current == '\r') || (current == '\n')) {
inLineBreak = true;
} else {
if (inLineBreak) {
margin();
append(prefix);
inLineBreak = false;
}
}
buffer.append(current);
}
}
}
/**
* @see org.eclipse.jst.j2ee.internal.internal.internal.codegen.api.IGenerationBuffer
*/
public void format(String format, String[] parms) {
if ((format != null) && (format.length() > 0)) {
StringBuffer buffer = getBuffer();
// A fast guess to avoid lots of reallocation.
buffer.ensureCapacity(buffer.length() + format.length() + (20 * parms.length));
int formatLen = format.length();
int formatPos = 0;
char parmMarker = getFormatParmMarker();
char formatChar;
boolean inParm = false;
StringBuffer parmNumber = new StringBuffer();
while (formatPos < formatLen) {
formatChar = format.charAt(formatPos);
formatPos++;
// If we are in a parm...
if (inParm) {
// If no number yet and the character is not a digit, print the parm marker and
// print this character if it is not a parm marker.
// Also we are no longer "inParm".
if ((parmNumber.length() == 0) && (!Character.isDigit(formatChar))) {
inParm = false;
buffer.append(parmMarker);
if (formatChar != parmMarker)
buffer.append(formatChar);
} else {
// If it is a digit, add it to the number buffer.
if (Character.isDigit(formatChar)) {
parmNumber.append(formatChar);
// If this was the last character, process the parm.
if (formatPos == formatLen)
append(parms[Integer.parseInt(parmNumber.toString())]);
} else {
// The number is done, get the parm and append it.
append(parms[Integer.parseInt(parmNumber.toString())]);
parmNumber.setLength(0);
inParm = false;
// Also, we need to consider the current character over again.
formatPos--;
}
}
} else {
// If it is a parm marker and not the last character, go into parm. Otherwise,
// just append it.
if ((formatChar == parmMarker) && (formatPos < formatLen))
inParm = true;
else
buffer.append(formatChar);
}
}
}
}
/**
* @see org.eclipse.jst.j2ee.internal.internal.internal.codegen.api.IGenerationBuffer
*/
public void format(String format, List parms) {
String[] stringParms = new String[parms.size()];
Iterator parmsIter = parms.iterator();
int i = 0;
while (parmsIter.hasNext()) {
stringParms[i] = parmsIter.next().toString();
i++;
}
format(format, stringParms);
}
/**
* @see org.eclipse.jst.j2ee.internal.internal.internal.codegen.api.IGenerationBuffer
*/
public void formatWithMargin(String format, String[] parms) {
formatWithMargin(format, parms, true);
}
/**
* @see org.eclipse.jst.j2ee.internal.internal.internal.codegen.api.IGenerationBuffer
*/
public void formatWithMargin(String format, String[] parms, boolean startMargin) {
if ((format != null) && (format.length() > 0)) {
StringBuffer buffer = getBuffer();
// A fast guess to avoid lots of reallocation.
buffer.ensureCapacity(buffer.length() + format.length() + (20 * parms.length));
if (startMargin)
margin();
int formatLen = format.length();
int formatPos = 0;
char parmMarker = getFormatParmMarker();
char formatChar;
boolean inParm = false;
StringBuffer parmNumber = new StringBuffer();
boolean inLineBreak = false;
while (formatPos < formatLen) {
formatChar = format.charAt(formatPos);
formatPos++;
// Check for line breaks to add margins.
// if (Character.getType(formatChar) == Character.LINE_SEPARATOR) { This should
// work, but getType is broken.
if ((formatChar == '\r') || (formatChar == '\n')) {
inLineBreak = true;
} else {
if (inLineBreak) {
margin();
inLineBreak = false;
}
}
// If we are in a parm...
if (inParm) {
// If no number yet and the character is not a digit, print the parm marker and
// print this character if it is not a parm marker.
// Also we are no longer "inParm".
if ((parmNumber.length() == 0) && (!Character.isDigit(formatChar))) {
inParm = false;
buffer.append(parmMarker);
if (formatChar != parmMarker)
buffer.append(formatChar);
} else {
// If it is a digit, add it to the number buffer.
if (Character.isDigit(formatChar)) {
parmNumber.append(formatChar);
// If this was the last character, process the parm.
if (formatPos == formatLen)
append(parms[Integer.parseInt(parmNumber.toString())]);
} else {
// The number is done, get the parm and append it.
appendWithMargin(parms[Integer.parseInt(parmNumber.toString())], false);
parmNumber.setLength(0);
inParm = false;
// Also, we need to consider the current character over again.
formatPos--;
}
}
} else {
// If it is a parm marker and not the last character, go into parm. Otherwise,
// just append it.
if ((formatChar == parmMarker) && (formatPos < formatLen))
inParm = true;
else
buffer.append(formatChar);
}
}
}
}
/**
* @see org.eclipse.jst.j2ee.internal.internal.internal.codegen.api.IGenerationBuffer
*/
public void formatWithMargin(String format, List parms) {
formatWithMargin(format, parms, true);
}
/**
* @see org.eclipse.jst.j2ee.internal.internal.internal.codegen.api.IGenerationBuffer
*/
public void formatWithMargin(String format, List parms, boolean startMargin) {
String[] stringParms = new String[parms.size()];
Iterator parmsIter = parms.iterator();
int i = 0;
while (parmsIter.hasNext()) {
stringParms[i] = parmsIter.next().toString();
i++;
}
formatWithMargin(format, stringParms, startMargin);
}
/**
* Returns the buffer.
*/
protected StringBuffer getBuffer() {
if (fBuffer == null)
fBuffer = new StringBuffer(200);
return fBuffer;
}
/**
* Returns the current margin string based on fIndentCount and fIndentString.
*/
protected StringBuffer getCurrentMargin() {
if (fCurrentMargin == null) {
fCurrentMargin = new StringBuffer();
for (int i = 0; i < fIndentCount; i++)
fCurrentMargin.append(fIndentString);
}
return fCurrentMargin;
}
/**
* @see org.eclipse.jst.j2ee.internal.internal.internal.codegen.api.IGenerationBuffer
*/
public char getFormatParmMarker() {
return fFormatParmMarker;
}
/**
* @see org.eclipse.jst.j2ee.internal.internal.internal.codegen.api.IGenerationBuffer
*/
public void indent() {
getCurrentMargin().append(fIndentString);
fIndentCount++;
}
/**
* @see org.eclipse.jst.j2ee.internal.internal.internal.codegen.api.IGenerationBuffer
*/
public void margin() {
// The tests are not strictly needed, but using them will reduce String
// related garbage problems.
if (fIndentCount > 0) {
if (fIndentCount == 1)
append(fIndentString);
else
append(getCurrentMargin().toString());
}
}
/**
* @see org.eclipse.jst.j2ee.internal.internal.internal.codegen.api.IGenerationBuffer
*/
public void setFormatParmMarker(char newFormatParmMarker) {
fFormatParmMarker = newFormatParmMarker;
}
/**
* @see org.eclipse.jst.j2ee.internal.internal.internal.codegen.api.IGenerationBuffer
*/
public void setIndent(int indentCount) {
int setCount = (indentCount > 0) ? indentCount : 0;
if (setCount != fIndentCount) {
fIndentCount = setCount;
fCurrentMargin = null;
}
}
/**
* The buffer contents is the code String.
*/
public String toString() {
return getBuffer().toString();
}
/**
* @see org.eclipse.jst.j2ee.internal.internal.internal.codegen.api.IGenerationBuffer
*/
public void unindent() {
if (fIndentCount > 0) {
fIndentCount--;
fCurrentMargin = null;
}
}
}