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

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 org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;
import org.apache.myfaces.trinidadbuild.plugin.faces.generator.taglib.AbstractConverterTagGenerator;
import org.apache.myfaces.trinidadbuild.plugin.faces.generator.taglib.AbstractValidatorTagGenerator;
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.MyFacesConverterTagGenerator;
import org.apache.myfaces.trinidadbuild.plugin.faces.generator.taglib.MyFacesValidatorTagGenerator;
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.generator.taglib.TrinidadConverterTagGenerator;
import org.apache.myfaces.trinidadbuild.plugin.faces.generator.taglib.TrinidadValidatorTagGenerator;
import org.apache.myfaces.trinidadbuild.plugin.faces.io.PrettyWriter;
import org.apache.myfaces.trinidadbuild.plugin.faces.parse.ComponentBean;
import org.apache.myfaces.trinidadbuild.plugin.faces.parse.ConverterBean;
import org.apache.myfaces.trinidadbuild.plugin.faces.parse.FacesConfigBean;
import org.apache.myfaces.trinidadbuild.plugin.faces.parse.MethodSignatureBean;
import org.apache.myfaces.trinidadbuild.plugin.faces.parse.PropertyBean;
import org.apache.myfaces.trinidadbuild.plugin.faces.parse.ValidatorBean;
import org.apache.myfaces.trinidadbuild.plugin.faces.util.ComponentFilter;
import org.apache.myfaces.trinidadbuild.plugin.faces.util.ConverterFilter;
import org.apache.myfaces.trinidadbuild.plugin.faces.util.FilteredIterator;
import org.apache.myfaces.trinidadbuild.plugin.faces.util.SourceTemplate;
import org.apache.myfaces.trinidadbuild.plugin.faces.util.Util;
import org.apache.myfaces.trinidadbuild.plugin.faces.util.ValidatorFilter;
import org.apache.myfaces.trinidadbuild.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;


