blob: 2a8db838940ac381a083671df9b5fdafff95cd94 [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.PropertyBean;
import org.apache.myfaces.buildtools.maven2.plugin.faces.util.FilteredIterator;
import org.apache.myfaces.buildtools.maven2.plugin.faces.util.SourceTemplate;
import org.apache.myfaces.buildtools.maven2.plugin.faces.util.Util;
import java.io.IOException;
import java.lang.reflect.Modifier;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
import java.util.TreeSet;
/**
* TODO: comment this!
*
* @author Bruno Aranda (latest modification by $Author$)
* @version $Revision$ $Date$
*/
public abstract class AbstractComponentTagGenerator implements ComponentTagGenerator
{
public void writeImports(PrettyWriter out,
SourceTemplate template,
String packageName,
String fullSuperclassName,
String superclassName,
ComponentBean component)
{
Collection components = new HashSet();
components.add(component);
writeImports(out, template, packageName, fullSuperclassName, superclassName, components);
}
public void writeImports(PrettyWriter out, SourceTemplate template, String packageName, String fullSuperclassName,
String superclassName, Collection components)
{
Set imports = new TreeSet();
for (Iterator lIterator = components.iterator(); lIterator.hasNext();)
{
ComponentBean component = (ComponentBean) lIterator.next();
Iterator properties = component.properties();
properties = new FilteredIterator(properties, new TagAttributeFilter());
// TODO: remove these imports
// FIXME: Actually last 2 can be kept when not abstract
//imports.add("javax.faces.component.UIComponent");
// superclassName is fully qualified if it collides
// with the generated class name and should not be
// imported when such a collision would occur
if (!superclassName.equals(fullSuperclassName))
{
imports.add(fullSuperclassName);
}
while (properties.hasNext())
{
PropertyBean property = (PropertyBean) properties.next();
String propertyClass = property.getPropertyClass();
String[] propertyClassParams = property.getPropertyClassParameters();
if (propertyClass != null && property.isLiteralOnly())
{
// Import the property class only if only litterals are supported
// otherwise the class will be a String inside the tag to support
// ValueBinding
imports.add(propertyClass);
}
// TODO: restore import and make reference to
// ConstantMethodBinding relative rather
// than absolute
//if (property.isMethodBinding() &&
// isStringMethodBindingReturnType(property))
//{
// imports.add("org.apache.myfaces.trinidadinternal.taglib.ConstantMethodBinding");
//}
}
addSpecificImports(imports, component);
}
// do not import implicit!
imports.removeAll(Util.PRIMITIVE_TYPES);
GeneratorHelper.writeImports(out, packageName, imports);
}
public void writeClassBegin(PrettyWriter out,
String className,
String superclassName,
ComponentBean component,
SourceTemplate template)
{
int modifiers = component.getTagClassModifiers();
String classStart = Modifier.toString(modifiers);
out.println("/**");
out.println(" * Auto-generated tag class.");
out.println(" */");
// TODO: use canonical ordering
classStart = classStart.replaceAll("public abstract", "abstract public");
out.println(classStart + " class " + className +
" extends " + superclassName);
out.println("{");
out.indent();
}
public void writeConstructor(PrettyWriter out,
ComponentBean component,
int modifiers) throws IOException
{
String fullClassName = component.getTagClass();
String className = Util.getClassFromFullClass(fullClassName);
out.println();
out.println("/**");
// TODO: restore this correctly phrased comment (tense vs. command)
//out.println(" * Constructs an instance of " + className + ".");
out.println(" * Construct an instance of the " + className + ".");
out.println(" */");
out.println("public " + className + "()");
out.println("{");
out.println("}");
}
public void writeGetComponentType(
PrettyWriter out,
ComponentBean component) throws IOException
{
String componentType = component.getComponentType();
out.println();
// The superclass does not necessarily need to have this method
//out.println("@Override");
out.println("public String getComponentType()");
out.println("{");
out.indent();
out.println("return \"" + componentType + "\";");
out.unindent();
out.println("}");
}
public void writeGetRendererType(
PrettyWriter out,
ComponentBean component) throws IOException
{
String rendererType = component.getRendererType();
out.println();
// The superclass does not necessarily need to have this method
//out.println("@Override");
out.println("public String getRendererType()");
out.println("{");
out.indent();
out.println("return " + Util.convertStringToLiteral(rendererType) + ";");
out.unindent();
out.println("}");
}
public void writeClassEnd(PrettyWriter out)
{
out.unindent();
out.println("}");
}
public void writePropertyMembers(PrettyWriter out,
ComponentBean component) throws IOException
{
Iterator properties = component.properties();
properties = new FilteredIterator(properties, new TagAttributeFilter());
while (properties.hasNext())
{
PropertyBean property = (PropertyBean) properties.next();
writePropertyDeclaration(out, property);
writePropertySetter(out, property);
}
}
public void writePropertyMembers(PrettyWriter out, Collection components) throws IOException
{
for (Iterator lIterator = components.iterator(); lIterator.hasNext();)
{
writePropertyMembers(out, (ComponentBean) lIterator.next());
}
}
public void writeReleaseMethod(PrettyWriter out,
ComponentBean component) throws IOException
{
Collection components = new HashSet();
components.add(component);
writeReleaseMethod(out, components);
}
public void writeReleaseMethod(
PrettyWriter out, Collection components) throws IOException
{
Collection all = new HashSet();
boolean special = false;
for (Iterator lIterator = components.iterator(); lIterator.hasNext();)
{
ComponentBean component = (ComponentBean) lIterator.next();
Iterator prop = component.properties();
// TODO: remove special case for UIXFormTag
special |= "org.apache.myfaces.trinidadinternal.taglib.UIXFormTag".equals(component.getTagClass());
while (prop.hasNext())
{
all.add(prop.next());
}
}
Iterator properties = all.iterator();
properties = new FilteredIterator(properties, new TagAttributeFilter());
if (properties.hasNext() || special)
{
out.println();
if (is12()){
out.println("@Override");
}
out.println("public void release()");
out.println("{");
out.indent();
out.println("super.release();");
while (properties.hasNext())
{
PropertyBean property = (PropertyBean) properties.next();
String propName = property.getPropertyName();
String propVar = "_" + propName;
out.print(propVar + " = ");
String type = GeneratorHelper.getJspPropertyType(property, is12());
// FIXME: support all primitive types. In practice, the only types
// that have come up are ValueExpression, String, and boolean
if ("boolean".equals(type))
out.println("false;");
else
out.println("null;");
}
out.unindent();
out.println("}");
}
}
protected void addSpecificImports(
Set imports,
ComponentBean component)
{
// nothing by default
}
/**
* Returns true if the method is being used for generating JSF 1.2 code.
*/
protected abstract boolean is12();
protected abstract void writePropertyDeclaration(PrettyWriter out,
PropertyBean property) throws IOException;
protected abstract void writePropertySetter(PrettyWriter out,
PropertyBean property) throws IOException;
protected abstract void writeSetPropertyMethodBody(PrettyWriter out,
String componentClass,
Iterator properties) throws IOException;
}