Project

General

Profile

Download (36.8 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
import org.hibernate.validator.constraints.Length;
49

    
50
import eu.etaxonomy.cdm.common.DOI;
51
import eu.etaxonomy.cdm.hibernate.search.DoiBridge;
52
import eu.etaxonomy.cdm.model.agent.Institution;
53
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
54
import eu.etaxonomy.cdm.model.common.TimePeriod;
55
import eu.etaxonomy.cdm.model.media.IdentifiableMediaEntity;
56
import eu.etaxonomy.cdm.model.name.TaxonNameBase;
57
import eu.etaxonomy.cdm.strategy.cache.reference.ArticleDefaultCacheStrategy;
58
import eu.etaxonomy.cdm.strategy.cache.reference.BookDefaultCacheStrategy;
59
import eu.etaxonomy.cdm.strategy.cache.reference.BookSectionDefaultCacheStrategy;
60
import eu.etaxonomy.cdm.strategy.cache.reference.GenericDefaultCacheStrategy;
61
import eu.etaxonomy.cdm.strategy.cache.reference.INomenclaturalReferenceCacheStrategy;
62
import eu.etaxonomy.cdm.strategy.cache.reference.IReferenceBaseCacheStrategy;
63
import eu.etaxonomy.cdm.strategy.cache.reference.JournalDefaultCacheStrategy;
64
import eu.etaxonomy.cdm.strategy.cache.reference.ReferenceDefaultCacheStrategy;
65
import eu.etaxonomy.cdm.strategy.match.Match;
66
import eu.etaxonomy.cdm.strategy.match.MatchMode;
67
import eu.etaxonomy.cdm.strategy.merge.Merge;
68
import eu.etaxonomy.cdm.strategy.merge.MergeMode;
69
import eu.etaxonomy.cdm.strategy.parser.ParserProblem;
70
import eu.etaxonomy.cdm.validation.Level2;
71
import eu.etaxonomy.cdm.validation.annotation.InReference;
72
import eu.etaxonomy.cdm.validation.annotation.NullOrNotEmpty;
73
import eu.etaxonomy.cdm.validation.annotation.ReferenceCheck;
74

    
75
/**
76
 * The upmost (abstract) class for references (information sources).
77
 * <P>
78
 * This class corresponds to: <ul>
79
 * <li> PublicationCitation according to the TDWG ontology
80
 * <li> Publication according to the TCS
81
 * <li> Reference according to the ABCD schema
82
 * </ul>
83
 *
84
 * @author m.doering
85
 * @created 08-Nov-2007 13:06:47
86
 */
87
@XmlAccessorType(XmlAccessType.FIELD)
88
@XmlType(name = "Reference", propOrder = {
89
	"type",
90
	"uri",
91
    "abbrevTitleCache",
92
    "protectedAbbrevTitleCache",
93
	"nomenclaturallyRelevant",
94
    "authorship",
95
    "referenceAbstract",
96
    "title",
97
    "abbrevTitle",
98
    "editor",
99
	"volume",
100
	"pages",
101
	"edition",
102
    "isbn",
103
    "issn",
104
    "doi",
105
    "seriesPart",
106
    "datePublished",
107
    "publisher",
108
    "placePublished",
109
    "institution",
110
    "school",
111
    "organization",
112
    "inReference"
113
})
114
@XmlRootElement(name = "Reference")
115
@Entity
116
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
117
@Audited
118
@Table(appliesTo="Reference", indexes = { @org.hibernate.annotations.Index(name = "ReferenceTitleCacheIndex", columnNames = { "titleCache" }) })
119
@InReference(groups = Level2.class)
120
@ReferenceCheck(groups = Level2.class)
121
public class Reference<S extends IReferenceBaseCacheStrategy> extends IdentifiableMediaEntity<S> implements INomenclaturalReference, IArticle, IBook, IPatent, IDatabase, IJournal, IBookSection,ICdDvd,IGeneric,IInProceedings, IProceedings, IPrintSeries, IReport, IThesis,IWebPage, IPersonalCommunication, IReference, Cloneable {
122
	private static final long serialVersionUID = -2034764545042691295L;
123
	private static final Logger logger = Logger.getLogger(Reference.class);
124

    
125
	@XmlAttribute(name ="type")
126
	@Column(name="refType")
127
	@NotNull
128
    @Type(type = "eu.etaxonomy.cdm.hibernate.EnumUserType",
129
    	parameters = {@org.hibernate.annotations.Parameter(name  = "enumClass", value = "eu.etaxonomy.cdm.model.reference.ReferenceType")}
130
    )
131
	protected ReferenceType type;
132

    
133
	//Title of the reference
134
	@XmlElement(name ="Title" )
135
	@Column(length=4096, name="title")
136
	@Lob
137
	@Field
138
	@Match(MatchMode.EQUAL_REQUIRED)
139
    //TODO Val #3379
140
//	@NullOrNotEmpty
141
	@Length(max = 4096)  //TODO is the length attribute really required twice (see @Column)??
142
	private String title;
143
	
144
	//Title of the reference
145
	@XmlElement(name ="AbbrevTitle" )
146
	@Field
147
	@Match(MatchMode.EQUAL)  //TODO check if this is correct
148
	@NullOrNotEmpty
149
	@Length(max = 255)
150
	private String abbrevTitle;
151
	
152
	//Title of the reference
153
	@XmlElement(name ="AbbrevTitleCache" )
154
	@Field
155
	@Match(MatchMode.CACHE)
156
    //TODO Val #3379
157
//	@NotNull
158
	@Length(max = 1024)
159
	private String abbrevTitleCache;
160
	
161
	@XmlElement(name = "protectedAbbrevTitleCache")
162
	@Merge(MergeMode.OR)
163
	private boolean protectedAbbrevTitleCache;
164

    
165
//********************************************************/
166

    
167

    
168
    @XmlElement(name = "Editor")
169
    @Field
170
    //TODO Val #3379
171
//    @NullOrNotEmpty
172
	@Length(max = 255)
173
	protected String editor;
174

    
175
    @XmlElement(name = "Volume")
176
    @Field
177
    //TODO Val #3379
178
//    @NullOrNotEmpty
179
	@Length(max = 255)
180
	protected String volume;
181

    
182
    @XmlElement(name = "Pages")
183
    @Field
184
    //TODO Val #3379
185
//    @NullOrNotEmpty
186
	@Length(max = 255)
187
	protected String pages;
188

    
189
    @XmlElement(name = "Edition")
190
    @Field
191
    //TODO Val #3379
192
//    @NullOrNotEmpty
193
	@Length(max = 255)
194
	protected String edition;
195

    
196
    @XmlElement(name = "ISBN")
197
    @Field
198
    //TODO Val #3379
199
//    @NullOrNotEmpty
200
	@Length(max = 255)
201
	@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}")
202
	protected String isbn;
203

    
204
    @XmlElement(name = "Doi")
205
    @Field
206
    @FieldBridge(impl = DoiBridge.class)
207
    @Type(type="doiUserType")
208
    @Column(length=DOI.MAX_LENGTH)
209
    protected DOI doi;
210

    
211

    
212
	@XmlElement(name = "ISSN")
213
    @Field
214
    //TODO Val #3379
215
//	@NullOrNotEmpty
216
	@Length(max = 255)
217
	@Pattern(regexp = "(?=.{9}$)\\d{4}([- ])\\d{4} (\\d|X)$", groups = Level2.class, message = "{eu.etaxonomy.cdm.model.reference.Reference.issn.message}")
218
	protected String issn;
219

    
220
    @XmlElement(name = "SeriesPart")
221
    @Field
222
    //TODO Val #3379
223
//    @NullOrNotEmpty
224
	@Length(max = 255)
225
	protected String seriesPart;
226

    
227
	@XmlElement(name = "Organization")
228
    @Field
229
    //TODO Val #3379
230
//	@NullOrNotEmpty
231
	@Length(max = 255)
232
	protected String organization;
233

    
234
	@XmlElement(name = "Publisher")
235
    @Field
236
    //TODO Val #3379
237
//	@NullOrNotEmpty
238
	@Length(max = 255)
239
	protected String publisher;
240

    
241

    
242
	@XmlElement(name = "PlacePublished")
243
    @Field
244
    //TODO Val #3379
245
//	@NullOrNotEmpty
246
	@Length(max = 255)
247
	protected String placePublished;
248

    
249
	@XmlElement(name = "Institution")
250
	@XmlIDREF
251
	@XmlSchemaType(name = "IDREF")
252
	@ManyToOne(fetch = FetchType.LAZY)
253
	@IndexedEmbedded
254
	@Cascade(CascadeType.SAVE_UPDATE)
255
	protected Institution institution;
256

    
257
	@XmlElement(name = "School")
258
    @XmlIDREF
259
    @XmlSchemaType(name = "IDREF")
260
	@ManyToOne(fetch = FetchType.LAZY)
261
	@IndexedEmbedded
262
	@Cascade(CascadeType.SAVE_UPDATE)
263
	protected Institution school;
264

    
265
    @XmlElement(name = "InReference")
266
    @XmlIDREF
267
    @XmlSchemaType(name = "IDREF")
268
    @ManyToOne(fetch = FetchType.LAZY)
269
//    @IndexedEmbedded
270
    @Cascade(CascadeType.SAVE_UPDATE)
271
   // @InReference(groups=Level2.class)
272
   	protected Reference<?> inReference;
273

    
274
//    @XmlElement(name = "FullReference")
275
//    @XmlIDREF
276
//    @XmlSchemaType(name = "IDREF")
277
//    @ManyToOne(fetch = FetchType.LAZY)
278
////    @IndexedEmbedded
279
//    @Cascade(CascadeType.SAVE_UPDATE)
280
//    protected Reference fullReference;
281
//
282
//    @XmlElement(name = "AbbreviatedReference")
283
//    @XmlIDREF
284
//    @XmlSchemaType(name = "IDREF")
285
//    @ManyToOne(fetch = FetchType.LAZY)
286
////    @IndexedEmbedded
287
//    @Cascade(CascadeType.SAVE_UPDATE)
288
//    protected Reference abbreviatedReference;
289

    
290

    
291
//********************************************************/
292

    
293
	//The date range assigned to the reference. ISO Date range like. Flexible, year can be left out, etc
294
	@XmlElement(name ="DatePublished" )
295
	@Embedded
296
	@IndexedEmbedded
297
	private TimePeriod datePublished = TimePeriod.NewInstance();
298

    
299
	@XmlElement(name ="Abstract" )
300
	@Column(length=65536, name="referenceAbstract")
301
	@Lob
302
    @Field
303
    //TODO Val #3379
304
//	@NullOrNotEmpty
305
	@Length(max = 65536)
306
	private String referenceAbstract;  //abstract is a reserved term in Java
307

    
308

    
309
	//URIs like DOIs, LSIDs or Handles for this reference
310
	@XmlElement(name = "URI")
311
	@Field(analyze = Analyze.NO)
312
	@Type(type="uriUserType")
313
	private URI uri;
314

    
315
	//flag to subselect only references that could be useful for nomenclatural citations. If a reference is used as a
316
	//nomenclatural reference in a name this flag should be automatically set
317
	@XmlElement(name = "IsNomenclaturallyRelevant")
318
	@Merge(MergeMode.OR)
319
	private boolean nomenclaturallyRelevant;
320

    
321
	@XmlElement(name = "Authorship")
322
	@XmlIDREF
323
	@XmlSchemaType(name = "IDREF")
324
	@ManyToOne(fetch = FetchType.LAZY)
325
	@IndexedEmbedded
326
	@Cascade(CascadeType.SAVE_UPDATE)
327
	private TeamOrPersonBase<?> authorship;
328
	
329
	
330

    
331
//	@XmlElement(name = "ReferenceIdentity")
332
//	@XmlIDREF
333
//	@XmlSchemaType(name = "IDREF")
334
//	@ManyToOne(fetch = FetchType.LAZY)
335
//	//@IndexedEmbedded
336
//	@Cascade(CascadeType.SAVE_UPDATE)
337
//	@Transient
338
//	private ReferenceIdentity referenceIdentity;
339

    
340
	@XmlAttribute
341
    @Match(MatchMode.IGNORE)
342
	private int parsingProblem = 0;
343

    
344
	@XmlAttribute
345
    @Match(MatchMode.IGNORE)
346
    private int problemStarts = -1;
347

    
348
    @XmlAttribute
349
    @Match(MatchMode.IGNORE)
350
    private int problemEnds = -1;
351

    
352
    @Transient
353
    @XmlAttribute
354
    @Match(MatchMode.IGNORE)
355
	private boolean cacheStrategyRectified = false;
356

    
357
    protected Reference(){
358
		this(ReferenceType.Generic);  //just in case someone uses constructor
359
	}
360

    
361
	protected Reference(ReferenceType type) {
362
		this.type = type;
363
	}
364
	
365
	@Override
366
    protected void initListener(){
367
        PropertyChangeListener listener = new PropertyChangeListener() {
368
            @Override
369
            public void propertyChange(PropertyChangeEvent ev) {
370
            	if (!ev.getPropertyName().equals("titleCache") && !ev.getPropertyName().equals("abbrevTitleCache") && !ev.getPropertyName().equals("cacheStrategy")){
371
            		if (! isProtectedTitleCache()){
372
            			titleCache = null;	
373
            		}
374
            		if (! isProtectedAbbrevTitleCache()){
375
            			abbrevTitleCache = null;	
376
            		}
377
            	}
378
            }
379
        };
380
        addPropertyChangeListener(listener);
381
    }
382

    
383

    
384
//*************************** GETTER / SETTER ******************************************/
385
	
386

    
387
	@Override
388
	public String getAbbrevTitleCache() {
389
		if (protectedAbbrevTitleCache){
390
            return this.abbrevTitleCache;
391
        }
392
        // is title dirty, i.e. equal NULL?
393
        if (abbrevTitleCache == null){
394
            this.abbrevTitleCache = generateAbbrevTitle();
395
            this.abbrevTitleCache = getTruncatedCache(this.abbrevTitleCache) ;
396
        }
397
        return abbrevTitleCache;	
398
	}
399

    
400
	@Override
401
	@Deprecated
402
	public void setAbbrevTitleCache(String abbrevTitleCache) {
403
		this.abbrevTitleCache = abbrevTitleCache;
404
	}
405
	
406
	@Override
407
	public void setAbbrevTitleCache(String abbrevTitleCache, boolean isProtected) {
408
		this.protectedAbbrevTitleCache = isProtected;	
409
		setAbbrevTitleCache(abbrevTitleCache);
410
	}
411
	
412
	@Override
413
	public boolean isProtectedAbbrevTitleCache() {
414
		return protectedAbbrevTitleCache;
415
	}
416

    
417
	@Override
418
	public void setProtectedAbbrevTitleCache(boolean protectedAbbrevTitleCache) {
419
		this.protectedAbbrevTitleCache = protectedAbbrevTitleCache;
420
	}
421

    
422
	@Override
423
	public String getAbbrevTitle() {
424
		return abbrevTitle;
425
	}
426

    
427
	@Override
428
	public void setAbbrevTitle(String abbrevTitle) {
429
		this.abbrevTitle = abbrevTitle;
430
	}
431
	
432

    
433
	@Override
434
    public String getEditor() {
435
		return editor;
436
	}
437

    
438

    
439
	@Override
440
    public void setEditor(String editor) {
441
		this.editor = editor;
442
	}
443

    
444
//	@Override
445
//    public String getSeries() {
446
//		return series;
447
//	}
448
//
449
//	@Override
450
//    public void setSeries(String series) {
451
//		this.series = series;
452
//	}
453

    
454
	@Override
455
    public String getVolume() {
456
		return volume;
457
	}
458

    
459
	@Override
460
    public void setVolume(String volume) {
461
		this.volume = volume;
462
	}
463

    
464
	@Override
465
    public String getPages() {
466
		return pages;
467
	}
468

    
469
	@Override
470
    public void setPages(String pages) {
471
		this.pages = pages;
472
	}
473

    
474
	@Override
475
    public String getEdition() {
476
		return edition;
477
	}
478

    
479
	@Override
480
    public void setEdition(String edition) {
481
		this.edition = edition;
482
	}
483

    
484
	@Override
485
    public String getIsbn() {
486
		return isbn;
487
	}
488

    
489
	@Override
490
    public void setIsbn(String isbn) {
491
		this.isbn = isbn;
492
	}
493

    
494
	@Override
495
    public String getIssn() {
496
		return issn;
497
	}
498

    
499
	@Override
500
    public void setIssn(String issn) {
501
		this.issn = issn;
502
	}
503
	
504
    @Override
505
	public DOI getDoi() {
506
		return doi;
507
	}
508

    
509
    @Override
510
	public void setDoi(DOI doi) {
511
		this.doi = doi;
512
	}
513

    
514
	@Override
515
    public String getSeriesPart() {
516
		return seriesPart;
517
	}
518

    
519
	@Override
520
    public void setSeriesPart(String seriesPart) {
521
		this.seriesPart = seriesPart;
522
	}
523

    
524
	@Override
525
    public String getOrganization() {
526
		return organization;
527
	}
528

    
529
	@Override
530
    public void setOrganization(String organization) {
531
		this.organization = organization;
532
	}
533

    
534
	@Override
535
    public String getPublisher() {
536
		return publisher;
537
	}
538

    
539
	@Override
540
    public void setPublisher(String publisher) {
541
		this.publisher = publisher;
542
	}
543

    
544
	@Override
545
    public void setPublisher(String publisher, String placePublished){
546
		this.publisher = publisher;
547
		this.placePublished = placePublished;
548
	}
549

    
550
	@Override
551
    public String getPlacePublished() {
552
		return placePublished;
553
	}
554

    
555
	@Override
556
    public void setPlacePublished(String placePublished) {
557
		this.placePublished = placePublished;
558
	}
559

    
560
	@Override
561
    public Institution getInstitution() {
562
		return institution;
563
	}
564

    
565
	@Override
566
    public void setInstitution(Institution institution) {
567
		this.institution = institution;
568
	}
569

    
570
	@Override
571
    public Institution getSchool() {
572
		return school;
573
	}
574

    
575
	@Override
576
    public void setSchool(Institution school) {
577
		this.school = school;
578
	}
579

    
580
	@Override
581
    public Reference getInReference() {
582
		return inReference;
583
	}
584

    
585
	@Override
586
    public void setInReference(Reference inReference) {
587
		this.inReference = inReference;
588
	}
589

    
590
	@Override
591
    public void setType(ReferenceType type) {
592
		this.setCacheStrategy(type.getCacheStrategy());
593
		this.type = type;
594
	}
595

    
596
	/**
597
	 * @return the type
598
	 */
599
	@Override
600
    public ReferenceType getType() {
601
		return type;
602
	}
603

    
604
	/**
605
	 * Whether this reference is of the given type
606
	 *
607
	 * @param type
608
	 * @return
609
	 */
610
	@Override
611
    public boolean isOfType(ReferenceType type){
612
		return type == getType();
613
	}
614

    
615
	/**
616
	 * Returns a string representing the title of <i>this</i> reference. If a
617
	 * reference has different titles (for instance abbreviated and not
618
	 * abbreviated) then for each title a new instance must be created.
619
	 *
620
	 * @return  the title string of <i>this</i> reference
621
	 * @see 	#getCitation()
622
	 */
623
	@Override
624
    public String getTitle(){
625
		return this.title;
626
	}
627
	/**
628
	 * @see 	#getTitle()
629
	 */
630
	@Override
631
    public void setTitle(String title){
632
		this.title = title;
633
	}
634

    
635
	/**
636
	 * Returns the date (mostly only the year) of publication / creation of
637
	 * <i>this</i> reference.
638
	 */
639
	@Override
640
    public TimePeriod getDatePublished(){
641
		return this.datePublished;
642
	}
643
	/**
644
	 * @see 	#getDatePublished()
645
	 */
646
	@Override
647
    public void setDatePublished(TimePeriod datePublished){
648
		this.datePublished = datePublished;
649
	}
650

    
651
	public boolean hasDatePublished(){
652
		boolean result =  ! ( (this.datePublished == null) || StringUtils.isBlank(datePublished.toString()));
653
		return result;
654
	}
655

    
656
	/**
657
	 * Returns the {@link eu.etaxonomy.cdm.model.agent.TeamOrPersonBase author (team)} who created the
658
	 * content of <i>this</i> reference.
659
	 *
660
	 * @return  the author (team) of <i>this</i> reference
661
	 * @see 	eu.etaxonomy.cdm.model.agent.TeamOrPersonBase
662
	 */
663
	@Override
664
    public TeamOrPersonBase getAuthorship(){
665
		return this.authorship;
666
	}
667

    
668
	/**
669
	 * @see #getAuthorship()
670
	 */
671
	@Override
672
    public void setAuthorship(TeamOrPersonBase authorship){
673
		this.authorship = authorship;
674
	}
675

    
676
	/**
677
	 * Returns the Uniform Resource Identifier (URI) corresponding to <i>this</i>
678
	 * reference. An URI is a string of characters used to identify a resource
679
	 * on the Internet.
680
	 *
681
	 * @return  the URI of <i>this</i> reference
682
	 */
683
	@Override
684
    public URI getUri(){
685
		return this.uri;
686
	}
687
	/**
688
	 * @see #getUri()
689
	 */
690
	@Override
691
    public void setUri(URI uri){
692
		this.uri = uri;
693
	}
694

    
695
	/**
696
	 * @return the referenceAbstract
697
	 */
698
	@Override
699
    public String getReferenceAbstract() {
700
		return referenceAbstract;
701
	}
702

    
703
	/**
704
	 * @param referenceAbstract the referenceAbstract to set
705
	 */
706
	@Override
707
    public void setReferenceAbstract(String referenceAbstract) {
708
		this.referenceAbstract = referenceAbstract;
709
	}
710

    
711

    
712

    
713

    
714
	/**
715
	 * Returns "true" if the isNomenclaturallyRelevant flag is set. This
716
	 * indicates that a {@link TaxonNameBase taxon name} has been originally
717
	 * published in <i>this</i> reference following the rules of a
718
	 * {@link eu.etaxonomy.cdm.model.name.NomenclaturalCode nomenclature code} and is therefore used for
719
	 * nomenclatural citations. This flag will be set as soon as <i>this</i>
720
	 * reference is used as a nomenclatural reference for any taxon name.<BR>
721
	 * FIXME what happens if the only taxon name referencing this reference is not
722
	 * any longer using this reference as a nomenclatural reference. How does the
723
	 * reference get informed about the fact that it is not nomenclaturally relevant
724
	 * anymore?
725
	 */
726
	public boolean isNomenclaturallyRelevant(){
727
		return this.nomenclaturallyRelevant;
728
	}
729

    
730
	/**
731
	 * @see #isNomenclaturallyRelevant()
732
	 */
733
	public void setNomenclaturallyRelevant(boolean nomenclaturallyRelevant){
734
		this.nomenclaturallyRelevant = nomenclaturallyRelevant;
735
	}
736

    
737

    
738
//	/**
739
//	 * Returns the full reference that belongs to this abbreviated reference. If this
740
//	 * reference is not abbreviated the full reference should be <code>null</code>.<BR>
741
//	 * A full reference should be added to a reference
742
//	 * which represents the abbreviated form of a reference. The full reference can be used
743
//	 * by publication tools to link to the unabbreviated and therefore more complete version
744
//	 * of the reference.
745
//	 *
746
//	 * @see #getAbbreviatedReference()
747
//	 * @return the full reference
748
//	 */
749
//	public Reference getFullReference() {
750
//		return fullReference;
751
//	}
752
//
753
//	/**
754
//	 * @see #getFullReference()
755
//	 * @param fullReference
756
//	 */
757
//	public void setFullReference(Reference fullReference) {
758
//		this.fullReference = fullReference;
759
//	}
760
//
761
//	/**
762
//	 * Returns the abbreviated reference that belongs to this full reference. If this
763
//	 * reference is not a full reference the abbeviated referece must be <code>null</code>.<BR>
764
//	 * An abbreviated reference should be added to a reference which represents the long (full)
765
//	 * form of a reference.
766
//	 * In future this may become a set or handled differently as there are multiple
767
//	 *
768
//	 * @see #getFullReference()
769
//	 * @return the full reference
770
//	 */
771
//	public Reference getAbbreviatedReference() {
772
//		return abbreviatedReference;
773
//	}
774
//
775
//	/**
776
//	 * @see #getAbbreviatedReference()
777
//	 * @param abbreviatedReference
778
//	 *
779
//	 */
780
//	public void setAbbreviatedReference(Reference abbreviatedReference) {
781
//		this.abbreviatedReference = abbreviatedReference;
782
//	}
783

    
784
//****************************************************  /
785

    
786
//	/**
787
//	 * Returns the string representing the name of the editor of <i>this</i>
788
//	 * generic reference. An editor is mostly a person (team) who assumed the
789
//	 * responsibility for the content of the publication as a whole without
790
//	 * being the author of this content.<BR>
791
//	 * If there is an editor then the generic reference must be some
792
//	 * kind of {@link PrintedUnitBase physical printed unit}.
793
//	 *
794
//	 * @return  the string identifying the editor of <i>this</i>
795
//	 * 			generic reference
796
//	 * @see 	#getPublisher()
797
//	 */
798
//	protected String getEditor(){
799
//		return this.editor;
800
//	}
801
//
802
//	/**
803
//	 * @see #getEditor()
804
//	 */
805
//	protected void setEditor(String editor){
806
//		this.editor = editor;
807
//	}
808
//
809
//	/**
810
//	 * Returns the string representing the series (for instance for books or
811
//	 * within journals) - and series part - in which <i>this</i> generic reference
812
//	 * was published.<BR>
813
//	 * If there is a series then the generic reference must be some
814
//	 * kind of {@link PrintedUnitBase physical printed unit} or an {@link Article article}.
815
//	 *
816
//	 * @return  the string identifying the series for <i>this</i>
817
//	 * 			generic reference
818
//	 */
819
//	protected String getSeries(){
820
//		return this.series;
821
//	}
822
//
823
//	/**
824
//	 * @see #getSeries()
825
//	 */
826
//	protected void setSeries(String series){
827
//		this.series = series;
828
//	}
829
//
830
//	/**
831
//	 * Returns the string representing the volume (for instance for books or
832
//	 * within journals) in which <i>this</i> generic reference was published.<BR>
833
//	 * If there is a volume then the generic reference must be some
834
//	 * kind of {@link PrintedUnitBase physical printed unit} or an {@link Article article}.
835
//	 *
836
//	 * @return  the string identifying the volume for <i>this</i>
837
//	 * 			generic reference
838
//	 */
839
//	protected String getVolume(){
840
//		return this.volume;
841
//	}
842
//
843
//	/**
844
//	 * @see #getVolume()
845
//	 */
846
//	protected void setVolume(String volume){
847
//		this.volume = volume;
848
//	}
849
//
850
//	/**
851
//	 * Returns the string representing the page(s) where the content of
852
//	 * <i>this</i> generic reference is located.<BR>
853
//	 * If there is a pages information then the generic reference must be some
854
//	 * kind of {@link PrintedUnitBase physical printed unit} or an {@link Article article}.
855
//	 *
856
//	 * @return  the string containing the pages corresponding to <i>this</i>
857
//	 * 			generic reference
858
//	 */
859
//	protected String getPages(){
860
//		return this.pages;
861
//	}
862
//
863
//	/**
864
//	 * @see #getPages()
865
//	 */
866
//	protected void setPages(String pages){
867
//		this.pages = pages;
868
//	}
869

    
870

    
871
	/**
872
	 * Returns a formatted string containing the entire reference citation,
873
	 * including authors, corresponding to <i>this</i> reference.
874
	 *
875
	 * @see  #generateTitle()
876
	 */
877
	// TODO implement
878
	@Transient
879
	public String getCitation(){
880
		rectifyCacheStrategy();
881
		if (getCacheStrategy() == null){
882
			logger.warn("No CacheStrategy defined for "+ this.getClass() + ": " + this.getUuid());
883
			return null;
884
		}else{
885
			return getCacheStrategy().getTitleCache(this);
886
		}
887
	}
888

    
889

    
890
	@Override
891
    public String generateTitle() {
892
		rectifyCacheStrategy();
893
		return super.generateTitle();
894
	}
895
	
896
    public String generateAbbrevTitle() {
897
		rectifyCacheStrategy(); //TODO needed, is called by getCacheStrategy already
898
		return getCacheStrategy().getAbbrevTitleCache(this);
899
	}
900

    
901
	/**
902
	 * Returns a string representation for the year of publication / creation
903
	 * of <i>this</i> reference. If the {@link #getDatePublished() datePublished}
904
	 * of this reference contains more date information then (starting) year
905
	 * only the year is returned.
906
	 * than  attribute.
907
	 */
908
	@Override
909
    @Transient
910
	public String getYear(){
911
		TimePeriod datePublished = this.getDatePublished();
912
		if (datePublished != null ){
913
			String result = getDatePublished().getYear();
914
			return result;
915
		}else{
916
			return null;
917
		}
918
	}
919

    
920
	/**
921
	 * Convenience method that returns a string representation for the publication date / creation
922
	 * of <i>this</i> reference. The string is obtained by
923
	 * {@link #getDatePublished()#toString() the string representation
924
	 * of the date published}.
925
	 */
926
	@Transient
927
	public String getDatePublishedString(){
928
		TimePeriod datePublished = this.getDatePublished();
929
		if (datePublished != null ){
930
			return getDatePublished().toString();
931
		}else{
932
			return null;
933
		}
934
	}
935

    
936

    
937
	@Override
938
    public int getParsingProblem(){
939
		return this.parsingProblem;
940
	}
941

    
942
	@Override
943
    public void setParsingProblem(int parsingProblem){
944
		this.parsingProblem = parsingProblem;
945
	}
946

    
947
	@Override
948
    public boolean hasProblem(){
949
		return parsingProblem != 0;
950
	}
951

    
952
	@Override
953
    public boolean hasProblem(ParserProblem problem) {
954
		return getParsingProblems().contains(problem);
955
	}
956

    
957
	@Override
958
    public int getProblemStarts(){
959
		return this.problemStarts;
960
	}
961

    
962
	@Override
963
    public void setProblemStarts(int start) {
964
		this.problemStarts = start;
965
	}
966

    
967
	@Override
968
    public int getProblemEnds(){
969
		return this.problemEnds;
970
	}
971

    
972
	@Override
973
    public void setProblemEnds(int end) {
974
		this.problemEnds = end;
975
	}
976

    
977
	@Override
978
    public void addParsingProblem(ParserProblem warning){
979
		parsingProblem = ParserProblem.addProblem(parsingProblem, warning);
980
	}
981

    
982
	@Override
983
    public void removeParsingProblem(ParserProblem problem) {
984
		parsingProblem = ParserProblem.removeProblem(parsingProblem, problem);
985
	}
986

    
987
	@Override
988
    @Transient
989
	public List<ParserProblem> getParsingProblems() {
990
		return ParserProblem.warningList(this.parsingProblem);
991
	}
992

    
993

    
994
	@Override
995
    @Transient
996
	public String getNomenclaturalCitation(String microReference) {
997
		rectifyCacheStrategy();
998
		String typeName = this.getType()== null ? "(no type defined)" : this.getType().getMessage();
999
		if (getCacheStrategy() == null){
1000
			logger.warn("No CacheStrategy defined for "+ typeName + ": " + this.getUuid());
1001
			return null;
1002
		}else{
1003
			if (getCacheStrategy() instanceof INomenclaturalReferenceCacheStrategy){
1004
				return ((INomenclaturalReferenceCacheStrategy)cacheStrategy).getNomenclaturalCitation(this, microReference);
1005
			}else {
1006
				logger.warn("No INomenclaturalReferenceCacheStrategy defined for "+ typeName + ": " + this.getUuid());
1007
				return null;
1008
			}
1009
		}
1010
	}
1011

    
1012

    
1013
	/**
1014
	 * Generates, according to the {@link eu.etaxonomy.cdm.strategy.strategy.cache.reference.IReferenceBaseCacheStrategy cache strategy}
1015
	 * assigned to <i>this</i> reference, a string that identifies <i>this</i>
1016
	 * reference and returns it. This string may be stored in the inherited
1017
	 * {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity#getTitleCache() titleCache} attribute.<BR>
1018
	 * This method overrides the generic and inherited generateTitle method
1019
	 * from {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity IdentifiableEntity}.
1020
	 *
1021
	 * @return  the string identifying <i>this</i> reference
1022
	 * @see  	#getCitation()
1023
	 * @see  	eu.etaxonomy.cdm.model.common.IdentifiableEntity#getTitleCache()
1024
	 * @see  	eu.etaxonomy.cdm.model.common.IdentifiableEntity#generateTitle()
1025
	 * @see  	eu.etaxonomy.cdm.strategy.strategy.cache.common.IIdentifiableEntityCacheStrategy#getTitleCache()
1026
	 */
1027
//	@Override
1028
//	public String generateTitle(){
1029
//		if (cacheStrategy == null){
1030
//			logger.warn("No CacheStrategy defined for Reference: " + this.getUuid());
1031
//			return null;
1032
//		}else{
1033
//			return cacheStrategy.getTitleCache(this);
1034
//		}
1035
//	}
1036

    
1037

    
1038

    
1039
//	/**
1040
//	 * Returns the reference identity object
1041
//	 * @return the referenceIdentity
1042
//	 */
1043
//	public ReferenceIdentity getReferenceIdentity() {
1044
//		return referenceIdentity;
1045
//	}
1046
//
1047
//	/**
1048
//	 * For bidirectional use only
1049
//	 * @param referenceIdentity the referenceIdentity to set
1050
//	 */
1051
//	protected void setReferenceIdentity(ReferenceIdentity referenceIdentity) {
1052
//		this.referenceIdentity = referenceIdentity;
1053
//	}
1054
//
1055
//	/**
1056
//	 * Returns the set of all identical references. Same as getReferenceIdentity().getReferences()
1057
//	 * @return
1058
//	 */
1059
//	public Set<Reference> identicalReferences(){
1060
//		return referenceIdentity.getReferences();
1061
//	}
1062

    
1063

    
1064
//********** Casting methods ***********************************/
1065

    
1066
	public IArticle castReferenceToArticle(){
1067
		setType(ReferenceType.Article);
1068
		return this;
1069
	}
1070

    
1071
	public IBook castReferenceToBook(){
1072
		setType(ReferenceType.Book);
1073
		return this;
1074
	}
1075

    
1076
	public IBookSection castReferenceToBookSection(){
1077
		setType(ReferenceType.BookSection);
1078
		return this;
1079
	}
1080

    
1081
	public ICdDvd castReferenceToCdDvd(){
1082
		setType(ReferenceType.CdDvd);
1083
		return this;
1084
	}
1085

    
1086
	public IDatabase castReferenceToDatabase(){
1087
		setType(ReferenceType.Database);
1088
		return this;
1089
	}
1090

    
1091
	public IGeneric castReferenceToGeneric(){
1092
		setType(ReferenceType.Generic);
1093
		return this;
1094
	}
1095

    
1096
	public IInProceedings castReferenceToInProceedings(){
1097
		setType(ReferenceType.InProceedings);
1098
		return this;
1099
	}
1100

    
1101
	public IJournal castReferenceToJournal(){
1102
		setType(ReferenceType.Journal);
1103
		return this;
1104
	}
1105

    
1106
	public IMap castReferenceToMap(){
1107
		setType(ReferenceType.Map);
1108
		return (IMap) this;
1109
	}
1110

    
1111
	public IPatent castReferenceToPatent(){
1112
		setType(ReferenceType.Patent);
1113
		return this;
1114
	}
1115

    
1116
	public IPersonalCommunication castReferenceToPersonalCommunication(){
1117
		setType(ReferenceType.PersonalCommunication);
1118
		return this;
1119
	}
1120

    
1121
	public IPrintSeries castReferenceToPrintSeries(){
1122
		setType(ReferenceType.PrintSeries);
1123
		return this;
1124
	}
1125

    
1126
	public IWebPage castReferenceToWebPage(){
1127
		setType(ReferenceType.WebPage);
1128
		return this;
1129
	}
1130

    
1131
	public IProceedings castReferenceToProceedings(){
1132
		setType(ReferenceType.Proceedings);
1133
		return this;
1134
	}
1135

    
1136
	public IReport castReferenceToReport(){
1137
		setType(ReferenceType.Report);
1138
		return this;
1139
	}
1140

    
1141
	public IThesis castReferenceToThesis(){
1142
		setType(ReferenceType.Thesis);
1143
		return this;
1144
	}
1145

    
1146

    
1147
	@Override
1148
    @Transient // prevent from being serialized by webservice
1149
	public IJournal getInJournal() {
1150
		IJournal journal = this.inReference;
1151
		return journal;
1152
	}
1153

    
1154
	@Override
1155
    public void setInJournal(IJournal journal) {
1156
		this.inReference = (Reference<JournalDefaultCacheStrategy>) journal;
1157

    
1158
	}
1159

    
1160
	@Override
1161
    @Transient // prevent from being serialized by webservice
1162
	public IPrintSeries getInSeries() {
1163
		IPrintSeries printSeries = this.inReference;
1164
		return printSeries;
1165
	}
1166

    
1167
	@Override
1168
    public void setInSeries(IPrintSeries inSeries) {
1169
		this.inReference = (Reference<IReferenceBaseCacheStrategy>) inSeries;
1170
	}
1171

    
1172
	@Override
1173
    @Transient // prevent from being serialized by webservice
1174
	public IBook getInBook() {
1175
		IBook book = this.inReference;
1176
		return book;
1177
	}
1178

    
1179
//********************** In-References *****************************************
1180

    
1181
	@Override
1182
    public void setInBook(IBook book) {
1183
		this.inReference = (Reference<BookDefaultCacheStrategy>) book;
1184
	}
1185

    
1186
	@Override
1187
    @Transient // prevent from being serialized by webservice
1188
	public IProceedings getInProceedings() {
1189
		IProceedings proceedings = this.inReference;
1190
		return proceedings;
1191
	}
1192

    
1193
	@Override
1194
    public void setInProceedings(IProceedings proceeding) {
1195
		this.inReference = (Reference<BookDefaultCacheStrategy>) proceeding;
1196
	}
1197

    
1198
//*************************** CACHE STRATEGIES ******************************/
1199

    
1200
    public S getCacheStrategy() {
1201
    	rectifyCacheStrategy();
1202
    	return this.cacheStrategy;
1203
    }
1204
	
1205
	/**
1206
	 * The type property of this class is mapped on the field level to the data base column, so
1207
	 * Hibernate will consequently use the {@link org.hibernate.property.DirectPropertyAccessor}
1208
	 * to set the property. This PropertyAccessor directly sets the field instead of using the according setter so
1209
	 * the CacheStrategy is not correctly set after the initialization of the bean. Thus we need to
1210
	 * validate the CacheStrategy before it is to be used.
1211
	 */
1212
	private void rectifyCacheStrategy() {
1213
		if(!cacheStrategyRectified ){
1214
			setType(getType());
1215
			cacheStrategyRectified = true;
1216
		}
1217
	}
1218

    
1219

    
1220
	//public void setCacheStrategy(S cacheStrategy){
1221
	//	this.cacheStrategy = cacheStrategy;
1222
	//}
1223

    
1224
	@Override
1225
    public void setCacheStrategy(IReferenceBaseCacheStrategy iReferenceBaseCacheStrategy) {
1226
		this.cacheStrategy = (S) iReferenceBaseCacheStrategy;
1227

    
1228
	}
1229

    
1230
	@Override
1231
    public void setCacheStrategy(ArticleDefaultCacheStrategy cacheStrategy) {
1232
		this.cacheStrategy = (S) cacheStrategy;
1233
	}
1234

    
1235
	@Override
1236
    public void setCacheStrategy(BookDefaultCacheStrategy cacheStrategy) {
1237
		this.cacheStrategy = (S) cacheStrategy;
1238
	}
1239

    
1240
	@Override
1241
    public void setCacheStrategy(JournalDefaultCacheStrategy cacheStrategy) {
1242
		this.cacheStrategy = (S) cacheStrategy;
1243
	}
1244

    
1245
	@Override
1246
    public void setCacheStrategy(BookSectionDefaultCacheStrategy cacheStrategy) {
1247
		this.cacheStrategy = (S) cacheStrategy;
1248
	}
1249

    
1250
	@Override
1251
    public void setCacheStrategy(GenericDefaultCacheStrategy cacheStrategy) {
1252
		this.cacheStrategy = (S) cacheStrategy;
1253
	}
1254

    
1255
	public void setCacheStrategy(ReferenceDefaultCacheStrategy cacheStrategy) {
1256
		this.cacheStrategy = (S)cacheStrategy;
1257

    
1258
	}
1259
	
1260
	
1261
	
1262
//    @Override
1263
//    protected void initListener(){
1264
//        PropertyChangeListener listener = new PropertyChangeListener() {
1265
//            @Override
1266
//            public void propertyChange(PropertyChangeEvent e) {
1267
//                boolean protectedByLowerCache = false;
1268
//                //authorship cache
1269
//                if (fieldHasCacheUpdateProperty(e.getPropertyName(), "authorshipCache")){
1270
//                    if (protectedAuthorshipCache){
1271
//                        protectedByLowerCache = true;
1272
//                    }else{
1273
//                        authorshipCache = null;
1274
//                    }
1275
//                }
1276
//
1277
//                //title cache
1278
//                if (! fieldHasNoUpdateProperty(e.getPropertyName(), "titleCache")){
1279
//                    if (isProtectedTitleCache()|| protectedByLowerCache == true ){
1280
//                        protectedByLowerCache = true;
1281
//                    }else{
1282
//                        titleCache = null;
1283
//                    }
1284
//                }
1285
//                //full title cache
1286
//                if (! fieldHasNoUpdateProperty(e.getPropertyName(), "fullTitleCache")){
1287
//                    if (isProtectedFullTitleCache()|| protectedByLowerCache == true ){
1288
//                        protectedByLowerCache = true;
1289
//                    }else{
1290
//                        fullTitleCache = null;
1291
//                    }
1292
//                }
1293
//            }
1294
//        };
1295
//        addPropertyChangeListener(listener);  //didn't use this.addXXX to make lsid.AssemblerTest run in cdmlib-remote
1296
//    }
1297

    
1298

    
1299
//*********************** CLONE ********************************************************/
1300

    
1301
	/**
1302
	 * Clones <i>this</i> reference. This is a shortcut that enables to create
1303
	 * a new instance that differs only slightly from <i>this</i> reference by
1304
	 * modifying only some of the attributes.
1305
	 *
1306
	 * @see eu.etaxonomy.cdm.model.media.IdentifiableMediaEntity#clone()
1307
	 * @see java.lang.Object#clone()
1308
	 */
1309
	@Override
1310
	public Object clone() {
1311
		try {
1312
			Reference<?> result = (Reference<?>)super.clone();
1313
			result.setDatePublished(datePublished != null? (TimePeriod)datePublished.clone(): null);
1314
			//no changes to: title, authorship, hasProblem, nomenclaturallyRelevant, uri
1315
			return result;
1316
		} catch (CloneNotSupportedException e) {
1317
			logger.warn("Object does not implement cloneable");
1318
			e.printStackTrace();
1319
			return null;
1320
		}
1321
	}
1322
	
1323
//******************************* toString *****************************/	
1324

    
1325
	@Override
1326
	public String toString() {
1327
		if (type != null){
1328
			String result = "Reference [type=" + type + ", id= " + this.getId() + ", uuid=" + this.uuid ;
1329
			result += title == null ? "" : ", title=" + title;
1330
			result += abbrevTitle == null ? "" : ", abbrevTitle=" + abbrevTitle;
1331
			result += "]";
1332
			return result;
1333
		}else{
1334
			return super.toString();
1335
		}
1336
	}
1337
	
1338
	
1339

    
1340

    
1341
}
1342

    
(23-23/28)