blob: 0f7220fe056aaa5e0a82ba5dfc1a8adbe9b88d5c [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.trinidadbuild.plugin.faces;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.apache.myfaces.trinidadbuild.plugin.faces.generator.taglib.ComponentTagGenerator;
import org.apache.myfaces.trinidadbuild.plugin.faces.generator.taglib.MyFacesComponentTagGenerator;
import org.apache.myfaces.trinidadbuild.plugin.faces.generator.taglib.TagAttributeFilter;
import org.apache.myfaces.trinidadbuild.plugin.faces.generator.taglib.TrinidadComponentTagGenerator;
import org.apache.myfaces.trinidadbuild.plugin.faces.io.PrettyWriter;
import org.apache.myfaces.trinidadbuild.plugin.faces.parse.*;
import org.apache.myfaces.trinidadbuild.plugin.faces.util.*;
import org.codehaus.plexus.util.FileUtils;
import org.xml.sax.EntityResolver;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.stream.XMLOutputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamWriter;
import javax.xml.transform.*;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import java.io.*;
import java.lang.reflect.Modifier;
import java.util.*;
/**
* @version $Id$
* @requiresDependencyResolution compile
* @goal generate-jsp-taglibs
* @phase generate-sources
*/
public class GenerateJspTaglibsMojo extends AbstractFacesMojo
{
/**
* Execute the Mojo.
*/
public void execute() throws MojoExecutionException
{
try
{
processIndex(project, resourcePath);
_generateTagHandlers();
_generateTagLibraryDescriptors();
}
catch (IOException e)
{
throw new MojoExecutionException("Error generating components", e);
}
}
// hook for custom component tag java content
protected void writeCustomComponentTagHandlerContent(
PrettyWriter out,
ComponentBean component) throws IOException
{
}
// hook for custom component tag java imports
protected void addCustomComponentTagHandlerImports(
Set imports,
ComponentBean component)
{
}
// hook for custom component descriptor content
protected void writeCustomComponentTagDescriptorContent(
XMLStreamWriter stream,
ComponentBean component)throws XMLStreamException
{
}
/**
* Generates tag library descriptors for parsed component metadata.
*/
private void _generateTagLibraryDescriptors() throws MojoExecutionException
{
try
{
// always add resources directory to project resource root
addResourceRoot(project, generatedResourcesDirectory.getCanonicalPath());
// taglibs map syntax requires distinct shortNames,
// which is a Good Thing!
for (Iterator i = taglibs.entrySet().iterator(); i.hasNext(); )
{
Map.Entry entry = (Map.Entry)i.next();
String shortName = (String)entry.getKey();
String namespaceURI = (String)entry.getValue();
FacesConfigBean facesConfig = getFacesConfig();
Iterator components = facesConfig.components();
components = new FilteredIterator(components, new SkipFilter());
components = new FilteredIterator(components, new ComponentTagLibraryFilter(namespaceURI));
Iterator validators = facesConfig.validators();
validators = new FilteredIterator(validators, new ValidatorTagLibraryFilter(namespaceURI));
Iterator converters = facesConfig.converters();
converters = new FilteredIterator(converters, new ConverterTagLibraryFilter(namespaceURI));
String targetPath = "META-INF/" + shortName + ".tld";
File targetFile = new File(generatedResourcesDirectory, targetPath);
String configPath = "META-INF/" + shortName + "-base.tld";
File configFile = new File(configSourceDirectory, configPath);
targetFile.delete();
boolean hasGeneratedTags = (components.hasNext() ||
converters.hasNext() ||
validators.hasNext());
if (hasGeneratedTags && configFile.exists())
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
XMLStreamWriter stream = outputFactory.createXMLStreamWriter(out);
_writeStartTagLibrary(stream, _XINCLUDE_JSP_TAG_LIBRARY_DTD);
// base goes first
stream.writeStartElement("xi", "include",
XIncludeFilter.XINCLUDE_NAMESPACE);
stream.writeNamespace("xi", XIncludeFilter.XINCLUDE_NAMESPACE);
stream.writeAttribute("href", configFile.toURL().toExternalForm());
stream.writeAttribute("xpointer", "/taglib/*");
stream.writeEndElement();
while (components.hasNext())
{
ComponentBean component = (ComponentBean)components.next();
_writeTag(stream, component);
}
while (converters.hasNext())
{
ConverterBean converter = (ConverterBean)converters.next();
_writeTag(stream, converter);
}
while (validators.hasNext())
{
ValidatorBean validator = (ValidatorBean)validators.next();
_writeTag(stream, validator);
}
_writeEndTagLibrary(stream);
stream.close();
InputStream mergedStream = new ByteArrayInputStream(out.toByteArray());
// expand all the xi:include elements
SAXParserFactory saxFactory = SAXParserFactory.newInstance();
saxFactory.setNamespaceAware(true);
saxFactory.setValidating(false);
SAXParser saxParser = saxFactory.newSAXParser();
XMLReader mergedReader = saxParser.getXMLReader();
mergedReader = new XIncludeFilter(mergedReader, configFile.toURL());
// even with validating=false, DTD is still downloaded so that
// any entities contained in the document can be expanded.
// the following disables that behavior, also saving the time
// spent to parse the DTD
mergedReader.setEntityResolver(new EntityResolver()
{
public InputSource resolveEntity(
String publicId,
String systemId)
{
return new InputSource(new ByteArrayInputStream(new byte[0]));
}
});
InputSource mergedInput = new InputSource(mergedStream);
Source mergedSource = new SAXSource(mergedReader, mergedInput);
targetFile.delete();
targetFile.getParentFile().mkdirs();
Result mergedResult = new StreamResult(new FileOutputStream(targetFile));
TransformerFactory transFactory = TransformerFactory.newInstance();
Transformer identity = transFactory.newTransformer();
if (!_is12())
{
identity.setOutputProperty(OutputKeys.DOCTYPE_PUBLIC,
_JSP_TAG_LIBRARY_DOCTYPE_PUBLIC);
identity.setOutputProperty(OutputKeys.DOCTYPE_SYSTEM,
_JSP_TAG_LIBRARY_DOCTYPE_SYSTEM);
}
identity.transform(mergedSource, mergedResult);
targetFile.setReadOnly();
}
else if (hasGeneratedTags)
{
targetFile.getParentFile().mkdirs();
OutputStream out = new FileOutputStream(targetFile);
XMLOutputFactory outputFactory = XMLOutputFactory.newInstance();
XMLStreamWriter stream = outputFactory.createXMLStreamWriter(out);
_writeStartTagLibrary(stream, _is12() ? "2.1" : "1.2", shortName, namespaceURI);
while (components.hasNext())
{
ComponentBean component = (ComponentBean)components.next();
_writeTag(stream, component);
}
while (converters.hasNext())
{
ConverterBean converter = (ConverterBean)converters.next();
_writeTag(stream, converter);
}
while (validators.hasNext())
{
ValidatorBean validator = (ValidatorBean)validators.next();
_writeTag(stream, validator);
}
_writeEndTagLibrary(stream);
stream.close();
}
else if (configFile.exists())
{
// copy if newer
if (configFile.lastModified() > targetFile.lastModified())
{
targetFile.delete();
targetFile.getParentFile().mkdirs();
FileUtils.copyFile(configFile, targetFile);
targetFile.setReadOnly();
}
}
}
}
catch (SAXException e)
{
throw new MojoExecutionException("Error generating tag library", e);
}
catch (ParserConfigurationException e)
{
throw new MojoExecutionException("Error generating tag library", e);
}
catch (TransformerException e)
{
throw new MojoExecutionException("Error generating tag library", e);
}
catch (XMLStreamException e)
{
throw new MojoExecutionException("Error generating tag library", e);
}
catch (IOException e)
{
throw new MojoExecutionException("Error generating tag libraries", e);
}
}
private void _writeStartTagLibrary(
XMLStreamWriter stream,
String dtd) throws XMLStreamException
{
stream.writeStartDocument("1.0");
stream.writeCharacters("\n");
if (!_is12())
stream.writeDTD(dtd);
stream.writeCharacters("\n");
stream.writeStartElement("taglib");
if (_is12())
{
stream.writeNamespace("", "http://java.sun.com/xml/ns/javaee");
stream.writeNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
stream.writeAttribute("xsi:schemaLocation", "http://java.sun.com/xml/ns/javaee/web-jsptaglibrary_2_1.xsd");
stream.writeAttribute("version", "2.1");
}
stream.writeCharacters("\n ");
}
private void _writeStartTagLibrary(
XMLStreamWriter stream,
String version,
String shortName,
String namespaceURI) throws XMLStreamException
{
_writeStartTagLibrary(stream, _JSP_TAG_LIBRARY_DTD);
stream.writeStartElement("tlib-version");
String tlibVersion = project.getVersion();
// Remove everything but dewey-decimal characters (i.e., numbers and periods)
tlibVersion = tlibVersion.replaceAll("[^.0-9]", "");
// Remove leading and/or trailing periods
while (tlibVersion.startsWith("."))
{
tlibVersion = tlibVersion.substring(1);
}
while (tlibVersion.endsWith("."))
{
tlibVersion = tlibVersion.substring(0, tlibVersion.length() - 1);
}
stream.writeCharacters(tlibVersion);
stream.writeEndElement();
if (!_is12())
{
stream.writeCharacters("\n ");
stream.writeStartElement("jsp-version");
stream.writeCharacters(version);
stream.writeEndElement();
}
stream.writeCharacters("\n ");
stream.writeStartElement("short-name");
stream.writeCharacters(shortName);
stream.writeEndElement();
stream.writeCharacters("\n ");
stream.writeStartElement("uri");
stream.writeCharacters(namespaceURI);
stream.writeEndElement();
}
private void _writeEndTagLibrary(
XMLStreamWriter stream) throws XMLStreamException
{
stream.writeCharacters("\n");
stream.writeEndElement();
stream.writeEndDocument();
}
/**
* Generates tag library descriptor for parsed component metadata.
*/
private void _writeTag(
XMLStreamWriter stream,
ComponentBean component) throws XMLStreamException
{
stream.writeCharacters("\n ");
stream.writeStartElement("tag");
stream.writeCharacters("\n ");
if (component.getDescription() != null)
{
stream.writeCharacters("\n ");
stream.writeStartElement("description");
stream.writeCData(component.getDescription());
stream.writeEndElement();
}
stream.writeStartElement("name");
stream.writeCharacters(component.getTagName().getLocalPart());
stream.writeEndElement();
stream.writeCharacters("\n ");
stream.writeStartElement("tag-class");
stream.writeCharacters(component.getTagClass());
stream.writeEndElement();
// In JSP 2.1, body-content is not optional
if (_is12())
{
stream.writeCharacters("\n ");
stream.writeStartElement("body-content");
stream.writeCharacters("JSP");
stream.writeEndElement();
}
GenerateJspTaglibsMojo.this.writeCustomComponentTagDescriptorContent(stream, component);
Iterator properties = component.properties(true);
properties = new FilteredIterator(properties, new TagAttributeFilter());
while (properties.hasNext())
{
PropertyBean property = (PropertyBean)properties.next();
writeTagAttribute(stream,
property.getPropertyName(),
property.getDescription(),
property.getUnsupportedAgents(),
property);
}
stream.writeCharacters("\n ");
stream.writeEndElement();
}
/**
* Generates tag library descriptor for parsed converter metadata.
*/
private void _writeTag(
XMLStreamWriter stream,
ConverterBean converter) throws XMLStreamException
{
stream.writeCharacters("\n ");
stream.writeStartElement("tag");
stream.writeCharacters("\n ");
if (converter.getDescription() != null)
{
stream.writeCharacters("\n ");
stream.writeStartElement("description");
stream.writeCData(converter.getDescription());
stream.writeEndElement();
}
stream.writeStartElement("name");
stream.writeCharacters(converter.getTagName().getLocalPart());
stream.writeEndElement();
stream.writeCharacters("\n ");
stream.writeStartElement("tag-class");
stream.writeCharacters(converter.getTagClass());
stream.writeEndElement();
// In JSP 2.1, body-content is not optional
if (_is12())
{
stream.writeCharacters("\n ");
stream.writeStartElement("body-content");
stream.writeCharacters("empty");
stream.writeEndElement();
}
// converters need an id attribute
writeTagAttribute(stream, "id", "the identifier for the converter", null, null);
Iterator properties = converter.properties();
properties = new FilteredIterator(properties, new TagAttributeFilter());
while (properties.hasNext())
{
PropertyBean property = (PropertyBean)properties.next();
writeTagAttribute(stream,
property.getPropertyName(),
property.getDescription(),
property.getUnsupportedAgents(),
property);
}
stream.writeCharacters("\n ");
stream.writeEndElement();
}
protected void writeTagAttribute(
XMLStreamWriter stream,
String propertyName,
String description,
String[] unsupportedAgents,
PropertyBean property) throws XMLStreamException
{
stream.writeCharacters("\n ");
stream.writeStartElement("attribute");
if (description != null ||
unsupportedAgents.length > 0)
{
stream.writeCharacters("\n ");
stream.writeStartElement("description");
if (unsupportedAgents != null &&
unsupportedAgents.length > 0)
{
if (description == null)
description = "";
description += "\n\n This attribute is not supported on the following agent types:\n";
for (int i=0; i < unsupportedAgents.length; i++)
{
description += " " + unsupportedAgents[i];
description += (i < unsupportedAgents.length - 1) ? "," : ".";
}
}
stream.writeCData(description);
stream.writeEndElement();
}
stream.writeCharacters("\n ");
stream.writeStartElement("name");
if (property != null)
stream.writeCharacters(property.getJspPropertyName());
else
stream.writeCharacters(propertyName);
stream.writeEndElement();
if (!_is12())
{
stream.writeCharacters("\n ");
stream.writeStartElement("rtexprvalue");
stream.writeCharacters("false");
stream.writeEndElement();
}
else
{
if (property != null)
{
if (property.isRequired())
{
stream.writeCharacters("\n ");
stream.writeStartElement("required");
stream.writeCharacters("true");
stream.writeEndElement();
}
if (property.isMethodExpression() || property.isMethodBinding())
{
stream.writeCharacters("\n ");
stream.writeStartElement("deferred-method");
stream.writeCharacters("\n ");
MethodSignatureBean sig = property.getMethodBindingSignature();
if (sig != null)
{
stream.writeStartElement("method-signature");
stream.writeCharacters(sig.getReturnType());
stream.writeCharacters(" myMethod(");
String[] params = sig.getParameterTypes();
for (int i = 0; i < params.length; i++)
{
if (i > 0)
stream.writeCharacters(", ");
stream.writeCharacters(params[i]);
}
stream.writeCharacters(")");
stream.writeEndElement();
}
stream.writeEndElement();
}
else if (!property.isLiteralOnly() ||
// "binding" is always a deferred-value
"binding".equals(propertyName))
{
stream.writeCharacters("\n ");
stream.writeStartElement("deferred-value");
String propertyClass = property.getPropertyClass();
// Writing java.lang.String is usually a bad idea - it
// means that null gets coerced to the empty string.
if (("java.lang.String".equals(propertyClass) && coerceStrings) ||
_CAN_COERCE.contains(property.getPropertyClass()))
{
stream.writeCharacters("\n ");
stream.writeStartElement("type");
// Trim out any use of generics here - since JSP coercion
// certainly can't do anything there
int genericIndex = propertyClass.indexOf('<');
if (genericIndex > 0)
propertyClass = propertyClass.substring(0, genericIndex);
stream.writeCharacters(propertyClass);
stream.writeEndElement();
stream.writeCharacters("\n ");
}
stream.writeEndElement();
}
else
{
stream.writeCharacters("\n ");
stream.writeStartElement("rtexprvalue");
// As of JSF 1.2, "id" can be set via an rtexprvalue (but
// *not* by a ValueExpression) - it has to be evaluated
// in the JSP
if ("id".equals(propertyName) && !disableIdExpressions)
stream.writeCharacters("true");
else
stream.writeCharacters("false");
stream.writeEndElement();
}
}
}
stream.writeCharacters("\n ");
stream.writeEndElement();
}
/**
* Generates tag library descriptor for parsed validator metadata.
*/
private void _writeTag(
XMLStreamWriter stream,
ValidatorBean validator) throws XMLStreamException
{
stream.writeCharacters("\n ");
stream.writeStartElement("tag");
if (validator.getDescription() != null)
{
stream.writeCharacters("\n ");
stream.writeStartElement("description");
stream.writeCData(validator.getDescription());
stream.writeEndElement();
}
stream.writeCharacters("\n ");
stream.writeStartElement("name");
stream.writeCharacters(validator.getTagName().getLocalPart());
stream.writeEndElement();
stream.writeCharacters("\n ");
stream.writeStartElement("tag-class");
stream.writeCharacters(validator.getTagClass());
stream.writeEndElement();
// In JSP 2.1, body-content is not optional
if (_is12())
{
stream.writeCharacters("\n ");
stream.writeStartElement("body-content");
stream.writeCharacters("empty");
stream.writeEndElement();
}
// validators need an id attribute
writeTagAttribute(stream, "id", "the identifier for the validator", null, null);
Iterator properties = validator.properties();
properties = new FilteredIterator(properties, new TagAttributeFilter());
while (properties.hasNext())
{
PropertyBean property = (PropertyBean)properties.next();
writeTagAttribute(stream,
property.getPropertyName(),
property.getDescription(),
property.getUnsupportedAgents(),
property);
}
stream.writeCharacters("\n ");
stream.writeEndElement();
}
/**
* Generates tag handlers for parsed component metadata.
*/
private void _generateTagHandlers() throws IOException
{
// Make sure generated source directory
// is added to compilation source path
project.addCompileSourceRoot(generatedSourceDirectory.getCanonicalPath());
FacesConfigBean facesConfig = getFacesConfig();
if (!facesConfig.hasComponents())
{
getLog().info("Nothing to generate - no components found");
}
else
{
Iterator components = facesConfig.components();
components = new FilteredIterator(components, new SkipFilter());
components = new FilteredIterator(components, new ComponentTagFilter());
components = new FilteredIterator(components, new ComponentTagClassFilter(packageContains));
Iterator validators = facesConfig.validators();
validators = new FilteredIterator(validators, new ValidatorTagFilter());
validators = new FilteredIterator(validators, new ValidatorTagClassFilter(packageContains));
Iterator converters = facesConfig.converters();
converters = new FilteredIterator(converters, new ConverterTagFilter());
converters = new FilteredIterator(converters, new ConverterTagClassFilter(packageContains));
// incremental unless forced
if (!force)
{
components = new FilteredIterator(components, new IfComponentModifiedFilter());
converters = new FilteredIterator(converters, new IfConverterModifiedFilter());
validators = new FilteredIterator(validators, new IfValidatorModifiedFilter());
}
if (!components.hasNext() && !converters.hasNext())
{
getLog().info("Nothing to generate - all JSP tags are up to date");
}
else
{
ComponentTagHandlerGenerator componentGen = new ComponentTagHandlerGenerator();
ConverterTagGenerator converterGen = new ConverterTagGenerator();
ValidatorTagGenerator validatorGen = new ValidatorTagGenerator();
int count = 0;
while (components.hasNext())
{
componentGen.generateTagHandler((ComponentBean)components.next());
count++;
}
while (converters.hasNext())
{
converterGen.generateTagHandler((ConverterBean)converters.next());
count++;
}
while (validators.hasNext())
{
validatorGen.generateTagHandler((ValidatorBean)validators.next());
count++;
}
getLog().info("Generated " + count + " JSP tag(s)");
}
}
}
class ConverterTagGenerator
{
public void generateTagHandler(
ConverterBean converter)
{
String fullClassName = converter.getTagClass();
try
{
getLog().debug("Generating " + fullClassName);
String sourcePath = Util.convertClassToSourcePath(fullClassName, ".java");
File targetFile = new File(generatedSourceDirectory, sourcePath);
targetFile.getParentFile().mkdirs();
StringWriter sw = new StringWriter();
PrettyWriter out = new PrettyWriter(sw);
String className = Util.getClassFromFullClass(fullClassName);
String packageName = Util.getPackageFromFullClass(fullClassName);
// header/copyright
writePreamble(out);
// package
out.println("package " + packageName + ";");
out.println();
_writeImports(out, converter);
out.println("/**");
// TODO: remove this blank line.
out.println();
out.println(" * Auto-generated tag class.");
out.println(" */");
if (_is12())
{
out.println("public class " + className +
" extends ConverterELTag");
}
else
{
out.println("public class " + className +
" extends ConverterTag");
}
out.println("{");
out.indent();
_writeConstructor(out, converter);
_writePropertyMethods(out, converter);
_writeDoStartTag(out, converter);
_writeCreateConverter(out, converter);
_writeSetProperties(out, converter);
_writeRelease(out, converter);
out.unindent();
out.println("}");
out.close();
// delay write in case of error
// timestamp should not be updated when an error occurs
// delete target file first, because it is readonly
targetFile.delete();
FileWriter fw = new FileWriter(targetFile);
StringBuffer buf = sw.getBuffer();
fw.write(buf.toString());
fw.close();
targetFile.setReadOnly();
}
catch (Throwable e)
{
getLog().error("Error generating " + fullClassName, e);
}
}
private void _writeImports(
PrettyWriter out,
ConverterBean converter)
{
Set imports = new TreeSet();
if (_is12())
{
imports.add("javax.faces.webapp.ConverterELTag");
imports.add("javax.faces.context.FacesContext");
imports.add("javax.faces.application.Application");
}
else
imports.add("javax.faces.webapp.ConverterTag");
imports.add("javax.servlet.jsp.JspException");
imports.add(converter.getConverterClass());
Iterator properties = converter.properties();
properties = new FilteredIterator(properties, new TagAttributeFilter());
if (properties.hasNext())
{
imports.add("javax.faces.convert.Converter");
if (_is12())
imports.add("javax.el.ValueExpression");
else
imports.add("javax.faces.el.ValueBinding");
imports.add("org.apache.myfaces.trinidadinternal.taglib.util.TagUtils");
}
while (properties.hasNext())
{
PropertyBean property = (PropertyBean)properties.next();
String propertyClass = property.getPropertyClass();
if (propertyClass != null)
imports.add(propertyClass);
if ("java.lang.String[]".equals(propertyClass))
{
imports.add("java.text.ParseException");
}
}
// do not import implicit!
imports.removeAll(Util.PRIMITIVE_TYPES);
String tagClass = converter.getTagClass();
String packageName = Util.getPackageFromFullClass(tagClass);
writeImports(out, packageName, imports);
}
private void _writeConstructor(
PrettyWriter out,
ConverterBean converter) throws IOException
{
String fullClassName = converter.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("}");
}
private void _writePropertyMethods(
PrettyWriter out,
ConverterBean converter) throws IOException
{
Iterator properties = converter.properties();
properties = new FilteredIterator(properties, new TagAttributeFilter());
while (properties.hasNext())
{
PropertyBean property = (PropertyBean)properties.next();
out.println();
_writePropertyMember(out, property);
_writePropertySet(out, property);
}
}
private void _writePropertyMember(
PrettyWriter out,
PropertyBean property) throws IOException
{
String propName = property.getPropertyName();
String propVar = "_" + Util.getVariableFromName(propName);
String jspPropType = _getJspPropertyType(property);
out.println("private " + jspPropType + " " + propVar + ";");
}
private void _writePropertySet(
PrettyWriter out,
PropertyBean property) throws IOException
{
String propName = property.getPropertyName();
String propVar = Util.getVariableFromName(propName);
String setMethod = Util.getPrefixedPropertyName("set", propName);
String jspPropType = _getJspPropertyType(property);
// TODO: restore coding standards, and make final
out.println("public void " + setMethod + "(" + jspPropType + " " + propVar + ")");
out.println("{");
out.indent();
out.println("_" + propVar + " = " + propVar + ";");
out.unindent();
out.println("}");
}
private void _writeDoStartTag(
PrettyWriter out,
ConverterBean converter) throws IOException
{
if (!_is12())
{
String converterFullClass = converter.getConverterClass();
String converterClass = Util.getClassFromFullClass(converterFullClass);
out.println();
// TODO: restore coding standards, and make final
out.println("@Override");
out.println("public int doStartTag() throws JspException");
out.println("{");
out.indent();
out.println("super.setConverterId(" + converterClass + ".CONVERTER_ID);");
out.println("return super.doStartTag();");
out.unindent();
out.println("}");
}
}
private void _writeCreateConverter(
PrettyWriter out,
ConverterBean converter) throws IOException
{
Iterator properties = converter.properties();
properties = new FilteredIterator(properties, new TagAttributeFilter());
if (properties.hasNext())
{
String converterFullClass = converter.getConverterClass();
String converterClass = Util.getClassFromFullClass(converterFullClass);
out.println();
// TODO: restore coding standards, and make final
out.println("@Override");
out.println("protected Converter createConverter() throws JspException");
out.println("{");
out.indent();
if (_is12())
{
out.println("String converterId = " + converterClass + ".CONVERTER_ID;");
out.println("Application appl = FacesContext.getCurrentInstance().getApplication();");
out.println(converterClass + " converter = " +
"(" + converterClass + ")appl.createConverter(converterId);");
}
else
{
out.println(converterClass + " converter = " +
"(" + converterClass + ")super.createConverter();");
}
out.println("_setProperties(converter);");
out.println("return converter;");
out.unindent();
out.println("}");
}
}
private void _writeSetProperties(
PrettyWriter out,
ConverterBean converter) throws IOException
{
Iterator properties = converter.properties();
properties = new FilteredIterator(properties, new TagAttributeFilter());
if (properties.hasNext())
{
String converterFullClass = converter.getConverterClass();
String converterClass = Util.getClassFromFullClass(converterFullClass);
out.println();
out.println("private void _setProperties(");
out.indent();
out.println(converterClass + " converter) throws JspException");
out.unindent();
out.println("{");
out.indent();
while (properties.hasNext())
{
PropertyBean property = (PropertyBean)properties.next();
_writeSetProperty(out, property);
}
out.unindent();
out.println("}");
}
}
private void _writeSetProperty(
PrettyWriter out,
PropertyBean property)
{
String propName = property.getPropertyName();
String propFullClass = property.getPropertyClass();
String propClass = Util.getClassFromFullClass(propFullClass);
String propVar = "_" + Util.getVariableFromName(propName);
out.println("if (" + propVar + " != null)");
out.println("{");
out.indent();
if (_is12())
{
out.println("if (!" + propVar + ".isLiteralText())");
out.println("{");
out.indent();
out.println("converter.setValueExpression(\"" + propName + "\", " +
propVar + ");");
out.unindent();
out.println("}");
String propType = _resolveType(propFullClass);
if (propType != null)
{
out.println("else");
out.println("{");
out.indent();
if ("StringArray".equals(propType))
{
out.println("try");
out.println("{");
}
out.println(propClass + " value = TagUtils.get" + propType + "(" + propVar + ".getValue(null));");
String setMethod = Util.getPrefixedPropertyName("set", propName);
out.println("converter." + setMethod + "(value);");
if ("StringArray".equals(propType))
{
out.println("}");
out.println("catch (ParseException pe)");
out.println("{");
out.indent();
out.println("throw new JspException(");
out.println(" pe.getMessage() + \": \" + \"Position \" + pe.getErrorOffset());");
out.unindent();
out.println("}");
}
out.unindent();
out.println("}");
}
}
else
{
out.println("if (TagUtils.isValueReference(" + propVar + "))");
out.println("{");
out.indent();
out.println("ValueBinding vb = TagUtils.getValueBinding(" + propVar + ");");
out.println("converter.setValueBinding(\"" + propName + "\", vb);");
out.unindent();
out.println("}");
String propType = _resolveType(propFullClass);
if (propType != null)
{
out.println("else");
out.println("{");
out.indent();
if ("StringArray".equals(propType))
{
out.println("try");
out.println("{");
}
out.println(propClass + " value = TagUtils.get" + propType + "(" + propVar + ");");
String setMethod = Util.getPrefixedPropertyName("set", propName);
out.println("converter." + setMethod + "(value);");
if ("StringArray".equals(propType))
{
out.println("}");
out.println("catch (ParseException pe)");
out.println("{");
out.indent();
out.println("throw new JspException(");
out.println(" pe.getMessage() + \": \" + \"Position \" + pe.getErrorOffset());");
out.unindent();
out.println("}");
}
out.unindent();
out.println("}");
}
}
out.unindent();
out.println("}");
}
private void _writeRelease(
PrettyWriter out,
ConverterBean converter) throws IOException
{
Iterator properties = converter.properties();
properties = new FilteredIterator(properties, new TagAttributeFilter());
if (properties.hasNext())
{
out.println();
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 = "_" + Util.getVariableFromName(propName);
out.println(propVar + " = null;");
}
out.unindent();
out.println("}");
}
}
private String _getJspPropertyType(PropertyBean property)
{
if (property.isMethodExpression())
return "MethodExpression";
if (_is12() && property.isMethodBinding())
return "MethodExpression";
if (_is12() && !property.isLiteralOnly())
return "ValueExpression";
return "String";
}
}
class ValidatorTagGenerator
{
public void generateTagHandler(
ValidatorBean validator)
{
String fullClassName = validator.getTagClass();
try
{
getLog().debug("Generating " + fullClassName);
String sourcePath = Util.convertClassToSourcePath(fullClassName, ".java");
File targetFile = new File(generatedSourceDirectory, sourcePath);
targetFile.getParentFile().mkdirs();
StringWriter sw = new StringWriter();
PrettyWriter out = new PrettyWriter(sw);
String className = Util.getClassFromFullClass(fullClassName);
String packageName = Util.getPackageFromFullClass(fullClassName);
// header/copyright
writePreamble(out);
// package
out.println("package " + packageName + ";");
out.println();
_writeImports(out, validator);
out.println("/**");
// TODO: remove this blank line.
out.println();
out.println(" * Auto-generated tag class.");
out.println(" */");
if (_is12())
{
out.println("public class " + className +
" extends ValidatorELTag");
}
else
{
out.println("public class " + className +
" extends ValidatorTag");
}
out.println("{");
out.indent();
_writeConstructor(out, validator);
_writePropertyMethods(out, validator);
_writeDoStartTag(out, validator);
_writeCreateValidator(out, validator);
_writeSetProperties(out, validator);
_writeRelease(out, validator);
out.unindent();
out.println("}");
out.close();
// delay write in case of error
// timestamp should not be updated when an error occurs
// delete target file first, because it is readonly
targetFile.delete();
FileWriter fw = new FileWriter(targetFile);
StringBuffer buf = sw.getBuffer();
fw.write(buf.toString());
fw.close();
targetFile.setReadOnly();
}
catch (Throwable e)
{
getLog().error("Error generating " + fullClassName, e);
}
}
private void _writeImports(
PrettyWriter out,
ValidatorBean validator)
{
Set imports = new TreeSet();
if (_is12())
{
imports.add("javax.faces.webapp.ValidatorELTag");
imports.add("javax.faces.context.FacesContext");
imports.add("javax.faces.application.Application");
}
else
imports.add("javax.faces.webapp.ValidatorTag");
imports.add("javax.servlet.jsp.JspException");
imports.add(validator.getValidatorClass());
Iterator properties = validator.properties();
properties = new FilteredIterator(properties, new TagAttributeFilter());
if (properties.hasNext())
{
imports.add("javax.faces.validator.Validator");
if (_is12())
imports.add("javax.el.ValueExpression");
else
imports.add("javax.faces.el.ValueBinding");
imports.add("org.apache.myfaces.trinidadinternal.taglib.util.TagUtils");
}
while (properties.hasNext())
{
PropertyBean property = (PropertyBean)properties.next();
String propertyClass = property.getPropertyClass();
if (propertyClass != null)
imports.add(propertyClass);
if ("java.lang.String[]".equals(propertyClass))
{
imports.add("java.text.ParseException");
}
}
// do not import implicit!
imports.removeAll(Util.PRIMITIVE_TYPES);
String tagClass = validator.getTagClass();
String packageName = Util.getPackageFromFullClass(tagClass);
writeImports(out, packageName, imports);
}
private void _writeConstructor(
PrettyWriter out,
ValidatorBean validator) throws IOException
{
String fullClassName = validator.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("}");
}
private void _writePropertyMethods(
PrettyWriter out,
ValidatorBean validator) throws IOException
{
Iterator properties = validator.properties();
properties = new FilteredIterator(properties, new TagAttributeFilter());
while (properties.hasNext())
{
PropertyBean property = (PropertyBean)properties.next();
out.println();
_writePropertyMember(out, property);
_writePropertySet(out, property);
}
}
private void _writePropertyMember(
PrettyWriter out,
PropertyBean property) throws IOException
{
String propName = property.getPropertyName();
String propVar = "_" + Util.getVariableFromName(propName);
String jspPropType = _getJspPropertyType(property);
out.println("private " + jspPropType + " " + propVar + ";");
}
private void _writePropertySet(
PrettyWriter out,
PropertyBean property) throws IOException
{
String propName = property.getPropertyName();
String propVar = Util.getVariableFromName(propName);
String setMethod = Util.getPrefixedPropertyName("set", propName);
String jspPropType = _getJspPropertyType(property);
// TODO: restore coding standards, and make final
out.println("public void " + setMethod + "(" + jspPropType + " " + propVar + ")");
out.println("{");
out.indent();
out.println("_" + propVar + " = " + propVar + ";");
out.unindent();
out.println("}");
}
private void _writeDoStartTag(
PrettyWriter out,
ValidatorBean validator) throws IOException
{
out.println();
if (!_is12())
{
String validatorFullClass = validator.getValidatorClass();
String validatorClass = Util.getClassFromFullClass(validatorFullClass);
// TODO: restore coding standards, and make final
out.println("@Override");
out.println("public int doStartTag() throws JspException");
out.println("{");
out.indent();
out.println("super.setValidatorId(" + validatorClass + ".VALIDATOR_ID);");
out.println("return super.doStartTag();");
out.unindent();
out.println("}");
}
}
private void _writeCreateValidator(
PrettyWriter out,
ValidatorBean validator) throws IOException
{
Iterator properties = validator.properties();
properties = new FilteredIterator(properties, new TagAttributeFilter());
if (properties.hasNext())
{
String validatorFullClass = validator.getValidatorClass();
String validatorClass = Util.getClassFromFullClass(validatorFullClass);
out.println();
// TODO: restore coding standards, and make final
out.println("@Override");
out.println("protected Validator createValidator() throws JspException");
out.println("{");
out.indent();
if (_is12())
{
out.println("String validatorId = " + validatorClass + ".VALIDATOR_ID;");
out.println("Application appl = FacesContext.getCurrentInstance().getApplication();");
out.println(validatorClass + " validator = " +
"(" + validatorClass + ")appl.createValidator(validatorId);");
}
else
{
out.println(validatorClass + " validator = " +
"(" + validatorClass + ")super.createValidator();");
}
out.println("_setProperties(validator);");
out.println("return validator;");
out.unindent();
out.println("}");
}
}
private void _writeSetProperties(
PrettyWriter out,
ValidatorBean validator) throws IOException
{
Iterator properties = validator.properties();
properties = new FilteredIterator(properties, new TagAttributeFilter());
if (properties.hasNext())
{
String validatorFullClass = validator.getValidatorClass();
String validatorClass = Util.getClassFromFullClass(validatorFullClass);
out.println();
out.println("private void _setProperties(");
out.indent();
out.println(validatorClass + " validator) throws JspException");
out.unindent();
out.println("{");
out.indent();
while (properties.hasNext())
{
PropertyBean property = (PropertyBean)properties.next();
_writeSetProperty(out, property);
}
out.unindent();
out.println("}");
}
}
private void _writeSetProperty(
PrettyWriter out,
PropertyBean property)
{
String propName = property.getPropertyName();
String propFullClass = property.getPropertyClass();
String propClass = Util.getClassFromFullClass(propFullClass);
String propVar = "_" + Util.getVariableFromName(propName);
out.println("if (" + propVar + " != null)");
out.println("{");
out.indent();
if (_is12())
{
out.println("if (!" + propVar + ".isLiteralText())");
out.println("{");
out.indent();
out.println("validator.setValueExpression(\"" + propName + "\", " +
propVar + ");");
out.unindent();
out.println("}");
String propType = _resolveType(propFullClass);
if (propType != null)
{
out.println("else");
out.println("{");
out.indent();
if ("StringArray".equals(propType))
{
out.println("try");
out.println("{");
}
out.println(propClass + " value = TagUtils.get" + propType + "(" + propVar + ".getValue(null));");
String setMethod = Util.getPrefixedPropertyName("set", propName);
out.println("validator." + setMethod + "(value);");
if ("StringArray".equals(propType))
{
out.println("}");
out.println("catch (ParseException pe)");
out.println("{");
out.indent();
out.println("throw new JspException(");
out.println(" pe.getMessage() + \": \" + \"Position \" + pe.getErrorOffset());");
out.unindent();
out.println("}");
}
out.unindent();
out.println("}");
}
}
else
{
out.println("if (TagUtils.isValueReference(" + propVar + "))");
out.println("{");
out.indent();
out.println("ValueBinding vb = TagUtils.getValueBinding(" + propVar + ");");
out.println("validator.setValueBinding(\"" + propName + "\", vb);");
out.unindent();
out.println("}");
String propType = _resolveType(propFullClass);
if (propType != null)
{
out.println("else");
out.println("{");
out.indent();
if ("StringArray".equals(propType))
{
out.println("try");
out.println("{");
}
out.println(propClass + " value = TagUtils.get" + propType + "(" + propVar + ");");
String setMethod = Util.getPrefixedPropertyName("set", propName);
out.println("validator." + setMethod + "(value);");
if ("StringArray".equals(propType))
{
out.println("}");
out.println("catch (ParseException pe)");
out.println("{");
out.indent();
out.println("throw new JspException(");
out.println(" pe.getMessage() + \": \" + \"Position \" + pe.getErrorOffset());");
out.unindent();
out.println("}");
}
out.unindent();
out.println("}");
}
}
out.unindent();
out.println("}");
}
private void _writeRelease(
PrettyWriter out,
ValidatorBean validator) throws IOException
{
Iterator properties = validator.properties();
properties = new FilteredIterator(properties, new TagAttributeFilter());
if (properties.hasNext())
{
out.println();
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 = "_" + Util.getVariableFromName(propName);
out.println(propVar + " = null;");
}
out.unindent();
out.println("}");
}
}
private String _getJspPropertyType(PropertyBean property)
{
if (property.isMethodExpression())
return "MethodExpression";
if (_is12() && property.isMethodBinding())
return "MethodExpression";
if (_is12() && !property.isLiteralOnly())
return "ValueExpression";
return "String";
}
}
class ComponentTagHandlerGenerator
{
private Set initComponentList(ComponentBean component,
String fullSuperclassName)
{
Set componentList = new HashSet();
componentList.add(component);
ComponentBean lBean = component;
while ((lBean = lBean.resolveSupertype()) != null &&
!fullSuperclassName.equals(lBean.getTagClass()))
{
getLog().debug(component.getComponentType()+
": Add additional Tags from: " + lBean.getComponentType());
componentList.add(lBean);
}
return componentList;
}
public void generateTagHandler(ComponentBean component)
{
ComponentTagGenerator generator;
Set componentList;
String fullSuperclassName = component.findJspTagSuperclass();
if (fullSuperclassName == null)
{
getLog().warn("Missing JSP Tag superclass for component: " + component.getComponentClass()
+ ", generation of this Tag is skipped");
return;
}
componentList = initComponentList(component, fullSuperclassName);
String fullClassName = component.getTagClass();
try
{
getLog().debug("Generating " + fullClassName);
String sourcePath = Util.convertClassToSourcePath(fullClassName, ".java");
File targetFile = new File(generatedSourceDirectory, sourcePath);
targetFile.getParentFile().mkdirs();
StringWriter sw = new StringWriter();
PrettyWriter out = new PrettyWriter(sw);
if (component.isTrinidadComponent())
{
generator = new TrinidadComponentTagGenerator(_is12());
}
else
{
generator = new MyFacesComponentTagGenerator(_is12());
}
String className = Util.getClassFromFullClass(fullClassName);
String packageName = Util.getPackageFromFullClass(fullClassName);
// header/copyright
writePreamble(out);
// package
out.println("package " + packageName + ";");
out.println();
String superclassName = Util.getClassFromFullClass(fullSuperclassName);
if (superclassName.equals(className))
{
superclassName = fullSuperclassName;
}
String componentFullClass = component.getComponentClass();
String componentClass = Util.getClassFromFullClass(componentFullClass);
generator.writeImports(out, null, packageName, fullSuperclassName, superclassName, componentList);
generator.writeClassBegin(out, className, superclassName, component, null);
int modifiers = component.getTagClassModifiers();
generator.writeConstructor(out, component, modifiers);
if (!Modifier.isAbstract(modifiers))
{
generator.writeGetComponentType(out, component);
generator.writeGetRendererType(out, component);
}
GenerateJspTaglibsMojo.this.writeCustomComponentTagHandlerContent(out, component);
generator.writePropertyMembers(out, componentList);
generator.writeSetPropertiesMethod(out, componentClass, componentList);
generator.writeReleaseMethod(out, componentList);
generator.writeClassEnd(out);
out.close();
// delay write in case of error
// timestamp should not be updated when an error occurs
// delete target file first, because it is readonly
targetFile.delete();
FileWriter fw = new FileWriter(targetFile);
StringBuffer buf = sw.getBuffer();
fw.write(buf.toString());
fw.close();
targetFile.setReadOnly();
}
catch (Throwable e)
{
getLog().error("Error generating " + fullClassName, e);
}
}
}
protected boolean is12()
{
return "1.2".equals(jsfVersion) || "12".equals(jsfVersion);
}
private boolean _is12()
{
return is12();
}
private class IfComponentModifiedFilter extends ComponentFilter
{
protected boolean accept(
ComponentBean component)
{
String tagClass = component.getTagClass();
String sourcePath = Util.convertClassToSourcePath(tagClass, ".java");
String templatePath = Util.convertClassToSourcePath(tagClass, "Template.java");
File targetFile = new File(generatedSourceDirectory, sourcePath);
File templateFile = new File(templateSourceDirectory, templatePath);
// accept if templateFile is newer or component has been modified
return (templateFile.lastModified() > targetFile.lastModified() ||
component.isModifiedSince(targetFile.lastModified()));
}
}
private class IfConverterModifiedFilter extends ConverterFilter
{
protected boolean accept(
ConverterBean converter)
{
String tagClass = converter.getTagClass();
String sourcePath = Util.convertClassToSourcePath(tagClass, ".java");
String templatePath = Util.convertClassToSourcePath(tagClass, "Template.java");
File targetFile = new File(generatedSourceDirectory, sourcePath);
File templateFile = new File(templateSourceDirectory, templatePath);
// accept if templateFile is newer or component has been modified
return (templateFile.lastModified() > targetFile.lastModified() ||
converter.isModifiedSince(targetFile.lastModified()));
}
}
private class IfValidatorModifiedFilter extends ValidatorFilter
{
protected boolean accept(
ValidatorBean validator)
{
String tagClass = validator.getTagClass();
String sourcePath = Util.convertClassToSourcePath(tagClass, ".java");
String templatePath = Util.convertClassToSourcePath(tagClass, "Template.java");
File targetFile = new File(generatedSourceDirectory, sourcePath);
File templateFile = new File(templateSourceDirectory, templatePath);
// accept if templateFile is newer or component has been modified
return (templateFile.lastModified() > targetFile.lastModified() ||
validator.isModifiedSince(targetFile.lastModified()));
}
}
/**
* @parameter expression="${project}"
* @required
* @readonly
*/
protected MavenProject project;
/**
* @parameter
* @required
*/
protected Map taglibs;
/**
* @parameter expression="META-INF/maven-faces-plugin/faces-config.xml"
* @required
* @readonly
*/
protected String resourcePath;
/**
* @parameter expression="src/main/conf"
* @required
*/
protected File configSourceDirectory;
/**
* @parameter expression="src/main/java-templates"
* @required
*/
protected File templateSourceDirectory;
/**
* @parameter expression="${project.build.directory}/maven-faces-plugin/main/java"
* @required
*/
protected File generatedSourceDirectory;
/**
* @parameter expression="${project.build.directory}/maven-faces-plugin/main/resources"
* @required
*/
protected File generatedResourcesDirectory;
/**
* @parameter
*/
protected String packageContains = "";
/**
* @parameter
*/
protected boolean force;
/**
* @parameter
*/
protected boolean disableIdExpressions;
/**
* @parameter
*/
protected boolean coerceStrings;
/**
* @parameter
*/
private String jsfVersion;
static private String _resolveType(
String className)
{
return (String)_RESOLVABLE_TYPES.get(className);
}
// TODO: for everything but Locale, String[], Date, and TimeZone,
// in JSF 1.2 we should already be going through coercion, and
// not need any of the "TagUtils" functions
static private Map _createResolvableTypes()
{
Map resolvableTypes = new HashMap();
resolvableTypes.put("boolean", "Boolean");
resolvableTypes.put("char", "Character");
resolvableTypes.put("java.util.Date", "Date");
resolvableTypes.put("int", "Integer");
resolvableTypes.put("float", "Float");
resolvableTypes.put("double", "Double");
resolvableTypes.put("java.util.Locale", "Locale");
resolvableTypes.put("long", "Long");
resolvableTypes.put("java.lang.String", "String");
resolvableTypes.put("java.lang.String[]", "StringArray");
resolvableTypes.put("java.util.TimeZone", "TimeZone");
return Collections.unmodifiableMap(resolvableTypes);
}
static final private Map _RESOLVABLE_TYPES = _createResolvableTypes();
static final private String _JSP_TAG_LIBRARY_DOCTYPE_PUBLIC =
"-//Sun Microsystems, Inc.//DTD JSP Tag Library 1.2//EN";
static final private String _JSP_TAG_LIBRARY_DOCTYPE_SYSTEM =
"http://java.sun.com/dtd/web-jsptaglibrary_1_2.dtd";
static final private String _JSP_TAG_LIBRARY_DTD =
"<!DOCTYPE taglib PUBLIC \n" +
" \"" + _JSP_TAG_LIBRARY_DOCTYPE_PUBLIC + "\"\n" +
" \"" + _JSP_TAG_LIBRARY_DOCTYPE_SYSTEM + "\" >\n";
static final private String _XINCLUDE_JSP_TAG_LIBRARY_DTD =
"<!DOCTYPE taglib PUBLIC\n" +
" \"" + _JSP_TAG_LIBRARY_DOCTYPE_PUBLIC + "\"\n" +
" \"" + _JSP_TAG_LIBRARY_DOCTYPE_SYSTEM + "\" [\n" +
" <!ELEMENT xi:include EMPTY>\n" +
" <!ATTLIST xi:include\n" +
" xmlns:xi CDATA #FIXED \"" + XIncludeFilter.XINCLUDE_NAMESPACE + "\"\n" +
" href CDATA #IMPLIED\n" +
" xpointer CDATA #IMPLIED>\n" +
"]>\n";
static final private Set _CAN_COERCE = new HashSet();
static
{
// What? Can't coerce Strings? How could that be? Well, take a look at:
// http://issues.apache.org/jira/browse/ADFFACES-377
// The silly coercion rules in JSP convert null to the
// empty string. So it's not that we can't coerce to
// String, we just really, really don't want to.
// _CAN_COERCE.add("java.lang.String");
// TODO: consider getting rid of coercion rules for
// all non-primitives
_CAN_COERCE.add("java.lang.Integer");
_CAN_COERCE.add("java.lang.Long");
_CAN_COERCE.add("java.lang.Boolean");
_CAN_COERCE.add("java.lang.Double");
_CAN_COERCE.add("java.lang.Float");
_CAN_COERCE.add("java.lang.Short");
_CAN_COERCE.add("java.lang.Character");
_CAN_COERCE.add("java.lang.Byte");
_CAN_COERCE.add("int");
_CAN_COERCE.add("long");
_CAN_COERCE.add("boolean");
_CAN_COERCE.add("double");
_CAN_COERCE.add("float");
_CAN_COERCE.add("short");
_CAN_COERCE.add("char");
_CAN_COERCE.add("byte");
// See http://issues.apache.org/jira/browse/ADFFACES-477: for
// "binding" and "converter" properties, we want the deferred-types
// there. Hardcoding these here is very ugly, but putting in
// all coercion rules would break how Trinidad handles Dates,
// and Lists of Colors, etc. - for those, we want to support
// raw Strings (which the JSP engine doesn't know how to coerce)
// and coerce them ourselves in the tag.
_CAN_COERCE.add("javax.faces.component.UIComponent");
_CAN_COERCE.add("javax.faces.convert.Converter");
}
}