/*
 * 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.
 */
import org.apache.tools.ant.filters.ReplaceTokens

/* ========================================================
 * Project setup
 * ======================================================== */

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'maven-publish'

apply from: 'common.gradle'

// global properties
ext.os = System.getProperty('os.name').toLowerCase()
ext.pluginsDir = "${rootDir}/specialpurpose"

// java settings
def jvmArguments = ['-Xms128M', '-Xmx1024M']
ext.ofbizMainClass = 'org.apache.ofbiz.base.start.Start'
javadoc.failOnError = true
sourceCompatibility = '1.8'
targetCompatibility = '1.8'

// Java compile options, syntax gradlew -PXlint build
tasks.withType(JavaCompile) {
    options.encoding = 'UTF-8'
    if (project.hasProperty('Xlint')) {
        options.compilerArgs << "-Xlint"
    }
}

// defines the footer files for svn and git info
def File gitFooterFile = file("${rootDir}/runtime/GitInfo.ftl")
def File svnFooterFile = file("${rootDir}/runtime/SvnInfo.ftl")

// root and subproject settings
defaultTasks 'build'

allprojects {
    repositories{
        jcenter()
        mavenLocal()
    }
}

subprojects {
    configurations {
        // compile-time plugin libraries
        pluginLibsCompile
        // runtime plugin libraries
        pluginLibsRuntime
        //compile-only libraries
        pluginLibsCompileOnly
    }
}

configurations {
    junitReport {
        description = 'libraries needed to run junitreport for OFBiz unit tests'
    }
    ofbizPlugins {
        description = 'ofbiz plugin dependencies configuration'
        transitive = true
    }
}

dependencies {
    // ofbiz compile libs
    compile 'apache-xerces:xercesImpl:2.9.1'
    compile 'com.google.zxing:core:3.2.1'
    compile 'com.googlecode.concurrentlinkedhashmap:concurrentlinkedhashmap-lru:1.0'
    compile 'com.googlecode.ez-vcard:ez-vcard:0.9.10'
    compile 'com.googlecode.owasp-java-html-sanitizer:owasp-java-html-sanitizer:20160628.1'
    compile 'com.ibm.icu:icu4j:57.1'
    compile 'com.lowagie:itext:2.1.7'
    compile 'com.sun.mail:javax.mail:1.5.1'
    compile 'com.sun.syndication:com.springsource.com.sun.syndication:0.9.0'
    compile 'com.thoughtworks.xstream:xstream:1.4.9'
    compile 'commons-cli:commons-cli:1.3.1'
    compile 'commons-net:commons-net:3.3'
    compile 'commons-validator:commons-validator:1.5.1'
    compile 'de.odysseus.juel:juel-impl:2.2.7'
    compile 'javax.el:javax.el-api:3.0.1-b04'
    compile 'javax.servlet:javax.servlet-api:3.1.0'
    compile 'javax.servlet.jsp:javax.servlet.jsp-api:2.3.0'
    compile 'junit:junit-dep:4.10'
    compile 'net.fortuna.ical4j:ical4j:1.0-rc3-atlassian-11'
    compile 'org.apache.ant:ant-junit:1.9.0'
    compile 'org.apache.axis2:axis2-kernel:1.7.1'
    compile 'org.apache.commons:commons-collections4:4.1'
    compile 'org.apache.commons:commons-csv:1.1'
    compile 'org.apache.commons:commons-dbcp2:2.1'
    compile 'org.apache.geronimo.components:geronimo-transaction:3.1.1'
    compile 'org.apache.geronimo.specs:geronimo-jms_1.1_spec:1.1.1'
    compile 'org.apache.httpcomponents:httpclient-cache:4.4.1'
    compile 'org.apache.logging.log4j:log4j-api:2.6.2' // the API of log4j 2
    compile 'org.apache.poi:poi:3.14'
    compile 'org.apache.shiro:shiro-core:1.3.0'
    compile 'org.apache.tika:tika-core:1.12'
    compile 'org.apache.tika:tika-parsers:1.12'
    compile 'org.apache.tomcat:tomcat-catalina-ha:8.0.39'
    compile 'org.apache.tomcat:tomcat-catalina:8.0.39'
    compile 'org.apache.tomcat:tomcat-jasper:8.0.39'
    compile 'org.apache.tomcat:tomcat-tribes:8.0.39'
    compile 'org.apache.xmlgraphics:fop:2.1'
    compile 'org.apache.xmlrpc:xmlrpc-client:3.1.2'
    compile 'org.apache.xmlrpc:xmlrpc-server:3.1.2'
    compile 'org.codehaus.groovy:groovy-all:2.4.5'
    compile 'org.freemarker:freemarker:2.3.25-incubating' // Remember to change the version number in FreeMarkerWorker class when upgrading
    compile 'org.hamcrest:hamcrest-all:1.3'
    compile 'org.owasp.esapi:esapi:2.1.0'
    compile 'org.springframework:spring-test:4.2.3.RELEASE'
    compile 'org.zapodot:jackson-databind-java-optional:2.4.2'
    compile 'oro:oro:2.0.8'
    compile 'wsdl4j:wsdl4j:1.6.2'

    // ofbiz unit-test compile libs
    testCompile 'org.mockito:mockito-core:1.+'

    // ofbiz runtime libs
    runtime 'de.odysseus.juel:juel-spi:2.2.7'
    runtime 'net.sf.barcode4j:barcode4j-fop-ext:2.1'
    runtime 'net.sf.barcode4j:barcode4j:2.1'
    runtime 'org.apache.axis2:axis2-transport-http:1.7.1'
    runtime 'org.apache.axis2:axis2-transport-local:1.7.1'
    runtime 'org.apache.derby:derby:10.11.1.1'
    runtime 'org.apache.geronimo.specs:geronimo-jaxrpc_1.1_spec:1.1'
    runtime 'org.apache.logging.log4j:log4j-1.2-api:2.6.2' // for external jars using the old log4j1.2: routes logging to log4j 2
    runtime 'org.apache.logging.log4j:log4j-core:2.6.2' // the implementation of the log4j 2 API
    runtime 'org.apache.logging.log4j:log4j-jul:2.6.2' // for external jars using the java.util.logging: routes logging to log4j 2
    runtime 'org.apache.logging.log4j:log4j-slf4j-impl:2.6.2' // for external jars using slf4j: routes logging to log4j 2
    runtime 'org.codeartisans.thirdparties.swing:batik-all:1.8pre-r1084380'

    // plugin libs
    subprojects.each { subProject ->
        compile project(path: subProject.path, configuration: 'pluginLibsCompile')
        runtime project(path: subProject.path, configuration: 'pluginLibsRuntime')
        compileOnly project(path: subProject.path, configuration: 'pluginLibsCompileOnly')
    }

    // libs needed for junitreport
    junitReport 'junit:junit:4.12'
    junitReport 'org.apache.ant:ant-junit:1.9.7'

    // local libs
    getDirectoryInActiveComponentsIfExists('lib').each { libDir ->
        compile fileTree(dir: libDir, include: '**/*.jar')
    }
    compile fileTree(dir: file("${rootDir}/lib"), include: '**/*.jar')
}

