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

import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;

import java.net.URL;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.TreeMap;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;

import javax.xml.parsers.ParserConfigurationException;

import org.apache.maven.artifact.Artifact;
import org.apache.maven.model.Dependency;
import org.apache.maven.model.Resource;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.project.MavenProject;

import org.codehaus.plexus.util.DirectoryScanner;
import org.codehaus.plexus.util.FileUtils;
import org.codehaus.plexus.util.IOUtil;
import org.codehaus.plexus.util.xml.Xpp3Dom;
import org.codehaus.plexus.util.xml.Xpp3DomBuilder;
import org.codehaus.plexus.util.xml.Xpp3DomWriter;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;

import org.xml.sax.SAXException;

  /*
   * Important informational note:
   *
   * The following XML code is similar to what would be seen in a pom file
   * under the maven-jdev-plugin tag if Libraries (e.g. JSP Runtime
   * and JSF 1.2) and Distributed Tag Libraries wanted to be added to the .jpr
   * project.
   *
   * What you see below are the defaults that are put in a project's .jpr
   * automatically without specifying anything.  See replaceLibraries(),
   * replaceTagLibraries() and replaceDefaultTagLibraries().
   *
   * Also note that by setting the property "jdev.plugin.add.libraries" to
   * false in a project's pom.xml file, no libraries will be added, default
   * or otherwise.  In kind, setting the property "jdev.plugin.add.taglibs"
   * to false will result in no tag libraries of any kind being added.
   *
   * As you would expect, the default for both of these properties is "true".
   *
   *   <plugin>
        <groupId>org.apache.myfaces.trinidadbuild</groupId>
        <artifactId>maven-jdev-plugin</artifactId>
        <version>1.2.4-SNAPSHOT</version>
        <inherited>true</inherited>
        <configuration>
          <libraries>
            <library>JSP Runtime</library>
            <library>JSF 1.2</library>
          </libraries>
          <distributedTagLibraries>
            <distributedTagLibrary>
              <property>
                <name>name</name>
                <value>JSF HTML</value>
              </property>
              <property>
                <name>version</name>
                <value>1.2</value>
              </property>
              <property>
                <name>jspVersion</name>
                <value>2.1</value>
              </property>
              <property>
                <name>tld</name>
                <value>html_basic.tld</value>
              </property>
              <property>
                <name>URI</name>
                <value>http://java.sun.com/jsf/html</value>
              </property>
            </distributedTagLibrary>
            <distributedTagLibrary>
              <property>
                <name>name</name>
                <value>JSF Core</value>
              </property>
              <property>
                <name>version</name>
                <value>1.2</value>
              </property>
              <property>
                <name>jspVersion</name>
                <value>2.1</value>
              </property>
              <property>
                <name>tld</name>
                <value>jsf_core.tld</value>
              </property>
              <property>
                <name>URI</name>
                <value>http://java.sun.com/jsf/core</value>
              </property>
            </distributedTagLibrary>
          </distributedTagLibraries>
        </configuration>
      </plugin>
 */

/**
 * Generates the JDeveloper Workspace and Projects
 * from a maven development environment.
 * @version $Id$
 * @goal jdev
 * @execute phase=process-resources
 * @requiresDependencyResolution test
 * @description Goal which generates the JDeveloper Workspace and Projects
 *              from a maven development environment.
 */
