<?xml version="1.0"?>

<project name="framework" default="all">

  <!-- build properties -->
  <property name="topdir"       location=".."/>
  <property name="osgi.dir"     location="${topdir}"/>
  <property name="ant.dir"      location="${topdir}/../ant"/>

  <property name="root.out.dir" location="${topdir}/out"/>
  <property name="jars.dir"     location="${topdir}/jars"/>
  <property name="outdir"       location="${root.out.dir}/${ant.project.name}"/>
  <property name="classout"     location="${outdir}/classes"/>
  <property name="classout_compact" location="${outdir}/classes_compact"/>
  <property name="javadoc.out.dir"  location="${outdir}/javadoc"/>
  <property name="docs.dir"     location="${root.out.dir}/doc"/>
  <property name="outdocdir"    location="${docs.dir}/${ant.project.name}"/>
  <!-- Location of templates used by the framework_doc-target. -->
  <property name="frameworkdoc_template"
            location="${ant.dir}/html_template/frameworkdoc.html"/>

  <property name="fw.base.version"   value="8.0.5"/>
  <property name="version.suffix"    value=""/>
  <condition property="fw.impl.version"
             value="${fw.base.version}"
             else="${fw.base.version}.${version.suffix}">
    <equals arg1="${version.suffix}" arg2=""/>
  </condition>

  <property name="jarfile"
            location="${topdir}/${ant.project.name}.jar"/>
  <property name="jarfile_compact"
            location="${topdir}/${ant.project.name}_compact.jar"/>
  <property name="source.jarfile"
            location="${topdir}/${ant.project.name}-source.jar"/>
  <property name="javadoc.jarfile"
            location="${topdir}/${ant.project.name}-javadoc.jar"/>
  <property name="jarfile_version"
            location="${jars.dir}/${ant.project.name}-${fw.impl.version}.jar"/>

  <import file="${ant.dir}/android.xml"/>

  <property name="proguard.libraryjar" value="${java.home}/lib/rt.jar"/>

  <!-- OSGi annotations -->
  <property name="osgi.annotation.jar" location="${topdir}/annotations/osgi.annotation-6.0.1.jar"/>

  <property name="src.dir" location="src"/>

  <property name="printClasses" location="true"/>

  <path id="compile.path">
    <pathelement location="${topdir}/framework/resources"/>
    <pathelement location="${osgi.annotation.jar}"/>
    <pathelement location="libs/asm-3.2.jar"/>
  </path>

  <path id="android.system.path">
    <pathelement location="${osgi.dir}/ee/android.jar"/>
  </path>

  <path id="empty.path">
  </path>

  <property name="androidSrcs"
            value="org/knopflerfish/framework/bundlestorage/dex/*.java"/>
  <property name="android.class.path.name" value="android.system.path"/>

  <!-- targets -->
  <target name="all"
          depends="jar, source.jar, save_javadoc_data, javadoc.jar">
  </target>

  <target name="compile">
    <antcall target="compile_full"/>
    <antcall target="compile_compact"/>
  </target>

  <target name        = "compile_full"
          unless      = "compact"
          description = "compiles all java sources">
    <mkdir dir="${classout}"/>

    <javac destdir           = "${classout}"
           srcdir            = "${src.dir}"
           debug             = "on"
           includeantruntime = "false"
           includes          = "**/*.java"
           excludes          = "${androidSrcs},**/package-info.java"
           classpathref      = "compile.path"
           >
      <compilerarg value="-Xlint:-options"/>
    </javac>
    <!-- Android parts (uses dalvik.*) -->
    <javac destdir           = "${classout}"
           srcdir            = "${src.dir}"
           debug             = "on"
           includeantruntime = "false"
           includejavaruntime = "true"
           includes          = "${androidSrcs}"
           excludes          = "**/package-info.java"
           source            = "1.6"
           target            = "1.6"
           bootclasspathref  = "${android.class.path.name}"
           classpathref      = "compile.path"
           >
      <compilerarg value="-Xlint:-options"/>
    </javac>
  </target>

  <target name="compile_compact"
          if="compact"
          description="compiles with file storage only">
    <mkdir dir="${classout_compact}"/>

    <javac destdir           = "${classout_compact}"
           srcdir            = "${src.dir}"
           debug             = "on"
           includeantruntime = "false"
           includes          = "**/*.java"
           excludes          = "org/knopflerfish/framework/validator/*.java,org/knopflerfish/framework/bundlestorage/dex/*.java,org/knopflerfish/framework/bundlestorage/memory/*.java,**/package-info.java,org/knopflerfish/framework/SecurePermissionOps.java,org/knopflerfish/framework/permissions/*.java"
           classpathref      = "compile.path"
           >
    </javac>
  </target>

  <target name="jar" depends="compile,genexports" description="build jar">
    <tstamp>
      <format property="framework.tstamp"
              pattern="'Build' EE MMMM d yyyy, HH:mm:ss"
              locale="en"/>
    </tstamp>

    <!-- delete in case the file is read-only -->
    <delete file="resources/version"/>
    <echo message="${fw.impl.version}"  file="resources/version"/>
    <delete file="resources/tstamp"/>
    <echo message="${framework.tstamp}" file="resources/tstamp"/>

    <condition property="version.isset">
      <isset property="version"/>
    </condition>

    <antcall target="writerelease"/>

    <delete file="${classout}/classes.dex"/>

    <loadfile srcfile="${src.dir}/org/osgi/framework/packageinfo"
              property="fw.spec.version">
      <filterchain>
        <striplinebreaks/>
        <replacestring from="version " to=""/>
      </filterchain>
    </loadfile>

    <antcall target="jar_file_full"/>
    <antcall target="jar_file_compact"/>
  </target>

  <target name   = "jar_file_full"
          unless = "compact">
    <jar basedir="${classout}"
         filesonly="true"
         jarfile="${jarfile}">
      <fileset dir="resources"/>
      <manifest>
        <attribute name="Main-class"             value="org.knopflerfish.framework.Main"/>
        <attribute name="Specification-Title"    value="OSGi Framework API"/>
        <attribute name="Specification-Version"  value="${fw.spec.version}"/>
        <attribute name="Specification-Vendor"   value="Open Service Gateway initiative"/>
        <attribute name="Implementation-Title"   value="Knopflerfish OSGi Framework"/>
        <attribute name="Implementation-Version" value="${fw.impl.version}" />
        <attribute name="Implementation-Vendor"  value="Knopflerfish"/>
        <attribute name="Bundle-Vendor"          value="Knopflerfish"/>
        <attribute name="Bundle-Version"         value="${fw.impl.version}"/>
        <attribute name="Bundle-SymbolicName"    value="org.knopflerfish.framework"/>
        <attribute name="Bundle-Name"            value="frameworkbundle"/>
        <attribute name="Bundle-Description"     value="Knopflerfish OSGi framework system bundle"/>
        <attribute name="Bundle-License"
                   value="&quot;http://www.knopflerfish.org/license.html&quot;;description=BSD;link=&quot;http://www.knopflerfish.org/license.html&quot;"/>
        <attribute name="Export-Package"         value="${fw.export-package}"/>
        <attribute name="Bundle-DocURL"          value="http://www.knopflerfish.org/releases/current/docs/bundledoc/index.html?docpage=framework/index.html"/>
        <attribute name="Bundle-GitURL"          value="https://github.com/knopflerfish/knopflerfish.org/tree/master/osgi/framework/"/>
        <attribute name="Build-Date"             value="${framework.tstamp}"/>
        <attribute name="SplashScreen-Image"     value="kfsplash.gif"/>
      </manifest>
    </jar>
    <mkdir dir="${jars.dir}"/>
    <copy file="${jarfile}"
          tofile="${jarfile_version}"
          overwrite="true"/>
    <antcall target="cond_dex_jars"/>
  </target>

  <target name = "jar_file_compact"
          if   = "compact">
    <jar basedir="${classout_compact}"
         filesonly="true"
         jarfile="${jarfile_compact}">
      <fileset dir="resources">
        <exclude name="kfsplash.gif"/>
      </fileset>
      <manifest>
        <attribute name="Main-class"             value="org.knopflerfish.framework.Main"/>
        <attribute name="Specification-Title"    value="OSGi Framework API"/>
        <attribute name="Specification-Version"  value="${fw.spec.version}"/>
        <attribute name="Specification-Vendor"   value="Open Service Gateway initiative"/>
        <attribute name="Implementation-Title"   value="Knopflerfish OSGi Framework"/>
        <attribute name="Implementation-Version" value="${fw.impl.version}" />
        <attribute name="Implementation-Vendor"  value="Knopflerfish"/>
        <attribute name="Bundle-Vendor"          value="Knopflerfish"/>
        <attribute name="Bundle-Version"         value="${fw.impl.version}"/>
        <attribute name="Bundle-SymbolicName"    value="org.knopflerfish.framework"/>
        <attribute name="Bundle-Name"            value="frameworkbundle"/>
        <attribute name="Bundle-Description"     value="Knopflerfish OSGi framework system bundle"/>
        <attribute name="Bundle-License"
                   value="&quot;http://www.knopflerfish.org/license.html&quot;;description=BSD;link=&quot;http://www.knopflerfish.org/license.html&quot;"/>
        <attribute name="Export-Package"         value="${fw.export-package}"/>
        <attribute name="Bundle-DocURL"          value="http://www.knopflerfish.org/releases/current/docs/bundledoc/index.html?docpage=framework/index.html"/>
        <attribute name="Bundle-GitURL"          value="https://github.com/knopflerfish/knopflerfish.org/tree/master/osgi/framework/"/>
        <attribute name="Build-Date"             value="${framework.tstamp}"/>
      </manifest>
    </jar>
    <antcall target="proguard_compact"/>
  </target>

  <target name = "proguard_compact"
          depends="install_proguard">
    <move file="${jarfile_compact}" tofile="${jarfile_compact}.tmp.jar"/>
    <proguard note="false">
      <!-- Specify the input jars, output jars, and library jars. -->
      <injar  file="${jarfile_compact}.tmp.jar" />
      <outjar file="${jarfile_compact}" />
      <libraryjar file="${proguard.libraryjar}" />
      <libraryjar file="${osgi.annotation.jar}" />

      <!-- Preserve Main. -->
      <keepclasseswithmembers access="public">
        <method access    ="public static"
                type      ="void"
                name      ="main"
                parameters="java.lang.String[]" />
      </keepclasseswithmembers>

      <!-- Keep KF dynamic  -->
      <keep name="org.knopflerfish.framework.FrameworkFactoryImpl"/>
      <keep name="org.knopflerfish.framework.bundlestorage.file.BundleStorageImpl">
        <constructor/>
      </keep>

      <!-- Keep OSGi interface -->
      <keep name="org.osgi.**" access="public">
        <field access="public,protected"/>
        <method access="public,protected"/>
        <constructor access="public,protected"/>
      </keep>

      <!-- Explicitly preserve all serialization members. The Serializable
           interface is only a marker interface, so it wouldn't save them.
           You can comment this out if your library doesn't use serialization.
           If your code contains serializable classes that have to be backward
           compatible, please refer to the manual. -->

      <keepclassmembers implements="java.io.Serializable">
        <field  access    ="static final"
                type      ="long"
                name      ="serialVersionUID" />
        <field  access    ="static final"
                type      ="java.io.ObjectStreamField[]"
                name      ="serialPersistentFields" />
        <method access    ="private"
                type      ="void"
                name      ="writeObject"
                parameters="java.io.ObjectOutputStream" />
        <method access    ="private"
                type      ="void"
                name      ="readObject"
                parameters="java.io.ObjectInputStream" />
        <method type      ="java.lang.Object"
                name      ="writeReplace"
                parameters="" />
        <method type      ="java.lang.Object"
                name      ="readResolve"
                parameters="" />
      </keepclassmembers>

    </proguard>
    <delete file="${jarfile_compact}.tmp.jar"/>
  </target>

  <target name="source.jar" if="bundle.build.source.jar">
    <jar basedir="${src.dir}"
         jarfile="${source.jarfile}"
         includes="**/*.java"
         excludes="**/package-info.java"
         manifestencoding="UTF-8">
    </jar>
  </target>

  <target name="save_javadoc_data" depends="genexports"
          if="generate.javadoc.data">
    <echo message="save_javadoc: to:${sources.file} src:${src.dir} "/>
    <echo file="${sources.file}" append="true"
          message="${src.dir}${line.separator}"/>
    <echo file="${exported.file}" append="true"
          message="${fw.export-package}${line.separator}"/>
  </target>

  <target name="javadoc.jar" if="bundle.build.javadoc.jar">
    <mkdir dir="${javadoc.out.dir}"/>

    <property name="javadoc.header"
              value="Knopflerfish OSGi Framework ${fw.impl.version}"/>

    <property name="javadoc.footer"
              value="Knopflerfish OSGi ${version}"/>

    <property name="javadoc.windowtitle"
              value="${javadoc.header} javadoc"/>

    <property name="javadoc.doctitle"
              value="${javadoc.header} API documentation"/>

    <javadoc header="${javadoc.header}"
             footer="${javadoc.footer}"
             windowtitle="${javadoc.windowtitle}"
             doctitle="${javadoc.doctitle}"
             destdir="${javadoc.out.dir}"
             classpathref="compile.path">
      <!-- Custome tags used by OSGi -->
      <tag name="ThreadSafe"    scope="all" description="ThreadSafe"/>
      <tag name="NotThreadSafe" scope="all" description="NotThreadSafe"/>
      <tag name="Immutable"     scope="all" description="Immutable"/>
      <tag name="security"      scope="all" description="Required Permissions"/>
      <tag name="noimplement"   scope="all"
           description="Consumers of this API must not implement this interface"/>
      <packageset dir="${src.dir}">
        <include name="org/osgi/**"/>
        <exclude name="org/knopflerfish/**"/>
      </packageset>

    </javadoc>

    <jar basedir="${javadoc.out.dir}"
         jarfile="${javadoc.jarfile}"
         includes="**"
         manifestencoding="UTF-8">
    </jar>
  </target>

  <target name="dex_jars"
          description="Dexifies framework.">
    <fail unless="android.exists" message="You must set the ANDROID_HOME property"/>
    <antcall target="cond_dex_jars" inheritRefs="true"/>
  </target>

  <!-- Helper taget that adds Android dex data to framework.jar. -->
  <target name="cond_dex_jars" if="android.exists">
    <dexify_bundle bundle="${jarfile}"/>
  </target>

  <target name="framework_doc"
          depends="bundle_tasks,genexports">
    <property name="bmfa.Bundle-Version" value="${fw.impl.version}"/>
    <property name="bmfa.Export-Package" value="${fw.export-package}"/>
    <makehtml template="${frameworkdoc_template}"
              outdir="${outdocdir}"
              manstyle="true">
      <fileset dir="doc">
        <include name="**/*.html"/>
      </fileset>
    </makehtml>

    <copy todir="${outdocdir}">
      <fileset dir="doc">
        <exclude name="**/*.html"/>
      </fileset>
    </copy>
  </target>

  <target name="run">
    <java fork="true"
          jar="${outdir}/${ant.project.name}.jar"
          />
  </target>

  <target name="writerelease" if="version.isset">
    <delete file="resources/release"/>
    <echo message="${version}" file="resources/release"/>
  </target>

  <target name="genexports" depends="bundle_tasks">
    <delete file="resources/exports"/>
    <bundleinfo  exports  = "fw.export-package"
                 addPackageinfoPackages = "true" >
     <exports dir="src" includes="org/osgi/**"/>
    </bundleinfo>
    <echo message="${fw.export-package}" file="resources/exports"/>
  </target>

  <target name="clean" description="removes all generated files">
    <delete dir="${outdir}"/>
    <delete file="${jarfile}"/>
  </target>

  <import file="${topdir}/../ant/bundletasks.xml"/>

</project>