def excludedJavaSources = []
excludedJavaSources.add 'org/apache/ofbiz/accounting/thirdparty/cybersource/IcsPaymentServices.java'
excludedJavaSources.add 'org/apache/ofbiz/accounting/thirdparty/ideal/IdealEvents.java'
excludedJavaSources.add 'org/apache/ofbiz/accounting/thirdparty/ideal/IdealPaymentServiceTest.java'
excludedJavaSources.add 'org/apache/ofbiz/accounting/thirdparty/orbital/OrbitalPaymentServices.java'
excludedJavaSources.add 'org/apache/ofbiz/accounting/thirdparty/paypal/PayPalServices.java'
excludedJavaSources.add 'org/apache/ofbiz/accounting/thirdparty/securepay/SecurePayPaymentServices.java'
excludedJavaSources.add 'org/apache/ofbiz/accounting/thirdparty/securepay/SecurePayServiceTest.java'
excludedJavaSources.add 'org/apache/ofbiz/accounting/thirdparty/verisign/PayflowPro.java'
excludedJavaSources.add 'org/apache/ofbiz/order/thirdparty/taxware/TaxwareException.java'
excludedJavaSources.add 'org/apache/ofbiz/order/thirdparty/taxware/TaxwareServices.java'
excludedJavaSources.add 'org/apache/ofbiz/order/thirdparty/taxware/TaxwareUTL.java'


// These files and directories present in config directories should not be included in ofbiz.jar see OFBIZ-8321
def excludedConfigFiles = []
excludedConfigFiles.add 'README'
excludedConfigFiles.add 'APACHE2_HEADER_FOR_XML'
excludedConfigFiles.add '*.txt'
excludedConfigFiles.add '*.jks'
excludedConfigFiles.add 'fop.xconf'
excludedConfigFiles.add 'GroovyInit.groovy'
excludedConfigFiles.add 'MiniLang.xslt'
excludedConfigFiles.add 'AutoImportTemplate.ftl'
excludedConfigFiles.add 'axis2'
excludedConfigFiles.add 'barcode'


sourceSets {
    main {
        java {
            srcDirs = getDirectoryInActiveComponentsIfExists('src/main/java')
            exclude excludedJavaSources
        }
        resources {
            srcDirs = getDirectoryInActiveComponentsIfExists('src/main/java')
            srcDirs += getDirectoryInActiveComponentsIfExists('config')
            srcDirs += "${rootDir}/framework/base/dtd"
            exclude excludedJavaSources
            exclude excludedConfigFiles
            // Below are necessary for unit tests run by Gradle and integration tests
            exclude { FileTreeElement elem -> elem.getName().contains('Labels.xml') }
            exclude { FileTreeElement elem -> elem.getName().contains('.properties') && 
                !elem.getName().contains('start.properties') && 
                !elem.getName().contains('load-data.properties') && 
                !elem.getName().contains('debug.properties') &&
                !elem.getName().contains('cache.properties') &&
                !elem.getName().contains('test.properties') &&
                !elem.getName().contains('rmi.properties')
            }
        }
    }

    test {
        java {
            srcDirs = getDirectoryInActiveComponentsIfExists('src/test/java')
        }
        resources {
            srcDirs = getDirectoryInActiveComponentsIfExists('src/test/java')
        }
    }
}

jar {
    manifest {
        attributes(
            "Implementation-Title": project.name,
            "Main-Class": ofbizMainClass,
            "Class-Path": getJarManifestClasspathForCurrentOs()
        )
    }
}

