/*
* 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.faces;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.StringWriter;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.xulfaces.annotation.faces.ATTRIBUTE;
import org.xulfaces.annotation.faces.COMPONENT;
import org.xulfaces.annotation.faces.RENDERER;
import org.xulfaces.annotation.faces.RENDERKIT;
import org.xulfaces.annotation.processor.VelocityTemplateEngine;
import com.sun.mirror.apt.AnnotationProcessor;
import com.sun.mirror.apt.AnnotationProcessorEnvironment;
import com.sun.mirror.declaration.TypeDeclaration;
/**
*
* @author kito31
* @version $Id: FacesAnnotationProcessor.java,v 1.8 2006/01/22 21:41:09 kito31 Exp $
*/
public class FacesAnnotationProcessor implements AnnotationProcessor {
private static final Log log = LogFactory.getLog(FacesAnnotationProcessor.class);
private AnnotationProcessorEnvironment apEnv;
private FacesConfig facesConfig = new FacesConfig();
public FacesAnnotationProcessor(AnnotationProcessorEnvironment env) {
this.apEnv = env;
}
public void process() {
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());
log.debug("Processing " + currentClass.getName() + " -->");
COMPONENT componentAnnotation = typeDeclaration.getAnnotation(COMPONENT.class);
if( (componentAnnotation != null) && (componentAnnotation.process())){
Component component = new Component(componentAnnotation,currentClass);
processComponentAnnotation(component, currentClass);
}
RENDERER rendererAnnotation = typeDeclaration.getAnnotation(RENDERER.class);
if (rendererAnnotation != null) {
processRendererAnnotation(rendererAnnotation, currentClass);
}
RENDERKIT renderKitAnnotation = typeDeclaration.getAnnotation(RENDERKIT.class);
if (renderKitAnnotation != null) {
processRenderKitAnnotation(renderKitAnnotation, currentClass);
}
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
VelocityTemplateEngine engine = new VelocityTemplateEngine();
try {
String filename = path + "/xulfaces-config.xml";
log.debug("Output file is " + filename + ".");
BufferedWriter bufferedWriter = new BufferedWriter(new FileWriter(filename));
log.debug("Output file created.");
engine.configure();
engine.prepareRender();
engine.setContextValue("facesConfig", this.facesConfig);
engine.renderTemplate(bufferedWriter, "faces-config.vm");
bufferedWriter.flush();
bufferedWriter.close();
} catch (Exception e1) {
throw new RuntimeException(e1);
}
}
private void processRenderKitAnnotation(RENDERKIT renderKitAnnotation, Class currentClass) {
String id = renderKitAnnotation.id();
RenderKit renderKit = this.facesConfig.getKits().get(id);
if (renderKit == null) {
renderKit = new RenderKit();
this.facesConfig.getKits().put(id, renderKit);
}
renderKit.populateWithAnnotation(renderKitAnnotation, currentClass);
}
private void processComponentAnnotation(Component component, Class currentClass) {
for (Field field : currentClass.getDeclaredFields()) {
ATTRIBUTE attributeAnnotation = field
.getAnnotation(ATTRIBUTE.class);
if(attributeAnnotation != null){
Attribute attribute = new Attribute(attributeAnnotation,field);
component.getAttributes().add(attribute);
}
}
StringWriter stringWriter = new StringWriter();
VelocityTemplateEngine engine = new VelocityTemplateEngine();
try {
engine.configure();
engine.prepareRender();
engine.setContextValue("component",component);
engine.renderTemplate(stringWriter,"component.vm");
this.facesConfig.components.put(currentClass.getName(),stringWriter.toString());
} catch (Exception e1) {
throw new RuntimeException(e1);
}
}
private String processRendererAnnotation(RENDERER rendererAnnotation, Class currentClass) {
StringWriter stringWriter = new StringWriter();
VelocityTemplateEngine engine = new VelocityTemplateEngine();
try {
engine.configure();
engine.prepareRender();
engine.setContextValue("family", rendererAnnotation.family());
engine.setContextValue("type", rendererAnnotation.type());
engine.setContextValue("classname", currentClass.getName());
engine.renderTemplate(stringWriter, "renderer.vm");
String kit = rendererAnnotation.kit();
RenderKit renderKit = this.facesConfig.getKits().get(kit);
if (renderKit == null) {
renderKit = new RenderKit();
}
renderKit.getRenderers().add(stringWriter.toString());
} catch (Exception e1) {
throw new RuntimeException(e1);
}
return stringWriter.toString();
}
public class RenderKit {
private String id;
private String classname;
private String description;
private String displayname;
private List<String> renderers = new ArrayList<String>();
public RenderKit() {
}
public void populateWithAnnotation(RENDERKIT renderKitAnnotation, Class currentClass) {
this.classname = currentClass.getName();
this.description = renderKitAnnotation.description();
this.displayname = renderKitAnnotation.displayname();
this.id = renderKitAnnotation.id();
}
public String getClassname() {
return classname;
}
public void setClassname(String classname) {
this.classname = classname;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getDisplayname() {
return displayname;
}
public void setDisplayname(String displayname) {
this.displayname = displayname;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public List<String> getRenderers() {
return renderers;
}
public void setRenderers(List<String> renderers) {
this.renderers = renderers;
}
}
public class FacesConfig {
private Map<String, RenderKit> kits = new HashMap<String, RenderKit>();
private Map<String, String> components = new HashMap<String, String>();
public Map<String, RenderKit> getKits() {
return kits;
}
public void setKits(Map<String, RenderKit> kits) {
this.kits = kits;
}
public Map<String, String> getComponents() {
return components;
}
public void setComponents(Map<String, String> components) {
this.components = components;
}
}
public class Component {
String type;
String classname;
List<Attribute> attributes = new ArrayList();
public Component(COMPONENT component,Class currentClass){
this.type = component.type();
this.classname = currentClass.getName();
}
public List<Attribute> getAttributes() {
return attributes;
}
public void setAttributes(List<Attribute> attributes) {
this.attributes = attributes;
}
public String getClassname() {
return classname;
}
public void setClassname(String classname) {
this.classname = classname;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
public class Attribute {
String name;
String type = "";
String description = "TODO !!";
public Attribute(ATTRIBUTE tagAttribute, Field field) {
this.name = tagAttribute.name();
if (this.name.equals("")) {
this.name = field.getName();
}
this.type = tagAttribute.type();
if (this.type.equals("")) {
this.type = field.getType().getName();
}
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 String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
}
}