You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ofbiz.apache.org by ha...@apache.org on 2011/09/20 08:23:03 UTC

svn commit: r1172989 - in /ofbiz/trunk: ./ framework/common/config/ framework/entity/ framework/entity/config/ framework/entity/entitydef/ framework/entity/src/org/ofbiz/entity/util/ framework/entityext/src/org/ofbiz/entityext/data/

Author: hansbak
Date: Tue Sep 20 06:23:02 2011
New Revision: 1172989

URL: http://svn.apache.org/viewvc?rev=1172989&view=rev
Log:
add 2 new tenant ant commands to load seed/demo data for a specific tenant only: './ant run-install-tenant -DtenantId' and './ant run-install-tenant-all' for all tenants in the tenant enttity

Modified:
    ofbiz/trunk/build.xml
    ofbiz/trunk/framework/common/config/general.properties
    ofbiz/trunk/framework/entity/config/entityengine.xml
    ofbiz/trunk/framework/entity/entitydef/entitygroup.xml
    ofbiz/trunk/framework/entity/entitydef/entitymodel.xml
    ofbiz/trunk/framework/entity/ofbiz-component.xml
    ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityDataLoader.java
    ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/data/EntityDataLoadContainer.java

Modified: ofbiz/trunk/build.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/build.xml?rev=1172989&r1=1172988&r2=1172989&view=diff
==============================================================================
--- ofbiz/trunk/build.xml (original)
+++ ofbiz/trunk/build.xml Tue Sep 20 06:23:02 2011
@@ -453,7 +453,155 @@ under the License.
             <arg value="file=${data-file}"/>
         </java>
     </target>