// Eclipse plugin settings
eclipse.classpath.file.whenMerged { classpath ->
    /* The code inside this block removes unnecessary entries
     * in the .classpath file which are generated automatically
     * due to the settings in the sourceSets block
     */
    def osDirSeparator = os.contains('windows') ? '\\' : '/'

    iterateOverActiveComponents { component ->
        def componentName = component.toString() - rootDir.toString() - osDirSeparator
        def eclipseEntry = os.contains('windows') ? componentName.replaceAll("\\\\", "/") : componentName

        classpath.entries.removeAll { entry ->
            // remove any "src" entries in .classpath of the form /componentName
            entry.kind == 'src' &&
            entry.path ==~ '.*/+(' + componentName.tokenize(osDirSeparator).last() + ')$' ||
            entry.path ==~ /(\/+framework)$/ ||
            entry.path ==~ /(\/+applications)$/ ||
            entry.path ==~ /(\/+specialpurpose)$/ ||
            entry.path ==~ /(\/+themes)$/ ||
            entry.path ==~ /(\/+hot-deploy)$/ ||
            entry.path ==~ eclipseEntry + '/config' ||
            entry.path ==~ eclipseEntry + '/dtd'
        }
    }
}
tasks.eclipse.dependsOn(cleanEclipse)

/* OWASP plugin
 *
 * If project property "enableOwasp" is flagged then
 * gradle will download required dependencies and
 * activate Gradle's OWASP plugin and its related tasks.
 *
 * Syntax: gradlew -PenableOwasp dependencyCheck
 */
buildscript {
    if (project.hasProperty('enableOwasp')) {
        repositories {
            mavenCentral()
        }
        dependencies {
            classpath 'org.owasp:dependency-check-gradle:1.4.0'
        }
    }
}
if (project.hasProperty('enableOwasp')) {
    apply plugin: 'org.owasp.dependencycheck'
}

/* ========================================================
 * Tasks
 * ======================================================== */

// ========== Task group labels ==========
def cleanupGroup = 'Cleaning'
def ofbizServer = 'OFBiz Server'
def ofbizPlugin = 'OFBiz Plugin'
def sysadminGroup = 'System Administration'
def committerGroup = 'OFBiz committers'

// ========== OFBiz Server tasks ==========

task loadDefault(group: ofbizServer) {
    dependsOn 'ofbiz --load-data'
    description 'Load default data; meant for OFBiz development, testing, and demo purposes'
}

task testIntegration(group: ofbizServer) {
    dependsOn 'ofbiz --test'
    description 'Run OFBiz integration tests; You must run loadDefault before running this task'
}

task terminateOfbiz(group: ofbizServer,
    description: 'Force termination of any running OFBiz servers, only use if \"--shutdown\" command fails') << {
    if (os.contains('windows')) {
        Runtime.getRuntime().exec("wmic process where \"CommandLine Like \'%org.apache.ofbiz.base.start.Start%\'\" Call Terminate")
    } else {
        def processOutput = new ByteArrayOutputStream()
        exec {
            commandLine 'ps', 'ax'
            standardOutput = processOutput
        }
        processOutput.toString().split(System.lineSeparator()).each { line ->
            if (line ==~ /.*org\.apache\.ofbiz\.base\.start\.Start.*/) {
                exec { commandLine 'kill', '-9', line.tokenize().first() }
            }
        }
    }
}

task loadAdminUserLogin(group: ofbizServer) {
    description 'Create admin user with temporary password equal to ofbiz. You must provide userLoginId'
    createOfbizCommandTask('executeLoadAdminUser',
        ['--load-data', 'file=/runtime/tmp/AdminUserLoginData.xml'],
        jvmArguments, false)
    executeLoadAdminUser.doFirst {
        copy {
            from ("${rootDir}/framework/resources/templates/AdminUserLoginData.xml") {
                filter(ReplaceTokens, tokens: [userLoginId: userLoginId])
            }
            into "${rootDir}/runtime/tmp/"
        }
    }
    dependsOn executeLoadAdminUser
    doLast {
        delete("${rootDir}/runtime/tmp/AdminUserLoginData.xml")
    }
}

task loadTenant(group: ofbizServer, description: 'Load data using tenantId') {

    createOfbizCommandTask('executeLoadTenant', [], jvmArguments, false)

    if (project.hasProperty('tenantId')) {
        executeLoadTenant.args '--load-data'
        executeLoadTenant.args "delegator=default#${tenantId}"
    }
    if (project.hasProperty('tenantReaders')) {
        executeLoadTenant.args '--load-data'
        executeLoadTenant.args "readers=${tenantReaders}"
    }
    if (project.hasProperty('tenantComponent')) {
        executeLoadTenant.args '--load-data'
        executeLoadTenant.args "component=${tenantComponent}"
    }

    executeLoadTenant.doFirst {
        if (!project.hasProperty('tenantId')) {
            throw new GradleException('Missing project property tenantId')
        }
    }
    dependsOn executeLoadTenant
}

