/*
* xulfaces : bring XUL power to Java
*
* Copyright (C) 2005 Olivier SCHMITT
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
*/
package org.xulfaces.annotation.processor.tag;
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.LineNumberReader;
import java.io.StringReader;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xulfaces.annotation.processor.VelocityTemplateEngine;
import org.xulfaces.annotation.taglib.ATTRIBUTE;
import org.xulfaces.annotation.taglib.TAG;
import com.sun.mirror.apt.AnnotationProcessor;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
import com.sun.mirror.declaration.TypeDeclaration;
/**
*
* @author kito31
* @version $Id: TagAnnotationProcessor.java,v 1.2 2007/04/01 16:42:00 kito31 Exp $
*/
public class TagAnnotationProcessor implements AnnotationProcessor {
private static final Log log = LogFactory.getLog(TagAnnotationProcessor.class);
private AnnotationProcessorEnvironment apEnv;
public TagAnnotationProcessor(AnnotationProcessorEnvironment env) {
this.apEnv = env;
}
public void process() {
if(log.isDebugEnabled()){
log.debug("Start processing ...");
}
String path = this.apEnv.getOptions().get("-s");
if (path == null) {
throw new NullPointerException("Destination directory is null ! (use -s dirname) ");
}
for (TypeDeclaration typeDeclaration : apEnv.getTypeDeclarations()) {
try {
Class currentClass = Class.forName(typeDeclaration.getQualifiedName());
TAG tagAnnotation = typeDeclaration.getAnnotation(TAG.class);
if (tagAnnotation != null) {
String sourceCode = "";
try {
String name = currentClass.getName();
name = "src/main/java/" + name.replace(".", "/") + ".java";
log.debug(name);
BufferedReader bufferedReader = new BufferedReader(new FileReader(name));
String line = null;
while ((line = bufferedReader.readLine()) != null) {
sourceCode = sourceCode + line + "\n";
}
bufferedReader.close();
} catch (Exception e) {
log.error(e);
throw new RuntimeException(e);
}
if (sourceCode != null) {
boolean containsGenerationTags = false;
LineNumberReader sourceFileReader = new LineNumberReader(new StringReader(sourceCode));
StringBuffer sourceCodeBuffer = new StringBuffer();
String line = null;
boolean startGeneration = false;
while ((line = sourceFileReader.readLine()) != null) {
if (line.contains("@StartGeneration")) {
sourceCodeBuffer.append(line);
sourceCodeBuffer.append("\n");
startGeneration = true;
containsGenerationTags = true;
if (log.isDebugEnabled()) {
log.debug("Processing TAG " + tagAnnotation.name());
}
Tag tag = new Tag(tagAnnotation, currentClass);
sourceCodeBuffer.append(processTagAnnotation(tag, currentClass));
}
else {
if(startGeneration){
if (line.contains("@EndGeneration")) {
sourceCodeBuffer.append(line);
sourceCodeBuffer.append("\n");
startGeneration = false;
}
}
else {
sourceCodeBuffer.append(line);
sourceCodeBuffer.append("\n");
}
}
}
if (containsGenerationTags) {
try {
String name = currentClass.getName();
name = "src/main/java/" + name.replace(".", "/") + ".java";
log.debug("Generate file " + name);
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(name));
bufferedWriter.write(sourceCodeBuffer.toString());
bufferedWriter.flush();
bufferedWriter.close();
} catch (Exception e) {
log.error(e);
throw new RuntimeException(e);
}
}
}
}
} catch (Exception e) {
log.error(e);
}
}
if(log.isDebugEnabled()){
log.debug("Tag annotations processed.");
}
}
private String processTagAnnotation(Tag tag, Class currentClass) {
for (Field field : currentClass.getDeclaredFields()) {
ATTRIBUTE attributeAnnotation = field.getAnnotation(ATTRIBUTE.class);
if (attributeAnnotation != null) {
log.debug("Processing ATTRIBUTE" + attributeAnnotation.name());
Attribute attribute = new Attribute(attributeAnnotation, field);
tag.getAttributes().add(attribute);
}
}
StringWriter writerForGeneratedCode = new StringWriter();
VelocityTemplateEngine engine = new VelocityTemplateEngine();
try {
engine.configure();
engine.prepareRender();
engine.setContextValue("tag", tag);
engine.renderTemplate(writerForGeneratedCode, "tagSetProperties.vm");
if (log.isDebugEnabled()) {
log.debug(writerForGeneratedCode.toString());
}
return writerForGeneratedCode.toString();
} catch (Exception e) {
log.error(e);
throw new RuntimeException(e);
}
}
public class Tag {
String name;
String bodycontent;
String description;
String tagclass;
private boolean process;
private boolean jsf;
List<Attribute> attributes = new ArrayList();
public Tag(TAG tagAnnotation, Class currentClass) {
this.name = tagAnnotation.name();
this.bodycontent = tagAnnotation.bodycontent();
this.description = tagAnnotation.description();
this.tagclass = tagAnnotation.tagclass();
if(this.tagclass.equals("")){
this.tagclass = currentClass.getName();
}
this.process = tagAnnotation.process();
this.jsf = tagAnnotation.jsf();
}
public List<Attribute> getAttributes() {
return attributes;
}
public void setAttributes(List<Attribute> attributes) {
this.attributes = attributes;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getBodycontent() {
return bodycontent;
}
public void setBodycontent(String bodycontent) {
this.bodycontent = bodycontent;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getTagclass() {
return tagclass;
}
public void setTagclass(String tagclass) {
this.tagclass = tagclass;
}
public boolean isProcess() {
return process;
}
public void setProcess(boolean process) {
this.process = process;
}
public boolean isJsf() {
return jsf;
}
public void setJsf(boolean jsf) {
this.jsf = jsf;
}
}
public class Attribute {
String name;
boolean supportsMethodBinding = false;
boolean required =false;
boolean rtexprvalue = false;
String type = "";
String mappedType;
String description = "TODO !!";
public Attribute(ATTRIBUTE tagAttribute, Field field) {
this.name = tagAttribute.name();
if (this.name.equals("")) {
this.name = field.getName();
}
this.type = field.getType().getName();
this.mappedType = tagAttribute.mappedType();
this.required = tagAttribute.required();
this.rtexprvalue =tagAttribute.rtexprvalue();
this.supportsMethodBinding = tagAttribute.supportsMethodBinding();
this.description = tagAttribute.description();
if(log.isDebugEnabled()){
log.debug("name " + name + " type " + type + " mappedType " + mappedType + " methodBinded " + supportsMethodBinding + " required " + required + " rtexprvalue " + rtexprvalue + " description "+ description );
}
}
public boolean isSupportsMethodBinding() {
return supportsMethodBinding;
}
public void setSupportsMethodBinding(boolean methodBinded) {
this.supportsMethodBinding = methodBinded;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public boolean isRequired() {
return required;
}
public void setRequired(boolean required) {
this.required = required;
}
public boolean isRtexprvalue() {
return rtexprvalue;
}
public void setRtexprvalue(boolean rtexprvalue) {
this.rtexprvalue = rtexprvalue;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public String getMappedType() {
return mappedType;
}
public void setMappedType(String mappedType) {
this.mappedType = mappedType;
}
}
}