← Back to team overview

dhis2-devs team mailing list archive

[Branch ~dhis2-devs-core/dhis2/trunk] Rev 20484: Resource tables, new solution done.

 

------------------------------------------------------------
revno: 20484
committer: Lars Helge Overland <larshelge@xxxxxxxxx>
branch nick: dhis2
timestamp: Fri 2015-10-02 19:20:28 +0200
message:
  Resource tables, new solution done.
added:
  dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/resourcetable/table/DataApprovalMinLevelResourceTable.java
modified:
  dhis-2/dhis-api/src/main/java/org/hisp/dhis/resourcetable/ResourceTableStore.java
  dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/resourcetable/DefaultResourceTableService.java
  dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/resourcetable/jdbc/JdbcResourceTableStore.java
  dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/resourcetable/table/CategoryOptionComboResourceTable.java
  dhis-2/dhis-services/dhis-service-administration/src/main/resources/META-INF/dhis/beans.xml


--
lp:dhis2
https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk

Your team DHIS 2 developers is subscribed to branch lp:dhis2.
To unsubscribe from this branch go to https://code.launchpad.net/~dhis2-devs-core/dhis2/trunk/+edit-subscription
=== modified file 'dhis-2/dhis-api/src/main/java/org/hisp/dhis/resourcetable/ResourceTableStore.java'
--- dhis-2/dhis-api/src/main/java/org/hisp/dhis/resourcetable/ResourceTableStore.java	2015-10-02 17:00:44 +0000
+++ dhis-2/dhis-api/src/main/java/org/hisp/dhis/resourcetable/ResourceTableStore.java	2015-10-02 17:20:28 +0000
@@ -29,9 +29,6 @@
  */
 
 import java.util.List;
-import java.util.Set;
-
-import org.hisp.dhis.organisationunit.OrganisationUnitLevel;
 
 /**
  * @author Lars Helge Overland
@@ -62,16 +59,4 @@
      * @param batchArgs the arguments to use for the update statement.
      */
     void batchUpdate( int columns, String tableName, List<Object[]> batchArgs );
-    
-    /**
-     * Creates and generates table.
-     */
-    void createAndPopulateDataElementCategoryOptionCombo();
-    
-    /**
-     * Creates and populates data approval minimum level table.
-     * 
-     * @param levels the organisation unit levels part of approval levels.
-     */
-    void createAndPopulateDataApprovalMinLevel( Set<OrganisationUnitLevel> levels );
 }

=== modified file 'dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/resourcetable/DefaultResourceTableService.java'
--- dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/resourcetable/DefaultResourceTableService.java	2015-10-02 17:00:44 +0000
+++ dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/resourcetable/DefaultResourceTableService.java	2015-10-02 17:20:28 +0000
@@ -31,10 +31,7 @@
 import java.util.ArrayList;
 import java.util.Collections;
 import java.util.List;
-import java.util.Set;
 
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
 import org.hisp.dhis.common.IdentifiableObjectManager;
 import org.hisp.dhis.common.comparator.IdentifiableObjectNameComparator;
 import org.hisp.dhis.dataapproval.DataApprovalLevelService;
@@ -42,7 +39,7 @@
 import org.hisp.dhis.dataelement.DataElement;
 import org.hisp.dhis.dataelement.DataElementCategory;
 import org.hisp.dhis.dataelement.DataElementCategoryCombo;
-import org.hisp.dhis.dataelement.DataElementCategoryService;
+import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
 import org.hisp.dhis.dataelement.DataElementGroupSet;
 import org.hisp.dhis.indicator.IndicatorGroupSet;
 import org.hisp.dhis.jdbc.StatementBuilder;
@@ -51,8 +48,10 @@
 import org.hisp.dhis.organisationunit.OrganisationUnitService;
 import org.hisp.dhis.period.PeriodService;
 import org.hisp.dhis.resourcetable.table.CategoryOptionComboNameResourceTable;
+import org.hisp.dhis.resourcetable.table.CategoryOptionComboResourceTable;
 import org.hisp.dhis.resourcetable.table.CategoryOptionGroupSetResourceTable;
 import org.hisp.dhis.resourcetable.table.CategoryResourceTable;