task createTenant(group: ofbizServer, description: 'Create a new tenant in your environment') {

    def databaseTemplateFile = "${rootDir}/framework/resources/templates/AdminNewTenantData-Derby.xml"

    task prepareAndValidateTenantArguments << {
        if (!project.hasProperty('tenantId')) {
            throw new GradleException('Project property tenantId is missing')
        }
        // dbPlatform values: D(Derby), M(MySQL), O(Oracle), P(PostgreSQL) (default D)
        if (project.hasProperty('dbPlatform')) {
            if (dbPlatform == 'D') {
                databaseTemplateFile = "${rootDir}/framework/resources/templates/AdminNewTenantData-Derby.xml"
            } else if (dbPlatform == 'M') {
                databaseTemplateFile = "${rootDir}/framework/resources/templates/AdminNewTenantData-MySQL.xml"
            } else if (dbPlatform == 'O') {
                databaseTemplateFile = "${rootDir}/framework/resources/templates/AdminNewTenantData-Oracle.xml"
            } else if (dbPlatform == 'P') {
                databaseTemplateFile = "${rootDir}/framework/resources/templates/AdminNewTenantData-PostgreSQL.xml"
            } else {
                throw new GradleException('Invalid value for property dbPlatform: ' + "${dbPlatform}")
            }
        }
    }

    task generateDatabaseTemplateFile(dependsOn: prepareAndValidateTenantArguments) << {
        def filterTokens = ['tenantId': tenantId,
            'tenantName': project.hasProperty('tenantName')? tenantName : tenantId,
            'domainName': project.hasProperty('domainName')? domainName : 'org.apache.ofbiz',
            'db-IP': project.hasProperty('dbIp')? dbIp : '',
            'db-User': project.hasProperty('dbUser')? dbUser : '',
            'db-Password': project.hasProperty('dbPassword')? dbPassword : '']

        generateFileFromTemplate(databaseTemplateFile, 'runtime/tmp',
            filterTokens, 'tmpFilteredTenantData.xml')
    }

    task generateAdminUserTemplateFile(dependsOn: prepareAndValidateTenantArguments) << {
        generateFileFromTemplate(
            "${rootDir}/framework/resources/templates/AdminUserLoginData.xml",
            'runtime/tmp',
            ['userLoginId': "${tenantId}-admin".toString()],
            'tmpFilteredUserLogin.xml')
    }

    // Load the tenants master database
    createOfbizCommandTask('loadTenantOnDefaultDelegator',
        ['--load-data', 'file=/runtime/tmp/tmpFilteredTenantData.xml'],
        jvmArguments, false)
    loadTenantOnDefaultDelegator.dependsOn(generateDatabaseTemplateFile, generateAdminUserTemplateFile)

    // Load the actual tenant data
    createOfbizCommandTask('loadTenantData', [], jvmArguments, false)
    loadTenantData.dependsOn(loadTenantOnDefaultDelegator)

    // Load the tenant admin user account
    createOfbizCommandTask('loadTenantAdminUserLogin', [], jvmArguments, false)
    loadTenantAdminUserLogin.dependsOn(loadTenantData)

    /* pass arguments to tasks, must be done this way
     * because we are in the configuration phase. We cannot
     * set the parameters at the execution phase. */
    if (project.hasProperty('tenantId')) {
        loadTenantData.args '--load-data'
        loadTenantData.args "delegator=default#${tenantId}"

        loadTenantAdminUserLogin.args '--load-data'
        loadTenantAdminUserLogin.args "delegator=default#${tenantId}"
        loadTenantAdminUserLogin.args '--load-data'
        loadTenantAdminUserLogin.args "file=${rootDir}/runtime/tmp/tmpFilteredUserLogin.xml"
    }
    if (project.hasProperty('tenantReaders')) {
        loadTenantData.args '--load-data'
        loadTenantData.args "readers=${tenantReaders}"
    }

    dependsOn(loadTenantAdminUserLogin)

    // cleanup
    doLast {
        delete("${rootDir}/runtime/tmp/tmpFilteredTenantData.xml")
        delete("${rootDir}/runtime/tmp/tmpFilteredUserLogin.xml")
    }
}

// ========== System Administration tasks ==========
task createTestReports(group: sysadminGroup, description: 'Generate HTML reports from junit XML output') << {
    ant.taskdef(name: 'junitreport',
        classname: 'org.apache.tools.ant.taskdefs.optional.junit.XMLResultAggregator',
        classpath: configurations.junitReport.asPath)
    ant.junitreport(todir: './runtime/logs/test-results') {
        fileset(dir: './runtime/logs/test-results') {
            include(name: '*.xml')
        }
        report(format:'frames', todir:'./runtime/logs/test-results/html')
    }
}
/*
 * TODO replace this code with something more declarative.
 * We are using it so that if tests fail we still get HTML reports
 */
gradle.taskGraph.afterTask { Task task, TaskState state ->
    if (task.name ==~ /^ofbiz.*--test.*/
        || task.name ==~ /^ofbiz.*-t.*/) {
        tasks.createTestReports.execute()
    }
}

