blob: 54f1cecb41f805eb434b9575003932e5910ec87c [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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.apache.myfaces.buildtools.maven2.plugin.faces.generator.taglib;
import org.apache.myfaces.buildtools.maven2.plugin.faces.generator.GeneratorHelper;
import org.apache.myfaces.buildtools.maven2.plugin.faces.io.PrettyWriter;
import org.apache.myfaces.buildtools.maven2.plugin.faces.parse.ComponentBean;
import org.apache.myfaces.buildtools.maven2.plugin.faces.parse.MethodSignatureBean;
import org.apache.myfaces.buildtools.maven2.plugin.faces.parse.PropertyBean;
import org.apache.myfaces.buildtools.maven2.plugin.faces.util.FilteredIterator;
import org.apache.myfaces.buildtools.maven2.plugin.faces.util.Util;
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
/**
* Component tag generator for myfaces
*
* @author Bruno Aranda (latest modification by $Author$)
* @version $Revision$ $Date$
*/
public class MyFacesComponentTagGenerator extends AbstractComponentTagGenerator
{
private boolean _is12;
public MyFacesComponentTagGenerator(boolean is12)
{
_is12 = is12;
}
protected boolean is12()
{
return _is12;
}
protected void addSpecificImports(Set imports,
ComponentBean component)
{
imports.add("javax.faces.component.UIComponent");
imports.add(component.getComponentClass());
if (_is12)
{
imports.add("javax.el.ValueExpression");
}
else
{
imports.add("javax.faces.el.ValueBinding");
imports.add("javax.faces.context.FacesContext");
}
Iterator properties = component.properties();
properties = new FilteredIterator(properties, new TagAttributeFilter());
while (properties.hasNext())
{
PropertyBean property = (PropertyBean) properties.next();
String propertyClass = property.getPropertyClass();
if (GeneratorHelper.isConverter(propertyClass))
{
if (!_is12)
{
imports.add("javax.faces.el.ValueBinding");
}
imports.add("javax.faces.convert.Converter");
}
else if (property.isMethodBinding())
{
if (_is12)
{
imports.add("javax.el.MethodExpression");
if (GeneratorHelper.isActionListener(property, _is12))
{
imports.add("javax.faces.event.MethodExpressionActionListener");
}
if (GeneratorHelper.isValueChangeListener(property, _is12))
{
imports.add("javax.faces.event.MethodExpressionValueChangeListener");
}
if (GeneratorHelper.isValidator(property, _is12))
{
imports.add("javax.faces.validator.MethodExpressionValidator");
}
}
else
{
imports.add("javax.faces.el.MethodBinding");
}
}
else if (property.isMethodExpression())
{
imports.add("javax.el.MethodExpression");
}
else if (GeneratorHelper.isActionListener(property, _is12))
{
imports.add("javax.faces.event.MethodExpressionActionListener");
}
else if (GeneratorHelper.isValueChangeListener(property, _is12))
{
imports.add("javax.faces.event.MethodExpressionValueChangeListener");
}
else if (GeneratorHelper.isValidator(property, _is12))
{
imports.add("javax.faces.validator.MethodExpressionValidator");
}
}
}
protected void writePropertyDeclaration(PrettyWriter out,
PropertyBean property) throws IOException
{
String fieldPropName = property.getFieldPropertyName();
String jspPropType = GeneratorHelper.getJspPropertyType(property, _is12);
out.println();
out.println("private " + jspPropType + " " + fieldPropName + ";");
}
protected void writePropertySetter(PrettyWriter out,
PropertyBean property) throws IOException
{
String propName = property.getPropertyName();
String fieldPropName = property.getFieldPropertyName();
String jspPropName = property.getJspPropertyName();
String propVar = Util.getVariableFromName(propName);
String setMethod = Util.getPrefixedPropertyName("set", jspPropName);
String jspPropType = GeneratorHelper.getJspPropertyType(property, _is12);
out.println("public void " + setMethod + "(" + jspPropType + " " + propVar + ")");
out.println("{");
out.indent();
out.println(fieldPropName + " = " + propVar + ";");
out.unindent();
out.println("}");
}
public void writeGetComponentType(PrettyWriter out,
ComponentBean component) throws IOException
{
String componentType = component.getComponentType();
if("javax.faces.HtmlColumn".equals(componentType))
{
componentType = "javax.faces.Column";
}
out.println();
// The superclass does not necessarily need to have this method
if (is12()){
out.println("@Override");
}
out.println("public String getComponentType()");
out.println("{");
out.indent();
out.println("return \"" + componentType + "\";");
out.unindent();
out.println("}");
}
public void writeSetPropertiesMethod(PrettyWriter out,
String componentClass,
ComponentBean component) throws IOException
{
Collection components = new HashSet();
components.add(component);
writeSetPropertiesMethod(out, componentClass, components);
}
public void writeSetPropertiesMethod(PrettyWriter out, String componentClass, Collection components)
throws IOException
{
Collection all = new HashSet();
for (Iterator lIterator = components.iterator(); lIterator.hasNext();)
{
ComponentBean component = (ComponentBean) lIterator.next();
Iterator prop = component.properties();
while (prop.hasNext())
{
all.add(prop.next());
}
}
Iterator properties = all.iterator();
properties = new FilteredIterator(properties, new TagAttributeFilter());
out.println();
if (_is12)
{
out.println("@Override");
}
out.println("protected void setProperties(UIComponent component)");
out.unindent();
out.println("{");
out.indent();
writeSetPropertyMethodBody(out, componentClass, properties);
out.unindent();
out.println("}");
}
protected void writeSetPropertyMethodBody(PrettyWriter out,
String componentClass,
Iterator properties) throws IOException
{
if("HtmlColumn".equals(componentClass))
{
componentClass = "UIColumn";
}
out.println("if (!(component instanceof " + componentClass + "))");
out.println("{");
out.indent();
out.print("throw new IllegalArgumentException(");
out.print("\"Component \" + component.getClass().getName() + \" is no " + componentClass + "\"");
out.println(");");
out.unindent();
out.println("}");
out.println(componentClass + " comp = (" + componentClass + ")component;");
out.println();
out.println("super.setProperties(component);");
out.println();
if (!_is12)
{
out.println("FacesContext context = getFacesContext();");
}
while (properties.hasNext())
{
PropertyBean property = (PropertyBean) properties.next();
_writeSetPropertiesCase(out, componentClass, property);
}
}
private void _writeSetPropertiesCase(
PrettyWriter out,
String componentClass,
PropertyBean property) throws IOException
{
if (property.isMethodBinding())
{
_writeSetMethodBinding(out, componentClass, property);
}
else if (property.isMethodExpression())
{
_writeSetMethodExpression(out, componentClass, property);
}
else if (GeneratorHelper.isConverter(property.getPropertyClass()))
{
_writeSetConverter(out, componentClass, property.getPropertyName());
}
else
{
_writeSetProperty(out, property);
}
}
private void _writeSetProperty(
PrettyWriter out,
PropertyBean property)
{
String propName = property.getPropertyName();
String propVar = "_" + propName;
out.println("if (" + propVar + " != null) ");
out.println("{");
out.indent();
if (property.isLiteralOnly())
{
if (_is12){
out.println("comp.getAttributes().put(\"" + propName + "\", " + propVar + ");");
}else{
String propertyClass = property.getPropertyClass().trim();
if (propertyClass.startsWith("java.lang.")){
propertyClass = propertyClass.replace("java.lang.", "");
}
if (propertyClass.endsWith("eger")){
propertyClass = propertyClass.replace("eger", "");
}
if (Util.isPrimitiveClass(propertyClass.toLowerCase())){
out.println("comp.getAttributes().put(\"" + propName + "\", " +
Util.getBoxedClass(propertyClass.toLowerCase())+".valueOf(" + propVar + "));");
}else{
out.println("comp.getAttributes().put(\"" + propName + "\", " + propVar + ");");
}
}
}
else if (_is12)
{
out.println("comp.setValueExpression(\"" + propName + "\", " + propVar + ");");
}
else
{
_writeSetValueBinding(out, property, propName, propVar);
}
out.unindent();
out.println("}");
}
private void _writeSetValueBinding(
PrettyWriter out,
PropertyBean property,
String propName,
String propVar)
{
out.println("if (isValueReference(" + propVar + "))");
out.println("{");
out.indent();
out.println("ValueBinding vb = context.getApplication().createValueBinding(" + propVar + ");");
out.println("comp.setValueBinding(\"" + propName + "\", vb);");
out.unindent();
out.println("}");
out.println("else");
out.println("{");
out.indent();
if (!is12() && "value".equals(propName))
{
out.println("comp.setValue(" + propVar + ");");
}
else
{
if (Util.isPrimitiveClass(property.getPropertyClass())){
out.println("comp.getAttributes().put(\"" + propName + "\", " +
Util.getBoxedClass(property.getPropertyClass())+".valueOf(" + propVar + "));");
}else{
String propertyClass = property.getPropertyClass().trim();
if (propertyClass.startsWith("java.lang.")){
propertyClass = propertyClass.replace("java.lang.", "");
}
if (propertyClass.endsWith("eger")){
propertyClass = propertyClass.replace("eger", "");
}
if (Util.isPrimitiveClass(propertyClass.toLowerCase())){
out.println("comp.getAttributes().put(\"" + propName + "\", " +
Util.getBoxedClass(propertyClass.toLowerCase())+".valueOf(" + propVar + "));");
}else{
out.println("comp.getAttributes().put(\"" + propName + "\", " + propVar + ");");
}
}
}
out.unindent();
out.println("}");
}
private void _writeSetMethodBinding(
PrettyWriter out,
String componentClass,
PropertyBean property) throws IOException
{
String propName = property.getPropertyName();
String propKey = Util.getConstantNameFromProperty(propName, "_KEY");
String propVar = "_" + propName;
if (_is12)
{
out.println("if (" + propVar + " != null)");
out.println("{");
out.indent();
if (GeneratorHelper.isActionListener(property, _is12))
{
out.println("comp.addActionListener(new MethodExpressionActionListener(" + propVar + "));");
}
else if (GeneratorHelper.isValueChangeListener(property, _is12))
{
out.println("comp.addValueChangeListener(new MethodExpressionValueChangeListener(" + propVar + "));");
}
else if (GeneratorHelper.isValidator(property, _is12))
{
out.println("comp.addValidator(new MethodExpressionValidator(" + propVar + "));");
}
else
{
out.println("bean.setProperty(" + componentClass + "." + propKey + ", " +
"new MethodExpressionMethodBinding(" + propVar + "));");
}
out.unindent();
out.println("}");
}
else
{
MethodSignatureBean signature = property.getMethodBindingSignature();
String[] paramTypes = (signature != null) ? signature.getParameterTypes() : null;
String classArray;
if (paramTypes == null || paramTypes.length == 0)
{
classArray = "new Class[0]";
}
else
{
StringBuffer sb = new StringBuffer();
sb.append("new Class[]{");
for (int i = 0; i < paramTypes.length; i++)
{
if (i > 0)
sb.append(',');
sb.append(paramTypes[i]);
sb.append(".class");
}
// TODO: remove trailing comma
sb.append(',');
sb.append('}');
classArray = sb.toString();
}
out.println("if (" + propVar + " != null)");
out.println("{");
out.indent();
if (isStringMethodBindingReturnType(signature) || property.getJspPropertyName().equals("action"))
{
out.println("MethodBinding mb;");
out.println("if (isValueReference(" + propVar + "))");
out.indent();
out.println("mb = context.getApplication().createMethodBinding(" + propVar + ", " + classArray + ");");
out.unindent();
out.println("else");
out.indent();
if (!is12() && property.getJspPropertyName().equals("action")){
out.println("mb = new org.apache.myfaces.shared_tomahawk.el.SimpleActionMethodBinding("+propVar+");");
}else{
out.println("throw new IllegalStateException(\"Invalid expression \" + "+propVar+");");
}
out.unindent();
}
else
{
// never a literal, no need for ConstantMethodBinding
out.println("MethodBinding mb = context.getApplication().createMethodBinding(" + propVar + ", " +
classArray + ");");
}
String setMethod = Util.getPrefixedPropertyName("set", propName);
out.println("comp."+setMethod+"(mb);");
out.unindent();
out.println("}");
}
}
private void _writeSetMethodExpression(
PrettyWriter out,
String componentClass,
PropertyBean property) throws IOException
{
String propName = property.getPropertyName();
String propVar = property.getFieldPropertyName();
out.println("if (" + propVar + " != null) ");
out.println("{");
out.indent();
if (GeneratorHelper.isAction(property))
{
out.println("comp.setActionExpression(" + propVar + ");");
}
else if (GeneratorHelper.isActionListener(property, _is12))
{
out.println("comp.addActionListener(new MethodExpressionActionListener(" + propVar + "));");
}
else
{
out.println("comp." + Util.getPrefixedPropertyName("set", propName) + "(" + propVar + ");");
}
out.unindent();
out.println("}");
}
private void _writeSetKeyStroke(
PrettyWriter out,
String componentClass,
String propName) throws IOException
{
String propKey = Util.getConstantNameFromProperty(propName, "_KEY");
String propVar = "_" + propName;
if (_is12)
{
out.println("if (" + propVar + " != null)");
out.println("{");
out.indent();
out.println("if (!" + propVar + ".isLiteralText())");
out.println("{");
out.indent();
out.println("bean.setValueExpression(" + componentClass + "." + propKey + ", " + propVar + ");");
out.unindent();
out.println("}");
out.println("else");
out.println("{");
out.indent();
out.println("Object val = " + propVar + ".getValue(null);");
out.println("if (val != null)");
out.indent();
out.println("bean.setProperty(" + componentClass + "." + propKey + ",");
out.println("\tKeyStroke.getKeyStroke(val.toString()));");
out.unindent();
out.unindent();
out.println("}");
out.unindent();
out.println("}");
}
else
{
out.println("if (" + propVar + " != null)");
out.println("{");
out.indent();
out.println("if (isValueReference(" + propVar + "))");
out.println("{");
out.indent();
out.println("ValueBinding vb = createValueBinding(" + propVar + ");");
out.println("bean.setValueBinding(" + componentClass + "." + propKey + ", vb);");
out.unindent();
out.println("}");
out.println("else");
out.println("{");
out.indent();
out.println("bean.setProperty(" + componentClass + "." + propKey + ",");
out.println("\tKeyStroke.getKeyStroke(" + propVar + "));");
out.unindent();
out.println("}");
out.unindent();
out.println("}");
}
}
private void _writeSetConverter(
PrettyWriter out,
String componentClass,
String propName) throws IOException
{
String propKey = Util.getConstantNameFromProperty(propName, "_KEY");
String propVar = "_" + propName;
out.println("if (" + propVar + " != null)");
out.println("{");
out.indent();
if (_is12)
{
out.println("if (!" + propVar + ".isLiteralText())");
out.println("{");
out.indent();
out.println("comp.setValueExpression(\"" + propName + "\", " + propVar + ");");
out.unindent();
out.println("}");
out.println("else");
out.println("{");
out.indent();
out.println("String s = " + propVar + ".getExpressionString();");
out.println("if (s != null)");
out.println("{");
out.indent();
out.println("Converter converter = getFacesContext().getApplication().");
out.indent();
out.println("createConverter(s);");
out.unindent();
out.println("comp.setConverter(converter);");
out.unindent();
out.println("}");
out.unindent();
out.println("}");
}
else
{
out.println("if (isValueReference(" + propVar + "))");
out.println("{");
out.indent();
out.println("ValueBinding vb = context.getApplication().createValueBinding(" + propVar + ");");
out.println("comp.setValueBinding(\"" +propName+ "\", vb);");
out.unindent();
out.println("}");
out.println("else");
out.println("{");
out.indent();
out.println("Converter converter = getFacesContext().getApplication().");
out.indent();
out.println("createConverter(" + propVar + ");");
out.unindent();
out.println("comp.setConverter(converter);");
out.unindent();
out.println("}");
}
out.unindent();
out.println("}");
}
private boolean isStringMethodBindingReturnType(
MethodSignatureBean sig)
{
return (sig != null && "java.lang.String".equals(sig.getReturnType()));
}
}