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

}