// ========== OFBiz Plugin Management ==========
task createPlugin(group: ofbizPlugin, description: 'create a new plugin component based on specified templates') << {
    if (!project.hasProperty('pluginResourceName')) {
        ext.pluginResourceName = pluginId.capitalize()
    }
    if (!project.hasProperty('webappName')) {
        ext.webappName = pluginId
    }
    if (!project.hasProperty('basePermission')) {
        ext.basePermission = pluginId.toUpperCase()
    }

    def filterTokens = ['component-name': pluginId,
        'component-resource-name': pluginResourceName,
        'webapp-name': webappName,
        'base-permission': basePermission]
    def templateDir = "${rootDir}/framework/resources/templates"
    def pluginDir = "${pluginsDir}/${pluginId}"

    mkdir pluginDir
    mkdir pluginDir+"/config"
    mkdir pluginDir+"/data"
    mkdir pluginDir+"/data/helpdata"
    mkdir pluginDir+"/dtd"
    mkdir pluginDir+"/documents"
    mkdir pluginDir+"/entitydef"
    mkdir pluginDir+"/lib"
    mkdir pluginDir+"/patches"
    mkdir pluginDir+"/patches/test"
    mkdir pluginDir+"/patches/qa"
    mkdir pluginDir+"/patches/production"
    mkdir pluginDir+"/script"
    mkdir pluginDir+"/servicedef"
    mkdir pluginDir+"/src"
    mkdir pluginDir+"/testdef"
    mkdir pluginDir+"/webapp"
    mkdir pluginDir+"/webapp/${webappName}"
    mkdir pluginDir+"/webapp/${webappName}/error"
    mkdir pluginDir+"/webapp/${webappName}/WEB-INF"
    mkdir pluginDir+"/webapp/${webappName}/WEB-INF/actions"
    mkdir pluginDir+"/widget/"

    generateFileFromTemplate(templateDir+"/ofbiz-component.xml", pluginDir,
        filterTokens, "ofbiz-component.xml")
    generateFileFromTemplate(templateDir+"/TypeData.xml", pluginDir+"/data",
        filterTokens, "${pluginResourceName}TypeData.xml")
    generateFileFromTemplate(templateDir+"/SecurityPermissionSeedData.xml", pluginDir+"/data",
        filterTokens, "${pluginResourceName}SecurityPermissionSeedData.xml")
    generateFileFromTemplate(templateDir+"/SecurityGroupDemoData.xml", pluginDir+"/data",
        filterTokens, "${pluginResourceName}SecurityGroupDemoData.xml")
    generateFileFromTemplate(templateDir+"/DemoData.xml", pluginDir+"/data",
        filterTokens, "${pluginResourceName}DemoData.xml")
    generateFileFromTemplate(templateDir+"/HELP.xml", pluginDir+"/data/helpdata",
        filterTokens, "HELP_${pluginResourceName}.xml")
    generateFileFromTemplate(templateDir+"/document.xml", pluginDir+"/documents",
        filterTokens, "${pluginResourceName}.xml")
    generateFileFromTemplate(templateDir+"/entitymodel.xml", pluginDir+"/entitydef",
        filterTokens, "entitymodel.xml")
    generateFileFromTemplate(templateDir+"/services.xml", pluginDir+"/servicedef",
        filterTokens, "services.xml")
    generateFileFromTemplate(templateDir+"/Tests.xml", pluginDir+"/testdef",
        filterTokens, "${pluginResourceName}Tests.xml")
    generateFileFromTemplate(templateDir+"/UiLabels.xml", pluginDir+"/config",
        filterTokens, "${pluginResourceName}UiLabels.xml")
    generateFileFromTemplate(templateDir+"/index.jsp", pluginDir+"/webapp/${webappName}",
        filterTokens, "index.jsp")
    generateFileFromTemplate(templateDir+"/error.jsp", pluginDir+"/webapp/${webappName}/error",
        filterTokens, "error.jsp")
    generateFileFromTemplate(templateDir+"/controller.xml", pluginDir+"/webapp/${webappName}/WEB-INF",
        filterTokens, "controller.xml")
    generateFileFromTemplate(templateDir+"/web.xml", pluginDir+"/webapp/${webappName}/WEB-INF",
        filterTokens, "web.xml")
    generateFileFromTemplate(templateDir+"/CommonScreens.xml", pluginDir+"/widget",
        filterTokens, "CommonScreens.xml")
    generateFileFromTemplate(templateDir+"/Screens.xml", pluginDir+"/widget",
        filterTokens, "${pluginResourceName}Screens.xml")
    generateFileFromTemplate(templateDir+"/Menus.xml", pluginDir+"/widget",
        filterTokens, "${pluginResourceName}Menus.xml")
    generateFileFromTemplate(templateDir+"/Forms.xml", pluginDir+"/widget",
        filterTokens, "${pluginResourceName}Forms.xml")
    generateFileFromTemplate(templateDir+"/build.gradle", pluginDir,
        filterTokens, "build.gradle")

    activatePlugin pluginId
    println "plugin successfully created in directory ${pluginsDir}/${pluginId}."
}

task installPlugin(group: ofbizPlugin, description: 'activate a plugin and run its install task if it exists') {

    doFirst {
        if (!project.hasProperty('pluginId')) {
            throw new GradleException('Missing property \"pluginId\"')
        }
    }

    if (project.hasProperty('pluginId')) {
        if (subprojectExists(":specialpurpose:${pluginId}")) {
            if (taskExistsInproject(":specialpurpose:${pluginId}", 'install')) {
                dependsOn ":specialpurpose:${pluginId}:install"
                doLast { println "installed plugin ${pluginId}" }
            } else {
                doLast { println "No install task defined for plugin ${pluginId}" }
            }
        } else {
            /* if the plugin is not added to component-load.xml, then add
             * it to the file and call gradle again to load the new plugin
             * as a gradle subproject and install it i.e. gradle calling gradle
             */
            doLast {
                activateAndInstallPlugin pluginId
            }
        }
    }
}

task uninstallPlugin(group: ofbizPlugin, description: 'run the uninstall task if exists for a plugin and deactivate it') {

    doFirst {
        if (!project.hasProperty('pluginId')) {
            throw new GradleException('Missing property \"pluginId\"')
        }
        if (!subprojectExists(":specialpurpose:${pluginId}")) {
            throw new GradleException("Plugin \"${pluginId}\" does not exist")
        }
    }

    if (project.hasProperty('pluginId') && taskExistsInproject(":specialpurpose:${pluginId}", 'uninstall')) {
        dependsOn ":specialpurpose:${pluginId}:uninstall"
    }

    doLast {
        deactivatePlugin pluginId
    }
}

