blob: 748c7cda976daffd12f38514e79f255ecb5d8a6d [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.generator.taglib;
import org.apache.myfaces.trinidadbuild.plugin.faces.io.PrettyWriter;
import org.apache.myfaces.trinidadbuild.plugin.faces.util.ClassLoaderUtils;
import org.apache.myfaces.trinidadbuild.plugin.faces.util.Util;
import org.apache.myfaces.trinidadbuild.plugin.faces.util.FilteredIterator;
import org.apache.myfaces.trinidadbuild.plugin.faces.parse.AbstractTagBean;
import org.apache.myfaces.trinidadbuild.plugin.faces.parse.PropertyBean;
import org.apache.myfaces.trinidadbuild.plugin.faces.generator.GeneratorHelper;
import org.apache.maven.plugin.logging.Log;
import org.apache.maven.plugin.MojoExecutionException;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Set;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.Collections;
public abstract class AbstractTagGenerator {
protected Log _log;
protected boolean _is12;
protected String _licenseHeader;
static final private String _AUTO_GENERATE_WARNING =
"// WARNING: This file was automatically generated. Do not edit it directly,\n"+
"// or you will lose your changes.\n\n";
public AbstractTagGenerator(boolean is12, String licenseHeader, Log log) {
this._log = log;
this._licenseHeader = licenseHeader;
this._is12 = is12;
}
protected void writePreamble(
PrettyWriter out)
{
out.write(_AUTO_GENERATE_WARNING);
out.write(_licenseHeader);
}
protected Log getLog() {
return _log;
}
protected boolean is12() {
return _is12;
}
protected File createFile(File generatedSourceDirectory, String fullClassName) {
getLog().debug("Generating " + fullClassName);
String sourcePath = Util.convertClassToSourcePath(fullClassName, ".java");
File targetFile = new File(generatedSourceDirectory, sourcePath);
targetFile.getParentFile().mkdirs();
return targetFile;
}
protected void writeConstructor(
PrettyWriter out,
AbstractTagBean abstractTag) throws IOException
{
String fullClassName = abstractTag.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("}");
}
protected void writePropertyMethods(
PrettyWriter out,
AbstractTagBean abstractTag) throws IOException
{
Iterator<PropertyBean> properties = abstractTag.properties();
properties = new FilteredIterator(properties, new TagAttributeFilter());
while (properties.hasNext())
{
PropertyBean property = 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("}");
}
protected void writeRelease(
PrettyWriter out,
AbstractTagBean abstractTag) throws IOException
{
Iterator<PropertyBean> properties = abstractTag.properties();
properties = new FilteredIterator(properties, new TagAttributeFilter());
if (properties.hasNext())
{
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 = 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";
}
protected void writeEnd(PrettyWriter out) {
out.unindent();
out.println("}");
out.close();
}
protected void writeImports(
PrettyWriter out,
AbstractTagBean abstractTagBean, Set<String> imports)
{
// do not import implicit!
imports.removeAll(Util.PRIMITIVE_TYPES);
String packageName = Util.getPackageFromFullClass(abstractTagBean.getTagClass());
GeneratorHelper.writeImports(out, packageName, imports);
}
protected final void writeHeader(PrettyWriter out, AbstractTagBean converter, Set<String> imports) {
String packageName = Util.getPackageFromFullClass(converter.getTagClass());
// header/copyright
writePreamble(out);
// package
out.println("package " + packageName + ";");
out.println();
writeImports(out, converter, imports);
out.println("/**");
out.println(" * Auto-generated tag class.");
out.println(" */");
}
protected void addImportsFromPropertes(AbstractTagBean abstractTagBean, Set<String> imports) {
Iterator<PropertyBean> properties = abstractTagBean.properties();
properties = new FilteredIterator(properties, new TagAttributeFilter());
while (properties.hasNext())
{
PropertyBean property = properties.next();
String propertyClass = property.getPropertyClass();
if (propertyClass != null)
imports.add(propertyClass);
if ("java.lang.String[]".equals(propertyClass))
{
imports.add("java.text.ParseException");
}
}
}
protected String resolveDateType(String className, boolean useMaxTime)
{
String type = (String)_RESOLVABLE_TYPES.get(className);
return useMaxTime ? type + "WithMaxTime" : type;
}
protected String resolveType(String className)
{
String type = (String)_RESOLVABLE_TYPES.get(className);
if (type != null)
return (String)_RESOLVABLE_TYPES.get(className);
try
{
// Enums may be set using String, add those as discovered.
if (ClassLoaderUtils.loadClass (className).isEnum())
{
_RESOLVABLE_TYPES .put (className, "Enum");
return "Enum";
}
}
catch (LinkageError le)
{
getLog().info("Linkage error resolving type " + className, le);
}
catch (ClassNotFoundException ce)
{
getLog().info ("ClassNotFound error resolving type " + className, ce);
}
return null;
}
// 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
private Map<String, String> _createResolvableTypes()
{
Map<String, String> resolvableTypes = new ConcurrentHashMap<String, String>();
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 (resolvableTypes);
}
private Map _RESOLVABLE_TYPES = _createResolvableTypes();
}