2 * Copyright (C) 2007 EDIT
3 * European Distributed Institute of Taxonomy
4 * http://www.e-taxonomy.eu
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.
10 package eu
.etaxonomy
.cdm
.io
.redlist
;
12 import java
.sql
.ResultSet
;
13 import java
.sql
.SQLException
;
14 import java
.sql
.Timestamp
;
15 import java
.util
.HashMap
;
16 import java
.util
.HashSet
;
19 import java
.util
.UUID
;
21 import org
.apache
.log4j
.Logger
;
22 import org
.joda
.time
.DateTime
;
24 import eu
.etaxonomy
.cdm
.common
.CdmUtils
;
25 import eu
.etaxonomy
.cdm
.io
.common
.CdmImportBase
;
26 import eu
.etaxonomy
.cdm
.io
.common
.ICdmIO
;
27 import eu
.etaxonomy
.cdm
.io
.common
.IImportConfigurator
.EDITOR
;
28 import eu
.etaxonomy
.cdm
.io
.common
.IPartitionedIO
;
29 import eu
.etaxonomy
.cdm
.io
.common
.ImportHelper
;
30 import eu
.etaxonomy
.cdm
.io
.common
.ResultSetPartitioner
;
31 import eu
.etaxonomy
.cdm
.io
.common
.Source
;
32 import eu
.etaxonomy
.cdm
.io
.common
.mapping
.DbImportMapping
;
33 import eu
.etaxonomy
.cdm
.model
.common
.AnnotatableEntity
;
34 import eu
.etaxonomy
.cdm
.model
.common
.Annotation
;
35 import eu
.etaxonomy
.cdm
.model
.common
.AnnotationType
;
36 import eu
.etaxonomy
.cdm
.model
.common
.CdmBase
;
37 import eu
.etaxonomy
.cdm
.model
.common
.ExtensionType
;
38 import eu
.etaxonomy
.cdm
.model
.common
.IdentifiableEntity
;
39 import eu
.etaxonomy
.cdm
.model
.common
.Language
;
40 import eu
.etaxonomy
.cdm
.model
.common
.MarkerType
;
41 import eu
.etaxonomy
.cdm
.model
.common
.User
;
48 public abstract class RoteListeDbImportBase
<CDM_BASE
extends CdmBase
> extends CdmImportBase
<RoteListeDbImportConfigurator
, RoteListeDbImportState
> implements ICdmIO
<RoteListeDbImportState
>, IPartitionedIO
<RoteListeDbImportState
> {
49 private static final Logger logger
= Logger
.getLogger(RoteListeDbImportBase
.class);
52 private String pluralString
;
53 private String dbTableName
;
55 private Class cdmTargetClass
;
64 public RoteListeDbImportBase(String pluralString
, String dbTableName
, Class cdmTargetClass
) {
65 this.pluralString
= pluralString
;
66 this.dbTableName
= dbTableName
;
67 this.cdmTargetClass
= cdmTargetClass
;
70 protected void doInvoke(RoteListeDbImportState state
){
71 logger
.info("start make " + getPluralString() + " ...");
72 RoteListeDbImportConfigurator config
= state
.getConfig();
73 Source source
= config
.getSource();
75 String strIdQuery
= getIdQuery();
76 String strRecordQuery
= getRecordQuery(config
);
78 int recordsPerTransaction
= config
.getRecordsPerTransaction();
80 ResultSetPartitioner partitioner
= ResultSetPartitioner
.NewInstance(source
, strIdQuery
, strRecordQuery
, recordsPerTransaction
);
81 while (partitioner
.nextPartition()){
82 partitioner
.doPartition(this, state
);
84 } catch (SQLException e
) {
85 logger
.error("SQLException:" + e
);
86 state
.setUnsuccessfull();
90 logger
.info("end make " + getPluralString() + " ... " + getSuccessString(true));
94 public boolean doPartition(ResultSetPartitioner partitioner
, RoteListeDbImportState state
) {
95 boolean success
= true ;
96 Set objectsToSave
= new HashSet();
98 DbImportMapping
<?
, ?
> mapping
= getMapping();
99 mapping
.initialize(state
, cdmTargetClass
);
101 ResultSet rs
= partitioner
.getResultSet();
104 success
&= mapping
.invoke(rs
,objectsToSave
);
106 } catch (SQLException e
) {
107 logger
.error("SQLException:" + e
);
111 partitioner
.startDoSave();
112 getCommonService().save(objectsToSave
);
121 protected abstract DbImportMapping
<?
, ?
> getMapping();
126 protected abstract String
getRecordQuery(RoteListeDbImportConfigurator config
);
131 protected String
getIdQuery(){
132 String result
= " SELECT id FROM " + getTableName();
137 * @see eu.etaxonomy.cdm.io.berlinModel.in.IPartitionedIO#getPluralString()
139 public String
getPluralString(){
146 protected String
getTableName(){
147 return this.dbTableName
;
150 protected boolean doIdCreatedUpdatedNotes(RoteListeDbImportState state
, IdentifiableEntity identifiableEntity
, ResultSet rs
, long id
, String namespace
)
152 boolean success
= true;
154 success
&= ImportHelper
.setOriginalSource(identifiableEntity
, state
.getConfig().getSourceReference(), id
, namespace
);
156 success
&= doCreatedUpdatedNotes(state
, identifiableEntity
, rs
, namespace
);
161 protected boolean doCreatedUpdatedNotes(RoteListeDbImportState state
, AnnotatableEntity annotatableEntity
, ResultSet rs
, String namespace
)
164 RoteListeDbImportConfigurator config
= state
.getConfig();
165 Object createdWhen
= rs
.getObject("Created_When");
166 String createdWho
= rs
.getString("Created_Who");
167 Object updatedWhen
= null;
168 String updatedWho
= null;
170 updatedWhen
= rs
.getObject("Updated_When");
171 updatedWho
= rs
.getString("Updated_who");
172 } catch (SQLException e
) {
173 //Table "Name" has no updated when/who
175 String notes
= rs
.getString("notes");
177 boolean success
= true;
179 //Created When, Who, Updated When Who
180 if (config
.getEditor() == null || config
.getEditor().equals(EDITOR
.NO_EDITORS
)){
182 }else if (config
.getEditor().equals(EDITOR
.EDITOR_AS_ANNOTATION
)){
183 String createdAnnotationString
= "Berlin Model record was created By: " + String
.valueOf(createdWho
) + " (" + String
.valueOf(createdWhen
) + ") ";
184 if (updatedWhen
!= null && updatedWho
!= null){
185 createdAnnotationString
+= " and updated By: " + String
.valueOf(updatedWho
) + " (" + String
.valueOf(updatedWhen
) + ")";
187 Annotation annotation
= Annotation
.NewInstance(createdAnnotationString
, Language
.DEFAULT());
188 annotation
.setCommentator(config
.getCommentator());
189 annotation
.setAnnotationType(AnnotationType
.TECHNICAL());
190 annotatableEntity
.addAnnotation(annotation
);
191 }else if (config
.getEditor().equals(EDITOR
.EDITOR_AS_EDITOR
)){
192 User creator
= getUser(createdWho
, state
);
193 User updator
= getUser(updatedWho
, state
);
194 DateTime created
= getDateTime(createdWhen
);
195 DateTime updated
= getDateTime(updatedWhen
);
196 annotatableEntity
.setCreatedBy(creator
);
197 annotatableEntity
.setUpdatedBy(updator
);
198 annotatableEntity
.setCreated(created
);
199 annotatableEntity
.setUpdated(updated
);
201 logger
.warn("Editor type not yet implemented: " + config
.getEditor());
206 if (CdmUtils
.isNotEmpty(notes
)){
207 String notesString
= String
.valueOf(notes
);
208 if (notesString
.length() > 65530 ){
209 notesString
= notesString
.substring(0, 65530) + "...";
210 logger
.warn("Notes string is longer than 65530 and was truncated: " + annotatableEntity
);
212 Annotation notesAnnotation
= Annotation
.NewInstance(notesString
, null);
213 //notesAnnotation.setAnnotationType(AnnotationType.EDITORIAL());
214 //notes.setCommentator(bmiConfig.getCommentator());
215 annotatableEntity
.addAnnotation(notesAnnotation
);
221 private User
getUser(String createdWho
, RoteListeDbImportState state
) {
222 //not relevant here, for users see ERMS import
226 private DateTime
getDateTime(Object timeString
){
227 if (timeString
== null){
230 DateTime dateTime
= null;
231 if (timeString
instanceof Timestamp
){
232 Timestamp timestamp
= (Timestamp
)timeString
;
233 dateTime
= new DateTime(timestamp
);
235 logger
.warn("time ("+timeString
+") is not a timestamp. Datetime set to current date. ");
236 dateTime
= new DateTime();
243 * Returns a map that holds all values of a ResultSet. This is needed if a value needs to
247 * @throws SQLException
249 protected Map
<String
, Object
> getValueMap(ResultSet rs
) throws SQLException
{
251 Map
<String
, Object
> valueMap
= new HashMap
<String
, Object
>();
252 int colCount
= rs
.getMetaData().getColumnCount();
253 for (int c
= 0; c
< colCount
; c
++){
254 Object value
= rs
.getObject(c
+1);
255 String label
= rs
.getMetaData().getColumnLabel(c
+1).toLowerCase();
256 if (value
!= null && ! CdmUtils
.Nz(value
.toString()).trim().equals("")){
257 valueMap
.put(label
, value
);
261 }catch(SQLException e
){
266 protected ExtensionType
getExtensionType(UUID uuid
, String label
, String text
, String labelAbbrev
){
267 ExtensionType extensionType
= (ExtensionType
)getTermService().find(uuid
);
268 if (extensionType
== null){
269 extensionType
= ExtensionType
.NewInstance(text
, label
, labelAbbrev
);
270 extensionType
.setUuid(uuid
);
271 getTermService().save(extensionType
);
273 return extensionType
;
276 protected MarkerType
getMarkerType(UUID uuid
, String label
, String text
, String labelAbbrev
){
277 MarkerType markerType
= (MarkerType
)getTermService().find(uuid
);
278 if (markerType
== null){
279 markerType
= MarkerType
.NewInstance(label
, text
, labelAbbrev
);
280 markerType
.setUuid(uuid
);
281 getTermService().save(markerType
);
288 * Reads a foreign key field from the result set and adds its value to the idSet.
291 * @throws SQLException
293 protected void handleForeignKey(ResultSet rs
, Set
<String
> idSet
, String attributeName
)
294 throws SQLException
{
295 Object idObj
= rs
.getObject(attributeName
);
297 String id
= String
.valueOf(idObj
);
303 * Returns true if i is a multiple of recordsPerTransaction
305 * @param recordsPerTransaction
308 protected boolean loopNeedsHandling(int i
, int recordsPerLoop
) {
310 return (i
% recordsPerLoop
) == 0;
313 protected void doLogPerLoop(int count
, int recordsPerLog
, String pluralString
){
314 if ((count
% recordsPerLog
) == 0 && count
!= 0 ){ logger
.info(pluralString
+ " handled: " + (count
));}