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