-
+    <!-- =================================
+          target: run-install-tenant
+         ================================= -->
+    <target name="run-install-tenant" depends="build,run-install-tenant-all,run-install-tenant-reader,run-install-tenant-component-all,run-install-tenant-component-reader"
+            description="This loads data using tenantId, syntax eg: ant run-install-tenant -DtenantId=DEMO1 (needs multitenant=Y in general.properties)">
+    </target>
+    <target name="check-tenant-id">
+        <java jar="ofbiz.jar" fork="true">
+            <jvmarg value="${memory.initial.param}"/>
+            <jvmarg value="${memory.max.param}"/>
+            <jvmarg value="${memory.maxpermsize.param}"/>
+            <arg value="install"/>
+            <arg value="readers=tenant"/>
+        </java>
+        <condition property="hasTenant">
+            <and>
+                <length string="${tenantId}" trim="true" when="greater" length="0"/>
+                <not><contains string="${tenantId}" substring="tenantId"/></not>
+                <or>
+                    <length string="${component}" trim="true" when="equal" length="0"/>
+                    <contains string="${component}" substring="component"/>
+                </or>
+            </and>
+        </condition>
+        <condition property="hasTenantComponent">
+            <and>
+                <length string="${tenantId}" trim="true" when="greater" length="0"/>
+                <not><contains string="${tenantId}" substring="tenantId"/></not>
+                <length string="${component}" trim="true" when="greater" length="0"/>
+                <not><contains string="${component}" substring="component"/></not>
+            </and>
+        </condition>
+    </target>
+    <target name="check-tenant-reader" depends="check-tenant-id" if="hasTenant">
+        <condition property="hasReader">
+            <and>
+                <length string="${data-readers}" trim="true" when="greater" length="0"/>
+                <not><contains string="${data-readers}" substring="data-readers"/></not>
+            </and>
+        </condition>
+        <condition property="noReader">
+            <or>
+                <length string="${data-readers}" trim="true" when="equal" length="0"/>
+                <contains string="${data-readers}" substring="data-readers"/>
+            </or>
+        </condition>
+    </target>
+    <target name="run-install-tenant-all" depends="check-tenant-reader" if="noReader">
+        <java jar="ofbiz.jar" fork="true">
+            <jvmarg value="${memory.initial.param}"/>
+            <jvmarg value="${memory.max.param}"/>
+            <jvmarg value="${memory.maxpermsize.param}"/>
+            <arg value="install"/>
+            <arg value="delegator=default#${tenantId}"/>
+        </java>
+    </target>
+    <target name="run-install-tenant-reader" depends="check-tenant-reader" if="hasReader">
+        <java jar="ofbiz.jar" fork="true">
+            <jvmarg value="${memory.initial.param}"/>
+            <jvmarg value="${memory.max.param}"/>
+            <jvmarg value="${memory.maxpermsize.param}"/>
+            <arg value="install"/>
+            <arg value="delegator=default#${tenantId}"/>
+            <arg value="readers=${data-readers}"/>
+        </java>
+    </target>
+    <!-- run-install-tenant-component -->
+    <target name="run-install-tenant-component" if="hasTenantComponent" depends="check-tenant-id">
+        <condition property="hasComponentReader">
+            <and>
+                <length string="${data-readers}" trim="true" when="greater" length="0"/>
+                <not><contains string="${data-readers}" substring="data-readers"/></not>
+            </and>
+        </condition>
+        <condition property="noComponentReader">
+            <or>
+                <length string="${data-readers}" trim="true" when="equal" length="0"/>
+                <contains string="${data-readers}" substring="data-readers"/>
+            </or>
+        </condition>
+    </target>
+    <target name="run-install-tenant-component-all" depends="run-install-tenant-component" if="noComponentReader">
+        <java jar="ofbiz.jar" fork="true">
+            <jvmarg value="${memory.initial.param}"/>
+            <jvmarg value="${memory.max.param}"/>
+            <jvmarg value="${memory.maxpermsize.param}"/>
+            <arg value="install"/>
+            <arg value="delegator=default#${tenantId}"/>
+            <arg value="component=${component}"/>
+        </java>
+    </target>
+    <target name="run-install-tenant-component-reader" depends="run-install-tenant-component" if="hasComponentReader">
+        <java jar="ofbiz.jar" fork="true">
+            <jvmarg value="${memory.initial.param}"/>
+            <jvmarg value="${memory.max.param}"/>
+            <jvmarg value="${memory.maxpermsize.param}"/>
+            <arg value="install"/>
+            <arg value="delegator=default#${tenantId}"/>
+            <arg value="readers=${data-readers}"/>
+            <arg value="component=${component}"/>
+        </java>
+    </target>
+    <!-- =================================
+          target: run-install-all-tenants
+         ================================= -->
+    <target name="run-install-all-tenants" depends="build,run-install-tenants-all,run-install-tenants-reader"
+           description="This loads data all tenants, syntax eg: ant run-install-all-tenants (needs multitenant=Y in general.properties)">
+    </target>
+    <target name="check-tenants-reader">
+        <property name="delegator" value="all-tenants"/>
+        <java jar="ofbiz.jar" fork="true">
+            <jvmarg value="${memory.initial.param}"/>
+            <jvmarg value="${memory.max.param}"/>
+            <jvmarg value="${memory.maxpermsize.param}"/>
+            <arg value="install"/>
+            <arg value="readers=tenant"/>
+        </java>
+        <condition property="hasReader">
+            <and>
+                <length string="${data-readers}" trim="true" when="greater" length="0"/>
+                <not><contains string="${data-readers}" substring="data-readers"/></not>
+            </and>
+        </condition>
+        <condition property="noReader">
+            <or>
+                <length string="${data-readers}" trim="true" when="equal" length="0"/>
+                <contains string="${data-readers}" substring="data-readers"/>
+            </or>
+        </condition>
+    </target>
+    <target name="run-install-tenants-all" depends="check-tenants-reader" if="noReader">
+        <java jar="ofbiz.jar" fork="true">
+            <jvmarg value="${memory.initial.param}"/>
+            <jvmarg value="${memory.max.param}"/>
+            <jvmarg value="${memory.maxpermsize.param}"/>
+            <arg value="install"/>
+            <arg value="delegator=${delegator}"/>
+        </java>
+    </target>
+    <target name="run-install-tenants-reader" depends="check-tenants-reader" if="hasReader">
+        <java jar="ofbiz.jar" fork="true">
+            <jvmarg value="${memory.initial.param}"/>
+            <jvmarg value="${memory.max.param}"/>
+            <jvmarg value="${memory.maxpermsize.param}"/>
+            <arg value="install"/>
+            <arg value="readers=${data-readers}"/>
+            <arg value="delegator=${delegator}"/>
+        </java>
+    </target>
     <!-- =================================
           target: run-create-tenant
          ================================= -->