task removePlugin(group: ofbizPlugin, description: 'Uninstall a plugin and delete its files') {
    if (project.hasProperty('pluginId') && subprojectExists(":specialpurpose:${pluginId}")) {
        dependsOn uninstallPlugin
    }

    doLast {
        if (file("${pluginsDir}/${pluginId}").exists()) {
            delete "${pluginsDir}/${pluginId}"
        } else {
            throw new GradleException("Directory not found: ${pluginsDir}/${pluginId}")
        }
    }
}

task pushPlugin(group: ofbizPlugin, description: 'push an existing plugin to local maven repository') {

    if (project.hasProperty('pluginId')) {
        doFirst {
            if (!subprojectExists(":specialpurpose:${pluginId}")) {
                throw new GradleException("Plugin ${pluginId} does not exist, cannot publish")
            }
        }
        task createPluginArchive(type: Zip) {
            from "${pluginsDir}/${pluginId}"
        }

        publishing {
            publications {
                ofbizPluginPublication(MavenPublication) {
                    artifactId pluginId
                    groupId project.hasProperty('pluginGroup')? pluginGroup :'org.apache.ofbiz.plugin'
                    version project.hasProperty('pluginVersion')? pluginVersion :'0.1.0-SNAPSHOT'

                    artifact createPluginArchive

                    pom.withXml {
                        if (project.hasProperty('pluginDescription')) {
                            asNode().appendNode('description', pluginDescription)
                        } else {
                            asNode().appendNode('description', "Publication of OFBiz plugin ${pluginId}")
                        }
                    }
                }
            }
        }

        if (subprojectExists(":specialpurpose:${pluginId}")) {
            dependsOn publishToMavenLocal
        }

    } else {
        doFirst { throw new GradleException('Missing property \"pluginId\"') }
    }
}

task pullPlugin(group: ofbizPlugin, description: 'Download and install a plugin with all dependencies') << {
    if (!project.hasProperty('dependencyId')) {
        throw new GradleException('You must pass the dependencyId of the plugin')
    }

    // Connect to a remote maven repository if defined
    if (project.hasProperty('repoUrl')) {
        repositories {
            maven {
                url repoUrl
                if (project.hasProperty('repoUser') && project.hasProperty('repoPassword')) {
                    credentials {
                        username repoUser
                        password repoPassword
                    }
                }
            }
        }
    }

    // download plugin and dependencies
    dependencies {
        ofbizPlugins dependencyId
    }

    // reverse the order of dependencies to install them before the plugin
    def ofbizPluginArchives = new ArrayList(configurations.ofbizPlugins.files)
    Collections.reverse(ofbizPluginArchives)

    // Extract and install plugin and dependencies
    ofbizPluginArchives.each { pluginArchive ->
        ext.pluginId = dependencyId.tokenize(':').get(1)
        println "installing plugin: ${pluginId}"
        copy {
            from zipTree(pluginArchive)
            into "${pluginsDir}/${pluginId}"
        }
        activateAndInstallPlugin pluginId
    }
}

// ========== Clean up tasks ==========
task cleanCatalina(group: cleanupGroup, description: 'Clean Catalina data in runtime/catalina/work') << {
    delete "${rootDir}/runtime/catalina/work"
}
task cleanData(group: cleanupGroup, description: 'Clean all DB data (Derby) under runtime/data') << {
    deleteAllInDirWithExclusions("${rootDir}/runtime/data/", ['README', 'derby.properties'])
}
task cleanDownloads(group: cleanupGroup, description: 'Clean all downloaded files') << {
    delete fileTree(dir: "${rootDir}/framework/base/lib", includes: ['activemq-*.jar'])
    delete fileTree(dir: "${rootDir}/framework/entity/lib/jdbc", includes: ['postgresql-*.jar'])
    delete fileTree(dir: "${rootDir}/framework/entity/lib/jdbc", includes: ['mysql-*.jar'])
}
task cleanLogs(group: cleanupGroup, description: 'Clean all logs in runtime/logs') << {
    deleteAllInDirWithExclusions("${rootDir}/runtime/logs/", ['README'])
}
task cleanOutput(group: cleanupGroup, description: 'Clean runtime/output directory') << {
    deleteAllInDirWithExclusions("${rootDir}/runtime/output/", ['README'])
}
task cleanIndexes(group: cleanupGroup, description: 'Remove search indexes (e.g. Lucene) from runtime/indexes') << {
    deleteAllInDirWithExclusions("${rootDir}/runtime/indexes/", ['README', 'index.properties'])
}
task cleanTempfiles(group: cleanupGroup, description: 'Remove file in runtime/tempfiles') << {
    deleteAllInDirWithExclusions("${rootDir}/runtime/tempfiles/", ['README'])
    deleteAllInDirWithExclusions("${rootDir}/runtime/tmp/", ['README'])
}
task cleanUploads(group: cleanupGroup, description: 'Remove uploaded files.') << {
    deleteAllInDirWithExclusions("${rootDir}/runtime/uploads/", [])
}
task cleanXtra(group: cleanupGroup, description: 'Clean extra generated files like .rej, .DS_Store, etc.') << {
    delete fileTree(dir: "${rootDir}", includes: ['**/.nbattrs', '**/*~','**/.#*', '**/.DS_Store', '**/*.rej', '**/*.orig'])
}
task cleanGradle(group: cleanupGroup, description: 'clean generated files from Gradle') << {
    delete file("${rootDir}/.gradle")
}
task cleanFooterFiles(group: cleanupGroup, description: 'clean generated footer files') << {
    delete gitFooterFile
    delete svnFooterFile
}
task cleanAnt(group: cleanupGroup, type: Delete, description: "clean old artifacts generated by Ant") << {
    /* TODO this task is temporary and should be deleted after some
     * time when users have updated their trees. */
    ['framework', 'specialpurpose', 'applications'].each { componentGroup ->
        file(componentGroup).eachDir { component ->
            delete file(component.toString() + '/build')
        }
    }
    delete 'ofbiz.jar'
}

