Project

General

Profile

Download (27.4 KB) Statistics
| Branch: | Tag: | Revision:
1
/**
2
* Copyright (C) 2007 EDIT
3
* European Distributed Institute of Taxonomy
4
* http://www.e-taxonomy.eu
5
*
6
* The contents of this file are subject to the Mozilla Public License Version 1.1
7
* See LICENSE.TXT at the top of this package for the full license terms.
8
*/
9

    
10
package eu.etaxonomy.cdm.model.reference;
11

    
12
import java.beans.PropertyChangeEvent;
13
import java.beans.PropertyChangeListener;
14
import java.net.URI;
15
import java.util.List;
16

    
17
import javax.persistence.Column;
18
import javax.persistence.Embedded;
19
import javax.persistence.Entity;
20
import javax.persistence.FetchType;
21
import javax.persistence.Inheritance;
22
import javax.persistence.InheritanceType;
23
import javax.persistence.Lob;
24
import javax.persistence.ManyToOne;
25
import javax.persistence.Transient;
26
import javax.validation.constraints.NotNull;
27
import javax.validation.constraints.Pattern;
28
import javax.xml.bind.annotation.XmlAccessType;
29
import javax.xml.bind.annotation.XmlAccessorType;
30
import javax.xml.bind.annotation.XmlAttribute;
31
import javax.xml.bind.annotation.XmlElement;
32
import javax.xml.bind.annotation.XmlIDREF;
33
import javax.xml.bind.annotation.XmlRootElement;
34
import javax.xml.bind.annotation.XmlSchemaType;
35
import javax.xml.bind.annotation.XmlType;
36

    
37
import org.apache.commons.lang.StringUtils;
38
import org.apache.log4j.Logger;
39
import org.hibernate.annotations.Cascade;
40
import org.hibernate.annotations.CascadeType;
41
import org.hibernate.annotations.Table;
42
import org.hibernate.annotations.Type;
43
import org.hibernate.envers.Audited;
44
import org.hibernate.search.annotations.Analyze;
45
import org.hibernate.search.annotations.Field;
46
import org.hibernate.search.annotations.FieldBridge;
47
import org.hibernate.search.annotations.IndexedEmbedded;
48

    
49
import eu.etaxonomy.cdm.common.DOI;
50
import eu.etaxonomy.cdm.hibernate.search.DoiBridge;
51
import eu.etaxonomy.cdm.model.agent.Institution;
52
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
53
import eu.etaxonomy.cdm.model.common.TimePeriod;
54
import eu.etaxonomy.cdm.model.media.IdentifiableMediaEntity;
55
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
56
import eu.etaxonomy.cdm.strategy.cache.reference.DefaultReferenceCacheStrategy;
57
import eu.etaxonomy.cdm.strategy.cache.reference.INomenclaturalReferenceCacheStrategy;
58
import eu.etaxonomy.cdm.strategy.match.Match;
59
import eu.etaxonomy.cdm.strategy.match.MatchMode;
60
import eu.etaxonomy.cdm.strategy.merge.Merge;
61
import eu.etaxonomy.cdm.strategy.merge.MergeMode;
62
import eu.etaxonomy.cdm.strategy.parser.ParserProblem;
63
import eu.etaxonomy.cdm.validation.Level2;
64
import eu.etaxonomy.cdm.validation.Level3;
65
import eu.etaxonomy.cdm.validation.annotation.InReference;
66
import eu.etaxonomy.cdm.validation.annotation.NoRecursiveInReference;
67
import eu.etaxonomy.cdm.validation.annotation.NullOrNotEmpty;
68
import eu.etaxonomy.cdm.validation.annotation.ReferenceCheck;
69

    
70
/**
71
 * The class for references (information sources). Originally
72
 * an abstract class with many subclasses. Not it is only
73
 * one class implementing many interfaces for safe use.
74
 * <P>
75
 * This class corresponds to: <ul>
76
 * <li> PublicationCitation according to the TDWG ontology
77
 * <li> Publication according to the TCS
78
 * <li> Reference according to the ABCD schema
79
 * </ul>
80
 *
81
 * @author m.doering
82
 * @created 08-Nov-2007 13:06:47
83
 */