Modified: ofbiz/trunk/framework/common/config/general.properties
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/common/config/general.properties?rev=1172989&r1=1172988&r2=1172989&view=diff
==============================================================================
--- ofbiz/trunk/framework/common/config/general.properties (original)
+++ ofbiz/trunk/framework/common/config/general.properties Tue Sep 20 06:23:02 2011
@@ -128,7 +128,7 @@ https.www.ofbiz.it=ABQIAAAAtt0d8djaYFkk8
 https.localhost=ABQIAAAAtt0d8djaYFkk8N5LJVcDSBQN-clGH2vvMMwJjYtcwF78UzZgEBTN70S6uIgRoAtXRkADNoesbw5etg
 http.localhost=ABQIAAAAtt0d8djaYFkk8N5LJVcDSBT2yXp_ZAY8_ufC3CFXhHIE1NvwkxR3euHYk9bpwvdF2Qg1EYO1LQitHA
 
-# -- Y if you want to display the multi-tenant textbox in the login page
+# -- Y if you want to display the multi-tenant textbox in the login page and install specify components which related to each tenant
 multitenant=N
 
 # -- Y if you use a cluster. Most of the time this should not be needed. Setting distributed-cache-clear-enabled="true" is enough 

Modified: ofbiz/trunk/framework/entity/config/entityengine.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/config/entityengine.xml?rev=1172989&r1=1172988&r2=1172989&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/config/entityengine.xml (original)
+++ ofbiz/trunk/framework/entity/config/entityengine.xml Tue Sep 20 06:23:02 2011
@@ -96,6 +96,7 @@ access. For a detailed description see t
 
     <!-- need to at least define a name for each component to use -->
     <!-- defining:
+        tenant       = OFBiz and External Tenant Data
         seed         = OFBiz and External Seed Data - to be maintained along with source and updated whenever a system deployment is updated
         seed-initial = OFBiz and External Seed Data - to be maintained along with source like other seed data, but only loaded initially and not updated when a system is updated except manually reviewing each line
         demo         = OFBiz Only Demo Data
@@ -103,6 +104,7 @@ access. For a detailed description see t
         ext-test     = External Test Data (custom)
         ext-demo     = External Demo Data (custom)
     -->
+    <entity-data-reader name="tenant"/>
     <entity-data-reader name="seed"/>
     <entity-data-reader name="seed-initial"/>
     <entity-data-reader name="demo"/>
@@ -149,6 +151,7 @@ access. For a detailed description see t
             use-fk-initially-deferred="false"
             join-style="ansi-no-parenthesis"
             alias-view-columns="true">
+        <read-data reader-name="tenant"/>
         <read-data reader-name="seed"/>
         <read-data reader-name="seed-initial"/>
         <read-data reader-name="demo"/>
@@ -177,6 +180,7 @@ access. For a detailed description see t
             use-indices-unique="false"
             alias-view-columns="false"
             use-order-by-nulls="true">
+        <read-data reader-name="tenant"/>
         <read-data reader-name="seed"/>
         <read-data reader-name="seed-initial"/>
         <read-data reader-name="demo"/>
@@ -226,6 +230,7 @@ access. For a detailed description see t
             alias-view-columns="false"
             use-order-by-nulls="true">
         <!-- beware use-indices-unique="false" is needed because of Derby bug with null values in a unique index -->
+        <read-data reader-name="tenant"/>
         <read-data reader-name="seed"/>
         <read-data reader-name="seed-initial"/>
         <read-data reader-name="demo"/>
@@ -251,6 +256,7 @@ access. For a detailed description see t
         use-indices-unique="false"
         alias-view-columns="false"
         use-order-by-nulls="true">
+        <read-data reader-name="tenant"/>
         <read-data reader-name="seed"/>
         <read-data reader-name="seed-initial"/>
         <read-data reader-name="demo"/>
