better use of generics in service layer and persistence list methods
[cdmlib-apps.git] / app-import / src / main / java / eu / etaxonomy / cdm / app / wp6 / palmae / PalmaePostImportUpdater.java
1 // $Id$
2 /**
3 * Copyright (C) 2007 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
11 package eu.etaxonomy.cdm.app.wp6.palmae;
12
13 import java.util.List;
14 import java.util.Set;
15 import java.util.UUID;
16
17 import org.apache.log4j.Logger;
18 import org.springframework.transaction.TransactionStatus;
19
20 import eu.etaxonomy.cdm.api.application.CdmApplicationController;
21 import eu.etaxonomy.cdm.app.common.CdmDestinations;
22 import eu.etaxonomy.cdm.database.DbSchemaValidation;
23 import eu.etaxonomy.cdm.database.ICdmDataSource;
24 import eu.etaxonomy.cdm.model.common.OriginalSourceType;
25 import eu.etaxonomy.cdm.model.description.Feature;
26 import eu.etaxonomy.cdm.model.description.FeatureNode;
27 import eu.etaxonomy.cdm.model.description.FeatureTree;
28 import eu.etaxonomy.cdm.model.description.TaxonDescription;
29 import eu.etaxonomy.cdm.model.description.TextData;
30 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
31 import eu.etaxonomy.cdm.model.reference.IReference;
32 import eu.etaxonomy.cdm.model.reference.Reference;
33 import eu.etaxonomy.cdm.model.taxon.Synonym;
34 import eu.etaxonomy.cdm.model.taxon.Taxon;
35 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
36
37 /**
38 * @author a.mueller
39 * @created 01.10.2009
40 */
41 public class PalmaePostImportUpdater {
42 private static final Logger logger = Logger.getLogger(PalmaePostImportUpdater.class);
43
44 static final ICdmDataSource cdmDestination = CdmDestinations.localH2Palmae();
45
46
47 private String relationships = "relationships";
48 private String taxonomicAccounts = "taxonomic accounts";
49 private String fossilRecord = "fossil record";
50
51 public boolean updateMissingFeatures(ICdmDataSource dataSource) {
52 try{
53 int count = 0;
54 UUID featureTreeUuid = PalmaeActivator.featureTreeUuid;
55 CdmApplicationController cdmApp = CdmApplicationController.NewInstance(dataSource, DbSchemaValidation.VALIDATE);
56
57 TransactionStatus tx = cdmApp.startTransaction();
58
59 FeatureTree tree = cdmApp.getFeatureTreeService().find(featureTreeUuid);
60 FeatureNode root = tree.getRoot();
61
62 List<Feature> featureList = cdmApp.getTermService().list(Feature.class, null, null, null, null);
63 for (Feature feature : featureList){
64 String label = feature.getLabel();
65 if (relationships.equals(label)){
66 FeatureNode newNode = FeatureNode.NewInstance(feature);
67 root.addChild(newNode);
68 count++;
69 }else if(taxonomicAccounts.equals(label)){
70 FeatureNode newNode = FeatureNode.NewInstance(feature);
71 root.addChild(newNode);
72 count++;
73 }else if(fossilRecord.equals(label)){
74 FeatureNode newNode = FeatureNode.NewInstance(feature);
75 root.addChild(newNode);
76 count++;
77 }
78 }
79 cdmApp.commitTransaction(tx);
80 if (count != 3){
81 logger.warn("Did not find 3 additional features but " + count);
82 return false;
83 }
84 logger.info("Feature tree updated!");
85 return true;
86 } catch (Exception e) {
87 e.printStackTrace();
88 logger.error("ERROR in feature tree update");
89 return false;
90 }
91
92 }
93
94 public boolean updateNameUsage(ICdmDataSource dataSource) {
95 try{
96 boolean result = true;
97 CdmApplicationController cdmApp = CdmApplicationController.NewInstance(dataSource, DbSchemaValidation.VALIDATE);
98
99 TransactionStatus tx = cdmApp.startTransaction();
100
101 int page = 0;
102 int count = cdmApp.getTaxonService().count(Taxon.class);
103 List<TaxonBase> taxonList = cdmApp.getTaxonService().list(TaxonBase.class, 100000, page, null, null);
104 int i = 0;
105
106 IReference treatmentReference = (IReference) cdmApp.getCommonService().getSourcedObjectByIdInSource(Reference.class, "palm_pub_ed_999999", "PublicationCitation");
107 if (treatmentReference == null){
108 logger.error("Treatment reference could not be found");
109 result = false;
110 }else{
111 for (TaxonBase nameUsage : taxonList){
112 if ((i++ % 100) == 0){System.out.println(i);};
113
114 try {
115 //if not in treatment
116 if (! isInTreatment(nameUsage, treatmentReference, false)){
117 //if connected treatment taxon can be found
118 Taxon acceptedTaxon = getAcceptedTreatmentTaxon(nameUsage, treatmentReference);
119 if (acceptedTaxon != null){
120 //add as citation and delete
121 addNameUsage(acceptedTaxon, nameUsage);
122 cdmApp.getTaxonService().delete(nameUsage);
123 }else{
124 logger.warn("Non treatment taxon has no accepted taxon in treatment: " + nameUsage + " (" + nameUsage.getId() +")" );
125 }
126 }
127 } catch (Exception e) {
128 result = false;
129 e.printStackTrace();
130 }
131 }
132 }
133 //add citation feature to feature tree
134 UUID featureTreeUuid = PalmaeActivator.featureTreeUuid;
135 FeatureTree tree = cdmApp.getFeatureTreeService().find(featureTreeUuid);
136 FeatureNode root = tree.getRoot();
137 List<Feature> featureList = cdmApp.getTermService().list(Feature.class, null, null, null, null);
138 count = 0;
139 for (Feature feature : featureList){
140 if (feature.equals(Feature.CITATION())){
141 FeatureNode newNode = FeatureNode.NewInstance(feature);
142 root.addChild(newNode);
143 count++;
144 }
145 }
146 if (count != 1){
147 logger.warn("Did not add exactly 1 features to the feature tree but " + count);
148 result = false;
149 }
150 //commit
151 cdmApp.commitTransaction(tx);
152 logger.info("NameUsage updated!");
153 return result;
154 } catch (Exception e) {
155 e.printStackTrace();
156 logger.error("ERROR in name usage update");
157 return false;
158 }
159
160 }
161
162 /**
163 * @param nameUsage
164 * @return
165 */
166 private Taxon getAcceptedTreatmentTaxon(TaxonBase nameUsage, IReference treatmentReference) {
167 boolean hasSynonymInTreatment = false;
168 TaxonNameBase name = nameUsage.getName();
169 Set<TaxonBase> candidateList = name.getTaxonBases();
170 for (TaxonBase candidate : candidateList){
171 if (candidate instanceof Taxon){
172 if (isInTreatment(candidate, treatmentReference, false)){
173 return (Taxon)candidate;
174 }
175 }else if (candidate instanceof Synonym){
176 Synonym synonym = (Synonym)candidate;
177 Set<Taxon> accTaxa = synonym.getAcceptedTaxa();
178 if (isInTreatment(synonym, treatmentReference, true)){
179 hasSynonymInTreatment = true;
180 }
181 for (Taxon accTaxon : accTaxa){
182 if (isInTreatment(accTaxon, treatmentReference, false)){
183 return accTaxon;
184 }
185 }
186 }else{
187 throw new IllegalStateException("TaxonBase should be either a Taxon or a Synonym but was " + nameUsage.getClass().getName());
188 }
189 }
190 if (hasSynonymInTreatment){
191 logger.warn("Non treatment taxon has synonym in treatment but no accepted taxon: " + nameUsage + " (" + nameUsage.getId() +")" );
192 }
193 return null;
194 }
195
196 /**
197 * @param taxonBase
198 * @param treatmentReference
199 * @return
200 */
201 private boolean isInTreatment(TaxonBase taxonBase, IReference treatmentReference, boolean silent) {
202 if (taxonBase.getSec().equals(treatmentReference)){
203 //treatment taxa
204 if (! silent){
205 if (taxonBase instanceof Taxon){
206 if (((Taxon)taxonBase).getTaxonNodes().size()< 1){
207 logger.warn("Taxon has treatment sec but is not in tree: " + taxonBase + " (" + taxonBase.getId() +")" );
208 }
209 }else if (taxonBase instanceof Synonym){
210 Synonym synonym = (Synonym)taxonBase;
211 boolean hasAccTaxonInTreatment = false;
212 for (Taxon accTaxon : synonym.getAcceptedTaxa()){
213 hasAccTaxonInTreatment |= isInTreatment(accTaxon, treatmentReference, false);
214 }
215 if (hasAccTaxonInTreatment == false){
216 logger.warn("Synonym has treatment reference but has no accepted taxon in tree: " + taxonBase + " (" + taxonBase.getId() +")" );
217 }
218 }else{
219 throw new IllegalStateException("TaxonBase should be either Taxon or Synonym");
220 }
221 }
222 return true;
223 }else{
224 //taxon not in treatment
225 if (! silent){
226 if (taxonBase instanceof Taxon){
227 if (((Taxon)taxonBase).getTaxonNodes().size()> 0){
228 logger.warn("Taxon has no treatment sec but is in tree: " + taxonBase + " (" + taxonBase.getId() +")" );
229 }
230 }else if (taxonBase instanceof Synonym){
231 Synonym synonym = (Synonym)taxonBase;
232 boolean hasAccTaxonInTreatment = false;
233 for (Taxon accTaxon : synonym.getAcceptedTaxa()){
234 hasAccTaxonInTreatment |= isInTreatment(accTaxon, treatmentReference, false);
235 }
236 if (hasAccTaxonInTreatment == true){
237 logger.warn("Synonym has no treatment reference but has accepted taxon in treatment: " + taxonBase + " (" + taxonBase.getId() +")" );
238 }
239 }else{
240 throw new IllegalStateException("TaxonBase should be either Taxon or Synonym but was ");
241 }
242 }
243 return false;
244 }
245 }
246
247 /**
248 * @param taxonCandidate
249 * @param taxon
250 */
251 private boolean addNameUsage(Taxon taxon, TaxonBase nameUsageTaxon) {
252 TaxonDescription myDescription = null;
253 for (TaxonDescription desc : taxon.getDescriptions()){
254 if (! desc.isImageGallery()){
255 myDescription = desc;
256 break;
257 }
258 }
259 if (myDescription == null){
260 return false;
261 }
262 TextData textData = TextData.NewInstance(Feature.CITATION());
263 //creates text (name: reference)
264 //textData.putText(nameUsageTaxon.getName().getTitleCache()+": " + nameUsageTaxon.getSec().getTitleCache(), Language.DEFAULT());
265 textData.addSource(OriginalSourceType.PrimaryTaxonomicSource, null, null, nameUsageTaxon.getSec(), null, nameUsageTaxon.getName(), nameUsageTaxon.getName().getTitleCache());
266 myDescription.addElement(textData);
267 return true;
268 }
269
270
271 /**
272 * @param args
273 */
274 public static void main(String[] args) {
275 PalmaePostImportUpdater updater = new PalmaePostImportUpdater();
276 try {
277 updater.updateMissingFeatures(cdmDestination);
278 updater.updateNameUsage(cdmDestination);
279 } catch (Exception e) {
280 e.printStackTrace();
281 logger.error("ERROR in feature tree update");
282 }
283 }
284 }