+import org.hisp.dhis.resourcetable.table.DataApprovalMinLevelResourceTable;
 import org.hisp.dhis.resourcetable.table.DataElementGroupSetResourceTable;
 import org.hisp.dhis.resourcetable.table.DataElementResourceTable;
 import org.hisp.dhis.resourcetable.table.DatePeriodResourceTable;
@@ -64,14 +63,14 @@
 import org.hisp.dhis.sqlview.SqlViewService;
 import org.springframework.transaction.annotation.Transactional;
 
+import com.google.common.collect.Lists;
+
 /**
  * @author Lars Helge Overland
  */
 public class DefaultResourceTableService
     implements ResourceTableService
 {
-    private static final Log log = LogFactory.getLog( DefaultResourceTableService.class );
-
     // -------------------------------------------------------------------------
     // Dependencies
     // -------------------------------------------------------------------------
@@ -97,13 +96,6 @@
         this.organisationUnitService = organisationUnitService;
     }
 
-    private DataElementCategoryService categoryService;
-
-    public void setCategoryService( DataElementCategoryService categoryService )
-    {
-        this.categoryService = categoryService;
-    }
-
     private PeriodService periodService;
 
     public void setPeriodService( PeriodService periodService )
@@ -160,7 +152,7 @@
     {
         resourceTableStore.generateResourceTable( new CategoryOptionGroupSetResourceTable(
             idObjectManager.getAllNoAcl( CategoryOptionGroupSet.class ),
-            statementBuilder.getColumnQuote(), categoryService.getAllDataElementCategoryOptionCombos() ) );
+            statementBuilder.getColumnQuote(), idObjectManager.getAllNoAcl( DataElementCategoryOptionCombo.class ) ) );
     }
 
     @Override
@@ -223,34 +215,25 @@
             periodService.getAllPeriods(), statementBuilder.getColumnQuote() ) );
     }
 
-    // -------------------------------------------------------------------------
-    // DataElementCategoryOptionComboTable
-    // -------------------------------------------------------------------------
-
     @Override
     @Transactional
     public void generateDataElementCategoryOptionComboTable()
     {
-        resourceTableStore.createAndPopulateDataElementCategoryOptionCombo();
-
-        log.info( "Data element category option combo table generated" );
+        resourceTableStore.generateResourceTable( new CategoryOptionComboResourceTable(
+            null, statementBuilder.getColumnQuote() ) );            
     }
 
-    // -------------------------------------------------------------------------
-    // DataApprovalMinLevelTable
-    // -------------------------------------------------------------------------
-
     @Override
     @Transactional
     public void generateDataApprovalMinLevelTable()
     {
-        Set<OrganisationUnitLevel> levels = dataApprovalLevelService.getOrganisationUnitApprovalLevels();
+        List<OrganisationUnitLevel> orgUnitLevels = Lists.newArrayList( 
+            dataApprovalLevelService.getOrganisationUnitApprovalLevels() );
         
-        if ( !levels.isEmpty() )
+        if ( orgUnitLevels.size() > 0 )
         {
-            resourceTableStore.createAndPopulateDataApprovalMinLevel( levels );
-        
-            log.info( "Data approval min level table generated" );
+            resourceTableStore.generateResourceTable( new DataApprovalMinLevelResourceTable( 
+                orgUnitLevels, statementBuilder.getColumnQuote() ) );
         }
     }
     

=== modified file 'dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/resourcetable/jdbc/JdbcResourceTableStore.java'
--- dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/resourcetable/jdbc/JdbcResourceTableStore.java	2015-10-02 17:00:44 +0000
+++ dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/resourcetable/jdbc/JdbcResourceTableStore.java	2015-10-02 17:20:28 +0000
@@ -30,16 +30,12 @@
 
 import java.util.List;
 import java.util.Optional;
-import java.util.Set;
 
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
-import org.hisp.dhis.commons.util.TextUtils;
 import org.hisp.dhis.dbms.DbmsManager;
