Project

General

Profile

Download (14.7 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.List;
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.description.Feature;
21
import eu.etaxonomy.cdm.model.name.Rank;
22
import eu.etaxonomy.cdm.model.name.RankClass;
23
import eu.etaxonomy.cdm.model.term.TermType;
24

    
25
/**
26
 * Creates a new term if a term with the same given uuid does not exist yet
27
 * @author a.mueller
28
 * @since 10.09.2010
29
 *
30
 */
31
public class SingleTermUpdater extends SchemaUpdaterStepBase {
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(List<ISchemaUpdaterStep> stepList, String stepName, UUID uuidTerm, String description,  String label, String abbrev, String dtype, UUID uuidVocabulary, UUID uuidLanguage, boolean isOrdered, UUID uuidAfterTerm){
40
		return new SingleTermUpdater(stepList, stepName, null, uuidTerm, null, null, description, label, abbrev, null, null, null, dtype, uuidVocabulary, uuidLanguage, isOrdered, uuidAfterTerm);
41
	}
42

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

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

    
57

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

    
77

    
78

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
205
		return;
206
	}
207

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

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

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

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

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

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

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

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

    
290

    
291

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

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

    
332
		return intOrderIndex.toString();
333
	}
334

    
335

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

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

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

    
353
}
(30-30/41)