/*
* 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.taglib;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.Map.Entry;
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 org.xulfaces.annotation.taglib.TLD;
import com.sun.mirror.apt.AnnotationProcessor;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
import com.sun.mirror.declaration.TypeDeclaration;
/**
*
* @author kito31
* @version $Id: TaglibAnnotationProcessor.java,v 1.5 2006/01/08 16:07:23 kito31 Exp $
*/
public class TaglibAnnotationProcessor implements AnnotationProcessor {
private static final Log log = LogFactory.getLog(TaglibAnnotationProcessor.class);
private Tld tld = new Tld();
private AnnotationProcessorEnvironment apEnv;
public TaglibAnnotationProcessor(AnnotationProcessorEnvironment env) {
this.apEnv = env;
}
private Map<String,String> getProcessorOptions(){
Map<String,String> options = new HashMap<String,String>();
Set<Entry<String,String>> entrySet = this.apEnv.getOptions().entrySet();
for(Entry<String,String> entry : entrySet){
String key = entry.getKey();
if(key.startsWith("-A-p=") ||key.startsWith("-A--package=")){
options.put("--package",key.substring(key.indexOf("=")+1));
}
}
return options;
}
public void process() {
this.tld = null;
Map<String,String> options = getProcessorOptions();
String packagename = options.get("--package");
String path = this.apEnv.getOptions().get("-s");
if(path == null){
throw new NullPointerException("Destination directory is null ! (use -s dirname) ");
}
if(packagename == null){
throw new NullPointerException("Package's name is null ! (use -A-p=my.package.doe option) ");
}
for (TypeDeclaration typeDeclaration : apEnv.getTypeDeclarations()) {
try {
Class currentClass = Class.forName(typeDeclaration
.getQualifiedName());
log.debug("Processing " + currentClass.getName() + " -->" );
if(packagename != null){
log.debug("Attempt to discover package -->" );
Package tldPackage = currentClass.getPackage();
if(tldPackage != null){
TLD tldAnnotation = tldPackage.getAnnotation(TLD.class);
if(tldAnnotation != null){
if(tld == null){
log.debug("Package found." );
log.debug("Package annotation found." );
log.debug("Attempt to create tld -->");
tld = new Tld(tldAnnotation);
log.debug("tld is created." );
}
}
}
}
TAG tagAnnotation = typeDeclaration.getAnnotation(TAG.class);
String name = "no name";
if (tagAnnotation != null) {
name = tagAnnotation.name();
}
log.debug("\ttag name is " + name);
process(currentClass);
log.debug("tag processed. ");
} catch (ClassNotFoundException e) {
e.printStackTrace();
}
}
try {
String filename = path + "/" + this.tld.getFilename();
log.debug("Output file is " + filename + ".");
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filename));
log.debug("Output file created.");
VelocityTemplateEngine engine = new VelocityTemplateEngine();
engine.configure();
engine.prepareRender();
engine.setContextValue("tld",tld);
engine.renderTemplate(bufferedWriter,"tld.vm");
bufferedWriter.close();
log.debug("Your TLD file is ready. ;o))");
} catch (Exception e1) {
e1.printStackTrace();
}
}
private void process(Class currentClass) {
if (currentClass != Object.class) {
TAG tagAnnotation = (TAG) currentClass.getAnnotation(TAG.class);
if(tagAnnotation != null){
Tag tag = new Tag(tagAnnotation,currentClass);
tld.getTags().add(tag);
processFields(currentClass,tag);
}
}
}
private void processFields(Class currentClass,Tag tag) {
if (currentClass != Object.class) {
for (Field field : currentClass.getDeclaredFields()) {
ATTRIBUTE attributeAnnotation = field
.getAnnotation(ATTRIBUTE.class);
if(attributeAnnotation != null){
Attribute attribute = new Attribute(attributeAnnotation,field);
tag.getAttributes().add(attribute);
}
}
processFields(currentClass.getSuperclass(),tag);
}
}
public class Tld {
String filename = "taglibray.tld";
String tlibversion = "1.1";
String jspversion= "1.2";
String shortname;
String uri;
String description = "TODO !!";
List<Tag> tags = new ArrayList<Tag>();
public Tld(TLD tldAnnotation) {
this.filename = tldAnnotation.filename();
this.tlibversion = tldAnnotation.tlibversion();
this.jspversion = tldAnnotation.jspversion();
this.shortname = tldAnnotation.shortname();
this.uri = tldAnnotation.uri();
this.description = tldAnnotation.description();
}
public Tld() {
// TODO Auto-generated constructor stub
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getJspversion() {
return jspversion;
}
public void setJspversion(String jspversion) {
this.jspversion = jspversion;
}
public String getShortname() {
return shortname;
}
public void setShortname(String shortname) {
this.shortname = shortname;
}
public String getTlibversion() {
return tlibversion;
}
public void setTlibversion(String tlibversion) {
this.tlibversion = tlibversion;
}
public String getUri() {
return uri;
}
public void setUri(String uri) {
this.uri = uri;
}
public List<Tag> getTags() {
return tags;
}
public void setTags(List<Tag> tags) {
this.tags = tags;
}
public String getFilename() {
return filename;
}
public void setFilename(String filename) {
this.filename = filename;
}
}
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 required =false;
boolean rtexprvalue = false;
String type = "";
String description = "TODO !!";
String mappedType;
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.description = tagAttribute.description();
}
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;
}
}
public Tld getTld() {
return tld;
}
public void setTld(Tld tld) {
this.tld = tld;
}
}