-import org.hisp.dhis.organisationunit.OrganisationUnitLevel;
 import org.hisp.dhis.resourcetable.ResourceTable;
 import org.hisp.dhis.resourcetable.ResourceTableStore;
-import org.springframework.jdbc.BadSqlGrammarException;
 import org.springframework.jdbc.core.JdbcTemplate;
 
 /**
@@ -155,114 +151,4 @@
         
         jdbcTemplate.batchUpdate( builder.toString(), batchArgs );
     }
-    
-    // -------------------------------------------------------------------------
-    // DataElementCategoryOptionComboTable
-    // -------------------------------------------------------------------------
-
-    @Override
-    public void createAndPopulateDataElementCategoryOptionCombo()
-    {
-        try
-        {
-            jdbcTemplate.execute( "DROP TABLE IF EXISTS " + TABLE_NAME_DATA_ELEMENT_CATEGORY_OPTION_COMBO );            
-        }
-        catch ( BadSqlGrammarException ex )
-        {
-            // Do nothing, table does not exist
-        }
-        
-        final String create = "CREATE TABLE " + TABLE_NAME_DATA_ELEMENT_CATEGORY_OPTION_COMBO + " (" +
-            "dataelementid INTEGER NOT NULL, " +
-            "dataelementuid VARCHAR(11) NOT NULL, " +
-            "categoryoptioncomboid INTEGER NOT NULL, " +
-            "categoryoptioncombouid VARCHAR(11) NOT NULL)";
-
-        log.info( "Create data element category option combo SQL: " + create );
-        
-        jdbcTemplate.execute( create );
-        
-        final String sql = 
-            "insert into " + TABLE_NAME_DATA_ELEMENT_CATEGORY_OPTION_COMBO + 
-            " (dataelementid, dataelementuid, categoryoptioncomboid, categoryoptioncombouid) " +
-            "select de.dataelementid as dataelementid, de.uid as dataelementuid, " +
-            "coc.categoryoptioncomboid as categoryoptioncomboid, coc.uid as categoryoptioncombouid " +
-            "from dataelement de " +
-            "join categorycombos_optioncombos cc on de.categorycomboid = cc.categorycomboid " +
-            "join categoryoptioncombo coc on cc.categoryoptioncomboid = coc.categoryoptioncomboid";
-        
-        log.info( "Insert data element category option combo SQL: " + sql );
-        
-        jdbcTemplate.execute( sql );
-        
-        final String index = "CREATE INDEX dataelement_categoryoptioncombo ON " + 
-            TABLE_NAME_DATA_ELEMENT_CATEGORY_OPTION_COMBO + " (dataelementuid, categoryoptioncombouid)";
-        
-        log.info( "Create data element category option combo index SQL: " + index );
-
-        jdbcTemplate.execute( index );        
-    }
-
-    // -------------------------------------------------------------------------
-    // DataApprovalMinLevelTable
-    // -------------------------------------------------------------------------
-
-    @Override
-    public void createAndPopulateDataApprovalMinLevel( Set<OrganisationUnitLevel> levels )
-    {
-        try
-        {
-            jdbcTemplate.execute( "drop table if exists " + TABLE_NAME_DATA_APPROVAL_MIN_LEVEL );            
-        }
-        catch ( BadSqlGrammarException ex )
-        {
-            // Do nothing, table does not exist
-        }
-        
-        final String create = "create table " + TABLE_NAME_DATA_APPROVAL_MIN_LEVEL + "(" +
-            "datasetid integer not null, " +
-            "periodid integer not null, " +
-            "organisationunitid integer not null, " +
-            "attributeoptioncomboid integer not null, " +
-            "minlevel integer not null);";
-
-        log.info( "Create data approval min level SQL: " + create );
-        
-        jdbcTemplate.execute( create );
-        
-        String sql = 
-            "insert into " + TABLE_NAME_DATA_APPROVAL_MIN_LEVEL + 
-            " (datasetid,periodid,organisationunitid,attributeoptioncomboid,minlevel) " +
-            "select da.datasetid, da.periodid, da.organisationunitid, da.attributeoptioncomboid, dal.level as minlevel " +
-            "from dataapproval da " +
-            "inner join dataapprovallevel dal on da.dataapprovallevelid=dal.dataapprovallevelid " +
-            "where not exists ( " +
-                "select 1 from dataapproval da2 " +
-                "inner join dataapprovallevel dal2 on da2.dataapprovallevelid=dal2.dataapprovallevelid " +
-                "inner join _orgunitstructure ous2 on da2.organisationunitid=ous2.organisationunitid " +
-                "where da.datasetid=da2.datasetid and da.periodid=da2.periodid and da.attributeoptioncomboid=da2.attributeoptioncomboid " +
-                "and dal2.level < dal.level " +
-                "and ( ";
-        
-        for ( OrganisationUnitLevel level : levels )
-        {
-            sql += "da.organisationunitid = ous2.idlevel" + level.getLevel() + " or ";
-        }
-        
-        sql = TextUtils.removeLastOr( sql ) + ") )";
-        
-        log.info( "Insert data approval min level SQL: " + sql );
-
-        jdbcTemplate.execute( sql );
-        
-        final String index = 
-            "create index in_dataapprovalminlevel_datasetid on _dataapprovalminlevel(datasetid);" +
-            "create index in_dataapprovalminlevel_periodid on _dataapprovalminlevel(periodid);" +
-            "create index in_dataapprovalminlevel_organisationunitid on _dataapprovalminlevel(organisationunitid);" +
-            "create index in_dataapprovalminlevel_attributeoptioncomboid on _dataapprovalminlevel(attributeoptioncomboid);";
-        
-        log.info( "Create data approval min level index SQL: " + index );
-        
-        jdbcTemplate.execute( index );
-    }
 }

=== modified file 'dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/resourcetable/table/CategoryOptionComboResourceTable.java'
--- dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/resourcetable/table/CategoryOptionComboResourceTable.java	2015-10-02 17:00:44 +0000
+++ dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/resourcetable/table/CategoryOptionComboResourceTable.java	2015-10-02 17:20:28 +0000
@@ -1,15 +1,50 @@
 package org.hisp.dhis.resourcetable.table;
 
+/*
+ * Copyright (c) 2004-2015, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
 import java.util.List;
 import java.util.Optional;
 
 import org.hisp.dhis.dataelement.DataElementCategoryOptionCombo;
 import org.hisp.dhis.resourcetable.ResourceTable;
 
+/**
+ * @author Lars Helge Overland
+ */
 public class CategoryOptionComboResourceTable
     extends ResourceTable<DataElementCategoryOptionCombo>
 {
-
+    public CategoryOptionComboResourceTable( List<DataElementCategoryOptionCombo> objects, String columnQuote )
+    {
+        super( objects, columnQuote );
+    }
+    
     @Override
     public String getTableName()
     {

=== added file 'dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/resourcetable/table/DataApprovalMinLevelResourceTable.java'
--- dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/resourcetable/table/DataApprovalMinLevelResourceTable.java	1970-01-01 00:00:00 +0000
+++ dhis-2/dhis-services/dhis-service-administration/src/main/java/org/hisp/dhis/resourcetable/table/DataApprovalMinLevelResourceTable.java	2015-10-02 17:20:28 +0000
@@ -0,0 +1,112 @@
+package org.hisp.dhis.resourcetable.table;
+
+/*
+ * Copyright (c) 2004-2015, University of Oslo
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright notice, this
+ * list of conditions and the following disclaimer.
+ *
+ * Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * Neither the name of the HISP project nor the names of its contributors may
+ * be used to endorse or promote products derived from this software without
+ * specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+import java.util.List;
+import java.util.Optional;
+
+import org.hisp.dhis.commons.util.TextUtils;
+import org.hisp.dhis.organisationunit.OrganisationUnitLevel;
+import org.hisp.dhis.resourcetable.ResourceTable;
+
+/**
+ * @author Lars Helge Overland
+ */
+public class DataApprovalMinLevelResourceTable
+    extends ResourceTable<OrganisationUnitLevel>
+{
+    public DataApprovalMinLevelResourceTable( List<OrganisationUnitLevel> objects, String columnQuote )
+    {
+        super( objects, columnQuote );
+    }
+
+    @Override
+    public String getTableName()
+    {
+        return "_dataapprovalminlevel";
+    }
+
+    @Override
+    public String getCreateTempTableStatement()
+    {
+        String sql = "create table " + getTempTableName() + "(" +
+            "datasetid integer not null, " +
+            "periodid integer not null, " +
+            "organisationunitid integer not null, " +
+            "attributeoptioncomboid integer not null, " +
+            "minlevel integer not null);";
+
+        return sql;
+    }
+
+    @Override
+    public Optional<String> getPopulateTempTableStatement()
+    {
+        String sql = 
+            "insert into " + getTempTableName() + 
+            " (datasetid,periodid,organisationunitid,attributeoptioncomboid,minlevel) " +
+            "select da.datasetid, da.periodid, da.organisationunitid, da.attributeoptioncomboid, dal.level as minlevel " +
+            "from dataapproval da " +
+            "inner join dataapprovallevel dal on da.dataapprovallevelid=dal.dataapprovallevelid " +
+            "where not exists ( " +
+                "select 1 from dataapproval da2 " +
+                "inner join dataapprovallevel dal2 on da2.dataapprovallevelid=dal2.dataapprovallevelid " +
+                "inner join _orgunitstructure ous2 on da2.organisationunitid=ous2.organisationunitid " +
+                "where da.datasetid=da2.datasetid and da.periodid=da2.periodid and da.attributeoptioncomboid=da2.attributeoptioncomboid " +
+                "and dal2.level < dal.level " +
+                "and ( ";
+        
+        for ( OrganisationUnitLevel level : objects )
+        {
+            sql += "da.organisationunitid = ous2.idlevel" + level.getLevel() + " or ";
+        }
+        
+        sql = TextUtils.removeLastOr( sql ) + ") )";
+        
+        return Optional.of( sql );
+    }
+
+    @Override
+    public Optional<List<Object[]>> getPopulateTempTableContent()
+    {
+        return Optional.empty();
+    }
+
+    @Override
+    public Optional<String> getCreateIndexStatement()
+    {
+        String sql = 
+            "create index in_dataapprovalminlevel_datasetid_" + getRandomSuffix() + " on " + getTempTableName() + "(datasetid);" +
+            "create index in_dataapprovalminlevel_periodid_" + getRandomSuffix() + " on " + getTempTableName() + "(periodid);" +
+            "create index in_dataapprovalminlevel_organisationunitid_" + getRandomSuffix() + " on " + getTempTableName() + "(organisationunitid);" +
+            "create index in_dataapprovalminlevel_attributeoptioncomboid_" + getRandomSuffix() + " on " + getTempTableName() + "(attributeoptioncomboid);";
+        
+        return Optional.of( sql );        
+    }
+}

=== modified file 'dhis-2/dhis-services/dhis-service-administration/src/main/resources/META-INF/dhis/beans.xml'
--- dhis-2/dhis-services/dhis-service-administration/src/main/resources/META-INF/dhis/beans.xml	2015-10-02 17:00:44 +0000
+++ dhis-2/dhis-services/dhis-service-administration/src/main/resources/META-INF/dhis/beans.xml	2015-10-02 17:20:28 +0000
@@ -13,7 +13,6 @@
     <property name="resourceTableStore" ref="org.hisp.dhis.resourcetable.ResourceTableStore" />
     <property name="idObjectManager" ref="org.hisp.dhis.common.IdentifiableObjectManager" />
     <property name="organisationUnitService" ref="org.hisp.dhis.organisationunit.OrganisationUnitService" />
-    <property name="categoryService" ref="org.hisp.dhis.dataelement.DataElementCategoryService" />
     <property name="periodService" ref="org.hisp.dhis.period.PeriodService" />
     <property name="sqlViewService" ref="org.hisp.dhis.sqlview.SqlViewService" />
     <property name="dataApprovalLevelService" ref="org.hisp.dhis.dataapproval.DataApprovalLevelService" />