@@ -273,6 +279,7 @@ access. For a detailed description see t
             field-type-name="daffodil"
             check-on-start="true"
             add-missing-on-start="true">
+        <read-data reader-name="tenant"/>
         <read-data reader-name="seed"/>
         <read-data reader-name="seed-initial"/>
         <read-data reader-name="demo"/>
@@ -297,6 +304,7 @@ access. For a detailed description see t
             check-on-start="true"
             add-missing-on-start="true"
             use-pk-constraint-names="false">
+        <read-data reader-name="tenant"/>
         <read-data reader-name="seed"/>
         <read-data reader-name="seed-initial"/>
         <read-data reader-name="demo"/>
@@ -325,6 +333,7 @@ access. For a detailed description see t
             table-type="InnoDB"
             character-set="latin1"
             collate="latin1_general_cs">
+        <read-data reader-name="tenant"/>
         <read-data reader-name="seed"/>
         <read-data reader-name="seed-initial"/>
         <read-data reader-name="demo"/>
@@ -355,6 +364,7 @@ access. For a detailed description see t
             table-type="InnoDB"
             character-set="latin1"
             collate="latin1_general_cs">
+        <read-data reader-name="tenant"/>
         <read-data reader-name="seed"/>
         <read-data reader-name="seed-initial"/>
         <read-data reader-name="demo"/>
@@ -385,6 +395,7 @@ access. For a detailed description see t
             table-type="InnoDB"
             character-set="latin1"
             collate="latin1_general_cs">
+        <read-data reader-name="tenant"/>
         <read-data reader-name="seed"/>
         <read-data reader-name="seed-initial"/>
         <read-data reader-name="demo"/>
@@ -415,6 +426,7 @@ access. For a detailed description see t
             table-type="InnoDB"
             character-set="latin1"
             collate="latin1_general_cs">
+        <read-data reader-name="tenant"/>
         <read-data reader-name="seed"/>
         <inline-jdbc
                 jdbc-driver="com.mysql.jdbc.Driver"
@@ -442,6 +454,7 @@ access. For a detailed description see t
             <!-- use this attribute to make the EntityListIterator more effective for pgjdbc 7.5devel and later:
                 result-fetch-size="50"
             -->
+        <read-data reader-name="tenant"/>
         <read-data reader-name="seed"/>
         <read-data reader-name="seed-initial"/>
         <read-data reader-name="demo"/>
@@ -479,6 +492,7 @@ access. For a detailed description see t
         result-fetch-size="50"
         use-binary-type-for-blob="true"
         use-order-by-nulls="true">
+        <read-data reader-name="tenant"/>
         <read-data reader-name="seed"/>
         <read-data reader-name="seed-initial"/>
         <read-data reader-name="demo"/>
@@ -512,6 +526,7 @@ access. For a detailed description see t
             result-fetch-size="50"
             use-binary-type-for-blob="true"
             use-order-by-nulls="true">
+        <read-data reader-name="tenant"/>
         <read-data reader-name="seed"/>
         <read-data reader-name="seed-initial"/>
         <read-data reader-name="demo"/>
@@ -545,6 +560,7 @@ access. For a detailed description see t
             result-fetch-size="50"
             use-binary-type-for-blob="true"
             use-order-by-nulls="true">
+        <read-data reader-name="tenant"/>
         <read-data reader-name="seed"/>
         <read-data reader-name="seed-initial"/>
         <read-data reader-name="demo"/>
@@ -576,6 +592,7 @@ access. For a detailed description see t
             alias-view-columns="false"
             join-style="ansi"
             use-order-by-nulls="true">
+        <read-data reader-name="tenant"/>
         <read-data reader-name="seed"/>
         <read-data reader-name="seed-initial"/>
         <read-data reader-name="demo"/>
@@ -616,6 +633,7 @@ access. For a detailed description see t
             add-missing-on-start="true"
             use-fk-initially-deferred="false"
             join-style="ansi">
+        <read-data reader-name="tenant"/>
         <read-data reader-name="seed"/>
         <read-data reader-name="seed-initial"/>
         <read-data reader-name="demo"/>
