/*
 *  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;

import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.apache.myfaces.buildtools.maven2.plugin.faces.generator.taglib.AbstractConverterTagGenerator;
import org.apache.myfaces.buildtools.maven2.plugin.faces.generator.taglib.AbstractValidatorTagGenerator;
import org.apache.myfaces.buildtools.maven2.plugin.faces.generator.taglib.ComponentTagGenerator;
import org.apache.myfaces.buildtools.maven2.plugin.faces.generator.taglib.MyFacesComponentTagGenerator;
import org.apache.myfaces.buildtools.maven2.plugin.faces.generator.taglib.MyFacesConverterTagGenerator;
import org.apache.myfaces.buildtools.maven2.plugin.faces.generator.taglib.MyFacesValidatorTagGenerator;
import org.apache.myfaces.buildtools.maven2.plugin.faces.generator.taglib.TagAttributeFilter;
import org.apache.myfaces.buildtools.maven2.plugin.faces.generator.taglib.TrinidadComponentTagGenerator;
import org.apache.myfaces.buildtools.maven2.plugin.faces.generator.taglib.TrinidadConverterTagGenerator;
import org.apache.myfaces.buildtools.maven2.plugin.faces.generator.taglib.TrinidadValidatorTagGenerator;
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.ConverterBean;
import org.apache.myfaces.buildtools.maven2.plugin.faces.parse.FacesConfigBean;
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.parse.ValidatorBean;
import org.apache.myfaces.buildtools.maven2.plugin.faces.util.ComponentFilter;
import org.apache.myfaces.buildtools.maven2.plugin.faces.util.ConverterFilter;
import org.apache.myfaces.buildtools.maven2.plugin.faces.util.FilteredIterator;
import org.apache.myfaces.buildtools.maven2.plugin.faces.util.Util;
import org.apache.myfaces.buildtools.maven2.plugin.faces.util.ValidatorFilter;
import org.apache.myfaces.buildtools.maven2.plugin.faces.util.XIncludeFilter;
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.OutputKeys;
import javax.xml.transform.Result;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.sax.SAXSource;
import javax.xml.transform.stream.StreamResult;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * @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    ");

    // In JSP 2.1, description goes up top
    if (_is12() && 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);

    // In JSP 2.0, description goes just before the attributes
    if (!_is12() && component.getDescription() != null)
    {
      stream.writeCharacters("\n    ");
      stream.writeStartElement("description");
      stream.writeCData(component.getDescription());
      stream.writeEndElement();
    }

    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 (_is12() && 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();
    }

    if (!_is12() && converter.getDescription() != null)
    {
      stream.writeCharacters("\n    ");
      stream.writeStartElement("description");
      stream.writeCData(converter.getDescription());
      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();
  }

  private void _writeTagAttributeDescription(
    XMLStreamWriter stream,
    String          description,
    String[]        unsupportedAgents) throws XMLStreamException
  {

    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();
    }
  }

  protected void writeTagAttribute(
    XMLStreamWriter stream,
    String          propertyName,
    String          description,
    String[]        unsupportedAgents,
    PropertyBean    property) throws XMLStreamException
  {
    stream.writeCharacters("\n    ");
    stream.writeStartElement("attribute");

    // In JSP 2.1, the description goes at the beginning
    if (_is12())
      _writeTagAttributeDescription(stream, description, unsupportedAgents);

    stream.writeCharacters("\n      ");
    stream.writeStartElement("name");
    
    if (property != null)
      stream.writeCharacters(property.getJspPropertyName());
    else
      stream.writeCharacters(propertyName);

    stream.writeEndElement();

    if (!_is12())
    {
      if (property != null)
      {        
        if (property.isRequired())
        {
          stream.writeCharacters("\n    ");
          stream.writeStartElement("required");
          stream.writeCharacters("true");
          stream.writeEndElement();
        }
      }
        
      stream.writeCharacters("\n      ");
      stream.writeStartElement("rtexprvalue");
      stream.writeCharacters("false");
      stream.writeEndElement();
      
      // In JSP 2.0, the tag description goes at the end
      _writeTagAttributeDescription(stream, description, unsupportedAgents);
    }
    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 if (property.isRtexprvalue())
        {
            stream.writeCharacters("\n      ");
            stream.writeStartElement("rtexprvalue");
            stream.writeCharacters("true");
            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 (_is12() && 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();
    }

    if (!_is12() && validator.getDescription() != null)
    {
      stream.writeCharacters("\n    ");
      stream.writeStartElement("description");
      stream.writeCData(validator.getDescription());
      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, MojoExecutionException {
    // Make sure generated source directory
    // is added to compilation source path
    project.addCompileSourceRoot(generatedSourceDirectory.getCanonicalPath());

    FacesConfigBean facesConfig = getFacesConfig();
    if (!facesConfig.hasComponents() && !facesConfig.hasConverters() && !facesConfig.hasValidators())
    {
      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() && !validators.hasNext())
      {
        getLog().info("Nothing to generate - all JSP tags are up to date");
      }
      else
      {
        ComponentTagHandlerGenerator componentGen = new ComponentTagHandlerGenerator();
        AbstractConverterTagGenerator converterGen = null;
        AbstractValidatorTagGenerator validatorGen = null;
        if (type == null || "trinidad".equals(type))
        {
          converterGen = new TrinidadConverterTagGenerator(is12(), getLicenseHeader(), getLog());
          validatorGen = new TrinidadValidatorTagGenerator(is12(), getLicenseHeader(), getLog());
        }
        else
        {
          converterGen = new MyFacesConverterTagGenerator(is12(), getLicenseHeader(), getLog());
          validatorGen = new MyFacesValidatorTagGenerator(is12(), getLicenseHeader(), getLog());    
        }
        int count = 0;
        while (components.hasNext())
        {
          ComponentBean component = (ComponentBean)components.next();
          if (!component.isTagClassExcluded())
          {
              componentGen.generateTagHandler(component);
              count++;
          }
        }
        while (converters.hasNext())
        {
          ConverterBean converter = (ConverterBean)converters.next();
          if (!converter.isTagClassExcluded())
          {
              converterGen.generateTagHandler(converter, generatedSourceDirectory);
              count++;
          }
        }
        while (validators.hasNext())
        {
          ValidatorBean validator = (ValidatorBean)validators.next();
          if (!validator.isTagClassExcluded())
          {
              validatorGen.generateTagHandler(validator, generatedSourceDirectory);
              count++;    
          }          
        }
        getLog().info("Generated " + count + " JSP tag(s)");
      }
    }
  }

  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;
      }else{
          if (is12() && "javax.faces.webapp.UIComponentTag".equalsIgnoreCase(fullSuperclassName)){
              fullSuperclassName = "javax.faces.webapp.UIComponentELTag";
          }else if (!is12() && "javax.faces.webapp.UIComponentELTag".equalsIgnoreCase(fullSuperclassName)){
              fullSuperclassName = "javax.faces.webapp.UIComponentTag";
          }
      }
      
      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());
        }

        getLog().debug("Generating " + fullClassName+", with generator: "+generator.getClass().getName());

        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;

  /**
   * @parameter expression="trinidad"
   */
  private String type;



  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");
  }
}