84
@XmlAccessorType(XmlAccessType.FIELD)
85
@XmlType(name = "Reference", propOrder = {
86
	"type",
87
	"uri",
88
    "abbrevTitleCache",
89
    "protectedAbbrevTitleCache",
90
	"nomenclaturallyRelevant",
91
    "authorship",
92
    "referenceAbstract",
93
    "title",
94
    "abbrevTitle",
95
    "editor",
96
	"volume",
97
	"pages",
98
	"edition",
99
    "isbn",
100
    "issn",
101
    "doi",
102
    "seriesPart",
103
    "datePublished",
104
    "publisher",
105
    "placePublished",
106
    "institution",
107
    "school",
108
    "organization",
109
    "inReference"
110
})
111
@XmlRootElement(name = "Reference")
112
@Entity
113
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
114
@Audited
115
@Table(appliesTo="Reference", indexes = { @org.hibernate.annotations.Index(name = "ReferenceTitleCacheIndex", columnNames = { "titleCache" }) })
116
//@InReference(groups=Level3.class)
117
@ReferenceCheck(groups=Level2.class)
118
@InReference(groups=Level3.class)
119
@NoRecursiveInReference(groups=Level3.class)  //may become Level1 in future  #
120
public class Reference
121
        extends IdentifiableMediaEntity<INomenclaturalReferenceCacheStrategy>
122
        implements IArticle, IBook, IPatent, IDatabase, IJournal, IBookSection,ICdDvd,
123
                   IGeneric,IInProceedings, IProceedings, IPrintSeries, IReport,
124
                   IThesis,IWebPage, IPersonalCommunication,
125
                   INomenclaturalReference, IReference,