@@ -639,6 +657,7 @@ access. For a detailed description see t
             fk-style="name_fk"
             use-fk-initially-deferred="false"
             join-style="ansi-no-parenthesis">
+        <read-data reader-name="tenant"/>
         <read-data reader-name="seed"/>
         <read-data reader-name="seed-initial"/>
         <read-data reader-name="demo"/>
@@ -666,6 +685,7 @@ access. For a detailed description see t
             add-missing-on-start="true"
             alias-view-columns="false"
             join-style="ansi">
+        <read-data reader-name="tenant"/>
         <read-data reader-name="seed"/>
         <read-data reader-name="seed-initial"/>
         <read-data reader-name="demo"/>
@@ -708,6 +728,7 @@ access. For a detailed description see t
             join-style="ansi"
             alias-view-columns="false"
             use-fk-initially-deferred="false">
+        <read-data reader-name="tenant"/>
         <read-data reader-name="seed"/>
         <read-data reader-name="seed-initial"/>
         <read-data reader-name="demo"/>
@@ -731,6 +752,7 @@ access. For a detailed description see t
             check-on-start="true"
             add-missing-on-start="true"
             join-style="ansi">
+        <read-data reader-name="tenant"/>
         <read-data reader-name="seed"/>
         <read-data reader-name="seed-initial"/>
         <read-data reader-name="demo"/>
@@ -758,6 +780,7 @@ access. For a detailed description see t
             join-style="ansi-no-parenthesis"
             alias-view-columns="false"
             always-use-constraint-keyword="true">
+        <read-data reader-name="tenant"/>
         <read-data reader-name="seed"/>
         <read-data reader-name="seed-initial"/>
         <read-data reader-name="demo"/>

Modified: ofbiz/trunk/framework/entity/entitydef/entitygroup.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/entitydef/entitygroup.xml?rev=1172989&r1=1172988&r2=1172989&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/entitydef/entitygroup.xml (original)
+++ ofbiz/trunk/framework/entity/entitydef/entitygroup.xml Tue Sep 20 06:23:02 2011
@@ -27,4 +27,6 @@ under the License.
     <entity-group group="org.ofbiz.tenant" entity="Tenant"/>
     <entity-group group="org.ofbiz.tenant" entity="TenantDataSource"/>
 <!--     <entity-group group="org.ofbiz.tenant" entity="TenantUserLogin"/> -->
+    <entity-group group="org.ofbiz.tenant" entity="Component"/>
+    <entity-group group="org.ofbiz.tenant" entity="TenantComponent"/>
 </entitygroup>

Modified: ofbiz/trunk/framework/entity/entitydef/entitymodel.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/entitydef/entitymodel.xml?rev=1172989&r1=1172988&r2=1172989&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/entitydef/entitymodel.xml (original)
+++ ofbiz/trunk/framework/entity/entitydef/entitymodel.xml Tue Sep 20 06:23:02 2011
@@ -121,4 +121,24 @@ under the License.
         <!- - NOTE: there is no FK to the UserLogin entity, which is in a higher-level component, and would normally be in a separate database - ->
     </entity>
     -->
+    <entity entity-name="Component" package-name="org.ofbiz.entity.tenant">
+        <description>Component Entity</description>
+        <field name="componentName" type="name"></field>
+        <field name="rootLocation" type="description"></field>
+        <prim-key field="componentName"/>
+    </entity>
+    <entity entity-name="TenantComponent" package-name="org.ofbiz.entity.tenant">
+        <description></description>
+        <field name="tenantId" type="id-ne"></field>
+        <field name="componentName" type="name"></field>
+        <field name="sequenceNum" type="numeric"></field>
+        <prim-key field="componentName"/>
+        <prim-key field="tenantId"/>
+        <relation type="one" fk-name="TNTCOMP_TNT" rel-entity-name="Tenant">
+            <key-map field-name="tenantId"/>
+        </relation>
+        <relation type="one" fk-name="COMP_CNT" rel-entity-name="Component">
+            <key-map field-name="componentName"/>
+        </relation>
+    </entity>
 </entitymodel>

