// $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
\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
- public static final SingleTermUpdater NewInstance(String stepName, UUID uuidTerm, String description, String label, String abbrev, String dtype, Integer orderIndex, UUID uuidVocabulary){\r
- return new SingleTermUpdater(stepName, uuidTerm, description, label, abbrev, dtype, orderIndex, uuidVocabulary);\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, 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 ICdmDataSource datasource;\r
-// private IProgressMonitor monitor;\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 Integer orderIndex;\r
- \r
- \r
-\r
- private SingleTermUpdater(String stepName, UUID uuidTerm, String description, String label, String abbrev, String dtype, Integer orderIndex, UUID uuidVocabulary) {\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.datasource = datasource;\r
-// this.monitor = monitor;\r
this.description = description;\r
this.dtype = dtype;\r
this.label = label;\r
- this.orderIndex = orderIndex;\r
+ this.isOrdered = isOrdered;\r
this.uuidTerm = uuidTerm;\r
this.uuidVocabulary = uuidVocabulary;\r
+ this.uuidAfterTerm = uuidAfterTerm;\r
+ this.uuidLanguage = uuidLanguage;\r
}\r
\r
-\r
-\r
- public boolean 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 true;\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
}else{\r
String warning = "Vocabulary ( "+ uuidVocabulary +" ) for term does not exist!";\r
monitor.warning(warning);\r
- return false;\r
+ return null;\r
}\r
- \r
- int termId;\r
- String sqlMaxId = " SELECT max(id)+1 as maxId FROM DefinedTermBase";\r
+\r
+ Integer termId;\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
}else{\r
String warning = "No defined terms do exist yet. Can't update terms!";\r
monitor.warning(warning);\r
- return false;\r
+ return null;\r
}\r
- \r
+\r
String id = Integer.toString(termId);\r
- String created = "2010-09-01 10:15:00";\r
+ String created = getNowString();\r
String defaultColor = "null";\r
- String protectedTitleCache = "b'0'";\r
+ String protectedTitleCache = getBoolean(false, datasource);\r
+ String orderIndex;\r
+ if (isOrdered){\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
+ 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 = 'e9f8cdb7-6819-44e8-95d3-e2d0690c3523'";\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
- return false;\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
}else{\r
String warning = "No representations do exist yet. Can't update terms!";\r
monitor.warning(warning);\r
- return false;\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
- \r
-// -- representation\r
-// INSERT INTO Representation (id, created, uuid, text, abbreviatedlabel, label, language_id) \r
-// SELECT ( @repId := max(id)+1 ) AS maxId ,'2010-06-01 18:49:07','fadb1730-9936-44e7-8911-884a84662b08', 'Google Earth','Google','Google Earth', @langId\r
-// FROM Representation;\r
-// ;\r
- \r
- //\r
-// -- representation\r
-// INSERT INTO Representation (id, created, uuid, text, abbreviatedlabel, label, language_id) \r
-// SELECT ( @repId := max(id)+1 ) AS maxId ,'2010-06-01 18:49:07','fadb1730-9936-44e7-8911-884a84662b08', 'Google Earth','Google','Google Earth', @langId\r
-// FROM Representation;\r
-// ;\r
-\r
- String sqlInsertMN = "INSERT INTO DefinedTermBase_Representation (DefinedTermBase_id, representations_id) " + \r
- " VALUES ("+ termId +"," +repId+ " )"; \r
- \r
- datasource.executeUpdate(sqlInsertMN);\r
- \r
-// -- defTerm <-> representation\r
-// INSERT INTO DefinedTermBase_Representation (DefinedTermBase_id, representations_id) \r
-// VALUES (@defTermId,@repId);\r
-// \r
- return true;\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
+\r
+ private String nullSafeStr(String str) {\r
+ if (str == null){\r
+ return " NULL ";\r
+ }else{\r
+ return "'" + str + "'";\r
+ }\r
+ }\r
+\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 " + 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
+ " supportstaxoninteraction = " + getBoolean(false, datasource) + ", " +\r
+ " supportstextdata = " + getBoolean(true, datasource) + " " +\r
+ " WHERE id = " + termId;\r
+ datasource.executeUpdate(sqlUpdate);\r
+ }\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
+ /**\r
+ * @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, CaseType caseType) throws SQLException {\r
+ ResultSet rs;\r
+ Integer intOrderIndex = null;\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 %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
+ }\r
+ if (intOrderIndex == null){\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
+ intOrderIndex =0;\r
+ }\r
+ }\r
+\r
+ return intOrderIndex.toString();\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