54fb1df6d7980e90671a0cf26f65a79768f99f80
[cdmlib.git] / cdmlib-persistence / src / main / java / eu / etaxonomy / cdm / database / update / SingleTermUpdater.java
1 // $Id$
2 /**
3 * Copyright (C) 2009 EDIT
4 * European Distributed Institute of Taxonomy
5 * http://www.e-taxonomy.eu
6 *
7 * The contents of this file are subject to the Mozilla Public License Version 1.1
8 * See LICENSE.TXT at the top of this package for the full license terms.
9 */
10 package eu.etaxonomy.cdm.database.update;
11
12 import java.sql.ResultSet;
13 import java.sql.SQLException;
14 import java.util.UUID;
15
16 import org.apache.log4j.Logger;
17
18 import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
19 import eu.etaxonomy.cdm.database.ICdmDataSource;
20 import eu.etaxonomy.cdm.model.common.TermType;
21 import eu.etaxonomy.cdm.model.description.Feature;
22 import eu.etaxonomy.cdm.model.name.Rank;
23 import eu.etaxonomy.cdm.model.name.RankClass;
24
25 /**
26 * Creates a new term if a term with the same given uuid does not exist yet
27 * @author a.mueller
28 * @date 10.09.2010
29 *
30 */
31 public class SingleTermUpdater extends SchemaUpdaterStepBase<SingleTermUpdater> implements ITermUpdaterStep{
32 @SuppressWarnings("unused")
33 private static final Logger logger = Logger.getLogger(SingleTermUpdater.class);
34
35 /**
36 * @Deprecated use {@link #NewInstance(String, TermType, UUID, String, String, String, String, UUID, UUID, boolean, UUID)} instead
37 */
38 @Deprecated
39 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){
40 return new SingleTermUpdater(stepName, null, uuidTerm, null, description, label, abbrev, dtype, uuidVocabulary, uuidLanguage, isOrdered, uuidAfterTerm);
41 }
42
43 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){
44 return new SingleTermUpdater(stepName, termType, uuidTerm, idInVocabulary, description, label, abbrev, dtype, uuidVocabulary, uuidLanguage, isOrdered, uuidAfterTerm);
45 }
46
47
48 private UUID uuidTerm ;
49 private String description;
50 private String label;
51 private String abbrev;
52 private String dtype;
53 private UUID uuidVocabulary;
54 private boolean isOrdered;
55 private UUID uuidAfterTerm;
56 private UUID uuidLanguage;
57 private String reverseDescription;
58 private String reverseLabel;
59 private String reverseAbbrev;
60 private RankClass rankClass;
61 private TermType termType;
62 private String idInVocabulary;
63 private boolean symmetric = false;
64 private boolean transitive = false;
65
66
67
68 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) {
69 super(stepName);
70 this.termType = termType;
71 this.idInVocabulary = idInVocabulary;
72 this.abbrev = abbrev;
73 this.description = description;
74 this.dtype = dtype;
75 this.label = label;
76 this.isOrdered = isOrdered;
77 this.uuidTerm = uuidTerm;
78 this.uuidVocabulary = uuidVocabulary;
79 this.uuidAfterTerm = uuidAfterTerm;
80 this.uuidLanguage = uuidLanguage;
81 }
82
83 @Override
84 public Integer invoke(ICdmDataSource datasource, IProgressMonitor monitor) throws SQLException{
85 String sqlCheckTermExists = " SELECT count(*) as n FROM DefinedTermBase WHERE uuid = '" + uuidTerm + "'";
86 Long n = (Long)datasource.getSingleValue(sqlCheckTermExists);
87 if (n != 0){
88 monitor.warning("Term already exists: " + label + "(" + uuidTerm + ")");
89 return -1;
90 }
91
92 //vocabulary id
93 int vocId;
94 String sqlVocId = " SELECT id FROM TermVocabulary WHERE uuid = '" + uuidVocabulary + "'";
95 ResultSet rs = datasource.executeQuery(sqlVocId);
96 if (rs.next()){
97 vocId = rs.getInt("id");
98 }else{
99 String warning = "Vocabulary ( "+ uuidVocabulary +" ) for term does not exist!";
100 monitor.warning(warning);
101 return null;
102 }
103
104 Integer termId;
105 String sqlMaxId = " SELECT max(id)+1 as maxId FROM DefinedTermBase";
106 rs = datasource.executeQuery(sqlMaxId);
107 if (rs.next()){
108 termId = rs.getInt("maxId");
109 }else{
110 String warning = "No defined terms do exist yet. Can't update terms!";
111 monitor.warning(warning);
112 return null;
113 }
114
115 String id = Integer.toString(termId);
116 String created = getNowString();
117 String defaultColor = "null";
118 String protectedTitleCache = getBoolean(false, datasource);
119 String orderIndex;
120 if (isOrdered){
121 orderIndex = getOrderIndex(datasource, vocId, monitor);
122 }else{
123 orderIndex = "null";
124 }
125 String titleCache = label != null ? label : (abbrev != null ? abbrev : description );
126 String idInVocStr = idInVocabulary == null ? "NULL" : "'" + idInVocabulary + "'";
127 String sqlInsertTerm = " INSERT INTO DefinedTermBase (DTYPE, id, uuid, created, termtype, idInVocabulary, protectedtitlecache, titleCache, orderindex, defaultcolor, vocabulary_id)" +
128 "VALUES ('" + dtype + "', " + id + ", '" + uuidTerm + "', '" + created + "', '" + termType.getKey() + "', " + idInVocStr + ", " + protectedTitleCache + ", '" + titleCache + "', " + orderIndex + ", " + defaultColor + ", " + vocId + ")";
129 datasource.executeUpdate(sqlInsertTerm);
130
131 updateFeatureTerms(termId, datasource, monitor);
132 updateRelationshipTerms(termId, datasource, monitor);
133 updateRanks(termId, datasource, monitor);
134
135 //
136 // INSERT INTO DefinedTermBase (DTYPE, id, uuid, created, protectedtitlecache, titleCache, orderindex, defaultcolor, vocabulary_id)
137 // 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
138 // FROM DefinedTermBase ;
139 //
140
141 //language id
142 Integer langId = getLanguageId(uuidLanguage, datasource, monitor);
143 if (langId == null){
144 return null;
145 }
146
147 //representation
148 int repId;
149 sqlMaxId = " SELECT max(id)+1 as maxId FROM Representation";
150 rs = datasource.executeQuery(sqlMaxId);
151 if (rs.next()){
152 repId = rs.getInt("maxId");
153 }else{
154 String warning = "No representations do exist yet. Can't update terms!";
155 monitor.warning(warning);
156 return null;
157 }
158
159 //standard representation
160 UUID uuidRepresentation = UUID.randomUUID();
161 String sqlInsertRepresentation = " INSERT INTO Representation (id, created, uuid, text, label, abbreviatedlabel, language_id) " +
162 "VALUES (" + repId + ", '" + created + "', '" + uuidRepresentation + "', '" + description + "', '" + label + "', '" + abbrev + "', " + langId + ")";
163
164 datasource.executeUpdate(sqlInsertRepresentation);
165
166 String sqlInsertMN = "INSERT INTO DefinedTermBase_Representation (DefinedTermBase_id, representations_id) " +
167 " VALUES ("+ termId +"," +repId+ " )";
168
169 datasource.executeUpdate(sqlInsertMN);
170
171 //reverse representation
172 if (hasReverseRepresentation()){
173 int reverseRepId = repId + 1;
174 UUID uuidReverseRepresentation = UUID.randomUUID();
175 String sqlInsertReverseRepresentation = " INSERT INTO Representation (id, created, uuid, text, label, abbreviatedlabel, language_id) " +
176 "VALUES (" + reverseRepId + ", '" + created + "', '" + uuidReverseRepresentation + "', '" + reverseDescription + "', '" + reverseLabel + "', '" + reverseAbbrev + "', " + langId + ")";
177
178 datasource.executeUpdate(sqlInsertReverseRepresentation);
179
180 String sqlReverseInsertMN = "INSERT INTO RelationshipTermBase_inverseRepresentation (DefinedTermBase_id, inverserepresentations_id) " +
181 " VALUES ("+ termId +"," +reverseRepId+ " )";
182
183 datasource.executeUpdate(sqlReverseInsertMN);
184 }
185
186 return termId;
187 }
188
189 private void updateFeatureTerms(Integer termId, ICdmDataSource datasource, IProgressMonitor monitor) throws SQLException {
190 if (dtype.equals(Feature.class.getSimpleName())){
191 String sqlUpdate = "UPDATE DefinedTermBase SET " +
192 " supportscategoricaldata = " + getBoolean(false, datasource) + ", " +
193 " supportscommontaxonname = " + getBoolean(false, datasource) + ", " +
194 " supportsdistribution = " + getBoolean(false, datasource) + ", " +
195 " supportsindividualassociation = " + getBoolean(false, datasource) + ", " +
196 " supportsquantitativedata = " + getBoolean(false, datasource) + ", " +
197 " supportstaxoninteraction = " + getBoolean(false, datasource) + ", " +
198 " supportstextdata = " + getBoolean(true, datasource) + " " +
199 " WHERE id = " + termId;
200 datasource.executeUpdate(sqlUpdate);
201 }
202 }
203
204 private void updateRelationshipTerms(Integer termId, ICdmDataSource datasource, IProgressMonitor monitor) throws SQLException {
205 if (dtype.contains("Relationship")){
206 String sqlUpdate = "UPDATE DefinedTermBase SET " +
207 " symmetrical = " + getBoolean(symmetric, datasource) + ", " +
208 " transitive = " + getBoolean(transitive, datasource) + " " +
209 " WHERE id = " + termId;
210 datasource.executeUpdate(sqlUpdate);
211 }
212 }
213
214 private void updateRanks(Integer termId, ICdmDataSource datasource, IProgressMonitor monitor) throws SQLException {
215 if (dtype.equals(Rank.class.getSimpleName())){
216 String sqlUpdate = "UPDATE DefinedTermBase " +
217 " SET rankClass = '" + rankClass.getKey() + "'" +
218 " WHERE id = " + termId;
219 datasource.executeUpdate(sqlUpdate);
220 }
221 }
222
223 public SingleTermUpdater setRankClass(RankClass rankClass) {
224 this.rankClass = rankClass;
225 return this;
226 }
227
228
229
230 /**
231 * @param datasource
232 * @param vocId
233 * @param monitor
234 * @return
235 * @throws SQLException
236 */
237 private String getOrderIndex(ICdmDataSource datasource, int vocId, IProgressMonitor monitor) throws SQLException {
238 ResultSet rs;
239 Integer intOrderIndex = null;
240 if (uuidAfterTerm == null){
241 return "1";
242 }
243 String sqlOrderIndex = " SELECT orderindex FROM DefinedTermBase WHERE uuid = '"+uuidAfterTerm+"' AND vocabulary_id = "+vocId+"";
244 rs = datasource.executeQuery(sqlOrderIndex);
245 if (rs.next()){
246 intOrderIndex = rs.getInt("orderindex") + 1;
247
248 String sqlUpdateLowerTerms = "UPDATE DefinedTermBase SET orderindex = orderindex + 1 WHERE vocabulary_id = " + vocId+ " AND orderindex >= " + intOrderIndex;
249 datasource.executeUpdate(sqlUpdateLowerTerms);
250 }else{
251 String warning = "The previous term has not been found in vocabulary. Put term to the end";
252 monitor.warning(warning);
253 }
254 if (intOrderIndex == null){
255 String sqlMaxOrderIndex = " SELECT max(orderindex) FROM DefinedTermBase WHERE vocabulary_id = " + vocId + "";
256 intOrderIndex = (Integer)datasource.getSingleValue(sqlMaxOrderIndex);
257 if (intOrderIndex != null){
258 intOrderIndex++;
259 }else{
260 String warning = "No term was found in vocabulary or vocabulary does not exist. Use order index '0'.";
261 monitor.warning(warning);
262 intOrderIndex =0;
263 }
264 }
265
266 return intOrderIndex.toString();
267 }
268
269
270 private boolean hasReverseRepresentation() {
271 return reverseLabel != null || reverseDescription != null || reverseAbbrev != null;
272 }
273
274 public SingleTermUpdater setReverseRepresentation(String reverseDescription, String reverseLabel, String reverseAbbrev) {
275 this.reverseLabel = reverseLabel;
276 this.reverseDescription = reverseDescription;
277 this.reverseAbbrev = reverseAbbrev;
278 return this;
279 }
280
281 public SingleTermUpdater setSymmetricTransitiv(boolean symmetric, boolean transitive){
282 this.symmetric = symmetric;
283 this.transitive = transitive;
284 return this;
285 }
286
287 }