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.INomenclaturalReferenceCacheStrategy;
57
import eu.etaxonomy.cdm.strategy.cache.reference.IReferenceCacheStrategy;
58
import eu.etaxonomy.cdm.strategy.cache.reference.NewDefaultReferenceCacheStrategy;
59
import eu.etaxonomy.cdm.strategy.match.Match;
60
import eu.etaxonomy.cdm.strategy.match.MatchMode;
61
import eu.etaxonomy.cdm.strategy.merge.Merge;
62
import eu.etaxonomy.cdm.strategy.merge.MergeMode;
63
import eu.etaxonomy.cdm.strategy.parser.ParserProblem;
64
import eu.etaxonomy.cdm.validation.Level2;
65
import eu.etaxonomy.cdm.validation.Level3;
66
import eu.etaxonomy.cdm.validation.annotation.InReference;
67
import eu.etaxonomy.cdm.validation.annotation.NoRecursiveInReference;
68
import eu.etaxonomy.cdm.validation.annotation.NullOrNotEmpty;
69
import eu.etaxonomy.cdm.validation.annotation.ReferenceCheck;
70

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

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

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

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

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

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

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

    
172
//********************************************************/
173

    
174

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

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

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

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

    
203
    @XmlElement(name = "ISBN")
204
    @Field
205
    //TODO Val #3379
206
//    @NullOrNotEmpty
207
    @Column(length=255)
208
	@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}")
209
	protected String isbn;
210

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

    
218

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

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

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

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

    
248

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

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

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

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

    
281
//********************************************************/
282

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

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

    
297

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

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

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

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

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

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

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

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

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

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

    
367

    
368
//*************************** GETTER / SETTER ******************************************/
369

    
370

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

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

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

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

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

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

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

    
416

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

    
422

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
684

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

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

    
708

    
709
//****************************************************  /
710

    
711

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

    
729

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

    
735
    public String generateAbbrevTitle() {
736
		return getCacheStrategy().getFullAbbrevTitleString(this);
737
	}
738

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

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

    
774

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

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

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

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

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

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

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

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

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

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

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

    
831

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

    
849

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

    
874

    
875

    
876
//********** Casting methods ***********************************/
877

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
961

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

    
969
	@Override
970
    public void setInJournal(IJournal journal) {
971
		this.inReference = (Reference)journal;
972

    
973
	}
974

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

    
982
	@Override
983
    public void setInSeries(IPrintSeries inSeries) {
984
		this.inReference = (Reference) inSeries;
985
	}
986

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

    
994
//********************** In-References *****************************************
995

    
996
	@Override
997
    public void setInBook(IBook book) {
998
		this.inReference = (Reference) book;
999
	}
1000

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

    
1008
	@Override
1009
    public void setInProceedings(IProceedings proceeding) {
1010
		this.inReference = (Reference) proceeding;
1011
	}
1012

    
1013
//*************************** CACHE STRATEGIES ******************************/
1014

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

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

    
1025

    
1026

    
1027
//*********************** CLONE ********************************************************/
1028

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

    
1051
//******************************* toString *****************************/
1052

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

    
1066

    
1067

    
1068

    
1069
}
1070

    
(23-23/27)