Project

General

Profile

Download (14.4 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.logging.log4j.LogManager;import org.apache.logging.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
public class SingleTermUpdater extends SchemaUpdaterStepBase {
31

    
32
	@SuppressWarnings("unused")
33
	private static final Logger logger = LogManager.getLogger(SingleTermUpdater.class);
34

    
35
// **************************** FACTORY METHODS ********************************/
36

    
37
	public static final SingleTermUpdater NewInstance(List<ISchemaUpdaterStep> stepList, String stepName, TermType termType, UUID uuidTerm, String idInVocabulary, String symbol,
38
	        String description,  String label, String abbrev, String dtype, UUID uuidVocabulary, UUID uuidLanguage, boolean isOrdered, UUID uuidAfterTerm){
39
		return new SingleTermUpdater(stepList, stepName, termType, uuidTerm, idInVocabulary, symbol,
40
		        description, label, abbrev, null, null, null, dtype, uuidVocabulary, uuidLanguage, isOrdered, uuidAfterTerm);
41
	}
42

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

    
51
// *************************** VARIABLES *****************************************/
52

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

    
72
// ***************************** CONSTRUCTOR ***************************************/
73

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

    
95
// ******************************* METHODS *************************************************/
96

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

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

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

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

    
150
		updateFeatureTerms(termId, datasource, monitor, caseType);
151
		updateRelationshipTerms(termId, datasource, monitor, caseType);
152
		updateRanks(termId, datasource, monitor, caseType);
153

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

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

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

    
180
		datasource.executeUpdate(caseType.replaceTableNames(sqlInsertRepresentation));
181

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

    
185
		datasource.executeUpdate(caseType.replaceTableNames(sqlInsertMN));
186

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

    
194
			datasource.executeUpdate(caseType.replaceTableNames(sqlInsertReverseRepresentation));
195

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

    
199
			datasource.executeUpdate(caseType.replaceTableNames(sqlReverseInsertMN));
200
		}
201

    
202
		return;
203
	}
204

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

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

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

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

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

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

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

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

    
287

    
288

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

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

    
329
		return intOrderIndex.toString();
330
	}
331

    
332

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

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

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

    
350
}
(30-30/41)