merge-update from trunk
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / database / update / SingleTermUpdater.java
index e34d79614afc4d2db3ebf82af243448e20cbd3b9..47036f8845c5ec20a6468053dd175762a53f008b 100644 (file)
@@ -1,9 +1,9 @@
 // $Id$\r
 /**\r
 * Copyright (C) 2009 EDIT\r
-* European Distributed Institute of Taxonomy \r
+* European Distributed Institute of Taxonomy\r
 * http://www.e-taxonomy.eu\r
-* \r
+*\r
 * The contents of this file are subject to the Mozilla Public License Version 1.1\r
 * See LICENSE.TXT at the top of this package for the full license terms.\r
 */\r
@@ -15,36 +15,60 @@ import java.util.UUID;
 \r
 import org.apache.log4j.Logger;\r
 \r
-import eu.etaxonomy.cdm.common.IProgressMonitor;\r
+import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;\r
 import eu.etaxonomy.cdm.database.ICdmDataSource;\r
+import eu.etaxonomy.cdm.model.common.TermType;\r
 import eu.etaxonomy.cdm.model.description.Feature;\r
+import eu.etaxonomy.cdm.model.name.Rank;\r
+import eu.etaxonomy.cdm.model.name.RankClass;\r
 \r
 /**\r
+ * Creates a new term if a term with the same given uuid does not exist yet\r
  * @author a.mueller\r
  * @date 10.09.2010\r
  *\r
  */\r