/*
 * Keep this task below all other clean tasks  The location of
 * declaration is important because it means that it will automatically
 * run whenever the task cleanAll executes (dependency matched by regex)
 */
def cleanTasks = getTasksMatchingRegex(/^clean.+/)
task cleanAll(group: cleanupGroup, dependsOn: [cleanTasks, clean]) {
    description 'Execute all cleaning tasks.'
}

// ========== Tasks for OFBiz committers ==========
def websiteDir = "${rootDir}/../site"
task copyDtds(group: committerGroup, description: 'Copy all DTDs from OFBiz instance to website') << {
    mkdir websiteDir+'/dtds'
    copy {
        from (fileTree("${rootDir}").files) {
            include '**/*.xsd'
            exclude '**/002*.xsd'
            exclude '**/068*.xsd'
            exclude '**/161*.xsd'
            exclude '**/196*.xsd'
            exclude '**/197*.xsd'
        }
        into websiteDir+'/dtds'
    }
}

task gitInfoFooter(group: committerGroup, description: 'Update the Git Branch-revision info in the footer if Git is used') << {
    def branch
    def revision
    def timestamp = new Date().format 'yyyy-MM-dd HH:mm:ss'
    def gitFolder = new File('.git')

    if (!gitFolder.exists()) {
      println ("Git is not used")
      return
    }

    def branchOutput = new ByteArrayOutputStream()
    exec{
        commandLine 'git', 'rev-parse', '--abbrev-ref', 'HEAD'
        standardOutput = branchOutput
    }
    branch = branchOutput.toString()
    def revisionOutput = new ByteArrayOutputStream()
    exec{
        commandLine 'git', 'rev-parse', 'HEAD'
        standardOutput = revisionOutput
    }
    revision = revisionOutput.toString()
    gitFooterFile.delete()
    gitFooterFile.createNewFile()
    gitFooterFile << '${uiLabelMap.CommonBranch} : ' + "${branch}" + System.lineSeparator()
    gitFooterFile << '${uiLabelMap.CommonRevision} : ' + "${revision}" + System.lineSeparator()
    gitFooterFile << '${uiLabelMap.CommonBuiltOn} : ' + "${timestamp}" + System.lineSeparator()
    gitFooterFile << '${uiLabelMap.CommonJavaVersion} : ' + "${org.gradle.internal.jvm.Jvm.current()}"
}

task svnInfoFooter(group: committerGroup, description: 'Update the Subversion revision info in the footer if Subversion is used') << {
    def timestamp = new Date().format 'yyyy-MM-dd HH:mm:ss'
    def svnOutput = new ByteArrayOutputStream()
    def svnFolder = new File('.svn')

    if (!svnFolder.exists()) {
      println ("Subversion is not used")
      return
    }

    exec{
        commandLine 'svn', 'info', '--xml'
        standardOutput = svnOutput
    }
    def info = new XmlParser().parseText(svnOutput.toString())
    svnFooterFile.delete()
    svnFooterFile.createNewFile()
    svnFooterFile << '${uiLabelMap.CommonBranch} : ' + "${info.entry.url.text()}" + System.lineSeparator()
    svnFooterFile << '${uiLabelMap.CommonRevision} : ' + "${info.entry.commit.@revision}" + System.lineSeparator()
    svnFooterFile << '${uiLabelMap.CommonBuiltOn} : ' + "${timestamp}" + System.lineSeparator()
    svnFooterFile << '${uiLabelMap.CommonJavaVersion} : ' + "${org.gradle.internal.jvm.Jvm.current()}"
}

/* ========================================================
 * Rules-based OFBiz server commands
 * ======================================================== */

tasks.addRule('Pattern: ofbiz <Commands>: Execute OFBiz startup commands') { String taskName ->
    if (taskName ==~ /^ofbiz\s.*/ || taskName == 'ofbiz') {
        def arguments = (taskName - 'ofbiz').toLowerCase().tokenize(' ')
        createOfbizCommandTask(taskName, arguments, jvmArguments, false)
    }
}

tasks.addRule('Pattern: ofbizDebug <Commands>: Execute OFBiz startup commands in remote debug mode') { String taskName ->
    if (taskName ==~ /^ofbizDebug\s.*/ || taskName == 'ofbizDebug') {
        def arguments = (taskName - 'ofbizDebug').toLowerCase().tokenize(' ')
        createOfbizCommandTask(taskName, arguments, jvmArguments, true)
    }
}

tasks.addRule('Pattern: ofbizBackground <Commands>: Execute OFBiz startup commands in background and output to console.log') { String taskName ->
    if (taskName ==~ /^ofbizBackground\s.*/ || taskName == 'ofbizBackground') {
        createOfbizBackgroundCommandTask(taskName)
    }
}

