<?xml version="1.0"?>
<!-- 
/*
 * Copyright 2001-2004 The Apache Software Foundation.
 * 
 * Licensed 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.
 */
 -->


<project
  xmlns:j="jelly:core"
  xmlns:ant="jelly:ant"
  xmlns:u="jelly:util"
  xmlns:def="jelly:define"
  xmlns:maven="jelly:maven"
  xmlns:x="jelly:xml"
  xmlns:jbuilder="jbuilder" >

  <goal name="jbuilder"
    description="Generate JBuilder project files"
    prereqs="jbuilder:generate-library, jbuilder:generate-project"/>

  <def:taglib uri="jbuilder">
    <!-- ================================================================== -->
    <!-- jbuilder:getDefaultProject                                         -->
    <!-- ================================================================== -->
    <!-- Determine the JBuilder default project template and user home      -->
    <!-- directory.                                                         -->
    <!--                                                                    -->
    <!-- The following parameters can be used with the getDefaultProject    -->
    <!-- tag by setting the appropriate attribute when invoking the tag:    -->
    <!--                                                                    -->
    <!-- @param project The name of the variable in the caller's context    -->
    <!--                that will contain the JBuilder default project.     -->
    <!-- @param userHome The name of the variable in the caller's context   -->
    <!--                 that will contain the JBuilder user home directory.-->
    <!-- ================================================================== -->
    <def:tag name="getDefaultProject">
      <j:set var="jbuilderDirs" value=".jbuilderX,.jbuilder9,.jbuilder8,.jbuilder7,.jbuilder6,.jbuilder5,.jbuilder4,.jbuilder" />
      <j:set var="${userHome}" value="null" scope="parent"/> 
      <j:set var="${project}" value="null" scope="parent"/> 
      <u:tokenize var="jbuilderDirList" delim=",">${jbuilderDirs}</u:tokenize>
      <j:forEach var="dir" items="${jbuilderDirList}">
        <j:set var="home" value="${maven.jbuilder.userHome}/${dir}" />
        <j:set var="defaultProject" value="${home}/Default.jpr" />
        <u:available file="${defaultProject}">
          <j:set var="${userHome}" value="${home}" scope="parent"/> 
          <j:set var="${project}" value="${defaultProject}" scope="parent"/> 
          <j:break/>
        </u:available>
      </j:forEach>
    </def:tag>

    <!-- ================================================================== -->
    <!-- jbuilder:generateArtifactLibrary                                   -->
    <!-- ================================================================== -->
    <!-- Generate a JBuilder library definition from an artifact. If the    -->
    <!-- dependency is versioned (i.e. is not a snapshot) or if an          -->
    <!-- unversioned library definition has not been created yet from the   -->
    <!-- corresponding artifact, then a versioned library definition is     -->
    <!-- created that refers to the dependency's jar in the local           -->
    <!-- repository. The versioned library definition is only written if it -->
    <!-- is already a dependency library or if it does not already exist.   -->
    <!-- If the dependency is a snapshot and an unversioned library         -->
    <!-- definition exists, then the unversioned library name is used for   -->
    <!-- the purposes of updating the libraryList, but no library           -->
    <!-- definition is written.                                             -->
    <!--                                                                    -->
    <!-- The following parameters can be used with the                      -->
    <!-- generateArtifactLibrary tag by setting the appropriate attribute   -->
    <!-- when invoking the tag:                                             -->
    <!--                                                                    -->
    <!-- @param artifact The artifact.                                      -->
    <!-- @param userHome The JBuilder user home directory.                  -->
    <!-- @param libraryList Optional name of a variable in the caller's     -->
    <!--                    context that contains a semi-colon separated    -->
    <!--                    list of library names. If the variable is       -->
    <!--                    supplied, then the name of the generated        -->
    <!--                    library will be appended.                       -->
    <!-- @param verbose Optional flag to enable verbose output.             -->
    <!-- ================================================================== -->
    <def:tag name="generateArtifactLibrary">
      <j:set var="libraryId" value="${artifact.dependency.artifactId}" />
      <j:set var="libraryVersion" value="${artifact.dependency.version}" />
      <!-- The default is to create a versioned library definition that refers
           to the jar in the local repository. -->
      <j:set var="libraryName" value="${libraryId}-${libraryVersion}" />
      <j:if test="${verbose}" >
        <ant:echo>Checking dependency ${libraryName} ...</ant:echo>
      </j:if>
      <j:if test="${userHome != null and userHome.length() gt 0}" >
        <j:set var="isSnapshot" value="${libraryVersion.equals('SNAPSHOT')}" />
        <j:set var="unversionedLibraryName" value="${libraryId}" />
        <j:set var="unversionedLibraryFile" value="${userHome}/${unversionedLibraryName}.library" />
        <j:set var="unversionedLibraryExists" value="false" />
        <u:available file="${unversionedLibraryFile}">
          <j:set var="unversionedLibraryExists" value="true" />
        </u:available>

        <j:choose>
          <!-- We create a versioned library definition that refers to the jar
               in the local repo if the dependency itself is versioned (ie. is not
               a snapshot) or if an unversioned library definition has not been
               created yet from the corresponding artifact. -->
          <j:when test="${!isSnapshot or !unversionedLibraryExists}" >
            <j:if test="${verbose and isSnapshot}" >
              <ant:echo>  unversioned library definition not found</ant:echo>
            </j:if>
            <j:set var="libraryFile" value="${userHome}/${libraryName}.library" />
            <j:set var="libraryExists" value="false" />
            <u:available file="${libraryFile}">
              <j:set var="libraryExists" value="true" />
            </u:available>

            <!-- Parse the existing library to determine if it was generated from a
                 maven dependency (i.e. by this tag) -->
            <j:set var="mavenGenerated" value="false" />
            <j:if test="${libraryExists}" >
              <u:file var="libraryFileFile" name="${libraryFile}"/>
              <x:parse var="doc" xml="${libraryFileFile}"/>
              <x:set var="root" select="$doc/*" />
              <x:set var="mavenElement" select="$root/maven-generated" />
              <j:if test="${!mavenElement.isEmpty()}" >
                <j:set var="mavenGenerated" value="true" />
                <j:set var="libraryType"><x:expr select="$root/maven-generated/libraryType" /></j:set>
              </j:if>
            </j:if>

            <j:if test="${!libraryExists or (mavenGenerated and libraryType == 'dependency') }" >
              <j:if test="${verbose}" >
                <ant:echo>  creating dependent ${libraryFile}</ant:echo>
              </j:if>
              <j:if test="${!verbose}" >
                <ant:echo>Creating dependent ${libraryFile} ...</ant:echo>
              </j:if>

              <!-- Get optional library source path property. -->
              <j:set var="librarySourceProp" value="maven.jbuilder.${libraryName}.librarySource" />
              <j:set var="librarySource" value="${librarySourceProp}" />

	            <j:file name="${libraryFile}" prettyPrint="true" xmlns="dummy">
                <library>
                  <x:comment>JBuilder Library Definition File</x:comment>
                  <fullname>${libraryName}</fullname>
                  <class>
                    <path><j:expr value="${artifact.path}"/></path>
                  </class>
                  <j:if test="${librarySource != null and librarySource.length() gt 0}" >
                    <source>
                      <path><j:expr value="${librarySource}" /></path>
                    </source>
                  </j:if>
                  <maven-generated>
                    <libraryType>dependency</libraryType>
                  </maven-generated>
                </library>
              </j:file>
            </j:if>
          </j:when>


          <!-- We create a versioned library definition that refers to the jar
               in the local repo if the dependency itself is versioned (ie. is not
               a snapshot) or if an unversioned library definition has not been
               created yet from the corresponding artifact. -->
          <j:otherwise>
            <j:set var="libraryName" value="${unversionedLibraryName}" />
            <j:if test="${verbose}" >
              <ant:echo>  referencing artifact library ${unversionedLibraryFile}</ant:echo>
            </j:if>
          </j:otherwise>
        </j:choose>
      </j:if>

      <j:if test="${libraryList != null}" >
        <j:set var="libs" value="${context.getVariable(libraryList)}" />
        <j:if test="${libs.length() > 0}" >
          <j:set var="libs" value="${libs};" />
        </j:if>
        <j:set var="libs" value="${libs}${libraryName}" />
        <j:set var="${libraryList}" value="${libs}" scope="parent" />
      </j:if>
    </def:tag>

    <!-- ================================================================== -->
    <!-- jbuilder:generateProjectLibrary                                    -->
    <!-- ================================================================== -->
    <!-- Generate a JBuilder library file from a project.                   -->
    <!--                                                                    -->
    <!-- The following parameters can be used with the                      -->
    <!-- generateProjectLibrary tag by setting the appropriate attribute    -->
    <!-- when invoking the tag:                                             -->
    <!--                                                                    -->
    <!-- @param project The project.                                        -->
    <!-- @param userHome The JBuilder user home directory.                  -->
    <!-- ================================================================== -->
    <def:tag name="generateProjectLibrary">
      <j:set var="libraryName" value="${project.artifactId}" />
      <j:set var="libraryFile" value="${userHome}/${libraryName}.library" />
      <ant:echo>Creating ${libraryFile} ...</ant:echo>
      <j:file name="${libraryFile}" prettyPrint="true" xmlns="dummy">
        <library>
          <x:comment>JBuilder Library Definition File</x:comment>
          <fullname>${libraryName}</fullname>
          <class>
            <path><j:expr value="${maven.build.dest}"/></path>
          </class>
          <source>
            <j:if test="${sourcesPresent}" >
              <path><j:expr value="${project.build.sourceDirectory}" /></path>
            </j:if>
          </source>
          <j:forEach var="lib" items="${project.dependencies}">
            <required><j:expr value="${lib.artifactId}"/></required>
          </j:forEach>
          <maven-generated>
            <libraryType>project</libraryType>
          </maven-generated>
        </library>
      </j:file>
    </def:tag>
  </def:taglib>

  <!-- ================================================================== -->
  <!-- jbuilder:generate-project                                          -->
  <!-- ================================================================== -->
  <!-- Creates a JBuilder project file.                                   -->
  <!-- ================================================================== -->
  <goal
    name="jbuilder:generate-project"
    description="Generate JBuilder [id_project].jpx file">

    <!-- This forces the javadoc plugin to load and read its properties -->
    <attainGoal name="maven-javadoc-plugin:register" />

    <!-- Initialize default values for project properties. If we find a default
         JBuilder project, then its values will override some of these. -->
    <j:set var="authorLabel"      value="@author" />
    <j:set var="backupPath"       value="bak" />
    <j:set var="beansInstantiate" value="false" />
    <j:set var="company"          value="${pom.organization.name}" />
    <j:set var="companyLabel"     value="Company: " />
    <j:set var="copyrightLabel"   value="Copyright: " />
    <j:set var="descriptionLabel" value="Description: " />
    <maven:makeRelativePath var="relativeDocPath" basedir="${basedir}" path="${pom.getPluginContext('maven-javadoc-plugin').getVariable('maven.javadoc.destdir')}" />
    <j:set var="docPath"          value="${relativeDocPath}" />
    <j:set var="docX" value="${maven.jbuilder.docpath}X" />
    <j:if test="${docX != 'X'}" >
      <j:set var="docPath" value="${maven.jbuilder.docpath}" />
    </j:if>
    <maven:makeRelativePath var="relativeOutPath" basedir="${basedir}" path="${maven.jbuilder.outpath}" />
    <j:set var="outPath"          value="${relativeOutPath}" />
    <j:set var="jdk"              value="java version ${java.vm.version}" />
    <j:set var="titleLabel"       value="Title: " />
    <j:set var="versionLabel"     value="@version" />
    <j:set var="workingDir"       value="." />

    <!-- Format the year. -->
    <tstamp>
       <format property="currentYear" pattern="yyyy" />
    </tstamp>
    <tstamp>
      <j:choose>
        <j:when test="${pom.inceptionYear.equals(currentYear)}">
          <format property="year" pattern="yyyy"/>
        </j:when>
        <j:otherwise>
          <format property="year" pattern="${pom.inceptionYear}-yyyy"/>
        </j:otherwise>
      </j:choose>
    </tstamp>

    <!-- Find and read the JBuilder default project properties. -->
    <jbuilder:getDefaultProject project="jbDefaultProject" userHome="jbUserHome" />
    <j:if test="${jbDefaultProject == null}" >
      <ant:echo>+------------------------------------------------------------------</ant:echo>
      <ant:echo>| WARNING!</ant:echo>
      <ant:echo>|</ant:echo>
      <ant:echo>| A JBuilder installation could not be found. The project files</ant:echo>
      <ant:echo>| being created will contain default values.</ant:echo>
      <ant:echo>+------------------------------------------------------------------</ant:echo>
    </j:if>
    <j:if test="${jbDefaultProject != null}" >
      <ant:echo>Reading default project ${jbDefaultProject}</ant:echo>
      <u:properties file="${jbDefaultProject}" var="defaultProps" />
      <j:set var="authorLabel"      value="${defaultProps.getProperty('sys[0].AuthorLabel')}" />
      <j:set var="backupPath"       value="${defaultProps.getProperty('sys[0].BackupPath')}" />
      <j:set var="backupPath"       value="${backupPath.replaceAll('%%\|', ':')}" />
      <j:set var="beansInstantiate" value="${defaultProps.getProperty('sys[0].BeansInstantiate')}" />
      <j:set var="companyLabel"     value="${defaultProps.getProperty('sys[0].CompanyLabel')}" />
      <j:set var="copyrightLabel"   value="${defaultProps.getProperty('sys[0].CopyrightLabel')}" />
      <j:set var="descriptionLabel" value="${defaultProps.getProperty('sys[0].DescriptionLabel')}" />
      <j:set var="titleLabel"       value="${defaultProps.getProperty('sys[0].TitleLabel')}" />
      <j:set var="versionLabel"     value="${defaultProps.getProperty('sys[0].VersionLabel')}" />
      <j:set var="jdk"              value="${defaultProps.getProperty('sys[0].JDK')}" />
      <available property="jdkDefPresent" file="${jbUserHome}/${jdk}.library" />
      <j:if test="${!jdkDefPresent}">
        <ant:echo>+------------------------------------------------------------------</ant:echo>
        <ant:echo>| WARNING!</ant:echo>
        <ant:echo>|</ant:echo>
        <ant:echo>| This project is being configured to use ${jdk}. This</ant:echo>
        <ant:echo>| JDK has not been configured yet in your JBuilder installation.</ant:echo>
        <ant:echo>| Go to Tools|Configure JDKs.</ant:echo>
        <ant:echo>+------------------------------------------------------------------</ant:echo>
      </j:if>
      <j:set var="defCompany"          value="${defaultProps.getProperty('sys[0].Company')}" />
    </j:if>

    <ant:echo>Creating ${basedir}/${pom.artifactId}.jpx ...</ant:echo>

    <!-- Format the copyright notice. -->
    <j:set var="copyright" value="Copyright (c) ${year} ${company} - All Rights Reserved." />

    <!-- Process the project's dependencies, build the project source path, and
         build the list of libraries it requires. -->
    <j:set var="includeTestPath" value="0" />
    <maven:makeRelativePath var="relativeSourcePath" basedir="${basedir}" path="${pom.build.sourceDirectory}" />
    <maven:makeRelativePath var="relativeTestPath" basedir="${basedir}" path="${pom.build.unitTestSourceDirectory}" />
    <j:set var="sourcePath" value="${relativeSourcePath}" />
    <j:set var="libraries" value="" />
    <!-- If the project has unit tests, add the test source code to the project
         path. -->
    <j:if test="${unitTestSourcesPresent}" >
      <j:set var="includeTestPath" value="1" />
      <j:set var="sourcePath" value="${sourcePath};${relativeTestPath}" />
    </j:if>
    <!-- If the project has resources, add the directories to the project path. -->
    <j:if test="${!pom.build.resources.isEmpty()}">
      <j:forEach var="resource" items="${pom.build.resources}">
        <u:available file="${resource.directory}">
          <j:set var="sourcePath" value="${sourcePath};${resource.directory}" />
        </u:available>
      </j:forEach>
    </j:if>
    <!-- Convert each of the project's dependencies into a required library. -->
    <j:forEach var="lib" items="${pom.artifacts}">
      <!-- If the project has a declared dependency on jUnit, we use the
           specified version. -->
      <j:if test="${lib.dependency.artifactId == 'junit'}" >
        <j:set var="junitArtifact" value="${lib}" />
      </j:if>
      <jbuilder:generateArtifactLibrary
        artifact="${lib}"
        userHome="${jbUserHome}"
        libraryList="libraries"
        verbose="${maven.jbuilder.verbose}" />
    </j:forEach>
    <!-- TODO: temporary -->
    <j:set var="testDependencies" value="${maven.jbuilder.testDependencies}" />
    <j:if test="${testDependencies != null and !testDependencies.isEmpty()}">
      <ant:fail>
        maven.jbuilder.testDependencies must be replaced with
        maven.jbuilder.testArtifacts, using artifacts instead of dependencies
      </ant:fail>
    </j:if>
    <!-- Convert each supplemental test dependency into a required library. -->
    <j:forEach var="lib" items="${maven.jbuilder.testArtifacts}">
      <!-- If the project has no declared dependency on jUnit, but a
           supplemental test dependency does, we use the version specified by
           the test dependency. -->
      <j:choose>
        <j:when test="${lib.dependency.artifactId == 'junit'}" >
          <j:if test="${junitArtifact == null}">
            <j:set var="junitArtifact" value="${lib}" />
            <jbuilder:generateArtifactLibrary
              artifact="${lib}"
              userHome="${jbUserHome}"
              libraryList="libraries"
              verbose="${maven.jbuilder.verbose}" />
          </j:if>
        </j:when>
        <j:otherwise>
          <jbuilder:generateArtifactLibrary
            artifact="${lib}"
            userHome="${jbUserHome}"
            libraryList="libraries"
            verbose="${maven.jbuilder.verbose}" />
        </j:otherwise>
      </j:choose>
    </j:forEach>
    <!-- Finally, if there are unit tests and we still do not have a specific
         dependency on jUnit, use the version from the test plugin. -->
    <j:if test="${unitTestSourcesPresent and junitArtifact == null}" >
      <!-- This goal forces the test plugin to be loaded.
           TODO: In Maven beta 9, use the special test:eclipse tag instead. -->
      <attainGoal name="test:prepare-filesystem" />
      <j:set var="testPluginProject" value="${pom.getPluginContext('maven-test-plugin').getVariable('plugin')}"/>
      <j:forEach var="testPluginArtifact" items="${testPluginProject.artifacts}">
        <j:if test="${testPluginArtifact.dependency.artifactId == 'junit'}">
          <j:set var="junitArtifact" value="${testPluginArtifact}"/>
        </j:if>
      </j:forEach>
      <jbuilder:generateArtifactLibrary
        artifact="${junitArtifact}"
        userHome="${jbUserHome}"
        libraryList="libraries"
        verbose="${maven.jbuilder.verbose}" />
    </j:if>

	  <j:file name="${basedir}/${pom.artifactId}.jpx" prettyPrint="true" xmlns="dummy">
  	  <project>
  	    <x:comment>JBuilder XML Project</x:comment>
        <property category="sys" name="Author"           value="${maven.username}" />
    	  <property category="sys" name="AuthorLabel"      value="${authorLabel}" />
        <property category="sys" name="BackupPath"       value="${backupPath}" />
        <property category="sys" name="BeansInstantiate" value="${beansInstantiate}" />
        <property category="sys" name="Company"          value="${company}" />
    	  <property category="sys" name="CompanyLabel"     value="${companyLabel}" />
        <property category="sys" name="Copyright"        value="${copyright}" />
        <property category="sys" name="CopyrightLabel"   value="${copyrightLabel}" />
        <maven:makeRelativePath var="relativeDefaultPath" basedir="${basedir}" path="${pom.build.sourceDirectory}" />
        <property category="sys" name="DefaultPath"      value="${relativeDefaultPath}" />
        <property category="sys" name="Description"      value="${pom.description}" />
        <property category="sys" name="DescriptionLabel" value="${descriptionLabel}" />
        <property category="sys" name="DocPath"          value="${docPath}" />
        <property category="sys" name="IncludeTestPath"  value="${includeTestPath}" />
        <property category="sys" name="JDK"              value="${jdk}" />
        <property category="sys" name="Libraries"        value="${libraries}" />
        <property category="sys" name="OutPath"          value="${outPath}" />
    	<property category="sys" name="SourcePath"       value="${sourcePath}" />
        <property category="sys" name="TestPath"         value="${relativeTestPath}" />
        <property category="sys" name="Title"            value="${pom.name}" />
        <property category="sys" name="TitleLabel"       value="${titleLabel}" />
        <property category="sys" name="Version"          value="${pom.currentVersion}" />
        <property category="sys" name="VersionLabel"     value="${versionLabel}" />
        <property category="sys" name="WorkingDirectory" value="${workingDir}" />

        <!-- Include any explicitly specified source files -->
        <u:tokenize var="sourceFileList" delim=",">${maven.jbuilder.additionalSources}</u:tokenize>
        <j:forEach var="file" items="${sourceFileList}">
          <u:available file="${file}">
            <file path="${file}" />
          </u:available>
        </j:forEach>

        <!-- Write the runtime configurations -->
        <j:set var="runtimeIndex" value="0" />
        <u:tokenize var="jbuilderAppList" delim=",">${maven.jbuilder.application.classes}</u:tokenize>
        <j:forEach var="app" items="${jbuilderAppList}">
          <property
            category="runtime.${runtimeIndex}"
            name="RunnableType"
            value="${maven.jbuilder.application.runner}" />
          <property
            category="runtime.${runtimeIndex}"
            name="application.class"
            value="${app}" />
          <property
            category="runtime.${runtimeIndex}"
            name="ConfigurationName"
            value="${app}" />
          <j:set var="runtimeIndex" value="${runtimeIndex + 1}" />
        </j:forEach>
        <u:tokenize var="jbuilderAppletList" delim=",">${maven.jbuilder.applets.classes}</u:tokenize>
        <j:forEach var="applet" items="${jbuilderAppletList}">
          <property
            category="runtime.${runtimeIndex}"
            name="RunnableType"
            value="${maven.jbuilder.applet.runner}" />
          <property
            category="runtime.${runtimeIndex}"
            name="applet.class"
            value="${applet}" />
          <property
            category="runtime.${runtimeIndex}"
            name="ConfigurationName"
            value="${applet}" />
          <j:set var="runtimeIndex" value="${runtimeIndex + 1}" />
        </j:forEach>
        <property category="runtime" name="ConfigurationCount" value="${runtimeIndex - 1}"/>

  	  </project>
  	</j:file>	
  </goal>

  <!-- ================================================================== -->
  <!-- jbuilder:generate-library                                          -->
  <!-- ================================================================== -->
  <!-- Creates a JBuilder library file.                                   -->
  <!-- ================================================================== -->
  <goal name="jbuilder:generate-library"
    description="Generate JBuilder [id_project].library file">

    <!-- Find and read the JBuilder default project properties. -->
    <jbuilder:getDefaultProject project="jbDefaultProject" userHome="jbUserHome" />
    <j:if test="${jbDefaultProject == null}" >
      <fail message="" >
+------------------------------------------------------------------
| ERROR!
|
| A JBuilder installation could not be found.
+------------------------------------------------------------------
      </fail>
    </j:if>

    <jbuilder:generateProjectLibrary
      project="${pom}"
      userHome="${jbUserHome}" />

    <j:forEach var="lib" items="${pom.artifacts}">
      <jbuilder:generateArtifactLibrary
        artifact="${lib}"
        userHome="${jbUserHome}"
        verbose="${maven.jbuilder.verbose}" />
    </j:forEach>
  </goal>

</project>