-public class SingleTermUpdater extends SchemaUpdaterStepBase {\r
+public class SingleTermUpdater extends SchemaUpdaterStepBase<SingleTermUpdater> implements ITermUpdaterStep{\r
        @SuppressWarnings("unused")\r
        private static final Logger logger = Logger.getLogger(SingleTermUpdater.class);\r
-       \r
+\r
+       /**\r
+        * @Deprecated use {@link #NewInstance(String, TermType, UUID, String, String, String, String, UUID, UUID, boolean, UUID)} instead\r
+        */\r
+       @Deprecated\r
        public static final SingleTermUpdater NewInstance(String stepName, UUID uuidTerm, String description,  String label, String abbrev, String dtype, UUID uuidVocabulary, UUID uuidLanguage, boolean isOrdered, UUID uuidAfterTerm){\r
-               return new SingleTermUpdater(stepName, uuidTerm, description, label, abbrev, dtype, uuidVocabulary, uuidLanguage, isOrdered, uuidAfterTerm);    \r
+               return new SingleTermUpdater(stepName, null, uuidTerm, null, description, label, abbrev, dtype, uuidVocabulary, uuidLanguage, isOrdered, uuidAfterTerm);\r
+       }\r
+\r
+       public static final SingleTermUpdater NewInstance(String stepName, TermType termType, UUID uuidTerm, String idInVocabulary, String description,  String label, String abbrev, String dtype, UUID uuidVocabulary, UUID uuidLanguage, boolean isOrdered, UUID uuidAfterTerm){\r
+               return new SingleTermUpdater(stepName, termType, uuidTerm, idInVocabulary, description, label, abbrev, dtype, uuidVocabulary, uuidLanguage, isOrdered, uuidAfterTerm);\r
        }\r
-       \r
-       private UUID uuidTerm ;\r
-       private String description;\r
-       private String label;\r
-       private String abbrev;\r
-       private String dtype;\r
-       private UUID uuidVocabulary;\r
-       private boolean isOrdered;\r
-       private UUID uuidAfterTerm;\r
-       private UUID uuidLanguage;\r
-       \r
-\r
-       private SingleTermUpdater(String stepName, UUID uuidTerm, String description, String label, String abbrev, String dtype, UUID uuidVocabulary, UUID uuidLanguage, boolean isOrdered, UUID uuidAfterTerm) {\r
+\r
+\r
+       private final UUID uuidTerm ;\r
+       private final String description;\r
+       private final String label;\r
+       private final String abbrev;\r
+       private final String dtype;\r
+       private final UUID uuidVocabulary;\r
+       private final boolean isOrdered;\r
+       private final UUID uuidAfterTerm;\r
+       private final UUID uuidLanguage;\r
+       private String reverseDescription;\r
+       private String reverseLabel;\r
+       private String reverseAbbrev;\r
+       private RankClass rankClass;\r
+       private final TermType termType;\r
+       private final String idInVocabulary;\r
+       private boolean symmetric = false;\r
+       private boolean transitive = false;\r
+\r
+\r
+\r
+       private SingleTermUpdater(String stepName, TermType termType, UUID uuidTerm, String idInVocabulary, String description, String label, String abbrev, String dtype, UUID uuidVocabulary, UUID uuidLanguage, boolean isOrdered, UUID uuidAfterTerm) {\r
                super(stepName);\r
+               this.termType = termType;\r
+               this.idInVocabulary = idInVocabulary;\r
                this.abbrev = abbrev;\r
                this.description = description;\r
                this.dtype = dtype;\r
@@ -56,19 +80,22 @@ public class SingleTermUpdater extends SchemaUpdaterStepBase {
                this.uuidLanguage = uuidLanguage;\r
        }\r
 \r
-\r
-\r
-       public Integer invoke(ICdmDataSource datasource, IProgressMonitor monitor) throws SQLException{\r
-               String sqlCheckTermExists = " SELECT count(*) as n FROM DefinedTermBase WHERE uuid = '" + uuidTerm + "'";\r
+       @Override\r
+       public Integer invoke(ICdmDataSource datasource, IProgressMonitor monitor, CaseType caseType) throws SQLException{\r
+               String sqlCheckTermExists = " SELECT count(*) as n " +\r
+                               " FROM " + caseType.transformTo("DefinedTermBase") +\r
+                               " WHERE uuid = '" + uuidTerm + "'";\r
                Long n = (Long)datasource.getSingleValue(sqlCheckTermExists);\r
                if (n != 0){\r
                        monitor.warning("Term already exists: " + label + "(" + uuidTerm + ")");\r
-                       return null;\r
+                       return -1;\r
                }\r
-               \r
+\r
                //vocabulary id\r
                int vocId;\r
-               String sqlVocId = " SELECT id FROM TermVocabulary WHERE uuid = '" + uuidVocabulary + "'";\r
+               String sqlVocId = " SELECT id " +\r
+                               " FROM  " + caseType.transformTo("TermVocabulary") +\r
+                               " WHERE uuid = '" + uuidVocabulary + "'";\r
                ResultSet rs = datasource.executeQuery(sqlVocId);\r
                if (rs.next()){\r
                        vocId = rs.getInt("id");\r
@@ -77,9 +104,9 @@ public class SingleTermUpdater extends SchemaUpdaterStepBase {
                        monitor.warning(warning);\r
                        return null;\r
                }\r
-               \r
+\r
                Integer termId;\r
-               String sqlMaxId = " SELECT max(id)+1 as maxId FROM DefinedTermBase";\r
+               String sqlMaxId = " SELECT max(id)+1 as maxId FROM " + caseType.transformTo("DefinedTermBase");\r
                rs = datasource.executeQuery(sqlMaxId);\r
                if (rs.next()){\r
                        termId = rs.getInt("maxId");\r
@@ -88,45 +115,43 @@ public class SingleTermUpdater extends SchemaUpdaterStepBase {
                        monitor.warning(warning);\r
                        return null;\r
                }\r
-               \r
+\r
                String id = Integer.toString(termId);\r
-               String created = "2010-09-16 10:15:00";\r
+               String created = getNowString();\r
                String defaultColor = "null";\r
                String protectedTitleCache = getBoolean(false, datasource);\r
                String orderIndex;\r
                if (isOrdered){\r
-                       orderIndex = getOrderIndex(datasource, vocId, monitor);\r
+                       orderIndex = getOrderIndex(datasource, vocId, monitor, caseType);\r
                }else{\r
                        orderIndex = "null";\r
                }\r
                String titleCache = label != null ? label : (abbrev != null ? abbrev : description );\r
-               String sqlInsertTerm = " INSERT INTO DefinedTermBase (DTYPE, id, uuid, created, protectedtitlecache, titleCache, orderindex, defaultcolor, vocabulary_id)" +\r
-                               "VALUES ('" + dtype + "', " + id + ", '" + uuidTerm + "', '" + created + "', " + protectedTitleCache + ", '" + titleCache + "', " + orderIndex + ", " + defaultColor + ", " + vocId + ")"; \r
-               datasource.executeUpdate(sqlInsertTerm);\r
-               \r
-               updateFeatureTerms(termId, datasource, monitor);\r
-               \r
+               String idInVocStr = idInVocabulary == null ? "NULL" : "'" + idInVocabulary + "'";\r
+               String sqlInsertTerm = " INSERT INTO @@DefinedTermBase@@ (DTYPE, id, uuid, created, termtype, idInVocabulary, protectedtitlecache, titleCache, orderindex, defaultcolor, vocabulary_id)" +\r
+                               "VALUES ('" + dtype + "', " + id + ", '" + uuidTerm + "', '" + created + "', '" + termType.getKey() + "', " + idInVocStr +  ", " + protectedTitleCache + ", '" + titleCache + "', " + orderIndex + ", " + defaultColor + ", " + vocId + ")";\r
+\r
+               datasource.executeUpdate(caseType.replaceTableNames(sqlInsertTerm));\r
+\r
+               updateFeatureTerms(termId, datasource, monitor, caseType);\r
+               updateRelationshipTerms(termId, datasource, monitor, caseType);\r
+               updateRanks(termId, datasource, monitor, caseType);\r
+\r
 //\r
-//             INSERT INTO DefinedTermBase (DTYPE, id, uuid, created, protectedtitlecache, titleCache, orderindex, defaultcolor, vocabulary_id) \r
+//             INSERT INTO DefinedTermBase (DTYPE, id, uuid, created, protectedtitlecache, titleCache, orderindex, defaultcolor, vocabulary_id)\r
 //             SELECT 'ReferenceSystem' ,  (@defTermId := max(id)+1)  as maxId , '1bb67042-2814-4b09-9e76-c8c1e68aa281', '2010-06-01 10:15:00', b'0', 'Google Earth', null, null, @refSysVocId\r
 //             FROM DefinedTermBase ;\r
 //\r
 \r
                //language id\r
-               int langId;\r
-               String sqlLangId = " SELECT id FROM DefinedTermBase WHERE uuid = '" + uuidLanguage + "'";\r
-               rs = datasource.executeQuery(sqlLangId);\r
-               if (rs.next()){\r
-                       langId = rs.getInt("id");\r
-               }else{\r
-                       String warning = "Term for default language (English) not  does not exist!";\r
-                       monitor.warning(warning);\r
+               Integer langId = getLanguageId(uuidLanguage, datasource, monitor, caseType);\r
+               if (langId == null){\r
                        return null;\r
                }\r
-               \r
+\r
                //representation\r
                int repId;\r
-               sqlMaxId = " SELECT max(id)+1 as maxId FROM Representation";\r
+               sqlMaxId = " SELECT max(id)+1 as maxId FROM " + caseType.transformTo("Representation");\r
                rs = datasource.executeQuery(sqlMaxId);\r
                if (rs.next()){\r
                        repId = rs.getInt("maxId");\r
@@ -135,28 +160,51 @@ public class SingleTermUpdater extends SchemaUpdaterStepBase {
                        monitor.warning(warning);\r
                        return null;\r
                }\r
-               \r
+\r
+               //standard representation\r
                UUID uuidRepresentation = UUID.randomUUID();\r
-               String sqlInsertRepresentation = " INSERT INTO Representation (id, created, uuid, text, abbreviatedlabel, label, language_id) " +\r
-                               "VALUES (" + repId + ", '" + created + "', '" + uuidRepresentation + "', '" + description +  "', '" + label +  "',  '" + abbrev +  "', " + langId + ")"; \r
-               \r
-               datasource.executeUpdate(sqlInsertRepresentation);\r
-               \r
-               String sqlInsertMN = "INSERT INTO DefinedTermBase_Representation (DefinedTermBase_id, representations_id) " + \r
-                               " VALUES ("+ termId +"," +repId+ " )";          \r
-               \r
-               datasource.executeUpdate(sqlInsertMN);\r
-               \r
+               String sqlInsertRepresentation = " INSERT INTO @@Representation@@ (id, created, uuid, text, label, abbreviatedlabel, language_id) " +\r
+                               "VALUES (" + repId + ", '" + created + "', '" + uuidRepresentation + "', " + nullSafeStr(description) +  ", " +nullSafeStr( label) +  ", " + nullSafeStr(abbrev) +  ", " + langId + ")";\r
+\r
+               datasource.executeUpdate(caseType.replaceTableNames(sqlInsertRepresentation));\r
+\r
+               String sqlInsertMN = "INSERT INTO @@DefinedTermBase_Representation@@ (DefinedTermBase_id, representations_id) " +\r
+                               " VALUES ("+ termId +"," +repId+ " )";\r
+\r
+               datasource.executeUpdate(caseType.replaceTableNames(sqlInsertMN));\r
+\r
+               //reverse representation\r
+               if (hasReverseRepresentation()){\r
+                       int reverseRepId = repId + 1;\r
+                       UUID uuidReverseRepresentation = UUID.randomUUID();\r
+                       String sqlInsertReverseRepresentation = " INSERT INTO @@Representation@@ (id, created, uuid, text, label, abbreviatedlabel, language_id) " +\r
+                                       "VALUES (" + reverseRepId + ", '" + created + "', '" + uuidReverseRepresentation + "', " + nullSafeStr(reverseDescription) +  ", " + nullSafeStr(reverseLabel) +  ",  " + nullSafeStr(reverseAbbrev) +  ", " + langId + ")";\r
+\r
+                       datasource.executeUpdate(caseType.replaceTableNames(sqlInsertReverseRepresentation));\r
+\r
+                       String sqlReverseInsertMN = "INSERT INTO @@RelationshipTermBase_inverseRepresentation@@ (DefinedTermBase_id, inverserepresentations_id) " +\r
+                                       " VALUES ("+ termId +"," +reverseRepId+ " )";\r
+\r
+                       datasource.executeUpdate(caseType.replaceTableNames(sqlReverseInsertMN));\r
+               }\r
+\r
                return termId;\r
        }\r
 \r
+       private String nullSafeStr(String str) {\r
+               if (str == null){\r
+                       return " NULL ";\r
+               }else{\r
+                       return "'" + str + "'";\r
+               }\r
+       }\r
 \r
-\r
-       private void updateFeatureTerms(Integer termId, ICdmDataSource datasource, IProgressMonitor monitor) {\r
+       private void updateFeatureTerms(Integer termId, ICdmDataSource datasource, IProgressMonitor monitor, CaseType caseType) throws SQLException {\r
                if (dtype.equals(Feature.class.getSimpleName())){\r
-                       String sqlUpdate = "UPDATE DefinedTermBase SET " + \r
-                               " supportscategoricaldata = " + getBoolean(false, datasource) + ", " + \r
-                               " supportscommontaxonname = " + getBoolean(false, datasource) + ", " + \r
+                       String sqlUpdate = "UPDATE  " + caseType.transformTo("DefinedTermBase") +\r
+                               " SET " +\r
+                               " supportscategoricaldata = " + getBoolean(false, datasource) + ", " +\r
+                               " supportscommontaxonname = " + getBoolean(false, datasource) + ", " +\r
                                " supportsdistribution = " + getBoolean(false, datasource) + ", " +\r
                                " supportsindividualassociation = " + getBoolean(false, datasource) + ", " +\r
                                " supportsquantitativedata = " + getBoolean(false, datasource) + ", " +\r
@@ -167,6 +215,30 @@ public class SingleTermUpdater extends SchemaUpdaterStepBase {
                }\r
        }\r
 \r
+       private void updateRelationshipTerms(Integer termId, ICdmDataSource datasource, IProgressMonitor monitor, CaseType caseType) throws SQLException {\r
+               if (dtype.contains("Relationship")){\r
+                       String sqlUpdate = "UPDATE "  + caseType.transformTo("DefinedTermBase") +\r
+                               " SET " +\r
+                               " symmetrical = " + getBoolean(symmetric, datasource) + ", " +\r
+                               " transitive = " + getBoolean(transitive, datasource) + " " +\r
+                               " WHERE id = " + termId;\r
+                       datasource.executeUpdate(sqlUpdate);\r
+               }\r
+       }\r
+\r
+       private void updateRanks(Integer termId, ICdmDataSource datasource, IProgressMonitor monitor, CaseType caseType) throws SQLException {\r
+               if (dtype.equals(Rank.class.getSimpleName())){\r
+                       String sqlUpdate = "UPDATE " + caseType.transformTo("DefinedTermBase") +\r
+                               " SET rankClass = '" + rankClass.getKey() + "'" +\r
+                               " WHERE id = " + termId;\r
+                       datasource.executeUpdate(sqlUpdate);\r
+               }\r
+       }\r
+\r
+       public SingleTermUpdater setRankClass(RankClass rankClass) {\r
+               this.rankClass = rankClass;\r
+               return this;\r
+       }\r
 \r
 \r
 \r
@@ -174,44 +246,61 @@ public class SingleTermUpdater extends SchemaUpdaterStepBase {
         * @param datasource\r
         * @param vocId\r
         * @param monitor\r
+        * @param caseType\r
         * @return\r
         * @throws SQLException\r
         */\r
-       private String getOrderIndex(ICdmDataSource datasource, int vocId, IProgressMonitor monitor) throws SQLException {\r
+       private String getOrderIndex(ICdmDataSource datasource, int vocId, IProgressMonitor monitor, CaseType caseType) throws SQLException {\r
                ResultSet rs;\r
                Integer intOrderIndex = null;\r
-               String sqlOrderIndex = " SELECT orderindex FROM DefinedTermBase WHERE uuid = '"+uuidAfterTerm+"' AND vocabulary_id = "+vocId+"";\r
+               if (uuidAfterTerm == null){\r
+                       return "1";\r
+               }\r
+               String sqlOrderIndex = " SELECT orderindex FROM %s WHERE uuid = '%s' AND vocabulary_id = %d ";\r
+               sqlOrderIndex = String.format(sqlOrderIndex, caseType.transformTo("DefinedTermBase"), uuidAfterTerm.toString(), vocId);\r
                rs = datasource.executeQuery(sqlOrderIndex);\r
                if (rs.next()){\r
                        intOrderIndex = rs.getInt("orderindex") + 1;\r
-                       \r
-                       String sqlUpdateLowerTerms = "UPDATE DefinedTermBase SET orderindex = orderindex + 1 WHERE vocabulary_id = " + vocId+ " AND orderindex >= " + intOrderIndex;\r
+\r
+                       String sqlUpdateLowerTerms = "UPDATE %s SET orderindex = orderindex + 1 WHERE vocabulary_id = %d AND orderindex >= %d ";\r
+                       sqlUpdateLowerTerms = String.format(sqlUpdateLowerTerms, caseType.transformTo("DefinedTermBase"), vocId, intOrderIndex );\r
                        datasource.executeUpdate(sqlUpdateLowerTerms);\r
                }else{\r
                        String warning = "The previous term has not been found in vocabulary. Put term to the end";\r
                        monitor.warning(warning);\r
-                       return "null";\r
                }\r
                if (intOrderIndex == null){\r
-                       String sqlMaxOrderIndex = " SELECT max(orderindex) FROM DefinedTermBase WHERE vocabulary_id = " + vocId + "";\r
+                       String sqlMaxOrderIndex = " SELECT max(orderindex) FROM %s WHERE vocabulary_id = %d";\r
+                       sqlMaxOrderIndex = String.format(sqlMaxOrderIndex, caseType.transformTo("DefinedTermBase"), vocId);\r
                        intOrderIndex = (Integer)datasource.getSingleValue(sqlMaxOrderIndex);\r
                        if (intOrderIndex != null){\r
                                intOrderIndex++;\r
                        }else{\r
                                String warning = "No term was found in vocabulary or vocabulary does not exist. Use order index '0'.";\r
                                monitor.warning(warning);\r
-                               return "0";\r
+                               intOrderIndex =0;\r
                        }\r
                }\r
-               \r
+\r
                return intOrderIndex.toString();\r
-//                     -- absence term max orderindex\r
-//                     SELECT (@maxAbsenceOrderIndex := max(orderindex)) AS b FROM DefinedTermBase WHERE DTYPE = 'AbsenceTerm';\r
-//\r
-//                     -- native reported in error\r
-//                     SELECT (@presenceOrderIndex := orderindex) AS a FROM DefinedTermBase WHERE uuid = '4ba212ef-041e-418d-9d43-2ebb191b61d8';\r
-//                     UPDATE DefinedTermBase SET uuid = '61cee840-801e-41d8-bead-015ad866c2f1', DTYPE = 'AbsenceTerm', vocabulary_id = 18, orderindex = @maxAbsenceOrderIndex + 1 WHERE uuid = '4ba212ef-041e-418d-9d43-2ebb191b61d8';\r
-//                     UPDATE DefinedTermBase SET orderindex = orderindex -1 WHERE DTYPE = 'PresenceTerm' AND orderindex > @presenceOrderIndex ;\r
        }\r
-       \r
+\r
+\r
+       private boolean hasReverseRepresentation() {\r
+               return  reverseLabel != null ||  reverseDescription != null ||  reverseAbbrev != null;\r
+       }\r
+\r
+       public SingleTermUpdater setReverseRepresentation(String reverseDescription, String reverseLabel, String reverseAbbrev) {\r
+               this.reverseLabel = reverseLabel;\r
+               this.reverseDescription = reverseDescription;\r
+               this.reverseAbbrev = reverseAbbrev;\r
+               return this;\r
+       }\r
+\r
+       public SingleTermUpdater setSymmetricTransitiv(boolean symmetric, boolean transitive){\r
+               this.symmetric = symmetric;\r
+               this.transitive = transitive;\r
+               return this;\r
+       }\r
+\r
 }\r