public class JDeveloperMojo
  extends AbstractMojo
{
  /**
   * Libraries to include in Classpath.
   * @parameter
   */
  private String[] libraries;

  /**
   * List of source root directories
   * @parameter
   */
  private File[] sourceRoots;

  /**
   * List of source root directories for the test project
   * @parameter
   */
  private File[] testSourceRoots;

  /**
   * List of resource root directories
   * @parameter
   */
  private File[] resourceRoots;

  /**
   * List of resource root directories for the test project
   * @parameter
   */
  private File[] testResourceRoots;

  /**
   * Force the Mojo to use the default project.xml or
   * workspace.xml file to be used in creation of the
   * workspace file (.jws) or project file (.jpr). Otherwise,
   * if a .jws or .jpr exists, it will be used instead.
   * @parameter expression="${force}" default-value=false
   *
   */
  private boolean force;

  /**
   * Compiler to be used by JDeveloper. "Ojc" is the default.  
   * If this parameter is absent or anything other than "Javac", "Ojc" will
   * be used.
   * @parameter expression="${jdev.compiler}" default-value="Ojc"
   */
  private String compiler;

  /**
   * Make the entire project before each run.  Running anything in the
   * project will automatically trigger a make of the entire project
   * followed by the run.
   * @parameter expression="${jdev.make.project}" default-value="false"
   */
  private boolean makeProject;

  /**
   * Default file to be run when JDeveloper project is run.
   * @parameter expression="${jdev.run.target}"
   */
  private String runTarget;

  /**
   * Create JDeveloper Workspace and Project Files that correspond to
   * the format used
   * @parameter expression="${jdev.release}" default-value="10.1.3.0.4"
   */
  private String release;

  /**
   * Name of the Maven Project
   * @parameter expression="${project}"
   * @required
   * @readonly
   */
  private MavenProject project;

  /**
   * List of reactorProjects
   * @parameter expression="${reactorProjects}"
   * @required
   * @readonly
   */
  private List reactorProjects;

  /**
   * Tag library directory used by each distributed tag library
   *
   * @parameter expression="${jdev.tag.lib.dir}"
   *            default-value="@oracle.home@lib/java/shared/oracle.jsf/1.2/jsf-ri.jar!/META-INF"
   */
  private String tagLibDirectory;

  /**
   * Tag libraries and their properties.
   * @parameter
   */
  private Properties[] distributedTagLibraries;

  /**
   * Execute the Mojo.
   */
  public void execute()
    throws MojoExecutionException
  {
    _parseRelease();
    try
    {
      generateWorkspace();
      generateProject();
      generateTestProject();
    }
    catch (IOException e)
    {
      throw new MojoExecutionException(e.getMessage());
    }
  }

  private void generateWorkspace()
    throws MojoExecutionException, IOException
  {
    if (!project.getCollectedProjects().isEmpty())
    {
      getLog().info("Generating JDeveloper " + release + " workspace: " +
                    project.getArtifactId());

      File workspaceFile = getJWorkspaceFile(project);

      try
      {
        Xpp3Dom workspaceDOM = readWorkspaceDOM(workspaceFile);
        replaceProjects(workspaceFile.getParentFile(), workspaceDOM);
        writeDOM(workspaceFile, workspaceDOM);
      }
      catch (XmlPullParserException e)
      {
        throw new MojoExecutionException("Error generating workspace", e);
      }
    }
  }

  private void generateProject()
    throws IOException, MojoExecutionException
  {
    if (!"pom".equals(project.getPackaging()))
    {
      File projectFile = getJProjectFile(project);

      // Get Project Properties to tell Mojo whether or not to add
      // library refs and taglibs to the project.
      Properties props = project.getProperties();
      String addLibs = (String)props.get(_PROPERTY_ADD_LIBRARY);
      String addTagLibs = (String)props.get(_PROPERTY_ADD_TAGLIBS);
      _addLibraries = (addLibs == null)
        ? true : (new Boolean(addLibs)).booleanValue();
      _addTagLibs   = (addTagLibs == null)
        ? true : (new Boolean(addTagLibs)).booleanValue();

      // TODO: read configuration for war:war goal
      File webappDir = new File(project.getBasedir(), "src/main/webapp");
      // TODO: read configuration for compiler:complie goal
      File outputDir =
        new File(project.getBuild().getDirectory(), "classes");

      MavenProject executionProject = project.getExecutionProject();
      List compileSourceRoots = executionProject.getCompileSourceRoots();
      if (sourceRoots != null)
      {
        for (int i = 0; i < sourceRoots.length; i++)
        {
          compileSourceRoots.add(sourceRoots[i].getAbsolutePath());
        }
      }

      List compileResourceRoots = executionProject.getResources();
      if (resourceRoots != null)
      {
        for (int i = 0; i < resourceRoots.length; i++)
        {
          Resource resource = new Resource();
          resource.setDirectory(resourceRoots[i].getAbsolutePath());
          compileResourceRoots.add(resource);
        }
      }

      getLog().info("Generating JDeveloper " + release + " Project " +
                    project.getArtifactId());

      Set pluginArtifacts = new LinkedHashSet();
      pluginArtifacts.addAll(project.getPluginArtifacts());

      // Note: include "compile", "provided", "system" and "runtime" scopes
      Set compileArtifacts = new LinkedHashSet();
      compileArtifacts.addAll(project.getCompileArtifacts());
      compileArtifacts.addAll(project.getRuntimeArtifacts());

      // Note: separate "runtime" vs. "compile" dependencies in JDeveloper?
      generateProject(projectFile, project.getArtifactId(),
                      project.getPackaging(), project.getDependencies(),
                      new ArrayList(compileArtifacts), compileSourceRoots,
                      compileResourceRoots,
                      Collections.singletonList(webappDir.getPath()),
                      outputDir);
    }
  }

  private void generateTestProject()
    throws IOException, MojoExecutionException
  {
    if (!"pom".equals(project.getPackaging()))
    {
      File projectFile = getJProjectTestFile(project);

      // Get Project Properties to tell Mojo whether or not to add
      // library refs and taglibs to the project.
      Properties props = project.getProperties();
      String addLibs = (String)props.get(_PROPERTY_ADD_LIBRARY);
      String addTagLibs = (String)props.get(_PROPERTY_ADD_TAGLIBS);
      _addLibraries = (addLibs == null)
        ? true : (new Boolean(addLibs)).booleanValue();
      _addTagLibs   = (addTagLibs == null)
        ? true : (new Boolean(addTagLibs)).booleanValue();
      File webappDir = new File(project.getBasedir(), "src/test/webapp");
      // TODO: read configuration for compiler:testCompile goal
      File outputDir =
        new File(project.getBuild().getDirectory(), "test-classes");

      // self dependency needed for test project
      List testDependencies = new ArrayList(project.getTestDependencies());
      Dependency selfDependency = new Dependency();
      selfDependency.setArtifactId(project.getArtifactId());
      selfDependency.setGroupId(project.getGroupId());
      selfDependency.setType(project.getPackaging());
      testDependencies.add(selfDependency);

      MavenProject executionProject = project.getExecutionProject();
      List compileSourceRoots =
        executionProject.getTestCompileSourceRoots();

      if (testSourceRoots != null)
      {
        for (int i = 0; i < testSourceRoots.length; i++)
        {
          compileSourceRoots.add(testSourceRoots[i].getAbsolutePath());
        }
      }

      List compileResourceRoots = executionProject.getTestResources();
      if (testResourceRoots != null)
      {
        for (int i = 0; i < testResourceRoots.length; i++)
        {
          Resource resource = new Resource();
          resource.setDirectory(testSourceRoots[i].getAbsolutePath());
          compileResourceRoots.add(resource);
        }
      }

      getLog().info("Generating JDeveloper " + release + " Project " +
                    project.getArtifactId() + "-test");

      // Note: all artifacts implicitly included in "test" scope
      generateProject(projectFile, project.getArtifactId() + "-test",
                      project.getPackaging(), testDependencies,
                      project.getTestArtifacts(), compileSourceRoots,
                      compileResourceRoots,
                      Collections.singletonList(webappDir.getPath()),
                      outputDir);
    }
  }

  private void generateProject(File projectFile, String projectName,
                               String packaging, List dependencies,
                               List artifacts, List sourceRoots,
                               List resourceRoots, List webSourceRoots,
                               File outputDir)
    throws IOException, MojoExecutionException
  {
    try
    {
      File projectDir = projectFile.getParentFile();
      Xpp3Dom projectDOM = readProjectDOM(projectFile);
      replaceWebappInfo(projectName, projectDOM);
      replaceSourcePaths(projectDir, sourceRoots, resourceRoots,
                         projectDOM);
      //replaceResourcePaths(projectDir, resourceRoots, projectDOM);
      replaceWebSourcePaths(projectDir, webSourceRoots, projectDOM);
      replaceDependencies(projectDir, dependencies, projectDOM);
      replaceLibraries(projectDir, artifacts, projectDOM);
      replaceTagLibraries(projectDOM);
      replaceOutputDirectory(projectDir, outputDir, projectDOM);
      replaceParameters(projectName, projectDOM);
      writeDOM(projectFile, projectDOM);

      if ("war".equals(packaging))
      {
        copyTagLibraries(projectDir, dependencies, artifacts);
      }
    }
    catch (XmlPullParserException e)
    {
      throw new MojoExecutionException("Error generating project", e);
    }
  }

  private void replaceProjects(File workspaceDir, Xpp3Dom workspaceDOM)
    throws XmlPullParserException
  {
    // /jws:workspace
    //   /list[@n="listOfChildren"]
    Xpp3Dom sourceDOM = workspaceDOM.getChild("list");

    // <hash>
    //   <value n="nodeClass" v="oracle.jdeveloper.model.JProject"/>
    //   <url n="URL" path="[workspace-relative-path-to-project.jpr]"/>
    // </hash>
    Xpp3Dom targetDOM = new Xpp3Dom("list");

    for (Iterator i = project.getCollectedProjects().iterator(); i.hasNext(); )
    {
      MavenProject collectedProject = (MavenProject) i.next();

      // if a child project is also a workspace, then don't 
      // put it in the .jws file.  It will have its own .jws
      // file.
      if (!"pom".equals(collectedProject.getPackaging()))
      {
        File projectFile = getJProjectFile(collectedProject);
        
        targetDOM.addChild(createProjectReferenceDOM(workspaceDir,
                                                     projectFile));
  
        File testProjectFile = getJProjectTestFile(collectedProject);
        targetDOM.addChild(createProjectReferenceDOM(workspaceDir,
                                                     testProjectFile));
      }
    }

    // TODO: use a better merge algorithm
    removeChildren(sourceDOM);

    // make sure to pass Boolean.FALSE to allow
    // multiple child elements with the same name
    Xpp3Dom.mergeXpp3Dom(sourceDOM, targetDOM, Boolean.FALSE);
  }

  private void replaceWebSourcePaths(File projectDir, List sourceRoots,
                                     Xpp3Dom projectDOM)
    throws XmlPullParserException
  {
    // /jpr:project
    //   /hash[@n="oracle.jdeveloper.model.J2eeSettings"]
    //     /hash[@n="webContentSet"]
    //       /list[@n="url-path"]
    Xpp3Dom pathsDOM =
      findNamedChild(projectDOM, "hash", "oracle.jdeveloper.model.J2eeSettings");
    Xpp3Dom contentSetDOM =
      findNamedChild(pathsDOM, "hash", "webContentSet");
    Xpp3Dom sourceDOM = findNamedChild(contentSetDOM, "list", "url-path");

    //
    // <url path="[relative-path-to-source-root]" />
    //
    Xpp3Dom targetDOM = new Xpp3Dom("list");
    for (Iterator i = sourceRoots.iterator(); i.hasNext(); )
    {
      File sourceRoot = new File((String) i.next());
      String relativeRoot = getRelativeDir(projectDir, sourceRoot);
      Xpp3Dom urlDOM = new Xpp3Dom("url");
      urlDOM.setAttribute("path", relativeRoot);
      targetDOM.addChild(urlDOM);
    }

    // TODO: use a better merge algorithm
    removeChildren(sourceDOM);

    // make sure to pass Boolean.FALSE to allow
    // multiple child elements with the same name
    Xpp3Dom.mergeXpp3Dom(sourceDOM, targetDOM, Boolean.FALSE);
  }

  private void replaceWebappInfo(String projectName, Xpp3Dom projectDOM)
    throws XmlPullParserException
  {
    // /jpr:project
    //   /hash[@n="oracle.jdeveloper.model.J2eeSettings"]
    //     /value[@n="j2eeWebAppName" v="maven-generated-webapp"]
    //     /value[@n="j2eeWebContextRoot" v="maven-generated-context-root"]
    Xpp3Dom settingsDOM =
      findNamedChild(projectDOM, "hash", "oracle.jdeveloper.model.J2eeSettings");
    Xpp3Dom webappNameDOM =
      findNamedChild(settingsDOM, "value", "j2eeWebAppName");
    Xpp3Dom webappContextDOM =
      findNamedChild(settingsDOM, "value", "j2eeWebContextRoot");

    // update the webapp name
    webappNameDOM.setAttribute("v", projectName + "-webapp");

    // update the webapp context root
    webappContextDOM.setAttribute("v", projectName + "-context-root");
  }

  private void replaceSourcePaths(File projectDir, List sourceRoots,
                                  List resourceRoots, Xpp3Dom projectDOM)
    throws XmlPullParserException
  {
    // /jpr:project
    //   /hash[@n="oracle.jdeveloper.model.PathsConfiguration"]
    //     /hash[@n="javaContentSet"]
    //       /list[@n="url-path"]
    Xpp3Dom pathsDOM =
      findNamedChild(projectDOM, "hash", "oracle.jdeveloper.model.PathsConfiguration");
    Xpp3Dom contentSetDOM =
      findNamedChild(pathsDOM, "hash", "javaContentSet");
    Xpp3Dom sourceDOM = findNamedChild(contentSetDOM, "list", "constituent-sets");

    //
    // <url path="[relative-path-to-source-root]" />
    //
    Xpp3Dom targetDOM = new Xpp3Dom("list");

    Collections.sort(sourceRoots);
    for (Iterator i = sourceRoots.iterator(); i.hasNext(); )
    {
      File sourceRoot = new File((String) i.next());
      Xpp3Dom hashDOM = new Xpp3Dom("hash");

      Xpp3Dom listDOM = new Xpp3Dom("list");
      listDOM.setAttribute("n", "pattern-filters");
      hashDOM.addChild(listDOM);

      Xpp3Dom stringDOM = new Xpp3Dom("string");
      stringDOM.setAttribute("v", "+**");
      listDOM.addChild(stringDOM);

      listDOM = new Xpp3Dom("list");
      listDOM.setAttribute("n", "url-path");
      hashDOM.addChild(listDOM);

      String relativeRoot = getRelativeDir(projectDir, sourceRoot);
      Xpp3Dom urlDOM = new Xpp3Dom("url");
      urlDOM.setAttribute("path", relativeRoot);
      listDOM.addChild(urlDOM);

      targetDOM.addChild(hashDOM);
    }

    // TODO: get bug fixed in 10.1.3 for copying resources
    Collections.sort(resourceRoots, new Comparator()
        {
          public int compare(Object a, Object b)
          {
            Resource ra = (Resource) a;
            Resource rb = (Resource) b;
            return ra.getDirectory().compareTo(rb.getDirectory());
          }

        });

    for (Iterator i = resourceRoots.iterator(); i.hasNext(); )
    {
      Resource resource = (Resource) i.next();
      File resourceRoot = new File(resource.getDirectory());
      String relativeRoot = getRelativeDir(projectDir, resourceRoot);

      Xpp3Dom hashDOM = new Xpp3Dom("hash");

      Xpp3Dom listDOM = new Xpp3Dom("list");
      listDOM.setAttribute("n", "pattern-filters");
      hashDOM.addChild(listDOM);

      Xpp3Dom stringDOM = null;
      // TODO: This is a Hack for excluding the golden files,
      // which are not really xml files.  We need a way, in
      // the pom file to specify excludes.
      if (relativeRoot.startsWith("src/test/resources"))
      {
        stringDOM = new Xpp3Dom("string");
        stringDOM.setAttribute("v",
                            "-oracle/adfinternal/view/faces/renderkit/golden/");
        listDOM.addChild(stringDOM);
      }

      stringDOM = new Xpp3Dom("string");
      stringDOM.setAttribute("v", "+**");
      listDOM.addChild(stringDOM);

      listDOM = new Xpp3Dom("list");
      listDOM.setAttribute("n", "url-path");
      hashDOM.addChild(listDOM);

      Xpp3Dom urlDOM = new Xpp3Dom("url");
      urlDOM.setAttribute("path", relativeRoot);
      listDOM.addChild(urlDOM);

      targetDOM.addChild(hashDOM);
    }

    // TODO: use a better merge algorithm
    removeChildren(sourceDOM);

    // make sure to pass Boolean.FALSE to allow
    // multiple child elements with the same name
    Xpp3Dom.mergeXpp3Dom(sourceDOM, targetDOM, Boolean.FALSE);
  }

  private void replaceResourcePaths(File projectDir, List resourceRoots,
                                    Xpp3Dom projectDOM)
    throws XmlPullParserException
  {
    // /jpr:project
    //   /hash[@n="oracle.ide.model.ResourcePaths"]
    //     /hash[@n="resourcesContentSet"]
    //       /list[@n="url-path"]

    Xpp3Dom pathsDOM =
      findNamedChild(projectDOM, "hash", "oracle.ide.model.ResourcePaths");
    Xpp3Dom contentSetDOM =
      findNamedChild(pathsDOM, "hash", "resourcesContentSet");
    Xpp3Dom sourceDOM = findNamedChild(contentSetDOM, "list", "url-path");

    //
    // <url path="[relative-path-to-source-root]" />
    //
    Xpp3Dom targetDOM = new Xpp3Dom("list");
    for (Iterator i = resourceRoots.iterator(); i.hasNext(); )
    {
      Resource resource = (Resource) i.next();
      File resourceRoot = new File(resource.getDirectory());
      String relativeRoot = getRelativeDir(projectDir, resourceRoot);
      Xpp3Dom urlDOM = new Xpp3Dom("url");
      urlDOM.setAttribute("path", relativeRoot);
      targetDOM.addChild(urlDOM);
    }

    // TODO: use a better merge algorithm
    removeChildren(sourceDOM);

    // make sure to pass Boolean.FALSE to allow
    // multiple child elements with the same name
    Xpp3Dom.mergeXpp3Dom(sourceDOM, targetDOM, Boolean.FALSE);
  }

  private void replaceDependencies(File projectDir, List dependencies,
                                   Xpp3Dom projectDOM)
    throws XmlPullParserException
  {
    // /jpr:project
    //   /hash[@n="oracle.ide.model.DependencyConfiguration"]
    //     /list[@n="dependencyList"]
    Xpp3Dom configDOM =
      findNamedChild(projectDOM, "hash", "oracle.ide.model.DependencyConfiguration");
    Xpp3Dom sourceDOM =
      findNamedChild(configDOM, "list", "dependencyList");

    Xpp3Dom targetDOM = new Xpp3Dom("list");
    for (Iterator i = dependencies.iterator(); i.hasNext(); )
    {
      Dependency dependency = (Dependency) i.next();
      MavenProject dependentProject =
        findDependentProject(dependency.getManagementKey());
      if (dependentProject != null)
      {
        File dependentProjectFile = getJProjectFile(dependentProject);
        String relativePath =
          getRelativeFile(projectDir, dependentProjectFile);

        Xpp3Dom hashDOM = new Xpp3Dom("hash");
        Xpp3Dom valueDOM = new Xpp3Dom("value");
        valueDOM.setAttribute("n", "class");
        valueDOM.setAttribute("v",
                              "oracle.jdeveloper.library.ProjectLibrary");
        Xpp3Dom srcOwnValDOM = new Xpp3Dom("value");
        srcOwnValDOM.setAttribute("n", "sourceOwnerURL");
        Xpp3Dom urlDOM = new Xpp3Dom("url");
        urlDOM.setAttribute("n", "sourceURL");
        urlDOM.setAttribute("path", relativePath);
        hashDOM.addChild(valueDOM);
        hashDOM.addChild(srcOwnValDOM);
        hashDOM.addChild(urlDOM);
        targetDOM.addChild(hashDOM);
      }
    }

    // TODO: use a better merge algorithm
    removeChildren(sourceDOM);

    // make sure to pass Boolean.FALSE to allow
    // multiple child elements with the same name
    Xpp3Dom.mergeXpp3Dom(sourceDOM, targetDOM, Boolean.FALSE);
  }

  private void replaceLibraries(File projectDir, List artifacts,
                                Xpp3Dom projectDOM)
    throws XmlPullParserException
  {
    // /jpr:project
    //   /hash[@n="oracle.jdevimpl.config.JProjectLibraries"]
    //     /hash[@n="internalDefinitions"]
    //       /list[@n="libraryDefinitions"]
    Xpp3Dom projectLibsDOM =
      findNamedChild(projectDOM, "hash", "oracle.jdevimpl.config.JProjectLibraries");
    Xpp3Dom internalDefsDOM =
      findNamedChild(projectLibsDOM, "hash", "internalDefinitions");
    Xpp3Dom sourceDefsDOM =
      findNamedChild(internalDefsDOM, "list", "libraryDefinitions");

    // /jpr:project
    //   /hash[@n="oracle.jdevimpl.config.JProjectLibraries"]
    //     /list[@n="libraryReferences"]
    Xpp3Dom sourceRefsDOM =
      findNamedChild(projectLibsDOM, "list", "libraryReferences");

    Xpp3Dom targetDefsDOM = new Xpp3Dom("list");
    Xpp3Dom targetRefsDOM = new Xpp3Dom("list");

    //
    // libraryDefinitions
    //
    // <hash>
    //   <list n="classPath">
    //     <url path="[path-to-artifact]" jar-entry="" />
    //   </list>
    //   <value n="deployedByDefault" v="true"/>
    //   <value n="description" v="[artifact.id]"/>
    //   <value n="id" v="[artifact.id]"/>
    // </hash>
    //

    // sort the artifacts
    Collections.sort(artifacts, new Comparator()
        {
          public int compare(Object a, Object b)
          {
            Artifact arta = (Artifact) a;
            Artifact artb = (Artifact) b;
            return arta.getId().compareTo(artb.getId());
          }

        });

    List libraryRefs = new LinkedList();
    for (Iterator i = artifacts.iterator(); i.hasNext(); )
    {
      Artifact artifact = (Artifact) i.next();

      if (!isDependentProject(artifact.getDependencyConflictId()))
      {
        String id = artifact.getId();
        String path = getRelativeFile(projectDir, artifact.getFile());

        // libraryDefinitions entry
        Xpp3Dom hashDOM = new Xpp3Dom("hash");
        Xpp3Dom listDOM = new Xpp3Dom("list");
        listDOM.setAttribute("n", "classPath");

        Xpp3Dom urlDOM = new Xpp3Dom("url");
        urlDOM.setAttribute("path", path);
        urlDOM.setAttribute("jar-entry", "");
        listDOM.addChild(urlDOM);
        hashDOM.addChild(listDOM);

        Xpp3Dom valueDOM = new Xpp3Dom("value");
        valueDOM.setAttribute("n", "deployedByDefault");
        valueDOM.setAttribute("v", "true");
        hashDOM.addChild(valueDOM);

        valueDOM = new Xpp3Dom("value");
        valueDOM.setAttribute("n", "description");
        valueDOM.setAttribute("v", id);
        hashDOM.addChild(valueDOM);

        valueDOM = new Xpp3Dom("value");
        valueDOM.setAttribute("n", "id");
        valueDOM.setAttribute("v", id);
        hashDOM.addChild(valueDOM);
        targetDefsDOM.addChild(hashDOM);

        libraryRefs.add(id);
      }
    }

    // This boolean is set by specifying the jdev.plugin.add.libraries
    // property at the top of a project's pom file.  There are projects
    // that don't need these libraries in their .jpr files to compile and this
    // property allows them to be excluded.
    //
    // IMPORTANT NOTE: if this property is set in a project,
    // then libraries will NOT be added, even though they
    // may be specified under the maven-jdev-plugin.
    if (_addLibraries)
    {
      // Add libraries.  The default libraries can be
      // overridden in the trunk/toplevel pom file.
      if (_releaseMajor >= 11)
      {
        // Add the default libraries
        libraryRefs.add(0,"JSF 1.2");
        libraryRefs.add(0,"JSP Runtime");
      }

      // Add the libraries
      if (libraries != null)
      {
        for (int i = 0; i < libraries.length; i++)
        {
          // Default libraries for release 11 were already
          // added above.
          if (   (_releaseMajor >= 11)
              && (   ("JSF 1.2".equalsIgnoreCase(libraries[i]))
                  || ("JSP Runtime".equalsIgnoreCase(libraries[i]))
                 )
             )
          {
            continue;
          }
          // Add the library
          libraryRefs.add(0, libraries[i]);
        }
      }
    }

    //
    // libraryReferences
    //
    // <hash>
    //   <value n="id" v="[artifact.id]"/>
    //   <value n="isJDK" v="false"/>
    // </hash>
    //
    Collections.sort(libraryRefs);

    for (Iterator i = libraryRefs.iterator(); i.hasNext(); )
    {
      String id = (String) i.next();

      // libraryReferences entry
      Xpp3Dom hashDOM = new Xpp3Dom("hash");
      Xpp3Dom valueDOM = new Xpp3Dom("value");
      valueDOM.setAttribute("n", "id");
      valueDOM.setAttribute("v", id);
      hashDOM.addChild(valueDOM);

      valueDOM = new Xpp3Dom("value");
      valueDOM.setAttribute("n", "isJDK");
      valueDOM.setAttribute("v", "false");
      hashDOM.addChild(valueDOM);
      targetRefsDOM.addChild(hashDOM);
    }

    // First, add JSP Runtime dependency if src/main/webapp exists
    // TODO: use a better merge algorithm
    removeChildren(sourceDefsDOM);
    removeChildren(sourceRefsDOM);

    // make sure to pass Boolean.FALSE to allow
    // multiple child elements with the same name
    Xpp3Dom.mergeXpp3Dom(sourceDefsDOM, targetDefsDOM, Boolean.FALSE);
    Xpp3Dom.mergeXpp3Dom(sourceRefsDOM, targetRefsDOM, Boolean.FALSE);
  }

  private void replaceLocalTagLibraries(Xpp3Dom targetLibsDOM)
    throws XmlPullParserException
  {
    TldContentHandler tldHandler = new TldContentHandler();
    String path = null;

    // Loop through all the .tld files in the WEB-INF dir
    // Parse each and get the values needed for the TagLibraries
    // hash in the .jpr file.
    try
    {
      File webInfDir =
        new File(project.getBasedir(), "src/main/webapp/WEB-INF");
      if (webInfDir == null)
      {
        return;
      }

      File[] files = webInfDir.listFiles();
      if (files == null)
      {
        return;
      }

      Xpp3Dom hashDOM = null;
      Xpp3Dom valueDOM = null;
      for (int i = 0; i < files.length; i++)
      {
        path = files[i].getPath();
        if (path.endsWith(".tld"))
        {
          hashDOM = new Xpp3Dom("hash");
          // we have a tag library.  Parse it and
          // get the values needed for the .jpr file

          // Parse
          tldHandler.parseTld(files[i]);
          // call gettors to get the values
          valueDOM = new Xpp3Dom("value");
          valueDOM.setAttribute("n", "jspVersion");
          valueDOM.setAttribute("v", tldHandler.getJspVersion());
          hashDOM.addChild(valueDOM);

          valueDOM = new Xpp3Dom("value");
          valueDOM.setAttribute("n", "name");
          valueDOM.setAttribute("v", tldHandler.getName());
          hashDOM.addChild(valueDOM);

          valueDOM = new Xpp3Dom("value");
          valueDOM.setAttribute("n", "prefix");
          valueDOM.setAttribute("v", tldHandler.getPrefix());
          hashDOM.addChild(valueDOM);

          valueDOM = new Xpp3Dom("value");
          valueDOM.setAttribute("n", "tldURL");
          valueDOM.setAttribute("v",
            "WEB-INF/" + path.substring(path.indexOf("WEB-INF") +  8));
          hashDOM.addChild(valueDOM);

          valueDOM = new Xpp3Dom("value");
          valueDOM.setAttribute("n", "URI");
          valueDOM.setAttribute("v", tldHandler.getURI());
          hashDOM.addChild(valueDOM);

          valueDOM = new Xpp3Dom("value");
          valueDOM.setAttribute("n", "version");
          valueDOM.setAttribute("v", tldHandler.getVersion());
          hashDOM.addChild(valueDOM);

          // Add each file's hash to the tag-libraries "list"
          targetLibsDOM.addChild(hashDOM);
        } // endif
      } // endfor
      return;
    }
    catch (SAXException saxex)
    {
      getLog().info("SAX Parse Exception parsing " + path + ": " +
                    saxex.getMessage(), saxex);
    }
    catch (IOException ioe)
    {
      getLog().info("Unable to open an InputStream to " + path, ioe);
    }
    catch (ParserConfigurationException pce)
    {
      getLog().info("Unable to create SAX parser for " + path, pce);
    }
  }


  private void replaceTagLibraries(Xpp3Dom projectDOM)
    throws XmlPullParserException
  {
    // This boolean is set by specifying the jdev.plugin.add.taglibs
    // property at the top of a project's pom file.  There are projects
    // that don't need taglibs in their .jpr files to compile and this
    // allows them to be excluded.
    if (!_addTagLibs)
    {
      return;
    }

    // /jpr:project
    //   /hash[@n="oracle.jdevimpl.webapp.jsp.libraries.model.ProjectTagLibraries"]
    //       /list[@n="tag-libaries"]
    Xpp3Dom projectTagsDOM =
      findNamedChild(projectDOM, "hash", "oracle.jdevimpl.webapp.jsp.libraries.model.ProjectTagLibraries");
    Xpp3Dom tagLibsDOM =
      findNamedChild(projectTagsDOM, "list", "tag-libraries");

    Xpp3Dom targetLibsDOM = new Xpp3Dom("list");

    //
    // tagLibraryDefinitions
    //
    //<hash>
    //  <hash n="baseLibrary">
    //    <value n="name" v="JSF HTML"></value>
    //    <value n="version" v="1.2"></value>
    //  </hash>
    //  <value n="jspVersion" v="2.1"></value>
    //  <value n="name" v="JSF HTML"></value>
    //
    //  <value n="tldURL" v="@oracle.home@lib/java/shared/oracle.jsf/1.2/jsf-ri.jar!/META-INF/html_basic.tld"></value>
    //  <value n="URI" v="http://java.sun.com/jsf/html"></value>
    //  <value n="version" v="1.2"></value>
    //</hash>
    //

    // Parent "hash"
    Xpp3Dom hashDOM = null;

    // <value...
    Xpp3Dom valueDOM = null;

    if (distributedTagLibraries != null &&
        distributedTagLibraries.length > 0)
    {
      // Process each distributed Tag Library
      for (int i = 0; i < distributedTagLibraries.length; i++)
      {
        Properties disTagLib = distributedTagLibraries[i];
        String nameName = null;
        String nameValue = null;
        String versionName = null;
        String versionValue = null;

        // Create parent hash for each taglib
        hashDOM = new Xpp3Dom("hash");

        // baseLibrary "hash" for each taglib
        Xpp3Dom hashBaseDOM = new Xpp3Dom("hash");
        hashBaseDOM.setAttribute("n", "baseLibrary");
        // Add baseLibrary hash to parent hash
        hashDOM.addChild(hashBaseDOM);

        // Process each property of the taglib
        for (Enumeration keys = disTagLib.propertyNames();
             keys.hasMoreElements(); )
        {
          // Get the name value pair
          String name = (String) keys.nextElement();
          String value = (String) disTagLib.get(name);

          // Put the name and version values
          // inside the baseLibrary hash.
          // This only happens once per taglib
          if ("name".equals(name))
          {
            nameName = name;
            nameValue = value;

            // n="name, v=<name of taglib> in baseLibrary
            valueDOM = new Xpp3Dom("value");
            valueDOM.setAttribute("n", name);
            valueDOM.setAttribute("v", value);
            hashBaseDOM.addChild(valueDOM);

            // Duplicate the "name"  <value...
            // outside of the baseLibrary
            // n="name, v=<name of taglib> in parent hash
            valueDOM = new Xpp3Dom("value");
            valueDOM.setAttribute("n", nameName);
            valueDOM.setAttribute("v", nameValue);
            hashDOM.addChild(valueDOM);
          }
          else if ("version".equals(name))
          {
            versionName = name;
            versionValue = value;

            // n="version" v=<taglib version> in baseLibrary
            valueDOM = new Xpp3Dom("value");
            valueDOM.setAttribute("n", name);
            valueDOM.setAttribute("v", value);
            hashBaseDOM.addChild(valueDOM);

            // Duplicate the "version" <value...
            // outside of the baseLibrary
            // n="version" v=<taglib version> in parent hash
            valueDOM = new Xpp3Dom("value");
            valueDOM.setAttribute("n", versionName);
            valueDOM.setAttribute("v", versionValue);
            hashDOM.addChild(valueDOM);
          }
          else
          {
            if ("tld".equals(name))
            {
              // Did not want to have a URL in the pom file.
              // I just wanted the user to specify the name
              // of the tld file.  So we fix it for JDev
              // here.
              name += "URL";
              value = tagLibDirectory + "/" + value;
            }
            valueDOM = new Xpp3Dom("value");
            valueDOM.setAttribute("n", name);
            valueDOM.setAttribute("v", value);
            hashDOM.addChild(valueDOM);
          }
        } //endfor processing each property

        // We are done with this disTagLib
        // Add it to the targetLibsDOM
        if (hashDOM != null)
        {
          targetLibsDOM.addChild(hashDOM);
        }
      } // endfor processing each distributed tag lib
    } //endif
    else
    {
      // Use Default tag library configuration.  See comment before
      // replaceTagLibraries.
      replaceDefaultTagLibraries(projectDOM, targetLibsDOM);
    }

    replaceLocalTagLibraries(targetLibsDOM);

    // First, add JSP Runtime dependency if src/main/webapp exists
    // TODO: use a better merge algorithm
    removeChildren(tagLibsDOM);

    // make sure to pass Boolean.FALSE to allow
    // multiple child elements with the same name
    Xpp3Dom.mergeXpp3Dom(tagLibsDOM, targetLibsDOM, Boolean.FALSE);
  }

  private void replaceDefaultTagLibraries(Xpp3Dom projectDOM,
                                          Xpp3Dom targetLibsDOM)
    throws XmlPullParserException
  {
    // Begin JSF HTML Tag lib
    Xpp3Dom hashDOM     = new Xpp3Dom("hash");
    Xpp3Dom hashBaseDOM = new Xpp3Dom("hash");
    Xpp3Dom valueDOM    = null;

    hashBaseDOM.setAttribute("n", "baseLibrary");

    // Add baseLibrary hash to parent hash
    hashDOM.addChild(hashBaseDOM);

    // Create parent hash for each taglib
    //        hashDOM = new Xpp3Dom("hash");

    // baseLibrary "hash" for each taglib
    // Xpp3Dom hashBaseDOM = new Xpp3Dom("hash");
    //        hashBaseDOM.setAttribute("n", "baseLibrary");

    // n="name, v=<name of taglib> in baseLibrary
    valueDOM = new Xpp3Dom("value");
    valueDOM.setAttribute("n", "name");
    valueDOM.setAttribute("v", "JSF HTML");
    hashBaseDOM.addChild(valueDOM);

    // Duplicate the "name"  <value...
    // outside of the baseLibrary
    // n="name, v=<name of taglib> in parent hash
    valueDOM = new Xpp3Dom("value");
    valueDOM.setAttribute("n", "name");
    valueDOM.setAttribute("v", "JSF HTML");
    hashDOM.addChild(valueDOM);

    // n="version" v=<taglib version> in baseLibrary
    valueDOM = new Xpp3Dom("value");
    valueDOM.setAttribute("n", "version");
    valueDOM.setAttribute("v", "1.2");
    hashBaseDOM.addChild(valueDOM);

    // Duplicate the "version" <value...
    // outside of the baseLibrary
    // n="name, v=<name of taglib> in parent hash
    valueDOM = new Xpp3Dom("value");
    valueDOM.setAttribute("n", "version");
    valueDOM.setAttribute("v", "1.2");
    hashDOM.addChild(valueDOM);

    valueDOM = new Xpp3Dom("value");
    valueDOM.setAttribute("n", "jspVersion");
    valueDOM.setAttribute("v", "2.1");
    hashDOM.addChild(valueDOM);

    valueDOM = new Xpp3Dom("value");
    valueDOM.setAttribute("n", "tldURL");
    valueDOM.setAttribute("v", tagLibDirectory + "/html_basic.tld");
    hashDOM.addChild(valueDOM);

    valueDOM = new Xpp3Dom("value");
    valueDOM.setAttribute("n", "URI");
    valueDOM.setAttribute("v", "http://java.sun.com/jsf/html");
    hashDOM.addChild(valueDOM);

    // We are done with this disTagLib
    // Add it to the targetLibsDOM
    if (hashDOM != null)
    {
      targetLibsDOM.addChild(hashDOM);
    }

    // Begin JSF Core Taglib
    hashDOM     = new Xpp3Dom("hash");
    hashBaseDOM = new Xpp3Dom("hash");

    hashBaseDOM.setAttribute("n", "baseLibrary");

    // Add baseLibrary hash to parent hash
    hashDOM.addChild(hashBaseDOM);

    // n="name, v=<name of taglib> in baseLibrary
    valueDOM = new Xpp3Dom("value");
    valueDOM.setAttribute("n", "name");
    valueDOM.setAttribute("v", "JSF Core");
    hashBaseDOM.addChild(valueDOM);

    // Duplicate the "name"  <value...
    // outside of the baseLibrary
    // n="name, v=<name of taglib> in parent hash
    valueDOM = new Xpp3Dom("value");
    valueDOM.setAttribute("n", "name");
    valueDOM.setAttribute("v", "JSF Core");
    hashDOM.addChild(valueDOM);

    // n="version" v=<taglib version> in baseLibrary
    valueDOM = new Xpp3Dom("value");
    valueDOM.setAttribute("n", "version");
    valueDOM.setAttribute("v", "1.2");
    hashBaseDOM.addChild(valueDOM);

    // Duplicate the "version" <value...
    // outside of the baseLibrary
    // n="name, v=<name of taglib> in parent hash
    valueDOM = new Xpp3Dom("value");
    valueDOM.setAttribute("n", "version");
    valueDOM.setAttribute("v", "1.2");
    hashDOM.addChild(valueDOM);

    valueDOM = new Xpp3Dom("value");
    valueDOM.setAttribute("n", "jspVersion");
    valueDOM.setAttribute("v", "2.1");
    hashDOM.addChild(valueDOM);

    valueDOM = new Xpp3Dom("value");
    valueDOM.setAttribute("n", "tldURL");
    valueDOM.setAttribute("v", tagLibDirectory + "/jsf_core.tld");
    hashDOM.addChild(valueDOM);

    valueDOM = new Xpp3Dom("value");
    valueDOM.setAttribute("n", "URI");
    valueDOM.setAttribute("v", "http://java.sun.com/jsf/core");
    hashDOM.addChild(valueDOM);

    // We are done with this disTagLib
    // Add it to the targetLibsDOM
    if (hashDOM != null)
    {
      targetLibsDOM.addChild(hashDOM);
    }
  }

  private void replaceParameters(String projectName, Xpp3Dom projectDOM)
    throws XmlPullParserException
  {
    if ((_releaseMajor >= 11) && (projectName != null))
    {
      replaceCompiler(projectDOM);
      replaceMakeProjectAndRunTarget(projectDOM);
    }
  }
  private void replaceCompiler(Xpp3Dom projectDOM)
    throws XmlPullParserException
  {
    // /jpr:project
    // <hash n="oracle.jdeveloper.compiler.OjcConfiguration">
    //   <value n="assertionsEnabled" v="true"/>
    //   <value n="compiler.name" v="Ojc"/>
    //   <list n="copyRes">
    //      <string v=".java"/>
    Xpp3Dom configDOM =
      findNamedChild(projectDOM, "hash",
                     "oracle.jdeveloper.compiler.OjcConfiguration");
    Xpp3Dom compilerDOM = findNamedChild(configDOM, "value", "compiler.name");
    String compilerValue = "Ojc";

    if (   (compiler != null)
        && "Javac".equalsIgnoreCase(compiler)
       )
    {
      compilerValue = "Javac";
    }
    compilerDOM.setAttribute("v", compilerValue);

    return;
  }

  private void replaceMakeProjectAndRunTarget(Xpp3Dom projectDOM)
    throws XmlPullParserException
  {
    // /jpr:project
    //   /hash[@n="oracle.jdeveloper.runner.RunConfigurations"]
    //     /hash[@n="runConfigurationDefinitions"]
    //       /hash[@n="Default"]
    //         /value[@n="makeProject" v="false"]
    //         /url[@n="targetURL" path="src/main/webapp/index.jspx"]
    Xpp3Dom configDOM =
      findNamedChild(projectDOM, "hash",
                     "oracle.jdeveloper.runner.RunConfigurations");
    Xpp3Dom defsDOM =
      findNamedChild(configDOM, "hash", "runConfigurationDefinitions");
    Xpp3Dom defaultDOM = findNamedChild(defsDOM, "hash", "Default");
    Xpp3Dom makeProjectDom =
      findNamedChild(defaultDOM, "value", "compileBeforeRun");

    if (makeProject)
    {
      makeProjectDom.setAttribute("v", "true");
    }
    else
    {
      makeProjectDom.setAttribute("v", "false");
    }

    if ((runTarget != null) && !"".equals(runTarget))
    {
      // Convert file separator chars to generic
      String targetURL = "";
      if (File.separatorChar == '/')
      {
        targetURL = runTarget.replace('\\', '/'); // Unix
      }
      else
      {
        targetURL = runTarget.replace('/', '\\'); // Windows
      }

      Xpp3Dom targetDOM = new Xpp3Dom("url");
      targetDOM.setAttribute("path", targetURL);
      targetDOM.setAttribute("n", "targetURL");
      defaultDOM.addChild(targetDOM);
    }

    return;
  }

  private void copyTagLibraries(File projectDir, List dependencies,
                                List artifacts)
    throws IOException
  {
    File targetDir = new File(projectDir, "src/main/webapp/WEB-INF");

    for (Iterator i = dependencies.iterator(); i.hasNext(); )
    {
      Dependency dependency = (Dependency) i.next();
      MavenProject dependentProject =
        findDependentProject(dependency.getManagementKey());
      if (dependentProject != null)
      {
        List resourceRoots = dependentProject.getResources();
        for (Iterator j = resourceRoots.iterator(); j.hasNext(); )
        {
          Resource resource = (Resource) j.next();
          String resourceRoot = resource.getDirectory();
          File resourceDirectory = new File(resourceRoot);
          if (resourceDirectory.exists())
          {
            DirectoryScanner scanner = new DirectoryScanner();
            scanner.setBasedir(resourceRoot);
            scanner.addDefaultExcludes();
            scanner.setIncludes(new String[]
                { "META-INF/*.tld" });
            scanner.scan();

            String[] tldFiles = scanner.getIncludedFiles();
            for (int k = 0; k < tldFiles.length; k++)
            {
              File sourceFile = new File(resourceDirectory, tldFiles[k]);
              File targetFile = new File(targetDir, sourceFile.getName());

              if (targetFile.exists())
              {
                targetFile.delete();
              }
              FileUtils.copyFile(sourceFile, targetFile);
            }
          }
        }
      }
    }


    Map sourceMap = new TreeMap();

    for (Iterator i = artifacts.iterator(); i.hasNext(); )
    {
      Artifact artifact = (Artifact) i.next();
      if (!isDependentProject(artifact.getDependencyConflictId()) &&
          "jar".equals(artifact.getType()))
      {
        File file = artifact.getFile();
        JarFile jarFile = new JarFile(file);
        Enumeration jarEntries = jarFile.entries();
        while (jarEntries.hasMoreElements())
        {
          JarEntry jarEntry = (JarEntry) jarEntries.nextElement();
          String name = jarEntry.getName();
          if (name.startsWith("META-INF/") && name.endsWith(".tld"))
          {
            List taglibs = (List) sourceMap.get(name);
            if (taglibs == null)
            {
              taglibs = new ArrayList();
              sourceMap.put(name, taglibs);
            }

            taglibs.add(file);
          }
        }
      }
    }

    for (Iterator i = sourceMap.entrySet().iterator(); i.hasNext(); )
    {
      Map.Entry e = (Map.Entry) i.next();
      List taglibs = (List) e.getValue();
      String name = (String) e.getKey();

      for (Iterator ti = taglibs.iterator(); ti.hasNext(); )
      {
        File file = (File) ti.next();
        File sourceFile = new File(name);
        StringBuffer buff = new StringBuffer(sourceFile.getName());
        if (taglibs.size() > 1)
        {
          String jarName =
            file.getName().substring(0, file.getName().length() -
                                     ".jar".length());
          buff.insert(buff.length() - ".tld".length(), "-" + jarName);
        }

        URL jarURL = file.toURL();
        URL sourceURL =
          new URL("jar:" + jarURL.toExternalForm() + "!/" + name);
        File targetFile = new File(targetDir, buff.toString());
        if (targetFile.exists())
        {
          targetFile.delete();
        }
        FileUtils.copyURLToFile(sourceURL, targetFile);
        targetFile.setReadOnly();
      }
    }
  }

  private void replaceOutputDirectory(File projectDir, File outputDir,
                                      Xpp3Dom projectDOM)
    throws XmlPullParserException
  {
    // /jpr:project
    //   /hash[@n="oracle.jdevimpl.config.JProjectPaths"]

    Xpp3Dom projectPathsDOM =
      findNamedChild(projectDOM, "hash", "oracle.jdevimpl.config.JProjectPaths");
    Xpp3Dom sourceDOM = new Xpp3Dom("url");

    //
    // <url @n="outputDirectory" path="[relative-path-to-output-dir]" />
    //
    sourceDOM.setAttribute("path", getRelativeDir(projectDir, outputDir));
    sourceDOM.setAttribute("n", "outputDirectory");
    projectPathsDOM.addChild(sourceDOM);
  }

  /**
   * Returns the JDeveloper project file for a Maven POM.
   *
   * @param project  the Maven POM
   *
   * @return  the JDeveloper project file
   */
  private File getJProjectFile(MavenProject project)
  {
    String jprName = project.getArtifactId() + ".jpr";
    return new File(project.getBasedir(), jprName);
  }

  /**
   * Returns the JDeveloper test project file for a Maven POM.
   *
   * @param project  the Maven POM
   *
   * @return  the JDeveloper test project file
   */
  private File getJProjectTestFile(MavenProject project)
  {
    String jprName = project.getArtifactId() + "-test.jpr";
    return new File(project.getBasedir(), jprName);
  }

  /**
   * Returns the JDeveloper workspace file for a Maven POM.
   *
   * @param project  the Maven POM
   *
   * @return  the JDeveloper workspace file
   */
  private File getJWorkspaceFile(MavenProject project)
  {
    String jwsName = project.getArtifactId() + ".jws";
    return new File(project.getBasedir(), jwsName);
  }

  /**
   * Reads a JDeveloper workspace file into DOM.
   *
   * @param workspaceFile  the JDeveloper workspace file
   *
   * @return the parsed DOM
   */
  private Xpp3Dom readWorkspaceDOM(File workspaceFile)
    throws IOException, XmlPullParserException
  {
    return readDOM(workspaceFile, release + "/workspace.xml");
  }

  /**
   * Reads a JDeveloper project file into DOM.
   *
   * @param projectFile  the JDeveloper project file
   *
   * @return the parsed DOM
   */
  private Xpp3Dom readProjectDOM(File projectFile)
    throws IOException, XmlPullParserException
  {
    return readDOM(projectFile, release + "/project.xml");
  }

  /**
   * Reads a source file into DOM, defaulting to a packaged resource if
   * the source file does not already exist.
   *
   * @param sourceFile    the source file to be parsed
   * @param resourcePath  the default packaged resource
   *
   * @return the parsed DOM
   */
  private Xpp3Dom readDOM(File sourceFile, String resourcePath)
    throws IOException, XmlPullParserException
  {
    Reader reader = null;
    try
    {
      if (!force && sourceFile.exists())
      {
        // parse the existing source file
        reader = new FileReader(sourceFile);
      }
      else
      {
        // parse the default resource file
        URL resource = getClass().getResource(resourcePath);

        // ensure that the resourcePath can be found
        if (resource == null)
        {
          throw new IOException("Unable to read resource: " +
                                resourcePath);
        }

        reader = new InputStreamReader(resource.openStream());
      }
      return Xpp3DomBuilder.build(reader);
    }
    finally
    {
      IOUtil.close(reader);
    }
  }

  /**
   * Writes a XML DOM to the target file.
   *
   * @param targetFile  the target file
   * @param sourceDOM   the source DOM
   */
  private void writeDOM(File targetFile, Xpp3Dom sourceDOM)
    throws IOException, XmlPullParserException
  {
    FileWriter writer = null;
    try
    {
      writer = new FileWriter(targetFile);
      Xpp3DomWriter.write(writer, sourceDOM);
    }
    finally
    {
      IOUtil.close(writer);
    }
  }

  private String getRelativeDir(File source, File target)
  {
    return getRelativePath(source, target, true);
  }

  private String getRelativeFile(File source, File target)
  {
    return getRelativePath(source, target, false);
  }

  /**
   * Returns the relative path between two files.
   *
   * @param source  the source file
   * @param target  the target file
   *
   * @return  the relative path between two files
   */
  private String getRelativePath(File source, File target,
                                 boolean isDirectory)
  {
    String sourcePath = source.getAbsolutePath();
    String targetPath = target.getAbsolutePath();

    if (targetPath.startsWith(sourcePath + File.separatorChar))
    {
      String relativePath = targetPath.substring(sourcePath.length() + 1);
      relativePath = relativePath.replace(File.separatorChar, '/');
      if (isDirectory)
      {
        relativePath += "/";
      }
      return relativePath;
    }
    else
    {
      String[] sourcePaths = sourcePath.split("\\" + File.separator);
      String[] targetPaths = targetPath.split("\\" + File.separator);

      // On Windows, the first element in the absolute path is a drive letter
      if (System.getProperty("os.name").startsWith("Windows"))
      {
        // uppercase the drive letter because Cygwin sometimes delivers
        // a lowercase drive letter
        sourcePaths[0] = sourcePaths[0].toUpperCase();
        targetPaths[0] = targetPaths[0].toUpperCase();
      }

      int sourcePathCount = sourcePaths.length;
      int targetPathCount = targetPaths.length;
      int commonPathCount = 0;

      int minPathCount = Math.min(sourcePathCount, targetPathCount);
      for (int i = 0; i < minPathCount; i++)
      {
        if (sourcePaths[i].equals(targetPaths[i]))
        {
          commonPathCount++;
        }
      }

      if (commonPathCount > 0)
      {
        int sourceRelativePathCount = sourcePathCount - commonPathCount;
        int targetRelativePathCount = targetPathCount - commonPathCount;

        int relativePathCount =
          sourceRelativePathCount + targetRelativePathCount;
        String[] relativePaths = new String[relativePathCount];

        for (int i = 0; i < sourceRelativePathCount; i++)
        {
          relativePaths[i] = "..";
        }

        for (int i = 0; i < targetRelativePathCount; i++)
        {
          relativePaths[sourceRelativePathCount + i] =
              targetPaths[commonPathCount + i];
        }

        // join
        StringBuffer relativePath = new StringBuffer();
        for (int i = 0; i < relativePathCount; i++)
        {
          if (i > 0)
          {
            relativePath.append("/");
          }
          relativePath.append(relativePaths[i]);
        }
        return relativePath.toString();
      }
      else
      {
        return targetPath;
      }
    }
  }

  private Xpp3Dom findNamedChild(Xpp3Dom parent, String childName,
                                 String attrValue)
  {
    Xpp3Dom[] hash = parent.getChildren(childName);
    for (int i = 0; i < hash.length; i++)
    {
      if (attrValue.equals(hash[i].getAttribute("n")))
      {
        return hash[i];
      }
    }

    Xpp3Dom child = new Xpp3Dom(childName);
    child.setAttribute("n", attrValue);
    parent.addChild(child);

    return child;
  }

  private MavenProject findDependentProject(String dependencyManagementKey)
  {
    for (Iterator i = reactorProjects.iterator(); i.hasNext(); )
    {
      MavenProject reactorProject = (MavenProject) i.next();
      String ident =
        reactorProject.getArtifact().getDependencyConflictId();
      if (ident.equals(dependencyManagementKey))
      {
        return reactorProject.getExecutionProject();
      }
    }

    return null;
  }

  private boolean isDependentProject(String dependencyManagementKey)
  {
    return (findDependentProject(dependencyManagementKey) != null);
  }

  private void removeChildren(Xpp3Dom parent)
  {
    while (parent.getChildCount() != 0)
    {
      parent.removeChild(0);
    }
  }

  private Xpp3Dom createProjectReferenceDOM(File workspaceDir,
                                            File projectFile)
  {
    Xpp3Dom hashDOM = new Xpp3Dom("hash");
    Xpp3Dom urlDOM = new Xpp3Dom("url");
    urlDOM.setAttribute("n", "URL");
    urlDOM.setAttribute("path", getRelativeFile(workspaceDir, projectFile));
    
    if (_releaseMajor < 11)
    {
      Xpp3Dom valueDOM = new Xpp3Dom("value");
      valueDOM.setAttribute("n", "nodeClass");
      valueDOM.setAttribute("v", "oracle.jdeveloper.model.JProject");
      hashDOM.addChild(valueDOM);
    }
    hashDOM.addChild(urlDOM);
    return hashDOM;
  }

  private void _parseRelease()
  {
    String nums[] = release.split("\\.");
    try
    {
      _releaseMajor = Integer.parseInt(nums[0]);
    }
    catch (NumberFormatException e)
    {
      // Default release is currently 10.x
      _releaseMajor = 10;
    }
  }

  private int     _releaseMajor = 0;
  private boolean _addLibraries = true;
  private boolean _addTagLibs   = true;

  private static final String _PROPERTY_ADD_LIBRARY = "jdev.plugin.add.libraries";
  private static final String _PROPERTY_ADD_TAGLIBS = "jdev.plugin.add.taglibs";

}
