Project

General

Profile

Download (14.5 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2009 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9
package eu.etaxonomy.cdm.database.update;
10

    
11
import java.sql.ResultSet;
12
import java.sql.SQLException;
13
import java.util.UUID;
14

    
15
import org.apache.log4j.Logger;
16

    
17
import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
18
import eu.etaxonomy.cdm.database.ICdmDataSource;
19
import eu.etaxonomy.cdm.model.description.Feature;
20
import eu.etaxonomy.cdm.model.name.Rank;
21
import eu.etaxonomy.cdm.model.name.RankClass;
22
import eu.etaxonomy.cdm.model.term.TermType;
23

    
24
/**
25
 * Creates a new term if a term with the same given uuid does not exist yet
26
 * @author a.mueller
27
 * @since 10.09.2010
28
 *
29
 */
30
public class SingleTermUpdater extends SchemaUpdaterStepBase {
31
	@SuppressWarnings("unused")
32
	private static final Logger logger = Logger.getLogger(SingleTermUpdater.class);
33

    
34
	/**
35
	 * @Deprecated use {@link #NewInstance(String, TermType, UUID, String, String, String, String, UUID, UUID, boolean, UUID)} instead
36
	 */
37
	@Deprecated
38
	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){
39
		return new SingleTermUpdater(stepName, null, uuidTerm, null, null, description, label, abbrev, null, null, null, dtype, uuidVocabulary, uuidLanguage, isOrdered, uuidAfterTerm);
40
	}
41

    
42
	public static final SingleTermUpdater NewInstance(String stepName, TermType termType, UUID uuidTerm, String idInVocabulary, String symbol,
43
	        String description,  String label, String abbrev, String dtype, UUID uuidVocabulary, UUID uuidLanguage, boolean isOrdered, UUID uuidAfterTerm){
44
		return new SingleTermUpdater(stepName, termType, uuidTerm, idInVocabulary, symbol,
45
		        description, label, abbrev, null, null, null, dtype, uuidVocabulary, uuidLanguage, isOrdered, uuidAfterTerm);
46
	}
47

    
48
	   public static final SingleTermUpdater NewReverseInstance(String stepName, TermType termType, UUID uuidTerm, String idInVocabulary, String symbol,
49
	           String description,  String label, String abbrev, String reverseDescription, String reverseLabel, String reverseAbbrev,
50
	           String dtype, UUID uuidVocabulary, UUID uuidLanguage, boolean isOrdered, UUID uuidAfterTerm){
51
	        return new SingleTermUpdater(stepName, termType, uuidTerm, idInVocabulary,symbol,
52
	                description, label, abbrev, reverseDescription, reverseLabel, reverseAbbrev,
53
	                dtype, uuidVocabulary, uuidLanguage, isOrdered, uuidAfterTerm);
54
	    }
55

    
56

    
57
	private final UUID uuidTerm ;
58
	private final String description;
59
	private final String label;
60
	private final String abbrev;
61
	private final String dtype;
62
	private final UUID uuidVocabulary;
63
	private final boolean isOrdered;
64
	private final UUID uuidAfterTerm;
65
	private final UUID uuidLanguage;
66
	private String reverseDescription;
67
	private String reverseLabel;
68
	private String reverseAbbrev;
69
	private RankClass rankClass;
70
	private final TermType termType;
71
	private final String idInVocabulary;
72
	private boolean symmetric = false;
73
	private boolean transitive = false;
74
	private String symbol;
75

    
76

    
77

    
78
	private SingleTermUpdater(String stepName, TermType termType, UUID uuidTerm, String idInVocabulary, String symbol,
79
	        String description, String label, String abbrev, String reverseDescription, String reverseLabel, String reverseAbbrev,
80
	        String dtype, UUID uuidVocabulary, UUID uuidLanguage, boolean isOrdered, UUID uuidAfterTerm) {
81
		super(stepName);
82
		this.termType = termType;
83
		this.idInVocabulary = idInVocabulary;
84
		this.symbol = symbol;
85
		this.abbrev = abbrev;
86
		this.description = description;
87
		this.dtype = dtype;
88
		this.label = label;
89
		this.isOrdered = isOrdered;
90
		this.uuidTerm = uuidTerm;
91
		this.uuidVocabulary = uuidVocabulary;
92
		this.uuidAfterTerm = uuidAfterTerm;
93
		this.uuidLanguage = uuidLanguage;
94
		this.reverseDescription = reverseDescription;
95
		this.reverseLabel = reverseLabel;
96
		this.reverseAbbrev = reverseAbbrev;
97
	}
98

    
99
    @Override
100
    public void invoke(ICdmDataSource datasource, IProgressMonitor monitor,
101
            CaseType caseType, SchemaUpdateResult result) throws SQLException {
102
		String sqlCheckTermExists = " SELECT count(*) as n " +
103
 				" FROM " + caseType.transformTo("DefinedTermBase") +
104
 				" WHERE uuid = '" + uuidTerm + "'";
105
		Long n = (Long)datasource.getSingleValue(sqlCheckTermExists);
106
		if (n != 0){
107
		    String message ="Term already exists: " + label + "(" + uuidTerm + ")";
108
			monitor.warning(message);
109
			result.addWarning(message, (String)null, getStepName());
110
			return;
111
		}
112

    
113
		//vocabulary id
114
		int vocId;
115
		String sqlVocId = " SELECT id " +
116
				" FROM  " + caseType.transformTo("TermVocabulary") +
117
				" WHERE uuid = '" + uuidVocabulary + "'";
118
		ResultSet rs = datasource.executeQuery(sqlVocId);
119
		if (rs.next()){
120
			vocId = rs.getInt("id");
121
		}else{
122
			String message = "Vocabulary ( "+ uuidVocabulary +" ) for term does not exist!";
123
			monitor.warning(message);
124
			result.addError(message, getStepName() + ", SingleTermUpdater.invoke");
125
            return;
126
		}
127

    
128
		String sqlMaxId;
129
        Integer termId = getMaxId(datasource, monitor, caseType, result);
130
        if (termId == null){
131
            return;
132
        }
133

    
134
		String id = Integer.toString(termId);
135
		String created = getNowString();
136
		String defaultColor = "null";
137
		String protectedTitleCache = getBoolean(false, datasource);
138
		String orderIndex;
139
		if (isOrdered){
140
			orderIndex = getOrderIndex(datasource, vocId, monitor, caseType);
141
		}else{
142
			orderIndex = "null";
143
		}
144
		String titleCache = label != null ? label : (abbrev != null ? abbrev : description );
145
		String idInVocStr = idInVocabulary == null ? "NULL" : "'" + idInVocabulary + "'";
146
		String symbol = this.symbol == null ? "NULL" : "'" + this.symbol + "'";
147
		String sqlInsertTerm = " INSERT INTO @@DefinedTermBase@@ (DTYPE, id, uuid, created, termtype, idInVocabulary, symbol, protectedtitlecache, titleCache, orderindex, defaultcolor, vocabulary_id)" +
148
				"VALUES ('" + dtype + "', " + id + ", '" + uuidTerm + "', '" + created + "', '" + termType.getKey() + "', " + idInVocStr + ", " + symbol +  ", " + protectedTitleCache + ", '" + titleCache + "', " + orderIndex + ", " + defaultColor + ", " + vocId + ")";
149
		sqlInsertTerm = caseType.replaceTableNames(sqlInsertTerm);
150
		datasource.executeUpdate(caseType.replaceTableNames(sqlInsertTerm));
151

    
152
		updateFeatureTerms(termId, datasource, monitor, caseType);
153
		updateRelationshipTerms(termId, datasource, monitor, caseType);
154
		updateRanks(termId, datasource, monitor, caseType);
155

    
156
		//language id
157
		Integer langId = getLanguageId(uuidLanguage, datasource, monitor, caseType);
158
		if (langId == null){
159
			String message = "LangId is null";
160
			result.addWarning(message);
161
		    return;
162
		}
163

    
164
		//representation
165
		int repId;
166
		sqlMaxId = " SELECT max(id)+1 as maxId FROM " + caseType.transformTo("Representation");
167
		rs = datasource.executeQuery(sqlMaxId);
168
		if (rs.next()){
169
			repId = rs.getInt("maxId");
170
		}else{
171
			String message = "No representations do exist yet. Can't update terms!";
172
			monitor.warning(message);
173
			result.addError(message, this, "invoke");
174
			return;
175
		}
176

    
177
		//standard representation
178
		UUID uuidRepresentation = UUID.randomUUID();
179
		String sqlInsertRepresentation = " INSERT INTO @@Representation@@ (id, created, uuid, text, label, abbreviatedlabel, language_id) " +
180
				"VALUES (" + repId + ", '" + created + "', '" + uuidRepresentation + "', " + nullSafeStr(description) +  ", " +nullSafeStr( label) +  ", " + nullSafeStr(abbrev) +  ", " + langId + ")";
181

    
182
		datasource.executeUpdate(caseType.replaceTableNames(sqlInsertRepresentation));
183

    
184
		String sqlInsertMN = "INSERT INTO @@DefinedTermBase_Representation@@ (DefinedTermBase_id, representations_id) " +
185
				" VALUES ("+ termId +"," +repId+ " )";
186

    
187
		datasource.executeUpdate(caseType.replaceTableNames(sqlInsertMN));
188

    
189
		//reverse representation
190
		if (hasReverseRepresentation()){
191
			int reverseRepId = repId + 1;
192
			UUID uuidReverseRepresentation = UUID.randomUUID();
193
			String sqlInsertReverseRepresentation = " INSERT INTO @@Representation@@ (id, created, uuid, text, label, abbreviatedlabel, language_id) " +
194
					"VALUES (" + reverseRepId + ", '" + created + "', '" + uuidReverseRepresentation + "', " + nullSafeStr(reverseDescription) +  ", " + nullSafeStr(reverseLabel) +  ",  " + nullSafeStr(reverseAbbrev) +  ", " + langId + ")";
195

    
196
			datasource.executeUpdate(caseType.replaceTableNames(sqlInsertReverseRepresentation));
197

    
198
			String sqlReverseInsertMN = "INSERT INTO @@TermBase_inverseRepresentation@@ (term_id, inverserepresentations_id) " +
199
					" VALUES ("+ termId +"," +reverseRepId+ " )";
200

    
201
			datasource.executeUpdate(caseType.replaceTableNames(sqlReverseInsertMN));
202
		}
203

    
204
		return;
205
	}
206

    
207
    /**
208
     * @param datasource
209
     * @param monitor
210
     * @param caseType
211
     * @param result
212
     * @return
213
     * @throws SQLException
214
     */
215
    protected Integer getMaxId(ICdmDataSource datasource, IProgressMonitor monitor, CaseType caseType,
216
            SchemaUpdateResult result) throws SQLException {
217

    
218
//       For some very strange reason max(id) gave back a wrong result when
219
//        executed here while updateing remote-webapp H2 test database, therefore
220
//        we took this workaround which worked. Can be removed when it does not
221
//        appear anymore
222

    
223
//        String sqlMaxId = " SELECT max(id)+1 as maxId"
224
//                + " FROM " + caseType.transformTo("DefinedTermBase");
225
        String sqlMaxId = " SELECT id  as maxId"
226
                + " FROM " + caseType.transformTo("DefinedTermBase") +
227
                 " ORDER BY id DESC ";
228
		ResultSet rs = datasource.executeQuery(sqlMaxId);
229
		while (rs.next()){
230
		    Integer termId = rs.getInt("maxId");
231
		    System.out.println(termId);
232
		    return termId +1;
233
		}
234
		String message = "No defined terms do exist yet. Can't update terms!";
235
		monitor.warning(message);
236
		result.addError(message, getStepName() + ", SingleTermUpdater.invoke");
237
        return null;
238
    }
239

    
240
	private String nullSafeStr(String str) {
241
		if (str == null){
242
			return " NULL ";
243
		}else{
244
			return "'" + str + "'";
245
		}
246
	}
247

    
248
	private void updateFeatureTerms(Integer termId, ICdmDataSource datasource, IProgressMonitor monitor, CaseType caseType) throws SQLException {
249
		if (dtype.equals(Feature.class.getSimpleName())){
250
			String sqlUpdate = "UPDATE  " + caseType.transformTo("DefinedTermBase") +
251
				" SET " +
252
				" supportscategoricaldata = " + getBoolean(false, datasource) + ", " +
253
				" supportscommontaxonname = " + getBoolean(false, datasource) + ", " +
254
				" supportsdistribution = " + getBoolean(false, datasource) + ", " +
255
				" supportsindividualassociation = " + getBoolean(false, datasource) + ", " +
256
				" supportsquantitativedata = " + getBoolean(false, datasource) + ", " +
257
				" supportstaxoninteraction = " + getBoolean(false, datasource) + ", " +
258
				" supportstextdata = " + getBoolean(true, datasource) +  " " +
259
				" WHERE id = " + termId;
260
			datasource.executeUpdate(sqlUpdate);
261
		}
262
	}
263

    
264
	private void updateRelationshipTerms(Integer termId, ICdmDataSource datasource, IProgressMonitor monitor, CaseType caseType) throws SQLException {
265
		if (dtype.contains("Relationship")){
266
			String sqlUpdate = "UPDATE "  + caseType.transformTo("DefinedTermBase") +
267
				" SET " +
268
				" symmetrical = " + getBoolean(symmetric, datasource) + ", " +
269
				" transitive = " + getBoolean(transitive, datasource) + " " +
270
				" WHERE id = " + termId;
271
			datasource.executeUpdate(sqlUpdate);
272
		}
273
	}
274

    
275
	private void updateRanks(Integer termId, ICdmDataSource datasource, IProgressMonitor monitor, CaseType caseType) throws SQLException {
276
		if (dtype.equals(Rank.class.getSimpleName())){
277
			String sqlUpdate = "UPDATE " + caseType.transformTo("DefinedTermBase") +
278
				" SET rankClass = '" + rankClass.getKey() + "'" +
279
				" WHERE id = " + termId;
280
			datasource.executeUpdate(sqlUpdate);
281
		}
282
	}
283

    
284
	public SingleTermUpdater setRankClass(RankClass rankClass) {
285
		this.rankClass = rankClass;
286
		return this;
287
	}
288

    
289

    
290

    
291
	/**
292
	 * @param datasource
293
	 * @param vocId
294
	 * @param monitor
295
	 * @param caseType
296
	 * @return
297
	 * @throws SQLException
298
	 */
299
	private String getOrderIndex(ICdmDataSource datasource, int vocId, IProgressMonitor monitor, CaseType caseType) throws SQLException {
300
		ResultSet rs;
301
		Integer intOrderIndex = null;
302
		if (uuidAfterTerm == null){
303
			return "1";
304
		}
305
		String sqlOrderIndex = " SELECT orderindex FROM %s WHERE uuid = '%s' AND vocabulary_id = %d ";
306
		sqlOrderIndex = String.format(sqlOrderIndex, caseType.transformTo("DefinedTermBase"), uuidAfterTerm.toString(), vocId);
307
		rs = datasource.executeQuery(sqlOrderIndex);
308
		if (rs.next()){
309
			intOrderIndex = rs.getInt("orderindex") + 1;
310

    
311
			String sqlUpdateLowerTerms = "UPDATE %s SET orderindex = orderindex + 1 WHERE vocabulary_id = %d AND orderindex >= %d ";
312
			sqlUpdateLowerTerms = String.format(sqlUpdateLowerTerms, caseType.transformTo("DefinedTermBase"), vocId, intOrderIndex );
313
			datasource.executeUpdate(sqlUpdateLowerTerms);
314
		}else{
315
			String warning = "The previous term has not been found in vocabulary. Put term to the end";
316
			monitor.warning(warning);
317
		}
318
		if (intOrderIndex == null){
319
			String sqlMaxOrderIndex = " SELECT max(orderindex) FROM %s WHERE vocabulary_id = %d";
320
			sqlMaxOrderIndex = String.format(sqlMaxOrderIndex, caseType.transformTo("DefinedTermBase"), vocId);
321
			intOrderIndex = (Integer)datasource.getSingleValue(sqlMaxOrderIndex);
322
			if (intOrderIndex != null){
323
				intOrderIndex++;
324
			}else{
325
				String warning = "No term was found in vocabulary or vocabulary does not exist. Use order index '0'.";
326
				monitor.warning(warning);
327
				intOrderIndex =0;
328
			}
329
		}
330

    
331
		return intOrderIndex.toString();
332
	}
333

    
334

    
335
	private boolean hasReverseRepresentation() {
336
		return  reverseLabel != null ||  reverseDescription != null ||  reverseAbbrev != null;
337
	}
338

    
339
	public SingleTermUpdater setReverseRepresentation(String reverseDescription, String reverseLabel, String reverseAbbrev) {
340
		this.reverseLabel = reverseLabel;
341
		this.reverseDescription = reverseDescription;
342
		this.reverseAbbrev = reverseAbbrev;
343
		return this;
344
	}
345

    
346
	public SingleTermUpdater setSymmetricTransitiv(boolean symmetric, boolean transitive){
347
		this.symmetric = symmetric;
348
		this.transitive = transitive;
349
		return this;
350
	}
351

    
352
}
(25-25/36)