/*
* Copyright 2008 Werner Guttmann
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.exolab.castor.builder.printing;
import java.lang.reflect.Array;
import java.util.ArrayList;
import org.exolab.javasource.JAnnotation;
import org.exolab.javasource.JClass;
import org.exolab.javasource.JEnum;
/**
* Helper class that provides convenience methods used
* by Velocity templates during {@link JClass} printing.
*/
public class TemplateHelper {
/**
* Removes all line breaks from a given string.
*
* @param string The string containing line breaks.
* @return A string without line breaks.
*/
public String removeLineBreaks(String string) {
return string.replaceAll("\n", "");
}
/**
* Takes a comment string and splits it into lines
* that have the maximum length of 70 chars,
*
* @param comment The comment as string.
* @return The comment string splitted into a list.
*/
public ArrayList<String> getLines(String comment) {
comment = removeLineBreaks(comment);
ArrayList<String> list = new ArrayList<String>();
do {
comment = computeLine(comment, list);
} while (comment.length() > 0);
return list;
}
/**
* Helper methods that computes the next line for
* {@link #getLines(String)}.
*
* @param comment The current comment string.
* @param list The current list.
* @return The comment without the next line.
*/
private String computeLine(String comment, ArrayList<String> list) {
if (comment == null) {
return "";
}
if (comment.length() <=70) {
list.add(comment);
return "";
}
int pos = comment.indexOf(' ', 70);
if (pos == -1) {
list.add(comment);
return "";
}
String line = comment.substring(0,pos);
list.add(line);
return comment.substring(pos + 1);
}
/**
* Returns true if the {@link JClass} instance is instance of JEnum.
*
* @param jClass The {@link JClass} instance to check.
* @return true if instance of JEnum.
*/
public boolean isEnum(final JClass jClass) {
return (jClass instanceof JEnum);
}
/**
* Converts the given {@link JAnnotation} to a string representation.
*
* @param annotation The annotation to translate.
* @param shift The intent.
* @return A string representation of the annotation.
*/
public String printAnnotation(final JAnnotation annotation, String shift) {
StringBuilder stringBuffer = new StringBuilder(32);
stringBuffer.append(shift);
stringBuffer.append("@");
stringBuffer.append(annotation.getAnnotationType().getLocalName());
stringBuffer.append("(");
// Single element annotation?
String[] elementNames = annotation.getElementNames();
if (elementNames.length == 1 && elementNames[0].equals(JAnnotation.VALUE)) {
// Just output value
stringBuffer.append(printAnnotationValue(annotation.getElementValueObject(JAnnotation.VALUE),shift));
} else if (elementNames.length > 0) {
// Max element name length?
int maxLength = 0;
for (int i = 0; i < elementNames.length; i++) {
int elementNameLength = elementNames[i].length();
if (elementNameLength > maxLength) { maxLength = elementNameLength; }
}
// Output element name and values
stringBuffer.append("\n");
stringBuffer.append(shift + " ");
for (int i = 0; i < elementNames.length; i++) {
int elementNameLength = elementNames[i].length();
// Output element name with padding
stringBuffer.append(elementNames[i]);
for (int p = 0; p < maxLength - elementNameLength; p++) {
stringBuffer.append(" ");
}
// Assignment operator
stringBuffer.append(" = ");
// Value
stringBuffer.append(printAnnotationValue(
annotation.getElementValueObject(elementNames[i]), shift));
if (i < elementNames.length - 1) {
stringBuffer.append(",");
stringBuffer.append("\n");
stringBuffer.append(shift + " ");
}
}
}
stringBuffer.append(")");
return stringBuffer.toString();
}
/**
* Helper method that translates an annotation value.
*
* @param elementValue The value to translate.
* @param shift The intent,
* @return The string representation of the value.
*/
private String printAnnotationValue(final Object elementValue, final String shift) {
// String?
if (elementValue instanceof String) {
return (String) elementValue;
} else if (elementValue instanceof JAnnotation) {
JAnnotation annotation = (JAnnotation) elementValue;
return printAnnotation(annotation, shift);
} else if (elementValue.getClass().isArray()) {
// Short hand for single item list
int listLength = Array.getLength(elementValue);
if (listLength == 1) {
return printAnnotationValue(Array.get(elementValue, 0), shift);
}
// Output list items
StringBuilder stringBuffer = new StringBuilder();
stringBuffer.append("\n");
stringBuffer.append("{");
stringBuffer.append("\n");
stringBuffer.append(shift);
for (int i = 0; i < listLength; i++) {
stringBuffer.append(shift);
stringBuffer.append(printAnnotationValue(Array.get(elementValue, i), shift));
if (i < listLength - 1) { stringBuffer.append(","); }
stringBuffer.append("\n");
}
stringBuffer.append("}");
return stringBuffer.toString();
}
throw new IllegalArgumentException("'" + elementValue + "' was not expected.");
}
}