Modified: ofbiz/trunk/framework/entity/ofbiz-component.xml
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/ofbiz-component.xml?rev=1172989&r1=1172988&r2=1172989&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/ofbiz-component.xml (original)
+++ ofbiz/trunk/framework/entity/ofbiz-component.xml Tue Sep 20 06:23:02 2011
@@ -34,7 +34,7 @@ under the License.
     <!-- these are for unit testing -->
     <entity-resource type="model" reader-name="main" loader="main" location="entitydef/entitymodel_test.xml"/>
 
-    <entity-resource type="data" reader-name="demo" loader="main" location="data/TenantDemoData.xml"/>
+    <entity-resource type="data" reader-name="tenant" loader="main" location="data/TenantDemoData.xml"/>
     
     <test-suite loader="main" location="testdef/entitytests.xml"/>
 </ofbiz-component>

Modified: ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityDataLoader.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityDataLoader.java?rev=1172989&r1=1172988&r2=1172989&view=diff
==============================================================================
--- ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityDataLoader.java (original)
+++ ofbiz/trunk/framework/entity/src/org/ofbiz/entity/util/EntityDataLoader.java Tue Sep 20 06:23:02 2011
@@ -176,6 +176,23 @@ public class EntityDataLoader {
         return urlList;
     }
 
+    public static <E> List<URL> getUrlByComponentList(String helperName, List<String> components, List<E> readerNames) {
+        String paths = getPathsString(helperName);
+        List<URL> urlList = new LinkedList<URL>();
+        for (String component : components) {
+            urlList.addAll(getUrlList(helperName, component, readerNames));
+        }
+        return urlList;
+    }
+
+    public static List<URL> getUrlByComponentList(String helperName, List<String> components) {
+        DatasourceInfo datasourceInfo = EntityConfigUtil.getDatasourceInfo(helperName);
+        List<URL> urlList = new LinkedList<URL>();
+        for (String component : components) {
+            urlList.addAll(getUrlList(helperName, component));
+        }
+        return urlList;
+    }
     public static int loadData(URL dataUrl, String helperName, Delegator delegator, List<Object> errorMessages) throws GenericEntityException {
         return loadData(dataUrl, helperName, delegator, errorMessages, -1);
     }

Modified: ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/data/EntityDataLoadContainer.java
URL: http://svn.apache.org/viewvc/ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/data/EntityDataLoadContainer.java?rev=1172989&r1=1172988&r2=1172989&view=diff
==============================================================================
--- ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/data/EntityDataLoadContainer.java (original)
+++ ofbiz/trunk/framework/entityext/src/org/ofbiz/entityext/data/EntityDataLoadContainer.java Tue Sep 20 06:23:02 2011
@@ -22,22 +22,30 @@ import java.io.File;
 import java.net.MalformedURLException;
 import java.net.URL;
 import java.text.NumberFormat;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.TreeSet;
 
 import javolution.util.FastList;
 
+import org.ofbiz.base.component.ComponentConfig;
 import org.ofbiz.base.container.Container;
 import org.ofbiz.base.container.ContainerConfig;
 import org.ofbiz.base.container.ContainerException;
 import org.ofbiz.base.util.Debug;
 import org.ofbiz.base.util.StringUtil;
+import org.ofbiz.base.util.UtilMisc;
+import org.ofbiz.base.util.UtilProperties;
 import org.ofbiz.base.util.UtilURL;
 import org.ofbiz.base.util.UtilValidate;
 import org.ofbiz.entity.Delegator;
 import org.ofbiz.entity.DelegatorFactory;
 import org.ofbiz.entity.GenericEntityException;
+import org.ofbiz.entity.GenericValue;
+import org.ofbiz.entity.condition.EntityCondition;
+import org.ofbiz.entity.condition.EntityExpr;
+import org.ofbiz.entity.condition.EntityOperator;
 import org.ofbiz.entity.datasource.GenericHelperInfo;
 import org.ofbiz.entity.jdbc.DatabaseUtil;
 import org.ofbiz.entity.model.ModelEntity;
@@ -59,6 +67,7 @@ public class EntityDataLoadContainer imp
     protected String directory = null;
     protected List<String> files = FastList.newInstance();
     protected String component = null;
