merge-update from trunk
[cdmlib.git] / cdmlib-services / src / main / java / eu / etaxonomy / cdm / api / service / NameServiceImpl.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.api.service;
12
13 import java.io.IOException;
14 import java.util.ArrayList;
15 import java.util.Collection;
16 import java.util.HashMap;
17 import java.util.HashSet;
18 import java.util.Iterator;
19 import java.util.List;
20 import java.util.Map;
21 import java.util.Set;
22 import java.util.UUID;
23
24 import org.apache.log4j.Logger;
25 import org.apache.lucene.index.CorruptIndexException;
26 import org.apache.lucene.index.Term;
27 import org.apache.lucene.queryParser.ParseException;
28 import org.apache.lucene.search.BooleanClause.Occur;
29 import org.apache.lucene.search.BooleanQuery;
30 import org.apache.lucene.search.FuzzyLikeThisQuery;
31 import org.apache.lucene.search.TopDocs;
32 import org.apache.lucene.search.WildcardQuery;
33 import org.hibernate.criterion.Criterion;
34 import org.springframework.beans.factory.annotation.Autowired;
35 import org.springframework.beans.factory.annotation.Qualifier;
36 import org.springframework.dao.DataAccessException;
37 import org.springframework.stereotype.Service;
38 import org.springframework.transaction.annotation.Transactional;
39
40 import eu.etaxonomy.cdm.api.service.config.DeleteConfiguratorBase;
41 import eu.etaxonomy.cdm.api.service.config.NameDeletionConfigurator;
42 import eu.etaxonomy.cdm.api.service.exception.ReferencedObjectUndeletableException;
43 import eu.etaxonomy.cdm.api.service.pager.Pager;
44 import eu.etaxonomy.cdm.api.service.pager.impl.AbstractPagerImpl;
45 import eu.etaxonomy.cdm.api.service.pager.impl.DefaultPagerImpl;
46 import eu.etaxonomy.cdm.api.service.search.DocumentSearchResult;
47 import eu.etaxonomy.cdm.api.service.search.ILuceneIndexToolProvider;
48 import eu.etaxonomy.cdm.api.service.search.ISearchResultBuilder;
49 import eu.etaxonomy.cdm.api.service.search.LuceneSearch;
50 import eu.etaxonomy.cdm.api.service.search.QueryFactory;
51 import eu.etaxonomy.cdm.api.service.search.SearchResult;
52 import eu.etaxonomy.cdm.api.service.search.SearchResultBuilder;
53 import eu.etaxonomy.cdm.common.monitor.IProgressMonitor;
54 import eu.etaxonomy.cdm.database.PermissionDeniedException;
55 import eu.etaxonomy.cdm.hibernate.HibernateProxyHelper;
56 import eu.etaxonomy.cdm.model.CdmBaseType;
57 import eu.etaxonomy.cdm.model.common.CdmBase;
58 import eu.etaxonomy.cdm.model.common.Language;
59 import eu.etaxonomy.cdm.model.common.OrderedTermVocabulary;
60 import eu.etaxonomy.cdm.model.common.ReferencedEntityBase;
61 import eu.etaxonomy.cdm.model.common.RelationshipBase;
62 import eu.etaxonomy.cdm.model.common.RelationshipBase.Direction;
63 import eu.etaxonomy.cdm.model.common.TermVocabulary;
64 import eu.etaxonomy.cdm.model.common.UuidAndTitleCache;
65 import eu.etaxonomy.cdm.model.description.DescriptionElementSource;
66 import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
67 import eu.etaxonomy.cdm.model.name.HybridRelationship;
68 import eu.etaxonomy.cdm.model.name.HybridRelationshipType;
69 import eu.etaxonomy.cdm.model.name.NameRelationship;
70 import eu.etaxonomy.cdm.model.name.NameRelationshipType;
71 import eu.etaxonomy.cdm.model.name.NameTypeDesignation;
72 import eu.etaxonomy.cdm.model.name.NomenclaturalStatus;
73 import eu.etaxonomy.cdm.model.name.NomenclaturalStatusType;
74 import eu.etaxonomy.cdm.model.name.NonViralName;
75 import eu.etaxonomy.cdm.model.name.Rank;
76 import eu.etaxonomy.cdm.model.name.SpecimenTypeDesignationStatus;
77 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
78 import eu.etaxonomy.cdm.model.name.TypeDesignationBase;
79 import eu.etaxonomy.cdm.model.occurrence.DerivedUnit;
80 import eu.etaxonomy.cdm.persistence.dao.common.ICdmGenericDao;
81 import eu.etaxonomy.cdm.persistence.dao.common.IOrderedTermVocabularyDao;
82 import eu.etaxonomy.cdm.persistence.dao.common.IReferencedEntityDao;
83 import eu.etaxonomy.cdm.persistence.dao.common.ITermVocabularyDao;
84 import eu.etaxonomy.cdm.persistence.dao.name.IHomotypicalGroupDao;
85 import eu.etaxonomy.cdm.persistence.dao.name.INomenclaturalStatusDao;
86 import eu.etaxonomy.cdm.persistence.dao.name.ITaxonNameDao;
87 import eu.etaxonomy.cdm.persistence.dao.name.ITypeDesignationDao;
88 import eu.etaxonomy.cdm.persistence.query.MatchMode;
89 import eu.etaxonomy.cdm.persistence.query.OrderHint;
90 import eu.etaxonomy.cdm.strategy.cache.TaggedText;
91 import eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy;
92 import eu.etaxonomy.cdm.strategy.parser.NonViralNameParserImpl;
93
94
95 @Service
96 @Transactional(readOnly = true)
97 public class NameServiceImpl extends IdentifiableServiceBase<TaxonNameBase,ITaxonNameDao> implements INameService {
98 static private final Logger logger = Logger.getLogger(NameServiceImpl.class);
99
100 @Autowired
101 protected ITermVocabularyDao vocabularyDao;
102 @Autowired
103 protected IOrderedTermVocabularyDao orderedVocabularyDao;
104 @Autowired
105 @Qualifier("refEntDao")
106 protected IReferencedEntityDao<ReferencedEntityBase> referencedEntityDao;
107 @Autowired
108 private INomenclaturalStatusDao nomStatusDao;
109 @Autowired
110 private ITypeDesignationDao typeDesignationDao;
111 @Autowired
112 private IHomotypicalGroupDao homotypicalGroupDao;
113 @Autowired
114 private ICdmGenericDao genericDao;
115 @Autowired
116 private ILuceneIndexToolProvider luceneIndexToolProvider;
117
118 /**
119 * Constructor
120 */
121 public NameServiceImpl(){
122 if (logger.isDebugEnabled()) { logger.debug("Load NameService Bean"); }
123 }
124
125 //********************* METHODS ****************************************************************//
126
127 /* (non-Javadoc)
128 * @see eu.etaxonomy.cdm.api.service.ServiceBase#delete(eu.etaxonomy.cdm.model.common.CdmBase)
129 */
130 @Override
131 public DeleteResult delete(TaxonNameBase name){
132 NameDeletionConfigurator config = new NameDeletionConfigurator();
133 DeleteResult result = delete(name, config);
134
135
136 return result;
137
138 }
139
140 /* (non-Javadoc)
141 * @see eu.etaxonomy.cdm.api.service.INameService#delete(eu.etaxonomy.cdm.model.name.TaxonNameBase, eu.etaxonomy.cdm.api.service.NameDeletionConfigurator)
142 */
143 @Override
144 public DeleteResult delete(TaxonNameBase name, NameDeletionConfigurator config) {
145 DeleteResult result = new DeleteResult();
146
147 if (name == null){
148 result.setAbort();
149 return result;
150 }
151 List<String> messages = new ArrayList<String>();
152 try{
153 messages = this.isDeletable(name, config);
154 }catch(Exception e){
155 result.addException(e);
156 result.setError();
157 return result;
158 }
159 if (messages.isEmpty()){
160 //remove references to this name
161 // if (config.isRemoveAllNameRelationships()){
162 removeNameRelationshipsByDeleteConfig(name, config);
163 //}
164 //remove name from homotypical group
165 HomotypicalGroup homotypicalGroup = name.getHomotypicalGroup();
166 if (homotypicalGroup != null){
167 homotypicalGroup.removeTypifiedName(name);
168 }
169
170
171
172
173
174
175 /*check if this name is still used somewhere
176
177 //name relationships
178 if (! name.getNameRelations().isEmpty() && !config.isRemoveAllNameRelationships()){
179 String message = "Name can't be deleted as it is used in name relationship(s). Remove name relationships prior to deletion.";
180 throw new ReferencedObjectUndeletableException(message);
181 // return null;
182 }
183
184 //concepts
185 if (! name.getTaxonBases().isEmpty()){
186 String message = "Name can't be deleted as it is used in concept(s). Remove or change concept prior to deletion.";
187 throw new ReferencedObjectUndeletableException(message);
188 }
189
190 //hybrid relationships
191 if (name.isInstanceOf(NonViralName.class)){
192 NonViralName nvn = CdmBase.deproxy(name, NonViralName.class);
193 // if (! nvn.getHybridChildRelations().isEmpty()){
194 // String message = "Name can't be deleted as it is a child in (a) hybrid relationship(s). Remove hybrid relationships prior to deletion.";
195 // throw new RuntimeException(message);
196 // }
197 if (! nvn.getHybridParentRelations().isEmpty()){
198 String message = "Name can't be deleted as it is a parent in (a) hybrid relationship(s). Remove hybrid relationships prior to deletion.";
199 throw new ReferencedObjectUndeletableException(message);
200 }
201 }
202 */
203 //all type designation relationships are removed as they belong to the name
204 deleteTypeDesignation(name, null);
205 // //type designations
206 // if (! name.getTypeDesignations().isEmpty()){
207 // String message = "Name can't be deleted as it has types. Remove types prior to deletion.";
208 // throw new ReferrencedObjectUndeletableException(message);
209 // }
210
211 /*check references with only reverse mapping
212 Set<CdmBase> referencingObjects = genericDao.getReferencingObjects(name);
213 for (CdmBase referencingObject : referencingObjects){
214 //DerivedUnit?.storedUnder
215 if (referencingObject.isInstanceOf(DerivedUnit.class)){
216 String message = "Name can't be deleted as it is used as derivedUnit#storedUnder by %s. Remove 'stored under' prior to deleting this name";
217 message = String.format(message, CdmBase.deproxy(referencingObject, DerivedUnit.class).getTitleCache());
218 throw new ReferencedObjectUndeletableException(message);
219 }
220 //DescriptionElementSource#nameUsedInSource
221 if (referencingObject.isInstanceOf(DescriptionElementSource.class)){
222 String message = "Name can't be deleted as it is used as descriptionElementSource#nameUsedInSource";
223 throw new ReferencedObjectUndeletableException(message);
224 }
225 //NameTypeDesignation#typeName
226 if (referencingObject.isInstanceOf(NameTypeDesignation.class)){
227 String message = "Name can't be deleted as it is used as a name type in a NameTypeDesignation";
228 throw new ReferencedObjectUndeletableException(message);
229 }
230
231 //TaxonNameDescriptions#taxonName
232 //deleted via cascade?
233
234 //NomenclaturalStatus
235 //deleted via cascade?
236
237 }
238
239 //TODO inline references
240
241 if (!config.isIgnoreIsBasionymFor() && name.isGroupsBasionym()){
242 String message = "Name can't be deleted as it is a basionym.";
243 throw new ReferencedObjectUndeletableException(message);
244 }
245 if (!config.isIgnoreHasBasionym() && (name.getBasionyms().size()>0)){
246 String message = "Name can't be deleted as it has a basionym.";
247 throw new ReferencedObjectUndeletableException(message);
248 }
249 if (!config.isIgnoreIsReplacedSynonymFor() && name.isReplacedSynonym()){
250 String message = "Name can't be deleted as it is a replaced synonym.";
251 throw new ReferencedObjectUndeletableException(message);
252 }
253 if (!config.isIgnoreHasReplacedSynonym() && (name.getReplacedSynonyms().size()>0)){
254 String message = "Name can't be deleted as it has a replaced synonym.";
255 throw new ReferencedObjectUndeletableException(message);
256 }
257
258 */
259 try{
260 UUID nameUuid = dao.delete(name);
261 }catch(Exception e){
262 result.addException(e);
263 result.setError();
264 }
265 return result;
266 }
267
268 for (String message: messages){
269 result.addException(new ReferencedObjectUndeletableException(message));
270 }
271 result.setError();
272 return result;
273 }
274
275 /* (non-Javadoc)
276 * @see eu.etaxonomy.cdm.api.service.INameService#deleteTypeDesignation(eu.etaxonomy.cdm.model.name.TaxonNameBase, eu.etaxonomy.cdm.model.name.TypeDesignationBase)
277 */
278 @Override
279 public void deleteTypeDesignation(TaxonNameBase name, TypeDesignationBase typeDesignation){
280 if (name == null && typeDesignation == null){
281 return;
282 }else if (name != null && typeDesignation != null){
283 removeSingleDesignation(name, typeDesignation);
284 }else if (name != null){
285 Set<TypeDesignationBase> designationSet = new HashSet<TypeDesignationBase>(name.getTypeDesignations());
286 for (Object o : designationSet){
287 TypeDesignationBase desig = CdmBase.deproxy(o, TypeDesignationBase.class);
288 removeSingleDesignation(name, desig);
289 }
290 }else if (typeDesignation != null){
291 Set<TaxonNameBase> nameSet = new HashSet<TaxonNameBase>(typeDesignation.getTypifiedNames());
292 for (Object o : nameSet){
293 TaxonNameBase singleName = CdmBase.deproxy(o, TaxonNameBase.class);
294 removeSingleDesignation(singleName, typeDesignation);
295 }
296 }
297 }
298
299 /**
300 * @param name
301 * @param typeDesignation
302 */
303 private void removeSingleDesignation(TaxonNameBase name, TypeDesignationBase typeDesignation) {
304 name.removeTypeDesignation(typeDesignation);
305 if (typeDesignation.getTypifiedNames().isEmpty()){
306 typeDesignation.removeType();
307 typeDesignationDao.delete(typeDesignation);
308 }
309 }
310
311
312
313 /**
314 * @param name
315 * @param config
316 */
317 private void removeNameRelationshipsByDeleteConfig(TaxonNameBase<?,?> name, NameDeletionConfigurator config) {
318 try {
319 if (config.isRemoveAllNameRelationships()){
320 Set<NameRelationship> rels = getModifiableSet(name.getNameRelations());
321 for (NameRelationship rel : rels){
322 name.removeNameRelationship(rel);
323 }
324 }else{
325 //relations to this name
326 Set<NameRelationship> rels = getModifiableSet(name.getRelationsToThisName());
327 for (NameRelationship rel : rels){
328 if (config.isIgnoreHasBasionym() && NameRelationshipType.BASIONYM().equals(rel.getType() )){
329 name.removeNameRelationship(rel);
330 }else if (config.isIgnoreHasReplacedSynonym() && NameRelationshipType.REPLACED_SYNONYM().equals(rel.getType())){
331 name.removeNameRelationship(rel);
332 }
333 }
334 //relations from this name
335 rels = getModifiableSet(name.getRelationsFromThisName());
336 for (NameRelationship rel : rels){
337 if (config.isIgnoreIsBasionymFor() && NameRelationshipType.BASIONYM().equals(rel.getType()) ){
338 name.removeNameRelationship(rel);
339 }else if (config.isIgnoreIsReplacedSynonymFor() && NameRelationshipType.REPLACED_SYNONYM().equals(rel.getType())){
340 name.removeNameRelationship(rel);
341 }
342 }
343
344 }
345 } catch (Exception e) {
346 throw new RuntimeException(e);
347 }
348 }
349
350 /**
351 * @param name
352 * @return
353 */
354 private Set<NameRelationship> getModifiableSet(Set<NameRelationship> relations) {
355 Set<NameRelationship> rels = new HashSet<NameRelationship>();
356 for (NameRelationship rel : relations){
357 rels.add(rel);
358 }
359 return rels;
360 }
361
362 //********************* METHODS ****************************************************************//
363
364 /**
365 * @deprecated To be removed for harmonization see http://dev.e-taxonomy.eu/trac/wiki/CdmLibraryConventions
366 * duplicate of findByName
367 */
368 @Override
369 @Deprecated
370 public List getNamesByName(String name){
371 return super.findCdmObjectsByTitle(name);
372 }
373
374 /**
375 * TODO candidate for harmonization
376 * new name findByName
377 */
378 @Override
379 public List<NonViralName> getNamesByNameCache(String nameCache){
380 List result = dao.findByName(nameCache, MatchMode.EXACT, null, null, null, null);
381 return result;
382 }
383
384
385 /**
386 * TODO candidate for harmonization
387 * new name saveHomotypicalGroups
388 *
389 * findByTitle
390 */
391 @Override
392 public List<NonViralName> findNamesByTitleCache(String titleCache, MatchMode matchMode, List<String> propertyPaths){
393 List result = dao.findByTitle(titleCache, matchMode, null, null, null ,propertyPaths);
394 return result;
395 }
396
397 /**
398 * TODO candidate for harmonization
399 * new name saveHomotypicalGroups
400 *
401 * findByTitle
402 */
403 @Override
404 public List<NonViralName> findNamesByNameCache(String nameCache, MatchMode matchMode, List<String> propertyPaths){
405 List result = dao.findByName(nameCache, matchMode, null, null, null ,propertyPaths);
406 return result;
407 }
408
409 /**
410 * @deprecated To be removed for harmonization see http://dev.e-taxonomy.eu/trac/wiki/CdmLibraryConventions
411 * Replace by load(UUID, propertyPaths)
412 */
413 @Override
414 @Deprecated
415 public NonViralName findNameByUuid(UUID uuid, List<String> propertyPaths){
416 return (NonViralName)dao.findByUuid(uuid, null ,propertyPaths);
417 }
418
419 /**
420 * TODO candidate for harmonization
421 */
422 @Override
423 public List getNamesByName(String name, CdmBase sessionObject){
424 return super.findCdmObjectsByTitle(name, sessionObject);
425 }
426
427 /**
428 * @deprecated To be removed for harmonization see http://dev.e-taxonomy.eu/trac/wiki/CdmLibraryConventions
429 * duplicate of findByTitle(clazz, queryString, matchmode, criteria, pageSize, pageNumber, orderHints, propertyPaths)
430 */
431 @Override
432 @Deprecated
433 public List findNamesByTitle(String title){
434 return super.findCdmObjectsByTitle(title);
435 }
436
437 /**
438 * @deprecated To be removed for harmonization see http://dev.e-taxonomy.eu/trac/wiki/CdmLibraryConventions
439 * duplicate of findByTitle()
440 */
441 @Override
442 @Deprecated
443 public List findNamesByTitle(String title, CdmBase sessionObject){
444 return super.findCdmObjectsByTitle(title, sessionObject);
445 }
446
447 /**
448 * TODO candidate for harmonization
449 * new name saveHomotypicalGroups
450 */
451 @Override
452 @Transactional(readOnly = false)
453 public Map<UUID, HomotypicalGroup> saveAllHomotypicalGroups(Collection<HomotypicalGroup> homotypicalGroups){
454 return homotypicalGroupDao.saveAll(homotypicalGroups);
455 }
456
457 /**
458 * TODO candidate for harmonization
459 * new name saveTypeDesignations
460 */
461 @Override
462 @Transactional(readOnly = false)
463 public Map<UUID, TypeDesignationBase> saveTypeDesignationAll(Collection<TypeDesignationBase> typeDesignationCollection){
464 return typeDesignationDao.saveAll(typeDesignationCollection);
465 }
466
467 /**
468 * TODO candidate for harmonization
469 * new name saveReferencedEntities
470 */
471 @Override
472 @Transactional(readOnly = false)
473 public Map<UUID, ReferencedEntityBase> saveReferencedEntitiesAll(Collection<ReferencedEntityBase> referencedEntityCollection){
474 return referencedEntityDao.saveAll(referencedEntityCollection);
475 }
476
477 /**
478 * TODO candidate for harmonization
479 * new name getNames
480 */
481 public List<TaxonNameBase> getAllNames(int limit, int start){
482 return dao.list(limit, start);
483 }
484
485 /**
486 * TODO candidate for harmonization
487 * new name getNomenclaturalStatus
488 */
489 @Override
490 public List<NomenclaturalStatus> getAllNomenclaturalStatus(int limit, int start){
491 return nomStatusDao.list(limit, start);
492 }
493
494 /**
495 * TODO candidate for harmonization
496 * new name getTypeDesignations
497 */
498 @Override
499 public List<TypeDesignationBase> getAllTypeDesignations(int limit, int start){
500 return typeDesignationDao.getAllTypeDesignations(limit, start);
501 }
502 /**
503 * FIXME Candidate for harmonization
504 * homotypicalGroupService.list
505 */
506 @Override
507 public List<HomotypicalGroup> getAllHomotypicalGroups(int limit, int start){
508 return homotypicalGroupDao.list(limit, start);
509 }
510
511 /**
512 * FIXME Candidate for harmonization
513 * remove
514 */
515 @Override
516 @Deprecated
517 public List<RelationshipBase> getAllRelationships(int limit, int start){
518 return dao.getAllRelationships(limit, start);
519 }
520
521 /**
522 * FIXME Candidate for harmonization
523 * is this not the same as termService.getVocabulary(VocabularyEnum.Rank)
524 * since this returns OrderedTermVocabulary
525 *
526 * (non-Javadoc)
527 * @see eu.etaxonomy.cdm.api.service.INameService#getRankVocabulary()
528 */
529 @Override
530 public OrderedTermVocabulary<Rank> getRankVocabulary() {
531 String uuidString = "ef0d1ce1-26e3-4e83-b47b-ca74eed40b1b";
532 UUID uuid = UUID.fromString(uuidString);
533 OrderedTermVocabulary<Rank> rankVocabulary =
534 (OrderedTermVocabulary)orderedVocabularyDao.findByUuid(uuid);
535 return rankVocabulary;
536 }
537
538 /**
539 * FIXME Candidate for harmonization
540 * is this the same as termService.getVocabulary(VocabularyEnum.NameRelationshipType)
541 * (non-Javadoc)
542 * @see eu.etaxonomy.cdm.api.service.INameService#getNameRelationshipTypeVocabulary()
543 */
544 @Override
545 public TermVocabulary<NameRelationshipType> getNameRelationshipTypeVocabulary() {
546 String uuidString = "6878cb82-c1a4-4613-b012-7e73b413c8cd";
547 UUID uuid = UUID.fromString(uuidString);
548 TermVocabulary<NameRelationshipType> nameRelTypeVocabulary =
549 vocabularyDao.findByUuid(uuid);
550 return nameRelTypeVocabulary;
551 }
552
553 /**
554 * FIXME Candidate for harmonization
555 * is this the same as termService.getVocabulary(VocabularyEnum.StatusType)
556 * (non-Javadoc)
557 * @see eu.etaxonomy.cdm.api.service.INameService#getStatusTypeVocabulary()
558 */
559 @Override
560 public TermVocabulary<NomenclaturalStatusType> getStatusTypeVocabulary() {
561 String uuidString = "bb28cdca-2f8a-4f11-9c21-517e9ae87f1f";
562 UUID uuid = UUID.fromString(uuidString);
563 TermVocabulary<NomenclaturalStatusType> nomStatusTypeVocabulary =
564 vocabularyDao.findByUuid(uuid);
565 return nomStatusTypeVocabulary;
566 }
567
568 /**
569 * FIXME Candidate for harmonization
570 * is this the same as termService.getVocabulary(VocabularyEnum.SpecimenTypeDesignationStatus)
571 * (non-Javadoc)
572 * @see eu.etaxonomy.cdm.api.service.INameService#getTypeDesignationStatusVocabulary()
573 */
574 @Override
575 public TermVocabulary<SpecimenTypeDesignationStatus> getSpecimenTypeDesignationStatusVocabulary() {
576 String uuidString = "ab177bd7-d3c8-4e58-a388-226fff6ba3c2";
577 UUID uuid = UUID.fromString(uuidString);
578 TermVocabulary<SpecimenTypeDesignationStatus> typeDesigStatusVocabulary =
579 vocabularyDao.findByUuid(uuid);
580 return typeDesigStatusVocabulary;
581 }
582
583 /**
584 * FIXME Candidate for harmonization
585 * is this the same as termService.getVocabulary(VocabularyEnum.SpecimenTypeDesignationStatus)
586 * and also seems to duplicate the above method, differing only in the DAO used and the return type
587 * (non-Javadoc)
588 * @see eu.etaxonomy.cdm.api.service.INameService#getTypeDesignationStatusVocabulary()
589 */
590 @Override
591 public OrderedTermVocabulary<SpecimenTypeDesignationStatus> getSpecimenTypeDesignationVocabulary() {
592 String uuidString = "ab177bd7-d3c8-4e58-a388-226fff6ba3c2";
593 UUID uuid = UUID.fromString(uuidString);
594 OrderedTermVocabulary<SpecimenTypeDesignationStatus> typeDesignationVocabulary =
595 (OrderedTermVocabulary)orderedVocabularyDao.findByUuid(uuid);
596 return typeDesignationVocabulary;
597 }
598
599
600 @Override
601 @Autowired
602 protected void setDao(ITaxonNameDao dao) {
603 this.dao = dao;
604 }
605
606 @Override
607 public Pager<HybridRelationship> getHybridNames(NonViralName name, HybridRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
608 Integer numberOfResults = dao.countHybridNames(name, type);
609
610 List<HybridRelationship> results = new ArrayList<HybridRelationship>();
611 if(AbstractPagerImpl.hasResultsInRange(numberOfResults.longValue(), pageNumber, pageSize)) { // no point checking again
612 results = dao.getHybridNames(name, type, pageSize, pageNumber,orderHints,propertyPaths);
613 }
614
615 return new DefaultPagerImpl<HybridRelationship>(pageNumber, numberOfResults, pageSize, results);
616 }
617
618 /* (non-Javadoc)
619 * @see eu.etaxonomy.cdm.api.service.INameService#listNameRelationships(eu.etaxonomy.cdm.model.name.TaxonNameBase, eu.etaxonomy.cdm.model.common.RelationshipBase.Direction, eu.etaxonomy.cdm.model.name.NameRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
620 */
621 @Override
622 public List<NameRelationship> listNameRelationships(TaxonNameBase name, Direction direction, NameRelationshipType type, Integer pageSize,
623 Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
624
625 Integer numberOfResults = dao.countNameRelationships(name, direction, type);
626
627 List<NameRelationship> results = new ArrayList<NameRelationship>();
628 if (AbstractPagerImpl.hasResultsInRange(numberOfResults.longValue(), pageNumber, pageSize)) { // no point checking again
629 results = dao.getNameRelationships(name, direction, type, pageSize, pageNumber, orderHints, propertyPaths);
630 }
631 return results;
632 }
633
634
635 protected LuceneSearch prepareFindByFuzzyNameSearch(Class<? extends CdmBase> clazz,
636 NonViralName nvn,
637 float accuracy,
638 int maxNoOfResults,
639 List<Language> languages,
640 boolean highlightFragments) {
641 String similarity = Float.toString(accuracy);
642 String searchSuffix = "~" + similarity;
643
644
645 BooleanQuery finalQuery = new BooleanQuery(false);
646 BooleanQuery textQuery = new BooleanQuery(false);
647
648 LuceneSearch luceneSearch = new LuceneSearch(luceneIndexToolProvider, TaxonNameBase.class);
649 QueryFactory queryFactory = luceneIndexToolProvider.newQueryFactoryFor(TaxonNameBase.class);
650
651 // SortField[] sortFields = new SortField[]{SortField.FIELD_SCORE, new SortField("titleCache__sort", SortField.STRING, false)};
652 // luceneSearch.setSortFields(sortFields);
653
654 // ---- search criteria
655 luceneSearch.setCdmTypRestriction(clazz);
656
657 FuzzyLikeThisQuery fltq = new FuzzyLikeThisQuery(maxNoOfResults, luceneSearch.getAnalyzer());
658 if(nvn.getGenusOrUninomial() != null && !nvn.getGenusOrUninomial().equals("")) {
659 fltq.addTerms(nvn.getGenusOrUninomial().toLowerCase(), "genusOrUninomial", accuracy, 3);
660 } else {
661 //textQuery.add(new RegexQuery (new Term ("genusOrUninomial", "^[a-zA-Z]*")), Occur.MUST_NOT);
662 textQuery.add(queryFactory.newTermQuery("genusOrUninomial", "_null_", false), Occur.MUST);
663 }
664
665 if(nvn.getInfraGenericEpithet() != null && !nvn.getInfraGenericEpithet().equals("")){
666 fltq.addTerms(nvn.getInfraGenericEpithet().toLowerCase(), "infraGenericEpithet", accuracy, 3);
667 } else {
668 //textQuery.add(new RegexQuery (new Term ("infraGenericEpithet", "^[a-zA-Z]*")), Occur.MUST_NOT);
669 textQuery.add(queryFactory.newTermQuery("infraGenericEpithet", "_null_", false), Occur.MUST);
670 }
671
672 if(nvn.getSpecificEpithet() != null && !nvn.getSpecificEpithet().equals("")){
673 fltq.addTerms(nvn.getSpecificEpithet().toLowerCase(), "specificEpithet", accuracy, 3);
674 } else {
675 //textQuery.add(new RegexQuery (new Term ("specificEpithet", "^[a-zA-Z]*")), Occur.MUST_NOT);
676 textQuery.add(queryFactory.newTermQuery("specificEpithet", "_null_", false), Occur.MUST);
677 }
678
679 if(nvn.getInfraSpecificEpithet() != null && !nvn.getInfraSpecificEpithet().equals("")){
680 fltq.addTerms(nvn.getInfraSpecificEpithet().toLowerCase(), "infraSpecificEpithet", accuracy, 3);
681 } else {
682 //textQuery.add(new RegexQuery (new Term ("infraSpecificEpithet", "^[a-zA-Z]*")), Occur.MUST_NOT);
683 textQuery.add(queryFactory.newTermQuery("infraSpecificEpithet", "_null_", false), Occur.MUST);
684 }
685
686 if(nvn.getAuthorshipCache() != null && !nvn.getAuthorshipCache().equals("")){
687 fltq.addTerms(nvn.getAuthorshipCache().toLowerCase(), "authorshipCache", accuracy, 3);
688 } else {
689 //textQuery.add(new RegexQuery (new Term ("authorshipCache", "^[a-zA-Z]*")), Occur.MUST_NOT);
690 }
691
692 textQuery.add(fltq, Occur.MUST);
693
694 finalQuery.add(textQuery, Occur.MUST);
695
696 luceneSearch.setQuery(finalQuery);
697
698 if(highlightFragments){
699 luceneSearch.setHighlightFields(queryFactory.getTextFieldNamesAsArray());
700 }
701 return luceneSearch;
702 }
703
704 protected LuceneSearch prepareFindByFuzzyNameCacheSearch(Class<? extends CdmBase> clazz,
705 String name,
706 float accuracy,
707 int maxNoOfResults,
708 List<Language> languages,
709 boolean highlightFragments) {
710
711 LuceneSearch luceneSearch = new LuceneSearch(luceneIndexToolProvider, TaxonNameBase.class);
712 QueryFactory queryFactory = luceneIndexToolProvider.newQueryFactoryFor(TaxonNameBase.class);
713
714 // SortField[] sortFields = new SortField[]{SortField.FIELD_SCORE, new SortField("titleCache__sort", SortField.STRING, false)};
715 // luceneSearch.setSortFields(sortFields);
716
717 // ---- search criteria
718 luceneSearch.setCdmTypRestriction(clazz);
719 FuzzyLikeThisQuery fltq = new FuzzyLikeThisQuery(maxNoOfResults, luceneSearch.getAnalyzer());
720
721 fltq.addTerms(name, "nameCache", accuracy, 3);
722
723 BooleanQuery finalQuery = new BooleanQuery(false);
724
725 finalQuery.add(fltq, Occur.MUST);
726
727 luceneSearch.setQuery(finalQuery);
728
729 if(highlightFragments){
730 luceneSearch.setHighlightFields(queryFactory.getTextFieldNamesAsArray());
731 }
732 return luceneSearch;
733 }
734
735 protected LuceneSearch prepareFindByExactNameSearch(Class<? extends CdmBase> clazz,
736 String name,
737 boolean wildcard,
738 List<Language> languages,
739 boolean highlightFragments) {
740 BooleanQuery finalQuery = new BooleanQuery();
741 BooleanQuery textQuery = new BooleanQuery();
742
743 LuceneSearch luceneSearch = new LuceneSearch(luceneIndexToolProvider, TaxonNameBase.class);
744 QueryFactory queryFactory = luceneIndexToolProvider.newQueryFactoryFor(TaxonNameBase.class);
745
746 // SortField[] sortFields = new SortField[]{SortField.FIELD_SCORE, new SortField("titleCache__sort", SortField.STRING, false)};
747 // luceneSearch.setSortFields(sortFields);
748
749 // ---- search criteria
750 luceneSearch.setCdmTypRestriction(clazz);
751
752 if(name != null && !name.equals("")) {
753 if(wildcard) {
754 textQuery.add(new WildcardQuery(new Term("nameCache", name + "*")), Occur.MUST);
755 } else {
756 textQuery.add(queryFactory.newTermQuery("nameCache", name, false), Occur.MUST);
757 }
758 }
759
760 luceneSearch.setQuery(textQuery);
761
762 if(highlightFragments){
763 luceneSearch.setHighlightFields(queryFactory.getTextFieldNamesAsArray());
764 }
765 return luceneSearch;
766 }
767
768 @Override
769 public List<SearchResult<TaxonNameBase>> findByNameFuzzySearch(
770 String name,
771 float accuracy,
772 List<Language> languages,
773 boolean highlightFragments,
774 List<String> propertyPaths,
775 int maxNoOfResults) throws CorruptIndexException, IOException, ParseException {
776
777 logger.info("Name to fuzzy search for : " + name);
778 // parse the input name
779 NonViralNameParserImpl parser = new NonViralNameParserImpl();
780 NonViralName nvn = parser.parseFullName(name);
781 if(name != null && !name.equals("") && nvn == null) {
782 throw new ParseException("Could not parse name " + name);
783 }
784 LuceneSearch luceneSearch = prepareFindByFuzzyNameSearch(null, nvn, accuracy, maxNoOfResults, languages, highlightFragments);
785
786 // --- execute search
787 TopDocs topDocs = luceneSearch.executeSearch(maxNoOfResults);
788
789
790 Map<CdmBaseType, String> idFieldMap = new HashMap<CdmBaseType, String>();
791 idFieldMap.put(CdmBaseType.NONVIRALNAME, "id");
792
793 // --- initialize taxa, highlight matches ....
794 ISearchResultBuilder searchResultBuilder = new SearchResultBuilder(luceneSearch, luceneSearch.getQuery());
795
796 @SuppressWarnings("rawtypes")
797 List<SearchResult<TaxonNameBase>> searchResults = searchResultBuilder.createResultSet(
798 topDocs, luceneSearch.getHighlightFields(), dao, idFieldMap, propertyPaths);
799
800 return searchResults;
801
802 }
803
804 @Override
805 public List<DocumentSearchResult> findByNameFuzzySearch(
806 String name,
807 float accuracy,
808 List<Language> languages,
809 boolean highlightFragments,
810 int maxNoOfResults) throws CorruptIndexException, IOException, ParseException {
811
812 logger.info("Name to fuzzy search for : " + name);
813 // parse the input name
814 NonViralNameParserImpl parser = new NonViralNameParserImpl();
815 NonViralName nvn = parser.parseFullName(name);
816 if(name != null && !name.equals("") && nvn == null) {
817 throw new ParseException("Could not parse name " + name);
818 }
819 LuceneSearch luceneSearch = prepareFindByFuzzyNameSearch(null, nvn, accuracy, maxNoOfResults, languages, highlightFragments);
820
821 // --- execute search
822 TopDocs topDocs = luceneSearch.executeSearch(maxNoOfResults);
823
824 Map<CdmBaseType, String> idFieldMap = new HashMap<CdmBaseType, String>();
825
826 // --- initialize taxa, highlight matches ....
827 ISearchResultBuilder searchResultBuilder = new SearchResultBuilder(luceneSearch, luceneSearch.getQuery());
828
829 @SuppressWarnings("rawtypes")
830 List<DocumentSearchResult> searchResults = searchResultBuilder.createResultSet(topDocs, luceneSearch.getHighlightFields());
831
832 return searchResults;
833 }
834
835 @Override
836 public List<DocumentSearchResult> findByFuzzyNameCacheSearch(
837 String name,
838 float accuracy,
839 List<Language> languages,
840 boolean highlightFragments,
841 int maxNoOfResults) throws CorruptIndexException, IOException, ParseException {
842
843 logger.info("Name to fuzzy search for : " + name);
844
845 LuceneSearch luceneSearch = prepareFindByFuzzyNameCacheSearch(null, name, accuracy, maxNoOfResults, languages, highlightFragments);
846
847 // --- execute search
848 TopDocs topDocs = luceneSearch.executeSearch(maxNoOfResults);
849 Map<CdmBaseType, String> idFieldMap = new HashMap<CdmBaseType, String>();
850
851 // --- initialize taxa, highlight matches ....
852 ISearchResultBuilder searchResultBuilder = new SearchResultBuilder(luceneSearch, luceneSearch.getQuery());
853
854 @SuppressWarnings("rawtypes")
855 List<DocumentSearchResult> searchResults = searchResultBuilder.createResultSet(topDocs, luceneSearch.getHighlightFields());
856
857 return searchResults;
858 }
859
860 @Override
861 public List<DocumentSearchResult> findByNameExactSearch(
862 String name,
863 boolean wildcard,
864 List<Language> languages,
865 boolean highlightFragments,
866 int maxNoOfResults) throws CorruptIndexException, IOException, ParseException {
867
868 logger.info("Name to exact search for : " + name);
869
870 LuceneSearch luceneSearch = prepareFindByExactNameSearch(null, name, wildcard, languages, highlightFragments);
871
872 // --- execute search
873
874
875 TopDocs topDocs = luceneSearch.executeSearch(maxNoOfResults);
876
877 Map<CdmBaseType, String> idFieldMap = new HashMap<CdmBaseType, String>();
878
879 // --- initialize taxa, highlight matches ....
880 ISearchResultBuilder searchResultBuilder = new SearchResultBuilder(luceneSearch, luceneSearch.getQuery());
881
882 @SuppressWarnings("rawtypes")
883 List<DocumentSearchResult> searchResults = searchResultBuilder.createResultSet(topDocs, luceneSearch.getHighlightFields());
884
885 return searchResults;
886 }
887
888 /* (non-Javadoc)
889 * @see eu.etaxonomy.cdm.api.service.INameService#pageNameRelationships(eu.etaxonomy.cdm.model.name.TaxonNameBase, eu.etaxonomy.cdm.model.common.RelationshipBase.Direction, eu.etaxonomy.cdm.model.name.NameRelationshipType, java.lang.Integer, java.lang.Integer, java.util.List, java.util.List)
890 */
891 @Override
892 public Pager<NameRelationship> pageNameRelationships(TaxonNameBase name, Direction direction, NameRelationshipType type, Integer pageSize,
893 Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
894 List<NameRelationship> results = listNameRelationships(name, direction, type, pageSize, pageNumber, orderHints, propertyPaths);
895 return new DefaultPagerImpl<NameRelationship>(pageNumber, results.size(), pageSize, results);
896 }
897
898 @Override
899 public List<NameRelationship> listFromNameRelationships(TaxonNameBase name, NameRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
900 return listNameRelationships(name, Direction.relatedFrom, type, pageSize, pageNumber, orderHints, propertyPaths);
901 }
902
903 @Override
904 public Pager<NameRelationship> pageFromNameRelationships(TaxonNameBase name, NameRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
905 List<NameRelationship> results = listNameRelationships(name, Direction.relatedFrom, type, pageSize, pageNumber, orderHints, propertyPaths);
906 return new DefaultPagerImpl<NameRelationship>(pageNumber, results.size(), pageSize, results);
907 }
908
909 @Override
910 public List<NameRelationship> listToNameRelationships(TaxonNameBase name, NameRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
911 return listNameRelationships(name, Direction.relatedTo, type, pageSize, pageNumber, orderHints, propertyPaths);
912 }
913
914 @Override
915 public Pager<NameRelationship> pageToNameRelationships(TaxonNameBase name, NameRelationshipType type, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints, List<String> propertyPaths) {
916 List<NameRelationship> results = listNameRelationships(name, Direction.relatedTo, type, pageSize, pageNumber, orderHints, propertyPaths);
917 return new DefaultPagerImpl<NameRelationship>(pageNumber, results.size(), pageSize, results);
918 }
919
920 @Override
921 public Pager<TypeDesignationBase> getTypeDesignations(TaxonNameBase name, SpecimenTypeDesignationStatus status,
922 Integer pageSize, Integer pageNumber) {
923 return getTypeDesignations(name, status, pageSize, pageNumber, null);
924 }
925
926 @Override
927 public Pager<TypeDesignationBase> getTypeDesignations(TaxonNameBase name, SpecimenTypeDesignationStatus status,
928 Integer pageSize, Integer pageNumber, List<String> propertyPaths){
929 Integer numberOfResults = dao.countTypeDesignations(name, status);
930
931 List<TypeDesignationBase> results = new ArrayList<TypeDesignationBase>();
932 if(AbstractPagerImpl.hasResultsInRange(numberOfResults.longValue(), pageNumber, pageSize)) {
933 results = dao.getTypeDesignations(name, null, status, pageSize, pageNumber, propertyPaths);
934 }
935
936 return new DefaultPagerImpl<TypeDesignationBase>(pageNumber, numberOfResults, pageSize, results);
937 }
938
939 /**
940 * FIXME Candidate for harmonization
941 * rename search
942 */
943 @Override
944 public Pager<TaxonNameBase> searchNames(String uninomial,String infraGenericEpithet, String specificEpithet, String infraspecificEpithet, Rank rank, Integer pageSize, Integer pageNumber, List<OrderHint> orderHints,
945 List<String> propertyPaths) {
946 Integer numberOfResults = dao.countNames(uninomial, infraGenericEpithet, specificEpithet, infraspecificEpithet, rank);
947
948 List<TaxonNameBase> results = new ArrayList<TaxonNameBase>();
949 if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
950 results = dao.searchNames(uninomial, infraGenericEpithet, specificEpithet, infraspecificEpithet, rank, pageSize, pageNumber, orderHints, propertyPaths);
951 }
952
953 return new DefaultPagerImpl<TaxonNameBase>(pageNumber, numberOfResults, pageSize, results);
954 }
955
956 /* (non-Javadoc)
957 * @see eu.etaxonomy.cdm.api.service.INameService#getUuidAndTitleCacheOfNames()
958 */
959 @Override
960 public List<UuidAndTitleCache> getUuidAndTitleCacheOfNames() {
961 return dao.getUuidAndTitleCacheOfNames();
962 }
963
964 @Override
965 public Pager<TaxonNameBase> findByName(Class<? extends TaxonNameBase> clazz, String queryString, MatchMode matchmode, List<Criterion> criteria, Integer pageSize,Integer pageNumber, List<OrderHint> orderHints,List<String> propertyPaths) {
966 Integer numberOfResults = dao.countByName(clazz, queryString, matchmode, criteria);
967
968 List<TaxonNameBase> results = new ArrayList<TaxonNameBase>();
969 if(numberOfResults > 0) { // no point checking again //TODO use AbstractPagerImpl.hasResultsInRange(numberOfResults, pageNumber, pageSize)
970 results = dao.findByName(clazz, queryString, matchmode, criteria, pageSize, pageNumber, orderHints, propertyPaths);
971 }
972
973 return new DefaultPagerImpl<TaxonNameBase>(pageNumber, numberOfResults, pageSize, results);
974 }
975
976 @Override
977 public HomotypicalGroup findHomotypicalGroup(UUID uuid) {
978 return homotypicalGroupDao.findByUuid(uuid);
979 }
980
981
982 /* (non-Javadoc)
983 * @see eu.etaxonomy.cdm.api.service.IIdentifiableEntityService#updateTitleCache(java.lang.Integer, eu.etaxonomy.cdm.strategy.cache.common.IIdentifiableEntityCacheStrategy)
984 */
985 @Override
986 @Transactional(readOnly = false)
987 public void updateTitleCache(Class<? extends TaxonNameBase> clazz, Integer stepSize, IIdentifiableEntityCacheStrategy<TaxonNameBase> cacheStrategy, IProgressMonitor monitor) {
988 if (clazz == null){
989 clazz = TaxonNameBase.class;
990 }
991 super.updateTitleCacheImpl(clazz, stepSize, cacheStrategy, monitor);
992 }
993
994
995 @Override
996 protected void setOtherCachesNull(TaxonNameBase name) {
997 if (name.isInstanceOf(NonViralName.class)){
998 NonViralName<?> nvn = CdmBase.deproxy(name, NonViralName.class);
999 if (! nvn.isProtectedNameCache()){
1000 nvn.setNameCache(null, false);
1001 }
1002 if (! nvn.isProtectedAuthorshipCache()){
1003 nvn.setAuthorshipCache(null, false);
1004 }
1005 if (! nvn.isProtectedFullTitleCache()){
1006 nvn.setFullTitleCache(null, false);
1007 }
1008 }
1009 }
1010
1011 /* (non-Javadoc)
1012 * @see eu.etaxonomy.cdm.api.service.INameService#getTaggedName(eu.etaxonomy.cdm.model.name.TaxonNameBase)
1013 */
1014 @Override
1015 public List<TaggedText> getTaggedName(UUID uuid) {
1016 TaxonNameBase taxonNameBase = dao.load(uuid);
1017 List taggedName = taxonNameBase.getTaggedName();
1018 return taggedName;
1019 }
1020
1021 @Override
1022 public List<String> isDeletable(TaxonNameBase name, DeleteConfiguratorBase config){
1023 List<String> result = new ArrayList<String>();
1024 name = (TaxonNameBase)HibernateProxyHelper.deproxy(name);
1025 NameDeletionConfigurator nameConfig = null;
1026 if (config instanceof NameDeletionConfigurator){
1027 nameConfig = (NameDeletionConfigurator) config;
1028 }else{
1029 result.add("The delete configurator should be of the type NameDeletionConfigurator.");
1030 return result;
1031 }
1032
1033 if (!name.getNameRelations().isEmpty() && !nameConfig.isRemoveAllNameRelationships()){
1034 if (!nameConfig.isIgnoreIsBasionymFor() && name.isGroupsBasionym()){
1035 String message = "Name can't be deleted as it is a basionym.";
1036 result.add(message);
1037 }
1038 if (!nameConfig.isIgnoreHasBasionym() && (name.getBasionyms().size()>0)){
1039 String message = "Name can't be deleted as it has a basionym.";
1040 result.add(message);
1041 }
1042 Set<NameRelationship> relationships = name.getNameRelations();
1043 for (NameRelationship rel: relationships){
1044 if (!rel.getType().equals(NameRelationshipType.BASIONYM())){
1045 String message = "Name can't be deleted as it is used in name relationship(s). Remove name relationships prior to deletion.";
1046 result.add(message);
1047 break;
1048 }
1049
1050 }
1051
1052 }
1053
1054 //concepts
1055 if (! name.getTaxonBases().isEmpty()){
1056 String message = "Name can't be deleted as it is used in concept(s). Remove or change concept prior to deletion.";
1057 result.add(message);
1058 }
1059
1060 //hybrid relationships
1061 if (name.isInstanceOf(NonViralName.class)){
1062 NonViralName nvn = CdmBase.deproxy(name, NonViralName.class);
1063 if (! nvn.getHybridParentRelations().isEmpty()){
1064 String message = "Name can't be deleted as it is a parent in (a) hybrid relationship(s). Remove hybrid relationships prior to deletion.";
1065 result.add(message);
1066 }
1067 }
1068 Set<CdmBase> referencingObjects = genericDao.getReferencingObjects(name);
1069 for (CdmBase referencingObject : referencingObjects){
1070 //DerivedUnit?.storedUnder
1071 if (referencingObject.isInstanceOf(DerivedUnit.class)){
1072 String message = "Name can't be deleted as it is used as derivedUnit#storedUnder by %s. Remove 'stored under' prior to deleting this name";
1073 message = String.format(message, CdmBase.deproxy(referencingObject, DerivedUnit.class).getTitleCache());
1074 result.add(message);
1075 }
1076 //DescriptionElementSource#nameUsedInSource
1077 if (referencingObject.isInstanceOf(DescriptionElementSource.class)){
1078 String message = "Name can't be deleted as it is used as descriptionElementSource#nameUsedInSource";
1079 result.add(message);
1080 }
1081 //NameTypeDesignation#typeName
1082 if (referencingObject.isInstanceOf(NameTypeDesignation.class)){
1083 String message = "Name can't be deleted as it is used as a name type in a NameTypeDesignation";
1084 result.add(message);
1085 }
1086
1087
1088
1089 }
1090
1091 //TODO inline references
1092
1093
1094 if (!nameConfig.isIgnoreIsReplacedSynonymFor() && name.isReplacedSynonym()){
1095 String message = "Name can't be deleted as it is a replaced synonym.";
1096 result.add(message);
1097 }
1098 if (!nameConfig.isIgnoreHasReplacedSynonym() && (name.getReplacedSynonyms().size()>0)){
1099 String message = "Name can't be deleted as it has a replaced synonym.";
1100 result.add(message);
1101 }
1102 return result;
1103
1104 }
1105
1106
1107 }