<?xml version="1.0" encoding="UTF-8"?>
<!-- 
// $Id: //open/dev/farrago/plugin/buildPlugin.xml#22 $
// Farrago is an extensible data management system.
// Copyright (C) 2005-2009 The Eigenbase Project
// Copyright (C) 2005-2009 SQLstream, Inc.
// Copyright (C) 2005-2009 LucidEra, Inc.
// Portions Copyright (C) 2004-2009 John V. Sichi
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License
// as published by the Free Software Foundation; either version 2
// of the License, or (at your option) any later Eigenbase-approved version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU General Public License for more details.
//  
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307  USA
-->
<!-- Farrago ant build targets for plugin creation -->

<project name="farragoPlugin" default="unspecified">

  <fail unless="plugin.dir"/>
  <fail unless="plugin.jar.basename"/>
  <fail unless="plugin.3p.classpath"/>

  <property name="plugin.classes.dir" 
    location="${plugin.dir}/classes"/>

  <property name="plugin.catalog.dir" 
    location="${plugin.dir}/catalog"/>

  <!-- By default, use Farrago's repository storage properties. -->
  <property
    name="plugin.repos.storage.propfile" 
    location="${farrago.ReposStorage.propfile}"/>

  <property name="plugin.xmi.dir" 
    location="${plugin.catalog.dir}/xmi"/>

  <property name="plugin.catalog.src.dir" 
    location="${plugin.catalog.dir}/java"/>

  <property name="plugin.catalog.sql.dir" 
    location="${plugin.catalog.dir}/sql"/>

  <property name="plugin.catalog.schema" value="${project.catalog.schema}"/>

  <property name="plugin.src.dir" 
    location="${plugin.dir}/src"/>

  <property name="plugin.jar.dir" 
    location="${plugin.dir}/plugin"/>

  <property name="plugin.jar.file" 
    location="${plugin.jar.dir}/${plugin.jar.basename}.jar"/>

  <property name="plugin.resource.dir" 
    location="${plugin.src.dir}/${plugin.resource.package}"/>

  <property name="plugin.parser.impl.dir" 
    location="${plugin.src.dir}/${plugin.parser.impl.package}"/>

  <property name="plugin.manifest.attr.name" 
    value="PluginFactoryClassName"/>

  <path id="plugin.classpath">
    <pathelement path="${plugin.3p.classpath}"/>
    <pathelement path="${farrago.run.classpath}"/>
    <pathelement location="${plugin.catalog.src.dir}"/>
  </path>
  <property name="plugin.classpath" refid="plugin.classpath"/>

  <target name="plugin.buildModel" depends="plugin.cleanModel">
    <fail unless="plugin.model.name"/>
    <fail unless="plugin.model.basename"/>
    <fail unless="plugin.model.prefix"/>
    <fail unless="plugin.model.package"/>
    <fail unless="plugin.factory.class"/>
    <property
       name="plugin.uml2mof.storageModel"
       value="${uml2mof.default.storageModel}"/>

    <mkdir dir="${plugin.catalog.src.dir}"/>
    <mkdir dir="${plugin.classes.dir}"/>
    <copy file="${farrago.catalog.dir}/templates/BTreeRepos.properties" 
      tofile="${plugin.catalog.dir}/ReposStorage.properties"/>
    <ac:if xmlns:ac="antlib:net.sf.antcontrib">
      <available file="${plugin.xmi.dir}/${plugin.model.basename}Model.uml"/>
      <ac:then>
        <farrago.extractArgoModel 
          umlFile="${plugin.xmi.dir}/${plugin.model.basename}Model.uml"
          umlBasename="${plugin.model.basename}Model"
          mofBasename="${plugin.model.basename}Mof"
          xmiDir="${plugin.xmi.dir}"
          storageModel="${plugin.uml2mof.storageModel}"/>
      </ac:then>
      <ac:else>
        <farrago.extractPoseidonModel 
          zumlFile="${plugin.xmi.dir}/${plugin.model.basename}Model.zuml"
          umlBasename="${plugin.model.basename}Model"
          mofBasename="${plugin.model.basename}Mof"
          xmiDir="${plugin.xmi.dir}"
          storageModel="${plugin.uml2mof.storageModel}"/>
      </ac:else>
    </ac:if>
    <farrago.transformExtensionModel
      mofBasename="${plugin.model.basename}Mof"
      modelPrefix="${plugin.model.prefix}"
      xmiDir="${plugin.xmi.dir}"/>
    <farrago.synthesizeMetamodel
      extMofBasename="${plugin.model.basename}Mof"
      xmiDir="${plugin.xmi.dir}"/>
    <farrago.antFork dir="${plugin.dir}" 
      target="plugin.forked_generateMetamodelCode"/>
    <farrago.javaCompile
      srcdir="${plugin.catalog.src.dir}"
      destdir="${plugin.catalog.src.dir}"
      classpathref="plugin.classpath">
      <include name="**/*.java"/>
    </farrago.javaCompile>
    <farrago.setReposProvider
      reposStorageProps="${plugin.repos.storage.propfile}"/>
    <ac:if xmlns:ac="antlib:net.sf.antcontrib">
      <equals arg1="${farrago.enki.provider}" arg2="ENKI_HIBERNATE"/>
      <then>
        <farrago.antFork dir="${plugin.dir}" 
          target="plugin.forked_configureMetamodelSchema"/>
      </then>
    </ac:if>
    <farrago.antFork dir="${plugin.dir}" 
      target="plugin.forked_importMetamodel"/>
    <farrago.javaExec
      classname="net.sf.farrago.catalog.FarragoReposUtil"
      classpathref="farrago.run.classpath">
      <sysproperty 
        key="net.sf.farrago.catalog" 
        value="${plugin.catalog.dir}"/>
      <arg value="exportSubModel"/>
      <arg 
        value="${plugin.xmi.dir}/${plugin.model.prefix}PluginModelExport.xmi"/>
      <arg value="${plugin.model.name}"/>
    </farrago.javaExec>
    <xslt style="${farrago.xmi.dir}/movePluginPackage.xsl"
      in="${plugin.xmi.dir}/${plugin.model.prefix}PluginModelExport.xmi"
      out="${plugin.xmi.dir}/${plugin.model.prefix}PluginModel.xmi" />
  </target>

  <target name="plugin.forked_generateMetamodelCode" depends="farrago.mdr_taskdef">
    <farrago.setReposProvider
      reposStorageProps="${plugin.repos.storage.propfile}"/>

    <!-- Make sure the MDR build trace file is configured. -->
    <farrago.configureTrace
      propFile="${FarragoMdrBuildTrace.properties}" logFile="${FarragoMdrBuildTrace.log}"/>

    <mdr logConfigFile="${FarragoMdrBuildTrace.properties}">
      <mapJava
        file="${plugin.xmi.dir}/FarragoMetamodel.xmi"
        dir="${plugin.catalog.src.dir}"
        extent="FarragoMetamodel"
        generatorClass="${farrago.enki.generator}"
        generatorOptions="tablePrefix='FEM_',plugin=true,include='${plugin.model.package}'"/>
    </mdr>

    <delete quiet="true">
      <fileset dir="." includes="mdr.bt?"/>
    </delete>

  </target>

  <target name="plugin.forked_configureMetamodelSchema" depends="farrago.mdr_taskdef">
    <farrago.setReposProvider
      reposStorageProps="${plugin.repos.storage.propfile}"/>

    <mkdir dir="${plugin.catalog.sql.dir}"/>

    <mdr
        propertiesFile="${plugin.repos.storage.propfile}"
        logConfigFile="${FarragoMdrBuildTrace.properties}"
        modelPathRef="plugin.classpath">
      <exportSchema
        mode="model-plugin"
        dir="${plugin.catalog.src.dir}"
        extent="FarragoMetamodel"/>
      <applyTablePrefix output="${plugin.catalog.sql.dir}">
        <fileset dir="${plugin.catalog.src.dir}">
          <include name="**/*.sql"/>
        </fileset>
      </applyTablePrefix>
    </mdr>

    <property 
        file="${plugin.repos.storage.propfile}"
        prefix="gensch"/>

    <!-- N.B. this expects that the given database already has the FEM
         metamodel in place and that we just need to create the plugin's
         tables. Otherwise, need to invoke farrago/catalog/sql/provider.sql 
         and create.sql as well. -->
    <echo>
      Configuring repository schema at:
      ${gensch.net.sf.farrago.dev.connection.schema.url}
    </echo>
    <sql
        driver="${gensch.net.sf.farrago.dev.connection.driver_class}"
        url="${gensch.net.sf.farrago.dev.connection.schema.url}"
        userid="${gensch.net.sf.farrago.dev.connection.username}"
        password="${gensch.net.sf.farrago.dev.connection.password}"
        classpathref="plugin.classpath">
      <fileset dir="${plugin.catalog.sql.dir}">
        <include name="**/create.sql"/>
      </fileset>
    </sql>
  </target>

  <target name="plugin.forked_importMetamodel" depends="farrago.mdr_taskdef">
    <mdr>
      <storageProperty
        name="org.eigenbase.enki.implementationType" 
        value="NETBEANS_MDR"/>
      <storageProperty
        name="org.netbeans.mdr.persistence.Dir"
        value="${plugin.catalog.dir}/FarragoCatalog"/>

      <createExtent name="FarragoMetamodel"/>
      <importXMI
        file="${plugin.xmi.dir}/FarragoMetamodel.xmi"
        extent="FarragoMetamodel"/>
    </mdr>
  </target>

  <target name="plugin.buildResources" depends="plugin.checkResourceUptodate"
    unless="plugin.resource.uptodate">
    <taskdef name="resgen" classname="org.eigenbase.resgen.ResourceGenTask">
      <classpath refid="farrago.run.classpath"/>
    </taskdef>
    <resgen
      srcdir="${plugin.src.dir}"
      destdir="${plugin.src.dir}"
      resdir="${plugin.classes.dir}"
      style="functor"
      locales="en_US">
      <include 
        name="${plugin.resource.package}/${plugin.resource.basename}.xml"/>
    </resgen>
  </target>

  <target name="plugin.checkResourceUptodate">
    <fail unless="plugin.resource.package"/>
    <fail unless="plugin.resource.basename"/>
    <uptodate property="plugin.resource.uptodate"
      srcfile="${plugin.resource.dir}/${plugin.resource.basename}.xml"
      targetfile="${plugin.resource.dir}/${plugin.resource.basename}.java"/>
  </target>

  <target name="plugin.buildParser" depends="plugin.checkParserUptodate"
    unless="plugin.parser.uptodate">
    <farrago.generateParser 
      combined="${plugin.parser.impl.dir}/CombinedParser.jj">
      <components>
        <fileset dir="${plugin.src.dir}" includes="${plugin.parser.jj}"/>
        <fileset refid="farrago.parser.common.ddl"/>
        <fileset refid="farrago.parser.common.sql"/>
      </components>
    </farrago.generateParser>
  </target>

  <target name="plugin.checkParserUptodate">
    <fail unless="plugin.parser.impl.package"/>
    <fail unless="plugin.parser.jj"/>
    <uptodate property="plugin.parser.uptodate"
      targetfile="${plugin.parser.impl.dir}/CombinedParser.jj">
      <srcfiles dir="${plugin.src.dir}" includes="${plugin.parser.jj}"/>
      <srcfiles refid="farrago.parser.common.ddl"/>
      <srcfiles refid="farrago.parser.common.sql"/>
    </uptodate>
  </target>

  <target name="plugin.buildJar">
    <fail unless="plugin.factory.class"/>
    <mkdir dir="${plugin.jar.dir}"/>
    <delete quiet="true" file="${plugin.jar.file}"/>
    <mkdir dir="${plugin.classes.dir}/META-INF"/>
    <manifest file="${plugin.classes.dir}/META-INF/MANIFEST.MF">
      <attribute
        name="${plugin.manifest.attr.name}"
        value="${plugin.factory.class}"/>
    </manifest>
    <jar destfile="${plugin.jar.file}" compress="true" 
      manifest="${plugin.classes.dir}/META-INF/MANIFEST.MF">
      <fileset dir="${plugin.classes.dir}">
        <include name="**/*.class"/>
        <include name="**/*.properties"/>
      </fileset>
    </jar>
    <antcall target="plugin.buildCatalogJar"/>
  </target>

  <target name="plugin.buildCatalogJar" if="plugin.model.prefix">
    <manifest file="${plugin.classes.dir}/META-INF/MANIFEST.MF" mode="update">
      <attribute
        name="PluginModel"
        value="${plugin.model.prefix}PluginModel.xmi"/>
    </manifest>
    <jar destfile="${plugin.jar.file}" compress="true" update="true"
      duplicate="fail"
      manifest="${plugin.classes.dir}/META-INF/MANIFEST.MF">
      <fileset dir="${plugin.catalog.src.dir}">
        <include name="**/*.class"/>
        <include name="**/*.properties"/>
        <include name="**/*.xml"/>
      </fileset>
      <fileset dir="${plugin.xmi.dir}">
        <include name="${plugin.model.prefix}PluginModel.xmi"/>
      </fileset>
    </jar>
  </target>

  <target name="plugin.clean">
    <delete includeEmptyDirs="true" quiet="true">
      <fileset dir="${plugin.classes.dir}" includes="**/*"/>
      <fileset dir="${plugin.jar.dir}" includes="**/*"/>
    </delete>
    <antcall target="plugin.cleanParser"/>
    <antcall target="plugin.cleanResource"/>
  </target>

  <target name="plugin.cleanModel" depends="plugin.clean">
    <delete includeEmptyDirs="true" quiet="true">
      <fileset dir="${plugin.xmi.dir}" includes="*.xmi"/>
      <fileset dir="${plugin.catalog.dir}" includes="FarragoCatalog.*"/>
      <fileset dir="${plugin.catalog.src.dir}" includes="**"/>
    </delete>
  </target>

  <target name="plugin.cleanParser" if="plugin.parser.jj">
    <delete includeEmptyDirs="true" quiet="true">
      <fileset dir="${plugin.parser.impl.dir}">
        <include name="*.java"/>
        <include name="*.jj"/>
      </fileset>
    </delete>
  </target>

  <target name="plugin.cleanResource" if="plugin.resource.package">
    <delete includeEmptyDirs="true" quiet="true">
      <fileset dir="${plugin.resource.dir}">
        <include name="${plugin.resource.basename}*.java"/>
      </fileset>
    </delete>
  </target>

</project>