+    protected List<String> components = FastList.newInstance();
     protected boolean useDummyFks = false;
     protected boolean maintainTxs = false;
     protected boolean tryInserts = false;
@@ -194,6 +203,42 @@ public class EntityDataLoadContainer imp
      * @see org.ofbiz.base.container.Container#start()
      */
     public boolean start() throws ContainerException {
+        if("all-tenants".equals(this.overrideDelegator)) {
+            if ("N".equals(UtilProperties.getPropertyValue("general.properties", "multitenant"))) {
+                Debug.logWarning("Please enable multitenant. (e.g. general.properties --> multitenant=Y)", module);
+                return true;
+            }
+            ContainerConfig.Container cfg = ContainerConfig.getContainer("dataload-container", configFile);
+            ContainerConfig.Container.Property delegatorNameProp = cfg.getProperty("delegator-name");
+            String delegatorName = null;
+            if (delegatorNameProp == null || UtilValidate.isEmpty(delegatorNameProp.value)) {
+                throw new ContainerException("Invalid delegator-name defined in container configuration");
+            } else {
+                delegatorName = delegatorNameProp.value;
+            }
+            Delegator delegator = DelegatorFactory.getDelegator(delegatorName);
+            if (delegator == null) {
+                throw new ContainerException("Invalid delegator name!");
+            }
+            List<EntityExpr> expr = FastList.newInstance();
+            expr.add(EntityCondition.makeCondition("disabled", EntityOperator.EQUALS, "N"));
+            expr.add(EntityCondition.makeCondition("disabled", EntityOperator.EQUALS, null));
+            List<GenericValue> tenantList;
+            try {
+                tenantList = delegator.findList("Tenant", EntityCondition.makeCondition(expr, EntityOperator.OR), null, null, null, false);
+            } catch (GenericEntityException e) {
+                throw new ContainerException(e.getMessage());
+            }
+            for (GenericValue tenant : tenantList) {
+                this.overrideDelegator = delegator.getDelegatorName() + "#" + tenant.getString("tenantId");
+                loadContainer();
+            }
+        } else {
+            loadContainer();
+        }
+        return true;
+    }
+    private void loadContainer() throws ContainerException{
         ContainerConfig.Container cfg = ContainerConfig.getContainer("dataload-container", configFile);
         ContainerConfig.Container.Property delegatorNameProp = cfg.getProperty("delegator-name");
         ContainerConfig.Container.Property entityGroupNameProp = cfg.getProperty("entity-group-name");
@@ -223,7 +268,6 @@ public class EntityDataLoadContainer imp
                 readerNames = StringUtil.split(this.readers, ",");
             }
         }
-
         String delegatorNameToUse = overrideDelegator != null ? overrideDelegator : delegatorName;
         String groupNameToUse = overrideGroup != null ? overrideGroup : entityGroupName;
         Delegator delegator = DelegatorFactory.getDelegator(delegatorNameToUse);
@@ -245,7 +289,58 @@ public class EntityDataLoadContainer imp
             throw new ContainerException(e.getMessage(), e);
         }
         TreeSet<String> modelEntityNames = new TreeSet<String>(modelEntities.keySet());
