--- /dev/null
+<project name="app-tenant-mgmt" default="clone-tenant" basedir=".">
+ <description>Manage Application layer folders and files containing per-tenant configurations</description>
+
+ <!-- Location of the 'tenants' directory for this CollectionSpace source code layer. -->
+ <property name="src.dir" value="${basedir}" />
+ <property name="tenants.dir" value="${src.dir}/services/common/src/main/cspace/config/services/tenants"/>
+
+ <!-- Locations of the tenant folders for the
+ template tenant and newly-cloned tenant. -->
+ <property name="template.tenant.dir" value="${tenants.dir}/${template.tenant.shortname}"/>
+ <property name="tenant.dir" value="${tenants.dir}/${tenant.shortname}"/>
+
+ <!-- Location of the tenant bindings delta files for the
+ template tenant and newly-cloned tenant. -->
+ <property name="tenant.bindings.delta.suffix" value="-tenant-bindings.delta.xml"/>
+ <property name="template.bindings.delta.file"
+ value="${template.tenant.dir}/${template.tenant.shortname}${tenant.bindings.delta.suffix}"/>
+ <property name="tenant.bindings.delta.file"
+ value="${tenant.dir}/${tenant.shortname}${tenant.bindings.delta.suffix}"/>
+
+ <!-- Imports a set of utility routines for managing tenant folders
+ from a separate Ant buildfile.
+ See http://wiki.apache.org/ant/NewAntFeaturesInDetail/Import -->
+ <import file="./tenant-utils-build.xml"/>
+
+ <!-- This target inherits from an existing target in the imported
+ utility routines buildfile, and adds its own behavior specific to this
+ CollectionSpace source code layer. -->
+ <target name="rename-files" depends="tenant-utils.rename-files">
+ <move todir="${tenants.dir}/${tenant.shortname}" includeemptydirs="false">
+ <fileset dir="${tenants.dir}/${tenant.shortname}"/>
+ <mapper type="regexp" from="^(.*?)${template.tenant.shortname}(.*)$" to="\1${tenant.shortname}\2"/>
+ </move>
+ </target>
+
+ <!-- This target inherits from an (essentially empty) target in the imported
+ utility routines buildfile, and adds its own behavior specific to this
+ CollectionSpace source code layer. -->
+ <target name="update-text-in-cloned-tenant"
+ depends="tenant-utils.update-text-in-cloned-tenant,
+ update-text-in-tenant-bindings-delta">
+ </target>
+
+ <target name="update-text-in-tenant-bindings-delta"
+ depends="update-tenant-id-in-tenant-bindings-delta,
+ remove-enclosing-xml-comments-in-tenant-bindings-delta">
+ </target>
+
+ <target name="update-tenant-id-in-tenant-bindings-delta">
+ <replaceregexp
+ file="${tenant.bindings.delta.file}"
+ match="<tenant:tenantBinding id="(.*)">"
+ replace="<tenant:tenantBinding id="${tenant.id}">"/>
+ </target>
+
+ <!-- Remove opening and closing XML comment tags, when found
+ on lines by themselves: the convention currently used
+ in the tenant bindings delta file. -->
+ <target name="remove-enclosing-xml-comments-in-tenant-bindings-delta">
+ <replaceregexp
+ file="${tenant.bindings.delta.file}"
+ match="^\s*?<!--\s*$"
+ replace=""
+ byline="true"
+ flags="gm"/>
+ <replaceregexp
+ file="${tenant.bindings.delta.file}"
+ match="^\s*?-->\s*$"
+ replace=""
+ byline="true"
+ flags="gm"/>
+ </target>
+
+ <!-- TODO: Delete the (obsolete) tenant-bindings.delta.xml and any
+ tenant-bindings.merged.xml file in the newly-cloned tenant. -->
+
+ <!-- This target inherits from an (essentially empty) target in the imported
+ utility routines buildfile, and adds its own behavior specific to this
+ CollectionSpace source code layer. -->
+ <target name="check-tenant-extended-properties"
+ depends="tenant-utils.check-tenant-extended-properties">
+ <!-- ID of the new tenant to create -->
+ <antcall target="check-property-is-defined">
+ <param name="property-to-check" value="tenant.id"/>
+ </antcall>
+ <antcall target="check-property-value-is-not-blank">
+ <param name="property-to-check" value="tenant.id"/>
+ <param name="property-to-check-value" value="${tenant.id}"/>
+ </antcall>
+ <echo message="tenant.id=${tenant.id}"/>
+ </target>
+
+</project>
\ No newline at end of file
--- /dev/null
+<project name="tenant-utils" basedir=".">
+ <description>Utilities for managing folders and files containing per-tenant configurations</description>
+
+ <!-- Import this Ant build file into any other Ant build file
+ via '<import file="./tenant-mgmt-build.xml"/>' -->
+
+ <!-- If a 'tenant.properties' file is provided, values for
+ properties used in this Ant buildfile will be read
+ from that file. -->
+ <!-- Values for these properties can instead, or also, be
+ provided at the command line when invoking Ant, via
+ one or more arguments similar to:
+ -Dvariable.name=somevalue -->
+ <!-- Where there are conflicts, values provided via the command line
+ are used in preference to those provided in the properties file. -->
+ <property file="tenant.properties" />
+
+ <!-- Main target -->
+
+ <target name="clone-tenant" depends="clone-template-folder,
+ clone-other-template-files,rename-files,update-text-in-cloned-tenant"
+ description="Make a copy ('clone') of an existing tenant (used as a template) to create a new tenant">
+ </target>
+
+ <!-- Main sub-targets -->
+
+ <target name="clone-template-folder"
+ depends="template-tenant-does-not-exist-error-check,tenant-already-exists-error-check">
+ <echo message="Cloning configuration from template tenant folder '${template.tenant.shortname}' to new tenant folder '${tenant.shortname}' ..."/>
+ <copy todir="${tenants.dir}/${tenant.shortname}">
+ <fileset dir="${tenants.dir}/${template.tenant.shortname}"/>
+ </copy>
+ </target>
+
+ <!-- This (essentially empty) target can be inherited and overridden by
+ any Ant buildfile that imports this tenant-utils buildfile. -->
+ <target name="clone-other-template-files" depends="clone-template-folder">
+ <echo message="Cloning other template files, where applicable ..."/>
+ </target>
+
+ <!-- This (essentially empty) target can be inherited and overridden by
+ any Ant buildfile that imports this tenant-utils buildfile. -->
+ <target name="rename-files" depends="clone-other-template-files">
+ <echo message="Renaming files, where applicable ..."/>
+ </target>
+
+ <!-- This (essentially empty) target can be inherited and overridden by
+ any Ant buildfile that imports this tenant-utils buildfile. -->
+ <target name="update-text-in-cloned-tenant" depends="rename-files">
+ <echo message="Updating text in the newly-cloned tenant ..."/>
+ </target>
+
+ <!-- Utility targets -->
+
+ <target name="check-template-properties">
+ <echo message="Checking that required template properties have been set ..."/>
+ <!-- Short name of the existing tenant to use as a template, when
+ creating a new tenant -->
+ <antcall target="check-property-is-defined">
+ <param name="property-to-check" value="template.tenant.shortname"/>
+ </antcall>
+ <antcall target="check-property-value-is-not-blank">
+ <param name="property-to-check" value="template.tenant.shortname"/>
+ <param name="property-to-check-value" value="${template.tenant.shortname}"/>
+ </antcall>
+ <echo message="template.tenant.shortname=${template.tenant.shortname}"/>
+ </target>
+
+ <target name="check-tenant-properties">
+ <echo message="Checking that required tenant properties have been set ..."/>
+ <!-- Short name of the new tenant to create -->
+ <antcall target="check-property-is-defined">
+ <param name="property-to-check" value="tenant.shortname"/>
+ </antcall>
+ <antcall target="check-property-value-is-not-blank">
+ <param name="property-to-check" value="tenant.shortname"/>
+ <param name="property-to-check-value" value="${tenant.shortname}"/>
+ </antcall>
+ <echo message="tenant.shortname=${tenant.shortname}"/>
+ </target>
+
+ <!-- Check that any required per-tenant properties, beyond the tenant shortname,
+ have been defined and are non-blank.
+ This (essentially empty) target can be inherited and overridden by
+ any Ant buildfile that imports this tenant-utils buildfile. -->
+ <target name="check-tenant-extended-properties">
+ <echo message="Checking that any required tenant extended properties have been set ..."/>
+ </target>
+
+ <target name="check-property-is-defined">
+ <fail message="'${property-to-check}' property is not defined. It is usually defined in either a 'tenant.properties' file, present in the same directory as this Ant build.xml file, or by adding a '-D${property-to-check}=somevalue' argument when running 'ant'.">
+ <condition>
+ <not><isset property="${property-to-check}"/></not>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="check-property-value-is-not-blank">
+ <fail message="'${property-to-check}' property is defined, but its value is blank (is empty or contains only whitespace characters). This property must contain a non-blank value, and must match the name of an existing tenant. Its value is usually set in either a 'tenant.properties' file, present in the same directory as this Ant build.xml file, or by adding a '-D${property-to-check}=somevalue' argument when running 'ant'.">
+ <condition>
+ <equals arg1="${property-to-check-value}" arg2="" trim="true"/>
+ </condition>
+ </fail>
+ </target>
+
+ <target name="template-exists" depends="check-template-properties">
+ <condition property="template.exists">
+ <available file="${tenants.dir}/${template.tenant.shortname}" type="dir"/>
+ </condition>
+ </target>
+
+ <target name="tenant-exists" depends="check-tenant-properties,check-tenant-extended-properties">
+ <condition property="tenant.exists">
+ <available file="${tenants.dir}/${tenant.shortname}" type="dir"/>
+ </condition>
+ </target>
+
+ <target name="template-tenant-does-not-exist-error-check" depends="template-exists" unless="${template.exists}">
+ <fail message="Could not find 'template' tenant folder '${template.tenant.shortname}' in ${tenants.dir} ... Check the name of the 'template' tenant, which must match the name of an existing tenant. Its value is usually set in a 'template.tenant.shortname' property, either in a 'tenant.properties' file, present in the same directory as this Ant build.xml file, or by adding a '-Dtemplate.tenant.shortname=somevalue' argument when running 'ant'."/>
+ </target>
+
+ <target name="tenant-already-exists-error-check" depends="tenant-exists" if="${tenant.exists}">
+ <fail message="Tenant folder '${tenant.shortname}' already exists as ${tenants.dir}/${tenant.shortname} ... To create a new tenant named '${tenant.shortname}', please move the existing folder outside of the CollectionSpace source code tree and re-run 'ant'. Or you can create a new tenant with a different name, by changing the 'tenant.shortname' value, in either a 'tenant.properties' file, present in the same directory as this Ant build.xml file, or by adding a '-Dtenant.shortname=somevalue' argument when running 'ant'."/>
+ </target>
+
+</project>
\ No newline at end of file
--- /dev/null
+# Values in this 'tenant.properties' file will be used
+# in targets in the Ant buildfile, build.xml, when copying
+# ("cloning") a 'template tenant' to create a new tenant
+
+# Values for these properties can instead, or also, be
+# provided at the command line when invoking Ant, via
+# one or more arguments similar to:
+# -Dvariable.name=somevalue
+#
+# Where there are conflicts, values provided via the command line
+# are used in preference to those provided in this properties file.
+
+# The short name for the existing tenant that will be copied,
+# or "cloned" to create a new tenant
+template.tenant.shortname=
+
+# The short name for the new tenant to be created
+tenant.shortname=
+
+# The ID for the new tenant to be created
+# (currently an integer; e.g. '5', '23')
+tenant.id=
+