126
                   Cloneable {
127

    
128
    private static final long serialVersionUID = -2034764545042691295L;
129
	private static final Logger logger = Logger.getLogger(Reference.class);
130

    
131
	@XmlAttribute(name ="type")
132
	@Column(name="refType")
133
	@NotNull
134
    @Type(type = "eu.etaxonomy.cdm.hibernate.EnumUserType",
135
    	parameters = {@org.hibernate.annotations.Parameter(name  = "enumClass", value = "eu.etaxonomy.cdm.model.reference.ReferenceType")}
136
    )
137
	@Audited
138
	protected ReferenceType type;
139

    
140
	//Title of the reference
141
	@XmlElement(name ="Title" )
142
	@Column(length=4096, name="title")
143
	@Lob
144
	@Field
145
	@Match(MatchMode.EQUAL_REQUIRED)
146
    //TODO Val #3379
147
//	@NullOrNotEmpty
148
	private String title;
149

    
150
	//Title of the reference
151
	@XmlElement(name ="AbbrevTitle" )
152
	@Field
153
	@Match(MatchMode.EQUAL)  //TODO check if this is correct
154
	@NullOrNotEmpty
155
	@Column(length=255)
156
	private String abbrevTitle;
157

    
158
	//Title of the reference
159
	@XmlElement(name ="AbbrevTitleCache" )
160
	@Field
161
	@Match(MatchMode.CACHE)
162
    //TODO Val #3379
163
//	@NotNull
164
	@Column(length=1024)
165
	private String abbrevTitleCache;
166

    
167
	@XmlElement(name = "protectedAbbrevTitleCache")
168
	@Merge(MergeMode.OR)
169
	private boolean protectedAbbrevTitleCache;
170

    
171
//********************************************************/
172

    
173

    
174
    @XmlElement(name = "Editor")
175
    @Field
176
    //TODO Val #3379
177
//    @NullOrNotEmpty
178
    @Column(length=255)
179
	protected String editor;
180

    
181
    @XmlElement(name = "Volume")
182
    @Field
183
    //TODO Val #3379
184
//    @NullOrNotEmpty
185
    @Column(length=255)
186
	protected String volume;
187

    
188
    @XmlElement(name = "Pages")
189
    @Field
190
    //TODO Val #3379
191
//    @NullOrNotEmpty
192
    @Column(length=255)
193
	protected String pages;
194

    
195
    @XmlElement(name = "Edition")
196
    @Field
197
    //TODO Val #3379
198
//    @NullOrNotEmpty
199
    @Column(length=255)
200
	protected String edition;
201

    
202
    @XmlElement(name = "ISBN")
203
    @Field
204
    //TODO Val #3379
205
//    @NullOrNotEmpty
206
    @Column(length=255)
207
	@Pattern(regexp = "(?=.{13}$)\\d{1,5}([- ])\\d{1,7}\\1\\d{1,6}\\1(\\d|X)$", groups = Level2.class, message = "{eu.etaxonomy.cdm.model.reference.Reference.isbn.message}")
208
	protected String isbn;
209

    
210
    @XmlElement(name = "Doi")
211
    @Field
212
    @FieldBridge(impl = DoiBridge.class)
213
    @Type(type="doiUserType")
214
    @Column(length=DOI.MAX_LENGTH)
215
    protected DOI doi;
216

    
217

    
218
	@XmlElement(name = "ISSN")
219
    @Field
220
    //TODO Val #3379
221
//	@NullOrNotEmpty
222
    @Column(length=255)
223
	@Pattern(regexp = "(?=.{9}$)\\d{4}([- ])\\d{4} (\\d|X)$", groups = Level2.class, message = "{eu.etaxonomy.cdm.model.reference.Reference.issn.message}")
224
	protected String issn;
225

    
226
    @XmlElement(name = "SeriesPart")
227
    @Field
228
    //TODO Val #3379
229
//    @NullOrNotEmpty
230
    @Column(length=255)
231
	protected String seriesPart;
232

    
233
	@XmlElement(name = "Organization")
234
    @Field
235
    //TODO Val #3379
236
//	@NullOrNotEmpty
237
    @Column(length=255)
238
	protected String organization;
239

    
240
	@XmlElement(name = "Publisher")
241
    @Field
242
    //TODO Val #3379
243
//	@NullOrNotEmpty
244
    @Column(length=255)
245
	protected String publisher;
246

    
247

    
248
	@XmlElement(name = "PlacePublished")
249
    @Field
250
    //TODO Val #3379
251
//	@NullOrNotEmpty
252
    @Column(length=255)
253
	protected String placePublished;
254

    
255
	@XmlElement(name = "Institution")
256
	@XmlIDREF
257
	@XmlSchemaType(name = "IDREF")
258
	@ManyToOne(fetch = FetchType.LAZY)
259
	@IndexedEmbedded
260
	@Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
261
	protected Institution institution;
262

    
263
	@XmlElement(name = "School")
264
    @XmlIDREF
265
    @XmlSchemaType(name = "IDREF")
266
	@ManyToOne(fetch = FetchType.LAZY)
267
	@IndexedEmbedded
268
	@Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
269
	protected Institution school;
270

    
271
    @XmlElement(name = "InReference")
272
    @XmlIDREF
273
    @XmlSchemaType(name = "IDREF")
274
    @ManyToOne(fetch = FetchType.LAZY)
275
//    @IndexedEmbedded
276
    @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
277
   // @InReference(groups=Level2.class)
278
   	protected Reference inReference;
279

    
280
//********************************************************/
281

    
282
	//The date range assigned to the reference. ISO Date range like. Flexible, year can be left out, etc
283
	@XmlElement(name ="DatePublished" )
284
	@Embedded
285
	@IndexedEmbedded
286
	private TimePeriod datePublished = TimePeriod.NewInstance();
287

    
288
	@XmlElement(name ="Abstract" )
289
	@Column(length=65536, name="referenceAbstract")
290
	@Lob
291
    @Field
292
    //TODO Val #3379
293
//	@NullOrNotEmpty
294
	private String referenceAbstract;  //abstract is a reserved term in Java
295

    
296

    
297
	//URIs like DOIs, LSIDs or Handles for this reference
298
	@XmlElement(name = "URI")
299
	@Field(analyze = Analyze.NO)
300
	@Type(type="uriUserType")
301
	private URI uri;
302

    
303
	//flag to subselect only references that could be useful for nomenclatural citations. If a reference is used as a
304
	//nomenclatural reference in a name this flag should be automatically set
305
	@XmlElement(name = "IsNomenclaturallyRelevant")
306
	@Merge(MergeMode.OR)
307
	private boolean nomenclaturallyRelevant;
308

    
309
	@XmlElement(name = "Authorship")
310
	@XmlIDREF
311
	@XmlSchemaType(name = "IDREF")
312
	@ManyToOne(fetch = FetchType.LAZY)
313
	@IndexedEmbedded
314
	@Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
315
	private TeamOrPersonBase<?> authorship;
316

    
317
	@XmlAttribute
318
    @Match(MatchMode.IGNORE)
319
	private int parsingProblem = 0;
320

    
321
	@XmlAttribute
322
    @Match(MatchMode.IGNORE)
323
    private int problemStarts = -1;
324

    
325
    @XmlAttribute
326
    @Match(MatchMode.IGNORE)
327
    private int problemEnds = -1;
328

    
329
    @Transient
330
    @XmlAttribute
331
    @Match(MatchMode.IGNORE)
332
	private boolean cacheStrategyRectified = false;
333

    
334
    protected Reference(){
335
		this(ReferenceType.Generic);  //just in case someone uses constructor
336
	}
337

    
338
	protected Reference(ReferenceType type) {
339
		super();
340
	    if (type == null){
341
			this.type = ReferenceType.Generic;
342
		} else{
343
			this.type = type;
344
		}
345
		this.setCacheStrategy(DefaultReferenceCacheStrategy.NewInstance());
346
	}
347

    
348
	@Override
349
    public void initListener(){
350
        PropertyChangeListener listener = new PropertyChangeListener() {
351
            @Override
352
            public void propertyChange(PropertyChangeEvent ev) {
353
            	if (!ev.getPropertyName().equals("titleCache") && !ev.getPropertyName().equals("abbrevTitleCache") && !ev.getPropertyName().equals("cacheStrategy")){
354
            		if (! isProtectedTitleCache()){
355
            			titleCache = null;
356
            		}
357
            		if (! isProtectedAbbrevTitleCache()){
358
            			abbrevTitleCache = null;
359
            		}
360
            	}
361
            }
362
        };
363
        addPropertyChangeListener(listener);
364
    }
365

    
366

    
367
//*************************** GETTER / SETTER ******************************************/
368

    
369

    
370
	@Override
371
	public String getAbbrevTitleCache() {
372
		if (protectedAbbrevTitleCache){
373
            return this.abbrevTitleCache;
374
        }
375
        // is reference dirty, i.e. equal NULL?
376
        if (abbrevTitleCache == null){
377
            this.abbrevTitleCache = generateAbbrevTitleCache();
378
            this.abbrevTitleCache = getTruncatedCache(this.abbrevTitleCache) ;
379
        }
380
        return abbrevTitleCache;
381
	}
382

    
383
	@Override
384
	@Deprecated
385
	public void setAbbrevTitleCache(String abbrevTitleCache) {
386
		this.abbrevTitleCache = abbrevTitleCache;
387
	}
388

    
389
	@Override
390
	public void setAbbrevTitleCache(String abbrevTitleCache, boolean isProtected) {
391
		this.protectedAbbrevTitleCache = isProtected;
392
		setAbbrevTitleCache(abbrevTitleCache);
393
	}
394

    
395
	@Override
396
	public boolean isProtectedAbbrevTitleCache() {
397
		return protectedAbbrevTitleCache;
398
	}
399

    
400
	@Override
401
	public void setProtectedAbbrevTitleCache(boolean protectedAbbrevTitleCache) {
402
		this.protectedAbbrevTitleCache = protectedAbbrevTitleCache;
403
	}
404

    
405
	@Override
406
	public String getAbbrevTitle() {
407
		return abbrevTitle;
408
	}
409

    
410
	@Override
411
	public void setAbbrevTitle(String abbrevTitle) {
412
		this.abbrevTitle = StringUtils.isBlank(abbrevTitle) ? null : abbrevTitle;
413
	}
414

    
415

    
416
	@Override
417
    public String getEditor() {
418
		return editor;
419
	}
420

    
421

    
422
	@Override
423
    public void setEditor(String editor) {
424
		this.editor = StringUtils.isBlank(editor)? null : editor;
425
	}
426

    
427
	@Override
428
    public String getVolume() {
429
		return volume;
430
	}
431

    
432
	@Override
433
    public void setVolume(String volume) {
434
		this.volume = StringUtils.isBlank(volume)? null : volume;
435
	}
436

    
437
	@Override
438
    public String getPages() {
439
		return pages;
440
	}
441

    
442
	@Override
443
    public void setPages(String pages) {
444
		this.pages = StringUtils.isBlank(pages)? null : pages;
445
	}
446

    
447
	@Override
448
    public String getEdition() {
449
		return edition;
450
	}
451

    
452
	@Override
453
    public void setEdition(String edition) {
454
		this.edition = StringUtils.isBlank(edition)? null : edition;
455
	}
456

    
457
	@Override
458
    public String getIsbn() {
459
		return isbn;
460
	}
461

    
462
	@Override
463
    public void setIsbn(String isbn) {
464
		this.isbn = StringUtils.isBlank(isbn)? null : isbn;
465
	}
466

    
467
	@Override
468
    public String getIssn() {
469
		return issn;
470
	}
471

    
472
	@Override
473
    public void setIssn(String issn) {
474
		this.issn = StringUtils.isBlank(issn)? null : issn;
475
	}
476

    
477
    @Override
478
	public DOI getDoi() {
479
		return doi;
480
	}
481

    
482
    @Override
483
	public void setDoi(DOI doi) {
484
		this.doi = doi;
485
	}
486

    
487
	@Override
488
    public String getSeriesPart() {
489
		return seriesPart;
490
	}
491

    
492
	@Override
493
    public void setSeriesPart(String seriesPart) {
494
		this.seriesPart = StringUtils.isBlank(seriesPart)? null : seriesPart;
495
	}
496

    
497
	@Override
498
    public String getOrganization() {
499
		return organization;
500
	}
501

    
502
	@Override
503
    public void setOrganization(String organization) {
504
		this.organization = StringUtils.isBlank(organization)? null : organization;
505
	}
506

    
507
	@Override
508
    public String getPublisher() {
509
		return publisher;
510
	}
511

    
512
	@Override
513
    public void setPublisher(String publisher) {
514
		this.publisher = StringUtils.isBlank(publisher)? null : publisher;
515
	}
516

    
517
	@Override
518
    public void setPublisher(String publisher, String placePublished){
519
		this.publisher = publisher;
520
		this.placePublished = placePublished;
521
	}
522

    
523
	@Override
524
    public String getPlacePublished() {
525
		return placePublished;
526
	}
527

    
528
	@Override
529
    public void setPlacePublished(String placePublished) {
530
		this.placePublished = StringUtils.isBlank(placePublished)? null: placePublished;
531
	}
532

    
533
	@Override
534
    public Institution getInstitution() {
535
		return institution;
536
	}
537

    
538
	@Override
539
    public void setInstitution(Institution institution) {
540
		this.institution = institution;
541
	}
542

    
543
	@Override
544
    public Institution getSchool() {
545
		return school;
546
	}
547

    
548
	@Override
549
    public void setSchool(Institution school) {
550
		this.school = school;
551
	}
552

    
553
	@Override
554
    public Reference getInReference() {
555
		return inReference;
556
	}
557

    
558
	@Override
559
    public void setInReference(Reference inReference) {
560
		this.inReference = inReference;
561
	}
562

    
563
	@Override
564
    public void setType(ReferenceType type) {
565
		if (type == null){
566
			this.type = ReferenceType.Generic;
567
		} else{
568
			this.type = type;
569
		}
570
	}
571
	@Override
572
    public ReferenceType getType() {
573
		return type;
574
	}
575

    
576
	/**
577
	 * Whether this reference is of the given type
578
	 *
579
	 * @param type
580
	 * @return
581
	 */
582
	@Override
583
    public boolean isOfType(ReferenceType type){
584
		return type == getType();
585
	}
586

    
587
	/**
588
	 * Returns a string representing the title of <i>this</i> reference. If a
589
	 * reference has different titles (for instance abbreviated and not
590
	 * abbreviated) then for each title a new instance must be created.
591
	 *
592
	 * @return  the title string of <i>this</i> reference
593
	 * @see 	#getCitation()
594
	 */
595
	@Override
596
    public String getTitle(){
597
		return this.title;
598
	}
599
	/**
600
	 * @see 	#getTitle()
601
	 */
602
	@Override
603
    public void setTitle(String title){
604
		this.title = StringUtils.isBlank(title)? null : title;
605
	}
606

    
607
	/**
608
	 * Returns the date (mostly only the year) of publication / creation of
609
	 * <i>this</i> reference.
610
	 */
611
	@Override
612
    public TimePeriod getDatePublished(){
613
		return this.datePublished;
614
	}
615
	/**
616
	 * @see 	#getDatePublished()
617
	 */
618
	@Override
619
    public void setDatePublished(TimePeriod datePublished){
620
		this.datePublished = datePublished;
621
	}
622

    
623
	public boolean hasDatePublished(){
624
		boolean result =  ! ( (this.datePublished == null) || StringUtils.isBlank(datePublished.toString()));
625
		return result;
626
	}
627

    
628
	/**
629
	 * Returns the {@link eu.etaxonomy.cdm.model.agent.TeamOrPersonBase author (team)} who created the
630
	 * content of <i>this</i> reference.
631
	 *
632
	 * @return  the author (team) of <i>this</i> reference
633
	 * @see 	eu.etaxonomy.cdm.model.agent.TeamOrPersonBase
634
	 */
635
	@Override
636
    public TeamOrPersonBase getAuthorship(){
637
		return this.authorship;
638
	}
639

    
640
	/**
641
	 * @see #getAuthorship()
642
	 */
643
	@Override
644
    public void setAuthorship(TeamOrPersonBase authorship){
645
		this.authorship = authorship;
646
	}
647

    
648
	/**
649
	 * Returns the Uniform Resource Identifier (URI) corresponding to <i>this</i>
650
	 * reference. An URI is a string of characters used to identify a resource
651
	 * on the Internet.
652
	 *
653
	 * @return  the URI of <i>this</i> reference
654
	 */
655
	@Override
656
    public URI getUri(){
657
		return this.uri;
658
	}
659
	/**
660
	 * @see #getUri()
661
	 */
662
	@Override
663
    public void setUri(URI uri){
664
		this.uri = uri;
665
	}
666

    
667
	/**
668
	 * @return the referenceAbstract
669
	 */
670
	@Override
671
    public String getReferenceAbstract() {
672
		return referenceAbstract;
673
	}
674

    
675
	/**
676
	 * @param referenceAbstract the referenceAbstract to set
677
	 */
678
	@Override
679
    public void setReferenceAbstract(String referenceAbstract) {
680
		this.referenceAbstract = StringUtils.isBlank(referenceAbstract)? null : referenceAbstract;
681
	}
682

    
683

    
684
	/**
685
	 * Returns "true" if the isNomenclaturallyRelevant flag is set. This
686
	 * indicates that a {@link TaxonNameBase taxon name} has been originally
687
	 * published in <i>this</i> reference following the rules of a
688
	 * {@link eu.etaxonomy.cdm.model.name.NomenclaturalCode nomenclature code} and is therefore used for
689
	 * nomenclatural citations. This flag will be set as soon as <i>this</i>
690
	 * reference is used as a nomenclatural reference for any taxon name.<BR>
691
	 * FIXME what happens if the only taxon name referencing this reference is not
692
	 * any longer using this reference as a nomenclatural reference. How does the
693
	 * reference get informed about the fact that it is not nomenclaturally relevant
694
	 * anymore?
695
	 */
696
	public boolean isNomenclaturallyRelevant(){
697
		return this.nomenclaturallyRelevant;
698
	}
699

    
700
	/**
701
	 * @see #isNomenclaturallyRelevant()
702
	 */
703
	public void setNomenclaturallyRelevant(boolean nomenclaturallyRelevant){
704
		this.nomenclaturallyRelevant = nomenclaturallyRelevant;
705
	}
706

    
707

    
708
//****************************************************  /
709

    
710

    
711
	/**
712
	 * Returns a formatted string containing the entire reference citation,
713
	 * including authors, corresponding to <i>this</i> reference.
714
	 *
715
	 * @see  #generateTitle()
716
	 */
717
	// TODO implement
718
	@Transient
719
	public String getCitation(){
720
		if (getCacheStrategy() == null){
721
			logger.warn("No CacheStrategy defined for "+ this.getClass() + ": " + this.getUuid());
722
			return null;
723
		}else{
724
			return getCacheStrategy().getTitleCache(this);
725
		}
726
	}
727

    
728

    
729
	@Override
730
    public String generateTitle() {
731
		return super.generateTitle();
732
	}
733

    
734
    public String generateAbbrevTitleCache() {
735
		return getCacheStrategy().getNomenclaturalCache(this);
736
	}
737

    
738
    public String fullAbbrevTitleString() {
739
        return getCacheStrategy().getFullAbbrevTitleString(this);
740
    }
741

    
742
	/**
743
	 * Returns a string representation for the year of publication / creation
744
	 * of <i>this</i> reference. If the {@link #getDatePublished() datePublished}
745
	 * of this reference contains more date information then (starting) year
746
	 * only the year is returned.
747
	 * than  attribute.
748
	 */
749
	@Override
750
    @Transient
751
	public String getYear(){
752
		TimePeriod datePublished = this.getDatePublished();
753
		if (datePublished != null ){
754
			String result = getDatePublished().getYear();
755
			return result;
756
		}else{
757
			return null;
758
		}
759
	}
760

    
761
	/**
762
	 * Convenience method that returns a string representation for the publication date / creation
763
	 * of <i>this</i> reference. The string is obtained by
764
	 * {@link #getDatePublished()#toString() the string representation
765
	 * of the date published}.
766
	 */
767
	@Transient
768
	public String getDatePublishedString(){
769
		TimePeriod datePublished = this.getDatePublished();
770
		if (datePublished != null ){
771
			return getDatePublished().toString();
772
		}else{
773
			return null;
774
		}
775
	}
776

    
777

    
778
	@Override
779
    public int getParsingProblem(){
780
		return this.parsingProblem;
781
	}
782

    
783
	@Override
784
    public void setParsingProblem(int parsingProblem){
785
		this.parsingProblem = parsingProblem;
786
	}
787

    
788
	@Override
789
    public boolean hasProblem(){
790
		return parsingProblem != 0;
791
	}
792

    
793
	@Override
794
    public boolean hasProblem(ParserProblem problem) {
795
		return getParsingProblems().contains(problem);
796
	}
797

    
798
	@Override
799
    public int getProblemStarts(){
800
		return this.problemStarts;
801
	}
802

    
803
	@Override
804
    public void setProblemStarts(int start) {
805
		this.problemStarts = start;
806
	}
807

    
808
	@Override
809
    public int getProblemEnds(){
810
		return this.problemEnds;
811
	}
812

    
813
	@Override
814
    public void setProblemEnds(int end) {
815
		this.problemEnds = end;
816
	}
817

    
818
	@Override
819
    public void addParsingProblem(ParserProblem warning){
820
		parsingProblem = ParserProblem.addProblem(parsingProblem, warning);
821
	}
822

    
823
	@Override
824
    public void removeParsingProblem(ParserProblem problem) {
825
		parsingProblem = ParserProblem.removeProblem(parsingProblem, problem);
826
	}
827

    
828
	@Override
829
    @Transient
830
	public List<ParserProblem> getParsingProblems() {
831
		return ParserProblem.warningList(this.parsingProblem);
832
	}
833

    
834

    
835
	@Override
836
    @Transient
837
    public String getNomenclaturalCitation(String microReference) {
838
		String typeName = this.getType()== null ? "(no type defined)" : this.getType().getMessage();
839
		if (getCacheStrategy() == null){
840
			logger.warn("No CacheStrategy defined for "+ typeName + ": " + this.getUuid());
841
			return null;
842
		}else{
843
		    if (getCacheStrategy() instanceof INomenclaturalReferenceCacheStrategy){
844
				return cacheStrategy.getNomenclaturalCitation(this, microReference);
845
			}else {
846
				logger.warn("No INomenclaturalReferenceCacheStrategy defined for "+ typeName + ": " + this.getUuid());
847
				return null;
848
			}
849
		}
850
	}
851

    
852

    
853
	/**
854
	 * Generates, according to the {@link eu.etaxonomy.cdm.strategy.strategy.cache.reference.IReferenceBaseCacheStrategy cache strategy}
855
	 * assigned to <i>this</i> reference, a string that identifies <i>this</i>
856
	 * reference and returns it. This string may be stored in the inherited
857
	 * {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity#getTitleCache() titleCache} attribute.<BR>
858
	 * This method overrides the generic and inherited generateTitle method
859
	 * from {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity IdentifiableEntity}.
860
	 *
861
	 * @return  the string identifying <i>this</i> reference
862
	 * @see  	#getCitation()
863
	 * @see  	eu.etaxonomy.cdm.model.common.IdentifiableEntity#getTitleCache()
864
	 * @see  	eu.etaxonomy.cdm.model.common.IdentifiableEntity#generateTitle()
865
	 * @see  	eu.etaxonomy.cdm.strategy.strategy.cache.common.IIdentifiableEntityCacheStrategy#getTitleCache()
866
	 */
867
//	@Override
868
//	public String generateTitle(){
869
//		if (cacheStrategy == null){
870
//			logger.warn("No CacheStrategy defined for Reference: " + this.getUuid());
871
//			return null;
872
//		}else{
873
//			return cacheStrategy.getTitleCache(this);
874
//		}
875
//	}
876

    
877

    
878

    
879
//********** Casting methods ***********************************/
880

    
881
	/**
882
	 * @return
883
	 */
884
	public IArticle castReferenceToArticle(){
885
		setType(ReferenceType.Article);
886
		return this;
887
	}
888

    
889
	public IBook castReferenceToBook(){
890
		setType(ReferenceType.Book);
891
		return this;
892
	}
893

    
894
	public IBookSection castReferenceToBookSection(){
895
		setType(ReferenceType.BookSection);
896
		return this;
897
	}
898

    
899
	public ICdDvd castReferenceToCdDvd(){
900
		setType(ReferenceType.CdDvd);
901
		return this;
902
	}
903

    
904
	public IDatabase castReferenceToDatabase(){
905
		setType(ReferenceType.Database);
906
		return this;
907
	}
908

    
909
	public IGeneric castReferenceToGeneric(){
910
		setType(ReferenceType.Generic);
911
		return this;
912
	}
913

    
914
	public IInProceedings castReferenceToInProceedings(){
915
		setType(ReferenceType.InProceedings);
916
		return this;
917
	}
918

    
919
	public IJournal castReferenceToJournal(){
920
		setType(ReferenceType.Journal);
921
		return this;
922
	}
923

    
924
	public IMap castReferenceToMap(){
925
		setType(ReferenceType.Map);
926
		return (IMap) this;
927
	}
928

    
929
	public IPatent castReferenceToPatent(){
930
		setType(ReferenceType.Patent);
931
		return this;
932
	}
933

    
934
	public IPersonalCommunication castReferenceToPersonalCommunication(){
935
		setType(ReferenceType.PersonalCommunication);
936
		return this;
937
	}
938

    
939
	public IPrintSeries castReferenceToPrintSeries(){
940
		setType(ReferenceType.PrintSeries);
941
		return this;
942
	}
943

    
944
	public IWebPage castReferenceToWebPage(){
945
		setType(ReferenceType.WebPage);
946
		return this;
947
	}
948

    
949
	public IProceedings castReferenceToProceedings(){
950
		setType(ReferenceType.Proceedings);
951
		return this;
952
	}
953

    
954
	public IReport castReferenceToReport(){
955
		setType(ReferenceType.Report);
956
		return this;
957
	}
958

    
959
	public IThesis castReferenceToThesis(){
960
		setType(ReferenceType.Thesis);
961
		return this;
962
	}
963

    
964

    
965
	@Override
966
    @Transient // prevent from being serialized by webservice
967
	public IJournal getInJournal() {
968
		IJournal journal = this.inReference;
969
		return journal;
970
	}
971

    
972
	@Override
973
    public void setInJournal(IJournal journal) {
974
		setInReference((Reference)journal);  //user setter to invoke aspect #1815
975
	}
976

    
977
	@Override
978
    @Transient // prevent from being serialized by webservice
979
	public IPrintSeries getInSeries() {
980
		return this.inReference;
981
	}
982

    
983
	@Override
984
    public void setInSeries(IPrintSeries inSeries) {
985
	    setInReference((Reference)inSeries);  //user setter to invoke aspect  #1815
986
	}
987

    
988
	@Override
989
    @Transient // prevent from being serialized by webservice
990
	public IBook getInBook() {
991
		IBook book = this.inReference;
992
		return book;
993
	}
994

    
995
//********************** In-References *****************************************
996

    
997
	@Override
998
    public void setInBook(IBook book) {
999
	    setInReference((Reference)book);  //user setter to invoke aspect #1815
1000
	}
1001

    
1002
	@Override
1003
    @Transient // prevent from being serialized by webservice
1004
	public IProceedings getInProceedings() {
1005
		IProceedings proceedings = this.inReference;
1006
		return proceedings;
1007
	}
1008

    
1009
	@Override
1010
    public void setInProceedings(IProceedings proceeding) {
1011
        setInReference((Reference)proceeding);  //user setter to invoke aspect #1815
1012
	}
1013

    
1014
//*************************** CACHE STRATEGIES ******************************/
1015

    
1016
    @Override
1017
    public INomenclaturalReferenceCacheStrategy getCacheStrategy() {
1018
    	return this.cacheStrategy;
1019
    }
1020

    
1021
	@Override
1022
    public void setCacheStrategy(INomenclaturalReferenceCacheStrategy referenceCacheStrategy) {
1023
		this.cacheStrategy = referenceCacheStrategy;
1024
	}
1025

    
1026

    
1027

    
1028
//*********************** CLONE ********************************************************/
1029

    
1030
	/**
1031
	 * Clones <i>this</i> reference. This is a shortcut that enables to create
1032
	 * a new instance that differs only slightly from <i>this</i> reference by
1033
	 * modifying only some of the attributes.
1034
	 *
1035
	 * @see eu.etaxonomy.cdm.model.media.IdentifiableMediaEntity#clone()
1036
	 * @see java.lang.Object#clone()
1037
	 */
1038
	@Override
1039
	public Object clone() {
1040
		try {
1041
			Reference result = (Reference)super.clone();
1042
			result.setDatePublished(datePublished != null? (TimePeriod)datePublished.clone(): null);
1043
			//no changes to: title, authorship, hasProblem, nomenclaturallyRelevant, uri
1044
			return result;
1045
		} catch (CloneNotSupportedException e) {
1046
			logger.warn("Object does not implement cloneable");
1047
			e.printStackTrace();
1048
			return null;
1049
		}
1050
	}
1051

    
1052
//******************************* toString *****************************/
1053

    
1054
	@Override
1055
	public String toString() {
1056
		if (type != null){
1057
			String result = "Reference [type=" + type + ", id= " + this.getId() + ", uuid=" + this.uuid ;
1058
			result += title == null ? "" : ", title=" + title;
1059
			result += abbrevTitle == null ? "" : ", abbrevTitle=" + abbrevTitle;
1060
			result += "]";
1061
			return result;
1062
		}else{
1063
			return super.toString();
1064
		}
1065
	}
1066

    
1067

    
1068

    
1069

    
1070
}
1071

    
(23-23/27)