-
+        // store all components
+        Collection<ComponentConfig> allComponents = ComponentConfig.getAllComponents();
+        for (ComponentConfig config : allComponents) {
+            //Debug.logInfo("- Stored component : " + config.getComponentName(), module);
+            GenericValue componentEntry = delegator.makeValue("Component");
+            componentEntry.set("componentName", config.getComponentName());
+            componentEntry.set("rootLocation", config.getRootLocation());
+            try {
+                GenericValue componentCheck = delegator.findByPrimaryKey("Component", UtilMisc.toMap("componentName", config.getComponentName()));
+                if (UtilValidate.isEmpty(componentCheck)) {
+                    componentEntry.create();
+                } else {
+                    componentEntry.store();
+                }
+            } catch (GenericEntityException e) {
+                Debug.logError(e.getMessage(), module);
+            }
+        }
+        // load specify components
+        if (UtilValidate.isNotEmpty(delegator.getDelegatorTenantId()) && "Y".equals(UtilProperties.getPropertyValue("general.properties", "multitenant"))) {
+            try {
+                List<EntityExpr> exprs = FastList.newInstance();
+                exprs.add(EntityCondition.makeCondition("rootLocation", EntityOperator.NOT_LIKE, "%hot-deploy%"));
+                EntityCondition cond = EntityCondition.makeCondition(exprs);
+                List<GenericValue> components = delegator.findList("Component", cond , null, null, null, false);
+                Debug.logInfo("===== Begin load specify components", module);
+                if (UtilValidate.isEmpty(this.component)) {
+                    for (GenericValue component : components) {
+                        this.components.add(component.getString("componentName"));
+                        //Debug.logInfo("- loaded default component : " + component.getString("componentName"), module);
+                    }
+                    Debug.logInfo("- Loaded components by default : " + components.size() + " components", module);
+                    List<GenericValue> tenantComponents = delegator.findByAnd("TenantComponent", UtilMisc.toMap("tenantId", delegator.getDelegatorTenantId()), UtilMisc.toList("sequenceNum"));
+                    for (GenericValue tenantComponent : tenantComponents) {
+                        this.components.add(tenantComponent.getString("componentName"));
+                        //Debug.logInfo("- loaded component by tenantId : " + tenantComponent.getString("tenantId") +", component : " + tenantComponent.getString("componentName"), module);
+                    }
+                    Debug.logInfo("- Loaded components by tenantId : " + delegator.getDelegatorTenantId() + ", " + tenantComponents.size() + " components", module);
+                } else {
+                    List<GenericValue> tenantComponents = delegator.findByAnd("TenantComponent", UtilMisc.toMap("tenantId", delegator.getDelegatorTenantId(), "componentName", this.component),
+                            UtilMisc.toList("sequenceNum"));
+                    for (GenericValue tenantComponent : tenantComponents) {
+                        this.components.add(tenantComponent.getString("componentName"));
+                        //Debug.logInfo("- loaded component by tenantId : " + tenantComponent.getString("tenantId") +", component : " + tenantComponent.getString("componentName"), module);
+                    }
+                    Debug.logInfo("- Loaded tenantId : " + delegator.getDelegatorTenantId() + " and component : " + this.component, module);
+                }
+                Debug.logInfo("===== Loaded : " + this.components.size() + " components", module);
+            } catch (GenericEntityException e) {
+                Debug.logError(e.getMessage(), module);
+            }
+        }
         // check for drop index/fks
         if (dropConstraints) {
             List<String> messages = FastList.newInstance();
@@ -322,13 +417,20 @@ public class EntityDataLoadContainer imp
         }
 
         // get the reader name URLs first
-        List<URL> urlList = null;
-        if (readerNames != null) {
-            urlList = EntityDataLoader.getUrlList(helperInfo.getHelperBaseName(), component, readerNames);
-        } else if (!"none".equalsIgnoreCase(this.readers)) {
-            urlList = EntityDataLoader.getUrlList(helperInfo.getHelperBaseName(), component);
+        List<URL> urlList = FastList.newInstance();
+        if (UtilValidate.isNotEmpty(this.components)) {
+            if (UtilValidate.isNotEmpty(readerNames)) {
+                urlList = EntityDataLoader.getUrlByComponentList(helperInfo.getHelperBaseName(), this.components, readerNames);
+            } else if (!"none".equalsIgnoreCase(this.readers)) {
+                urlList = EntityDataLoader.getUrlByComponentList(helperInfo.getHelperBaseName(), this.components);
+            }
+        } else {
+            if (UtilValidate.isNotEmpty(readerNames)) {
+                urlList = EntityDataLoader.getUrlList(helperInfo.getHelperBaseName(), component, readerNames);
+            } else if (!"none".equalsIgnoreCase(this.readers)) {
+                urlList = EntityDataLoader.getUrlList(helperInfo.getHelperBaseName(), component);
+            }
         }
-
         // need a list if it is empty
         if (urlList == null) {
             urlList = FastList.newInstance();
@@ -462,10 +564,7 @@ public class EntityDataLoadContainer imp
                 }
             }
         }
-
-        return true;
     }
-
     /**
      * @see org.ofbiz.base.container.Container#stop()
      */