/* ========================================================
 * Helper Functions
 * ======================================================== */

def createOfbizCommandTask(taskName, arguments, jvmArguments, isDebugMode) {

    def ofbizJarName = buildDir.toString()+'/libs/'+project.name+'.jar'

    task(type: JavaExec, dependsOn: build, taskName) {
        jvmArgs(jvmArguments)
        debug = isDebugMode
        classpath = files(ofbizJarName)
        main = ofbizMainClass
        arguments.each { argument ->
            args argument
        }

    }
}

def createOfbizBackgroundCommandTask(taskName) {
    def sourceTask = taskName.tokenize().first()
    def arguments = (taskName - sourceTask)

    def gradleRunner = os.contains('windows') ? 'gradlew.bat' : './gradlew'

    task (taskName) {
        doLast {
            spawnProcess(gradleRunner, "ofbiz ${arguments}")
        }
    }
}

def spawnProcess(command, arguments) {
    ProcessBuilder pb = new ProcessBuilder(command, arguments)
    File consoleLog = file("${rootDir}/runtime/logs/console.log");

    pb.directory(file("${rootDir}"))
    pb.redirectErrorStream(true)
    pb.redirectOutput(ProcessBuilder.Redirect.appendTo(consoleLog))
    pb.start()
}

def getDirectoryInActiveComponentsIfExists(String dirName) {
    def dirInComponents = []
    iterateOverActiveComponents { component ->
        def subDir = file(component.toString() + '/' + dirName)
        if (subDir.exists()) {
            dirInComponents.add subDir
        }
    }
    return dirInComponents
}

def deleteAllInDirWithExclusions(dirName, exclusions) {
    ant.delete (includeEmptyDirs: 'true', verbose: 'on') {
        fileset(dir: dirName, includes: '**/*', erroronmissingdir: "false") {
            exclusions.each { exclusion ->
                exclude name: exclusion
            }
        }
    }
}

def getTasksMatchingRegex(theRegex) {
    def filteredTasks = []
    tasks.each { task ->
        if (task.name ==~ theRegex) {
            filteredTasks.add(task)
        }
    }
    return filteredTasks
}

def generateFileFromTemplate(templateFileInFullPath, targetDirectory, filterTokens, newFileName) {
    copy {
        from (templateFileInFullPath) {
            filter ReplaceTokens, tokens: filterTokens
            rename templateFileInFullPath.tokenize('/').last(), newFileName
        }
        into targetDirectory
    }
}

def getJarManifestClasspathForCurrentOs() {
    def osClassPath = ''
    if (os.contains('windows')) {
        configurations.runtime.files.each { cpEntry ->
            osClassPath += '\\' + cpEntry.toString() + ' '
        }
    } else {
        osClassPath = configurations.runtime.files.collect { "$it" }.join(' ')
    }
    return osClassPath
}

def componentExistsInRegister(componentRegister, componentName) {
    def componentFound = false
    componentRegister.children().each { component ->
        if (componentName.equals(component.@"component-location")) {
            componentFound = true
        }
    }
    return componentFound
}

def subprojectExists(fullyQualifiedProject) {
    def projectFound = false
    subprojects.each { subproject ->
        if (subproject.getPath().equals(fullyQualifiedProject.toString())) {
            projectFound = true
        }
    }
    return projectFound
}

def taskExistsInproject(fullyQualifiedProject, taskName) {
    def taskExists = false
    subprojects.each { subProject ->
        if (subProject.getPath().equals(fullyQualifiedProject.toString())) {
            subProject.tasks.each { projTask ->
                if (taskName.equals(projTask.name)) {
                    taskExists = true
                }
            }
        }
    }
    return taskExists
}

def activatePlugin(pluginId) {
    def pluginLoadFile = "${pluginsDir}/component-load.xml"
    def componentRegister = new XmlParser().parse(pluginLoadFile)

    // check that plugin directory exists.
    if (!file("${pluginsDir}/${pluginId}").exists()) {
        throw new GradleException("Cannot add plugin \"${pluginId}\", directory does not exist")
    }

    // only add plugin if it does not exist in component-load.xml
    if (!componentExistsInRegister(componentRegister, pluginId)) {
        componentRegister.appendNode('load-component', ['component-location':pluginId])
        groovy.xml.XmlUtil.serialize(componentRegister, new FileWriter(pluginLoadFile))
        println "Activated plugin ${pluginId}"
    } else {
        println "The plugin ${pluginId} is already activated"
    }
}

def deactivatePlugin(pluginId) {
    def pluginLoadFile = "${pluginsDir}/component-load.xml"
    def componentRegister = new XmlParser().parse(pluginLoadFile)

    // Ensure that the plugin exists in component-load.xml then remove it
    if (componentExistsInRegister(componentRegister, pluginId)) {
        componentRegister.children().removeIf { plugin ->
            pluginId.equals(plugin.@"component-location")
        }
        groovy.xml.XmlUtil.serialize(componentRegister, new FileWriter(pluginLoadFile))
        println "Deactivated plugin ${pluginId}"
    } else {
        println "The plugin ${pluginId} is not active"
    }
}

def activateAndInstallPlugin(pluginId) {
    activatePlugin pluginId
    def gradleRunner = os.contains('windows') ? 'gradlew.bat' : './gradlew'
    exec { commandLine gradleRunner, 'installPlugin', "-PpluginId=${pluginId}" }
}