/**
 * @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(
   @SuppressWarnings("unused") PrettyWriter  out,
   @SuppressWarnings("unused") ComponentBean component
    ) throws IOException
  {
  }

  // hook for custom component tag java imports
  protected void addCustomComponentTagHandlerImports(
    @SuppressWarnings("unused") Set           imports,
    @SuppressWarnings("unused") ComponentBean component)
  {
  }

  // hook for custom component descriptor content
  protected void writeCustomComponentTagDescriptorContent(
   @SuppressWarnings("unused") XMLStreamWriter  stream,
   @SuppressWarnings("unused") 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<Map.Entry> i = taglibs.entrySet().iterator(); i.hasNext(); )
      {
        Map.Entry 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.toURI().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.toURI().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 (JsfVersion.isJSF11(jsfVersion))
          {
            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, !JsfVersion.isJSF11(jsfVersion) ? "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 (JsfVersion.isJSF11(jsfVersion))
      stream.writeDTD(dtd);

    stream.writeCharacters("\n");
    stream.writeStartElement("taglib");
    if (!JsfVersion.isJSF11(jsfVersion))
    {
      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 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 (JsfVersion.isJSF11(jsfVersion))
    {
      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 (!JsfVersion.isJSF11(jsfVersion) && 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 (!JsfVersion.isJSF11(jsfVersion))
    {
      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 (JsfVersion.isJSF11(jsfVersion) && 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 (!JsfVersion.isJSF11(jsfVersion) && 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 (!JsfVersion.isJSF11(jsfVersion))
    {
      stream.writeCharacters("\n    ");
      stream.writeStartElement("body-content");
      stream.writeCharacters("empty");
      stream.writeEndElement();
    }

    if (JsfVersion.isJSF11(jsfVersion) && 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<PropertyBean> properties = converter.properties();
    properties = new FilteredIterator(properties, new TagAttributeFilter());
    while (properties.hasNext())
    {
      PropertyBean property = 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 (!JsfVersion.isJSF11(jsfVersion))
      _writeTagAttributeDescription(stream, description, unsupportedAgents);

    stream.writeCharacters("\n      ");
    stream.writeStartElement("name");

    if (property != null)
      stream.writeCharacters(property.getJspPropertyName());
    else
      stream.writeCharacters(propertyName);

    stream.writeEndElement();

    if (JsfVersion.isJSF11(jsfVersion))
    {
      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
        {
          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 (property.isRtexprvalue() || ("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 (!JsfVersion.isJSF11(jsfVersion) && 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 (!JsfVersion.isJSF11(jsfVersion))
    {
      stream.writeCharacters("\n    ");
      stream.writeStartElement("body-content");
      stream.writeCharacters("empty");
      stream.writeEndElement();
    }

    if (JsfVersion.isJSF11(jsfVersion) && 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<PropertyBean> properties = validator.properties();
    properties = new FilteredIterator(properties, new TagAttributeFilter());
    while (properties.hasNext())
    {
      PropertyBean property = 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(!JsfVersion.isJSF11(jsfVersion), getLicenseHeader(), getLog());
          validatorGen = new TrinidadValidatorTagGenerator(!JsfVersion.isJSF11(jsfVersion), getLicenseHeader(), getLog());
        }
        else
        {
          converterGen = new MyFacesConverterTagGenerator(!JsfVersion.isJSF11(jsfVersion), getLicenseHeader(), getLog());
          validatorGen = new MyFacesValidatorTagGenerator(!JsfVersion.isJSF11(jsfVersion), getLicenseHeader(), getLog());
        }
        int count = 0;
        while (components.hasNext())
        {
          componentGen.generateTagHandler((ComponentBean)components.next());
          count++;
        }
        while (converters.hasNext())
        {
          converterGen.generateTagHandler((ConverterBean)converters.next(), generatedSourceDirectory);
          count++;
        }
        while (validators.hasNext())
        {
          validatorGen.generateTagHandler((ValidatorBean)validators.next(), 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;
      }

      componentList = initComponentList(component, fullSuperclassName);

      String fullClassName = component.getTagClass();
      try
      {
        String className = Util.getClassFromFullClass(fullClassName);
        String packageName = Util.getPackageFromFullClass(fullClassName);

        TemplateFile templateFile = new TemplateFile(fullClassName, packageName, className);
        boolean hasTemplate = templateFile.exists();
        SourceTemplate sourceTemplate = null;
        String overrideClassName = null;
        String sourcePath = templateFile.getSourcePath();

        if (hasTemplate)
        {
          className = templateFile.getClassName();
          fullClassName = templateFile.getFullClassName();
          overrideClassName = className;

          if (!templateFile.isSubclass())
          {
            // Merged template use case
            sourceTemplate = new SourceTemplate(templateFile.getFile());
          }
        }

        getLog().debug("Generating " + fullClassName);

        File targetFile = new File(generatedSourceDirectory, sourcePath);

        targetFile.getParentFile().mkdirs();
        StringWriter sw = new StringWriter();
        PrettyWriter out = new PrettyWriter(sw);

        if (component.isTrinidadComponent())
        {
          generator = new TrinidadComponentTagGenerator(!JsfVersion.isJSF11(jsfVersion));
        }
        else
        {
          generator = new MyFacesComponentTagGenerator(!JsfVersion.isJSF11(jsfVersion));
        }

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

        // 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,
          sourceTemplate, hasTemplate);

        int modifiers = component.getTagClassModifiers();
        generator.writeConstructor(out, component, overrideClassName, 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();

        if (templateFile.isSubclass())
        {
          // If there is a sub-class, copy the file to the directory in the compiler path
          File destFile = new File(generatedSourceDirectory, templateFile.getOriginalSourcePath());

          Util.copyFile(templateFile.getFile(), destFile);
          destFile.setReadOnly();
        }
      }
      catch (Throwable e)
      {
        getLog().error("Error generating " + fullClassName, e);
      }
    }
  }

  private class IfComponentModifiedFilter extends ComponentFilter
  {
    protected boolean accept(
      ComponentBean component)
    {
      String tagClass = component.getTagClass();

      TemplateFile templateFile = new TemplateFile(tagClass);
      String sourcePath = Util.convertClassToSourcePath(tagClass, ".java");
      File targetFile = new File(generatedSourceDirectory, sourcePath);

      long templateFileModified = templateFile.lastModified();
      long targetLastMoified = targetFile.lastModified();

      // accept if templateFile is newer or component has been modified
      return templateFileModified > targetLastMoified ||
        component.isModifiedSince(targetLastMoified);
    }
  }

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

  private class TemplateFile
  {
    private TemplateFile(
      String fullTagClassName)
    {
      this(fullTagClassName,
        Util.getPackageFromFullClass(fullTagClassName),
        Util.getClassFromFullClass(fullTagClassName));
    }

    private TemplateFile(
      String fullTagClassName,
      String packageName,
      String tagClassName)
    {
      _originalSourcePath = Util.convertClassToSourcePath(fullTagClassName, ".java");
      String templatePath = Util.convertClassToSourcePath(fullTagClassName, "Template.java");
      File templateFile = new File(templateSourceDirectory, templatePath);
      // New style, meaning that the template is named the same as the desired tag name and the
      // generator creates the base class of the template with "Partial" pre-pended to the name:
      File subclassFile = new File(templateSourceDirectory, _originalSourcePath);

      boolean templateExists = templateFile.exists();
      boolean subclassExists = subclassFile.exists();
      if (templateExists && subclassExists)
      {
        throw new IllegalStateException(
          String.format("Both a template tag file, '%s' and a subclass file, '%s' exists.",
            templateFile, subclassFile));
      }

      _isSubclass = subclassExists;

      _file = subclassExists ? subclassFile : templateExists ? templateFile : null;

      if (_isSubclass)
      {
        _className = "Partial" + tagClassName;
        _fullClassName = packageName + "." + _className;
        _sourcePath = Util.convertClassToSourcePath(_fullClassName, ".java");
      }
      else
      {
        _className = tagClassName;
        _fullClassName = fullTagClassName;
        _sourcePath = _originalSourcePath;
      }
    }

    final String getSourcePath()
    {
      return _sourcePath;
    }

    final boolean isSubclass()
    {
      return _isSubclass;
    }

    final boolean exists()
    {
      return _file != null;
    }

    final long lastModified()
    {
      if (_lastModified == -1)
      {
        _lastModified = _file == null ? 0 : _file.lastModified();
      }

      return _lastModified;
    }

    final File getFile()
    {
      return _file;
    }

    final String getClassName()
    {
      return _className;
    }

    final String getFullClassName()
    {
      return _fullClassName;
    }

    final String getOriginalSourcePath()
    {
      return _originalSourcePath;
    }

    private long _lastModified = -1;
    final private String _className;
    final private String _fullClassName;
    final private String _sourcePath;
    final private String _originalSourcePath;
    final private File _file;
    final private boolean _isSubclass;
  }

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