Project

General

Profile

Download (27.3 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 = generateAbbrevTitle();
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 generateAbbrevTitle() {
735
		return getCacheStrategy().getFullAbbrevTitleString(this);
736
	}
737

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

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

    
773

    
774
	@Override
775
    public int getParsingProblem(){
776
		return this.parsingProblem;
777
	}
778

    
779
	@Override
780
    public void setParsingProblem(int parsingProblem){
781
		this.parsingProblem = parsingProblem;
782
	}
783

    
784
	@Override
785
    public boolean hasProblem(){
786
		return parsingProblem != 0;
787
	}
788

    
789
	@Override
790
    public boolean hasProblem(ParserProblem problem) {
791
		return getParsingProblems().contains(problem);
792
	}
793

    
794
	@Override
795
    public int getProblemStarts(){
796
		return this.problemStarts;
797
	}
798

    
799
	@Override
800
    public void setProblemStarts(int start) {
801
		this.problemStarts = start;
802
	}
803

    
804
	@Override
805
    public int getProblemEnds(){
806
		return this.problemEnds;
807
	}
808

    
809
	@Override
810
    public void setProblemEnds(int end) {
811
		this.problemEnds = end;
812
	}
813

    
814
	@Override
815
    public void addParsingProblem(ParserProblem warning){
816
		parsingProblem = ParserProblem.addProblem(parsingProblem, warning);
817
	}
818

    
819
	@Override
820
    public void removeParsingProblem(ParserProblem problem) {
821
		parsingProblem = ParserProblem.removeProblem(parsingProblem, problem);
822
	}
823

    
824
	@Override
825
    @Transient
826
	public List<ParserProblem> getParsingProblems() {
827
		return ParserProblem.warningList(this.parsingProblem);
828
	}
829

    
830

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

    
848

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

    
873

    
874

    
875
//********** Casting methods ***********************************/
876

    
877
	/**
878
	 * @return
879
	 */
880
	public IArticle castReferenceToArticle(){
881
		setType(ReferenceType.Article);
882
		return this;
883
	}
884

    
885
	public IBook castReferenceToBook(){
886
		setType(ReferenceType.Book);
887
		return this;
888
	}
889

    
890
	public IBookSection castReferenceToBookSection(){
891
		setType(ReferenceType.BookSection);
892
		return this;
893
	}
894

    
895
	public ICdDvd castReferenceToCdDvd(){
896
		setType(ReferenceType.CdDvd);
897
		return this;
898
	}
899

    
900
	public IDatabase castReferenceToDatabase(){
901
		setType(ReferenceType.Database);
902
		return this;
903
	}
904

    
905
	public IGeneric castReferenceToGeneric(){
906
		setType(ReferenceType.Generic);
907
		return this;
908
	}
909

    
910
	public IInProceedings castReferenceToInProceedings(){
911
		setType(ReferenceType.InProceedings);
912
		return this;
913
	}
914

    
915
	public IJournal castReferenceToJournal(){
916
		setType(ReferenceType.Journal);
917
		return this;
918
	}
919

    
920
	public IMap castReferenceToMap(){
921
		setType(ReferenceType.Map);
922
		return (IMap) this;
923
	}
924

    
925
	public IPatent castReferenceToPatent(){
926
		setType(ReferenceType.Patent);
927
		return this;
928
	}
929

    
930
	public IPersonalCommunication castReferenceToPersonalCommunication(){
931
		setType(ReferenceType.PersonalCommunication);
932
		return this;
933
	}
934

    
935
	public IPrintSeries castReferenceToPrintSeries(){
936
		setType(ReferenceType.PrintSeries);
937
		return this;
938
	}
939

    
940
	public IWebPage castReferenceToWebPage(){
941
		setType(ReferenceType.WebPage);
942
		return this;
943
	}
944

    
945
	public IProceedings castReferenceToProceedings(){
946
		setType(ReferenceType.Proceedings);
947
		return this;
948
	}
949

    
950
	public IReport castReferenceToReport(){
951
		setType(ReferenceType.Report);
952
		return this;
953
	}
954

    
955
	public IThesis castReferenceToThesis(){
956
		setType(ReferenceType.Thesis);
957
		return this;
958
	}
959

    
960

    
961
	@Override
962
    @Transient // prevent from being serialized by webservice
963
	public IJournal getInJournal() {
964
		IJournal journal = this.inReference;
965
		return journal;
966
	}
967

    
968
	@Override
969
    public void setInJournal(IJournal journal) {
970
		setInReference((Reference)journal);  //user setter to invoke aspect #1815
971
	}
972

    
973
	@Override
974
    @Transient // prevent from being serialized by webservice
975
	public IPrintSeries getInSeries() {
976
		return this.inReference;
977
	}
978

    
979
	@Override
980
    public void setInSeries(IPrintSeries inSeries) {
981
	    setInReference((Reference)inSeries);  //user setter to invoke aspect  #1815
982
	}
983

    
984
	@Override
985
    @Transient // prevent from being serialized by webservice
986
	public IBook getInBook() {
987
		IBook book = this.inReference;
988
		return book;
989
	}
990

    
991
//********************** In-References *****************************************
992

    
993
	@Override
994
    public void setInBook(IBook book) {
995
	    setInReference((Reference)book);  //user setter to invoke aspect #1815
996
	}
997

    
998
	@Override
999
    @Transient // prevent from being serialized by webservice
1000
	public IProceedings getInProceedings() {
1001
		IProceedings proceedings = this.inReference;
1002
		return proceedings;
1003
	}
1004

    
1005
	@Override
1006
    public void setInProceedings(IProceedings proceeding) {
1007
        setInReference((Reference)proceeding);  //user setter to invoke aspect #1815
1008
	}
1009

    
1010
//*************************** CACHE STRATEGIES ******************************/
1011

    
1012
    @Override
1013
    public INomenclaturalReferenceCacheStrategy getCacheStrategy() {
1014
    	return this.cacheStrategy;
1015
    }
1016

    
1017
	@Override
1018
    public void setCacheStrategy(INomenclaturalReferenceCacheStrategy referenceCacheStrategy) {
1019
		this.cacheStrategy = referenceCacheStrategy;
1020
	}
1021

    
1022

    
1023

    
1024
//*********************** CLONE ********************************************************/
1025

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

    
1048
//******************************* toString *****************************/
1049

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

    
1063

    
1064

    
1065

    
1066
}
1067

    
(23-23/27)