minor
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / reference / Reference.java
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
13 import java.net.URI;
14 import java.util.List;
15
16 import javax.persistence.Column;
17 import javax.persistence.Embedded;
18 import javax.persistence.Entity;
19 import javax.persistence.FetchType;
20 import javax.persistence.Inheritance;
21 import javax.persistence.InheritanceType;
22 import javax.persistence.Lob;
23 import javax.persistence.ManyToOne;
24 import javax.persistence.Transient;
25 import javax.validation.constraints.NotNull;
26 import javax.validation.constraints.Pattern;
27 import javax.xml.bind.annotation.XmlAccessType;
28 import javax.xml.bind.annotation.XmlAccessorType;
29 import javax.xml.bind.annotation.XmlAttribute;
30 import javax.xml.bind.annotation.XmlElement;
31 import javax.xml.bind.annotation.XmlIDREF;
32 import javax.xml.bind.annotation.XmlRootElement;
33 import javax.xml.bind.annotation.XmlSchemaType;
34 import javax.xml.bind.annotation.XmlType;
35
36 import org.apache.commons.lang.StringUtils;
37 import org.apache.log4j.Logger;
38 import org.hibernate.annotations.Cascade;
39 import org.hibernate.annotations.CascadeType;
40 import org.hibernate.annotations.Table;
41 import org.hibernate.annotations.Type;
42 import org.hibernate.envers.Audited;
43 import org.hibernate.search.annotations.Analyze;
44 import org.hibernate.search.annotations.Field;
45 import org.hibernate.search.annotations.IndexedEmbedded;
46 import org.hibernate.validator.constraints.Length;
47
48 import eu.etaxonomy.cdm.model.agent.Institution;
49 import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
50 import eu.etaxonomy.cdm.model.common.TimePeriod;
51 import eu.etaxonomy.cdm.model.media.IdentifiableMediaEntity;
52 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
53 import eu.etaxonomy.cdm.strategy.cache.reference.ArticleDefaultCacheStrategy;
54 import eu.etaxonomy.cdm.strategy.cache.reference.BookDefaultCacheStrategy;
55 import eu.etaxonomy.cdm.strategy.cache.reference.BookSectionDefaultCacheStrategy;
56 import eu.etaxonomy.cdm.strategy.cache.reference.GenericDefaultCacheStrategy;
57 import eu.etaxonomy.cdm.strategy.cache.reference.INomenclaturalReferenceCacheStrategy;
58 import eu.etaxonomy.cdm.strategy.cache.reference.IReferenceBaseCacheStrategy;
59 import eu.etaxonomy.cdm.strategy.cache.reference.JournalDefaultCacheStrategy;
60 import eu.etaxonomy.cdm.strategy.cache.reference.ReferenceDefaultCacheStrategy;
61 import eu.etaxonomy.cdm.strategy.match.Match;
62 import eu.etaxonomy.cdm.strategy.match.MatchMode;
63 import eu.etaxonomy.cdm.strategy.merge.Merge;
64 import eu.etaxonomy.cdm.strategy.merge.MergeMode;
65 import eu.etaxonomy.cdm.strategy.parser.ParserProblem;
66 import eu.etaxonomy.cdm.validation.Level2;
67 import eu.etaxonomy.cdm.validation.annotation.InReference;
68 import eu.etaxonomy.cdm.validation.annotation.NullOrNotEmpty;
69 import eu.etaxonomy.cdm.validation.annotation.ReferenceCheck;
70
71 /**
72 * The upmost (abstract) class for references (information sources).
73 * <P>
74 * This class corresponds to: <ul>
75 * <li> PublicationCitation according to the TDWG ontology
76 * <li> Publication according to the TCS
77 * <li> Reference according to the ABCD schema
78 * </ul>
79 *
80 * @author m.doering
81 * @created 08-Nov-2007 13:06:47
82 */
83 @XmlAccessorType(XmlAccessType.FIELD)
84 @XmlType(name = "Reference", propOrder = {
85 "type",
86 "uri",
87 "abbrevTitleCache",
88 "protectedAbbrevTitleCache",
89 "nomenclaturallyRelevant",
90 "authorTeam",
91 "referenceAbstract",
92 "title",
93 "abbrevTitle",
94 "editor",
95 "volume",
96 "pages",
97 "series",
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 = Level2.class)
117 @ReferenceCheck(groups = Level2.class)
118 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 {
119 private static final long serialVersionUID = -2034764545042691295L;
120 private static final Logger logger = Logger.getLogger(Reference.class);
121
122 @XmlAttribute(name ="type")
123 @Column(name="refType")
124 @NotNull
125 @Type(type = "eu.etaxonomy.cdm.hibernate.EnumUserType",
126 parameters = {@org.hibernate.annotations.Parameter(name = "enumClass", value = "eu.etaxonomy.cdm.model.reference.ReferenceType")}
127 )
128 protected ReferenceType type;
129
130 //Title of the reference
131 @XmlElement(name ="Title" )
132 @Column(length=4096, name="title")
133 @Lob
134 @Field
135 @Match(MatchMode.EQUAL_REQUIRED)
136 //TODO Val #3379
137 // @NullOrNotEmpty
138 @Length(max = 4096) //TODO is the length attribute really requried twice (see @Column)??
139 private String title;
140
141 //Title of the reference
142 @XmlElement(name ="AbbrevTitle" )
143 @Field
144 @Match(MatchMode.EQUAL) //TODO check if this is correct
145 @NullOrNotEmpty
146 @Length(max = 255)
147 private String abbrevTitle;
148
149 //Title of the reference
150 @XmlElement(name ="AbbrevTitleCache" )
151 @Field
152 @Match(MatchMode.CACHE)
153 //TODO Val #3379
154 // @NotNull
155 @Length(max = 1024)
156 private String abbrevTitleCache;
157
158 @XmlElement(name = "protectedAbbrevTitleCache")
159 @Merge(MergeMode.OR)
160 private boolean protectedAbbrevTitleCache;
161
162 //********************************************************/
163
164
165 @XmlElement(name = "Editor")
166 @Field
167 //TODO Val #3379
168 // @NullOrNotEmpty
169 @Length(max = 255)
170 protected String editor;
171
172 @XmlElement(name = "Series")
173 @Field
174 //TODO Val #3379
175 // @NullOrNotEmpty
176 @Length(max = 255)
177 protected String series;
178
179 @XmlElement(name = "Volume")
180 @Field
181 //TODO Val #3379
182 // @NullOrNotEmpty
183 @Length(max = 255)
184 protected String volume;
185
186 @XmlElement(name = "Pages")
187 @Field
188 //TODO Val #3379
189 // @NullOrNotEmpty
190 @Length(max = 255)
191 protected String pages;
192
193 @XmlElement(name = "Edition")
194 @Field
195 //TODO Val #3379
196 // @NullOrNotEmpty
197 @Length(max = 255)
198 protected String edition;
199
200 @XmlElement(name = "ISBN")
201 @Field
202 //TODO Val #3379
203 // @NullOrNotEmpty
204 @Length(max = 255)
205 @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}")
206 protected String isbn;
207
208 @XmlElement(name = "Doi")
209 @Field
210 @NullOrNotEmpty
211 @Length(max = 255)
212 // @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.doi.message}")
213 protected String doi;
214
215
216 @XmlElement(name = "ISSN")
217 @Field
218 //TODO Val #3379
219 // @NullOrNotEmpty
220 @Length(max = 255)
221 @Pattern(regexp = "(?=.{9}$)\\d{4}([- ])\\d{4} (\\d|X)$", groups = Level2.class, message = "{eu.etaxonomy.cdm.model.reference.Reference.issn.message}")
222 protected String issn;
223
224 @XmlElement(name = "SeriesPart")
225 @Field
226 //TODO Val #3379
227 // @NullOrNotEmpty
228 @Length(max = 255)
229 protected String seriesPart;
230
231 @XmlElement(name = "Organization")
232 @Field
233 //TODO Val #3379
234 // @NullOrNotEmpty
235 @Length(max = 255)
236 protected String organization;
237
238 @XmlElement(name = "Publisher")
239 @Field
240 //TODO Val #3379
241 // @NullOrNotEmpty
242 @Length(max = 255)
243 protected String publisher;
244
245
246 @XmlElement(name = "PlacePublished")
247 @Field
248 //TODO Val #3379
249 // @NullOrNotEmpty
250 @Length(max = 255)
251 protected String placePublished;
252
253 @XmlElement(name = "Institution")
254 @XmlIDREF
255 @XmlSchemaType(name = "IDREF")
256 @ManyToOne(fetch = FetchType.LAZY)
257 @IndexedEmbedded
258 @Cascade(CascadeType.SAVE_UPDATE)
259 protected Institution institution;
260
261 @XmlElement(name = "School")
262 @XmlIDREF
263 @XmlSchemaType(name = "IDREF")
264 @ManyToOne(fetch = FetchType.LAZY)
265 @IndexedEmbedded
266 @Cascade(CascadeType.SAVE_UPDATE)
267 protected Institution school;
268
269 @XmlElement(name = "InReference")
270 @XmlIDREF
271 @XmlSchemaType(name = "IDREF")
272 @ManyToOne(fetch = FetchType.LAZY)
273 // @IndexedEmbedded
274 @Cascade(CascadeType.SAVE_UPDATE)
275 // @InReference(groups=Level2.class)
276 protected Reference<?> inReference;
277
278 // @XmlElement(name = "FullReference")
279 // @XmlIDREF
280 // @XmlSchemaType(name = "IDREF")
281 // @ManyToOne(fetch = FetchType.LAZY)
282 //// @IndexedEmbedded
283 // @Cascade(CascadeType.SAVE_UPDATE)
284 // protected Reference fullReference;
285 //
286 // @XmlElement(name = "AbbreviatedReference")
287 // @XmlIDREF
288 // @XmlSchemaType(name = "IDREF")
289 // @ManyToOne(fetch = FetchType.LAZY)
290 //// @IndexedEmbedded
291 // @Cascade(CascadeType.SAVE_UPDATE)
292 // protected Reference abbreviatedReference;
293
294
295 //********************************************************/
296
297 //The date range assigned to the reference. ISO Date range like. Flexible, year can be left out, etc
298 @XmlElement(name ="DatePublished" )
299 @Embedded
300 @IndexedEmbedded
301 private TimePeriod datePublished = TimePeriod.NewInstance();
302
303 @XmlElement(name ="Abstract" )
304 @Column(length=65536, name="referenceAbstract")
305 @Lob
306 @Field
307 //TODO Val #3379
308 // @NullOrNotEmpty
309 @Length(max = 65536)
310 private String referenceAbstract; //abstract is a reserved term in Java
311
312
313 //URIs like DOIs, LSIDs or Handles for this reference
314 @XmlElement(name = "URI")
315 @Field(analyze = Analyze.NO)
316 @Type(type="uriUserType")
317 private URI uri;
318
319 //flag to subselect only references that could be useful for nomenclatural citations. If a reference is used as a
320 //nomenclatural reference in a name this flag should be automatically set
321 @XmlElement(name = "IsNomenclaturallyRelevant")
322 @Merge(MergeMode.OR)
323 private boolean nomenclaturallyRelevant;
324
325 @XmlElement(name = "AuthorTeam")
326 @XmlIDREF
327 @XmlSchemaType(name = "IDREF")
328 @ManyToOne(fetch = FetchType.LAZY)
329 @IndexedEmbedded
330 @Cascade(CascadeType.SAVE_UPDATE)
331 private TeamOrPersonBase<?> authorTeam;
332
333 // @XmlElement(name = "ReferenceIdentity")
334 // @XmlIDREF
335 // @XmlSchemaType(name = "IDREF")
336 // @ManyToOne(fetch = FetchType.LAZY)
337 // //@IndexedEmbedded
338 // @Cascade(CascadeType.SAVE_UPDATE)
339 // @Transient
340 // private ReferenceIdentity referenceIdentity;
341
342 @XmlAttribute
343 @Match(MatchMode.IGNORE)
344 private int parsingProblem = 0;
345
346 @XmlAttribute
347 @Match(MatchMode.IGNORE)
348 private int problemStarts = -1;
349
350 @XmlAttribute
351 @Match(MatchMode.IGNORE)
352 private int problemEnds = -1;
353
354 @Transient
355 @XmlAttribute
356 @Match(MatchMode.IGNORE)
357 private boolean cacheStrategyRectified = false;
358
359 protected Reference(){
360 this(ReferenceType.Generic);
361 }
362
363 protected Reference(ReferenceType type) {
364 this.type = type;
365 this.cacheStrategy =(S) type.getCacheStrategy();
366 }
367
368
369 //*************************** GETTER / SETTER ******************************************/
370
371
372 @Override
373 public String getAbbrevTitleCache() {
374 if (protectedAbbrevTitleCache){
375 return this.abbrevTitleCache;
376 }
377 // is title dirty, i.e. equal NULL?
378 if (abbrevTitleCache == null){
379 this.abbrevTitleCache = generateAbbrevTitle();
380 this.abbrevTitleCache = getTruncatedCache(this.abbrevTitleCache) ;
381 }
382 return abbrevTitleCache;
383 }
384
385 @Override
386 @Deprecated
387 public void setAbbrevTitleCache(String abbrevTitleCache) {
388 this.abbrevTitleCache = abbrevTitleCache;
389 }
390
391 @Override
392 public void setAbbrevTitleCache(String abbrevTitleCache, boolean isProtected) {
393 this.protectedAbbrevTitleCache = isProtected;
394 setAbbrevTitleCache(abbrevTitleCache);
395 }
396
397 @Override
398 public boolean isProtectedAbbrevTitleCache() {
399 return protectedAbbrevTitleCache;
400 }
401
402 @Override
403 public void setProtectedAbbrevTitleCache(boolean protectedAbbrevTitleCache) {
404 this.protectedAbbrevTitleCache = protectedAbbrevTitleCache;
405 }
406
407 @Override
408 public String getAbbrevTitle() {
409 return abbrevTitle;
410 }
411
412 @Override
413 public void setAbbrevTitle(String abbrevTitle) {
414 this.abbrevTitle = abbrevTitle;
415 }
416
417
418 @Override
419 public String getEditor() {
420 return editor;
421 }
422
423
424 @Override
425 public void setEditor(String editor) {
426 this.editor = editor;
427 }
428
429 @Override
430 public String getSeries() {
431 return series;
432 }
433
434 @Override
435 public void setSeries(String series) {
436 this.series = series;
437 }
438
439 @Override
440 public String getVolume() {
441 return volume;
442 }
443
444 @Override
445 public void setVolume(String volume) {
446 this.volume = volume;
447 }
448
449 @Override
450 public String getPages() {
451 return pages;
452 }
453
454 @Override
455 public void setPages(String pages) {
456 this.pages = pages;
457 }
458
459 @Override
460 public String getEdition() {
461 return edition;
462 }
463
464 @Override
465 public void setEdition(String edition) {
466 this.edition = edition;
467 }
468
469 @Override
470 public String getIsbn() {
471 return isbn;
472 }
473
474 @Override
475 public void setIsbn(String isbn) {
476 this.isbn = isbn;
477 }
478
479 @Override
480 public String getIssn() {
481 return issn;
482 }
483
484 @Override
485 public void setIssn(String issn) {
486 this.issn = issn;
487 }
488
489 @Override
490 public String getDoi() {
491 return doi;
492 }
493
494 @Override
495 public void setDoi(String doi) {
496 this.doi = doi;
497 }
498
499 @Override
500 public String getSeriesPart() {
501 return seriesPart;
502 }
503
504 @Override
505 public void setSeriesPart(String seriesPart) {
506 this.seriesPart = seriesPart;
507 }
508
509 @Override
510 public String getOrganization() {
511 return organization;
512 }
513
514 @Override
515 public void setOrganization(String organization) {
516 this.organization = organization;
517 }
518
519 @Override
520 public String getPublisher() {
521 return publisher;
522 }
523
524 @Override
525 public void setPublisher(String publisher) {
526 this.publisher = publisher;
527 }
528
529 @Override
530 public void setPublisher(String publisher, String placePublished){
531 this.publisher = publisher;
532 this.placePublished = placePublished;
533 }
534
535 @Override
536 public String getPlacePublished() {
537 return placePublished;
538 }
539
540 @Override
541 public void setPlacePublished(String placePublished) {
542 this.placePublished = placePublished;
543 }
544
545 @Override
546 public Institution getInstitution() {
547 return institution;
548 }
549
550 @Override
551 public void setInstitution(Institution institution) {
552 this.institution = institution;
553 }
554
555 @Override
556 public Institution getSchool() {
557 return school;
558 }
559
560 @Override
561 public void setSchool(Institution school) {
562 this.school = school;
563 }
564
565 @Override
566 public Reference getInReference() {
567 return inReference;
568 }
569
570 @Override
571 public void setInReference(Reference inReference) {
572 this.inReference = inReference;
573 }
574
575 @Override
576 public void setType(ReferenceType type) {
577 this.setCacheStrategy(type.getCacheStrategy());
578 this.type = type;
579 }
580
581 /**
582 * @return the type
583 */
584 @Override
585 public ReferenceType getType() {
586 return type;
587 }
588
589 /**
590 * Whether this reference is of the given type
591 *
592 * @param type
593 * @return
594 */
595 @Override
596 public boolean isOfType(ReferenceType type){
597 return type == getType();
598 }
599
600 /**
601 * Returns a string representing the title of <i>this</i> reference. If a
602 * reference has different titles (for instance abbreviated and not
603 * abbreviated) then for each title a new instance must be created.
604 *
605 * @return the title string of <i>this</i> reference
606 * @see #getCitation()
607 */
608 @Override
609 public String getTitle(){
610 return this.title;
611 }
612 /**
613 * @see #getTitle()
614 */
615 @Override
616 public void setTitle(String title){
617 this.title = title;
618 }
619
620 /**
621 * Returns the date (mostly only the year) of publication / creation of
622 * <i>this</i> reference.
623 */
624 @Override
625 public TimePeriod getDatePublished(){
626 return this.datePublished;
627 }
628 /**
629 * @see #getDatePublished()
630 */
631 @Override
632 public void setDatePublished(TimePeriod datePublished){
633 this.datePublished = datePublished;
634 }
635
636 public boolean hasDatePublished(){
637 boolean result = ! ( (this.datePublished == null) || StringUtils.isBlank(datePublished.toString()));
638 return result;
639 }
640
641 /**
642 * Returns the {@link eu.etaxonomy.cdm.model.agent.TeamOrPersonBase author (team)} who created the
643 * content of <i>this</i> reference.
644 *
645 * @return the author (team) of <i>this</i> reference
646 * @see eu.etaxonomy.cdm.model.agent.TeamOrPersonBase
647 */
648 @Override
649 public TeamOrPersonBase getAuthorTeam(){
650 return this.authorTeam;
651 }
652
653 /**
654 * @see #getAuthorTeam()
655 */
656 @Override
657 public void setAuthorTeam(TeamOrPersonBase authorTeam){
658 this.authorTeam = authorTeam;
659 }
660
661 /**
662 * Returns the Uniform Resource Identifier (URI) corresponding to <i>this</i>
663 * reference. An URI is a string of characters used to identify a resource
664 * on the Internet.
665 *
666 * @return the URI of <i>this</i> reference
667 */
668 @Override
669 public URI getUri(){
670 return this.uri;
671 }
672 /**
673 * @see #getUri()
674 */
675 @Override
676 public void setUri(URI uri){
677 this.uri = uri;
678 }
679
680 /**
681 * @return the referenceAbstract
682 */
683 @Override
684 public String getReferenceAbstract() {
685 return referenceAbstract;
686 }
687
688 /**
689 * @param referenceAbstract the referenceAbstract to set
690 */
691 @Override
692 public void setReferenceAbstract(String referenceAbstract) {
693 this.referenceAbstract = referenceAbstract;
694 }
695
696
697
698
699 /**
700 * Returns "true" if the isNomenclaturallyRelevant flag is set. This
701 * indicates that a {@link TaxonNameBase taxon name} has been originally
702 * published in <i>this</i> reference following the rules of a
703 * {@link eu.etaxonomy.cdm.model.name.NomenclaturalCode nomenclature code} and is therefore used for
704 * nomenclatural citations. This flag will be set as soon as <i>this</i>
705 * reference is used as a nomenclatural reference for any taxon name.<BR>
706 * FIXME what happens if the only taxon name referencing this reference is not
707 * any longer using this reference as a nomenclatural reference. How does the
708 * reference get informed about the fact that it is not nomenclaturally relevant
709 * anymore?
710 */
711 public boolean isNomenclaturallyRelevant(){
712 return this.nomenclaturallyRelevant;
713 }
714
715 /**
716 * @see #isNomenclaturallyRelevant()
717 */
718 public void setNomenclaturallyRelevant(boolean nomenclaturallyRelevant){
719 this.nomenclaturallyRelevant = nomenclaturallyRelevant;
720 }
721
722
723 // /**
724 // * Returns the full reference that belongs to this abbreviated reference. If this
725 // * reference is not abbreviated the full reference should be <code>null</code>.<BR>
726 // * A full reference should be added to a reference
727 // * which represents the abbreviated form of a reference. The full reference can be used
728 // * by publication tools to link to the unabbreviated and therefore more complete version
729 // * of the reference.
730 // *
731 // * @see #getAbbreviatedReference()
732 // * @return the full reference
733 // */
734 // public Reference getFullReference() {
735 // return fullReference;
736 // }
737 //
738 // /**
739 // * @see #getFullReference()
740 // * @param fullReference
741 // */
742 // public void setFullReference(Reference fullReference) {
743 // this.fullReference = fullReference;
744 // }
745 //
746 // /**
747 // * Returns the abbreviated reference that belongs to this full reference. If this
748 // * reference is not a full reference the abbeviated referece must be <code>null</code>.<BR>
749 // * An abbreviated reference should be added to a reference which represents the long (full)
750 // * form of a reference.
751 // * In future this may become a set or handled differently as there are multiple
752 // *
753 // * @see #getFullReference()
754 // * @return the full reference
755 // */
756 // public Reference getAbbreviatedReference() {
757 // return abbreviatedReference;
758 // }
759 //
760 // /**
761 // * @see #getAbbreviatedReference()
762 // * @param abbreviatedReference
763 // *
764 // */
765 // public void setAbbreviatedReference(Reference abbreviatedReference) {
766 // this.abbreviatedReference = abbreviatedReference;
767 // }
768
769 //**************************************************** /
770
771 // /**
772 // * Returns the string representing the name of the editor of <i>this</i>
773 // * generic reference. An editor is mostly a person (team) who assumed the
774 // * responsibility for the content of the publication as a whole without
775 // * being the author of this content.<BR>
776 // * If there is an editor then the generic reference must be some
777 // * kind of {@link PrintedUnitBase physical printed unit}.
778 // *
779 // * @return the string identifying the editor of <i>this</i>
780 // * generic reference
781 // * @see #getPublisher()
782 // */
783 // protected String getEditor(){
784 // return this.editor;
785 // }
786 //
787 // /**
788 // * @see #getEditor()
789 // */
790 // protected void setEditor(String editor){
791 // this.editor = editor;
792 // }
793 //
794 // /**
795 // * Returns the string representing the series (for instance for books or
796 // * within journals) - and series part - in which <i>this</i> generic reference
797 // * was published.<BR>
798 // * If there is a series then the generic reference must be some
799 // * kind of {@link PrintedUnitBase physical printed unit} or an {@link Article article}.
800 // *
801 // * @return the string identifying the series for <i>this</i>
802 // * generic reference
803 // */
804 // protected String getSeries(){
805 // return this.series;
806 // }
807 //
808 // /**
809 // * @see #getSeries()
810 // */
811 // protected void setSeries(String series){
812 // this.series = series;
813 // }
814 //
815 // /**
816 // * Returns the string representing the volume (for instance for books or
817 // * within journals) in which <i>this</i> generic reference was published.<BR>
818 // * If there is a volume then the generic reference must be some
819 // * kind of {@link PrintedUnitBase physical printed unit} or an {@link Article article}.
820 // *
821 // * @return the string identifying the volume for <i>this</i>
822 // * generic reference
823 // */
824 // protected String getVolume(){
825 // return this.volume;
826 // }
827 //
828 // /**
829 // * @see #getVolume()
830 // */
831 // protected void setVolume(String volume){
832 // this.volume = volume;
833 // }
834 //
835 // /**
836 // * Returns the string representing the page(s) where the content of
837 // * <i>this</i> generic reference is located.<BR>
838 // * If there is a pages information then the generic reference must be some
839 // * kind of {@link PrintedUnitBase physical printed unit} or an {@link Article article}.
840 // *
841 // * @return the string containing the pages corresponding to <i>this</i>
842 // * generic reference
843 // */
844 // protected String getPages(){
845 // return this.pages;
846 // }
847 //
848 // /**
849 // * @see #getPages()
850 // */
851 // protected void setPages(String pages){
852 // this.pages = pages;
853 // }
854
855
856 /**
857 * Returns a formatted string containing the entire reference citation,
858 * including authors, corresponding to <i>this</i> reference.
859 *
860 * @see #generateTitle()
861 */
862 // TODO implement
863 @Transient
864 public String getCitation(){
865 rectifyCacheStrategy();
866 if (cacheStrategy == null){
867 logger.warn("No CacheStrategy defined for "+ this.getClass() + ": " + this.getUuid());
868 return null;
869 }else{
870 return cacheStrategy.getTitleCache(this);
871 }
872 }
873
874 /* (non-Javadoc)
875 * @see eu.etaxonomy.cdm.model.common.IdentifiableEntity#generateTitle()
876 */
877 @Override
878 public String generateTitle() {
879 rectifyCacheStrategy();
880 return super.generateTitle();
881 }
882
883 public String generateAbbrevTitle() {
884 rectifyCacheStrategy();
885 return this.cacheStrategy.getAbbrevTitleCache(this);
886 }
887
888 /**
889 * Returns a string representation for the year of publication / creation
890 * of <i>this</i> reference. If the {@link #getDatePublished() datePublished}
891 * of this reference contains more date information then (starting) year
892 * only the year is returned.
893 * than attribute.
894 */
895 @Override
896 @Transient
897 public String getYear(){
898 TimePeriod datePublished = this.getDatePublished();
899 if (datePublished != null ){
900 String result = getDatePublished().getYear();
901 return result;
902 }else{
903 return null;
904 }
905 }
906
907 /**
908 * Convenience method that returns a string representation for the publication date / creation
909 * of <i>this</i> reference. The string is obtained by
910 * {@link #getDatePublished()#toString() the string representation
911 * of the date published}.
912 */
913 @Transient
914 public String getDatePublishedString(){
915 TimePeriod datePublished = this.getDatePublished();
916 if (datePublished != null ){
917 return getDatePublished().toString();
918 }else{
919 return null;
920 }
921 }
922
923
924
925 /* (non-Javadoc)
926 * @see eu.etaxonomy.cdm.model.common.IParsable#getHasProblem()
927 */
928 @Override
929 public int getParsingProblem(){
930 return this.parsingProblem;
931 }
932
933 /* (non-Javadoc)
934 * @see eu.etaxonomy.cdm.model.common.IParsable#setHasProblem(boolean)
935 */
936 @Override
937 public void setParsingProblem(int parsingProblem){
938 this.parsingProblem = parsingProblem;
939 }
940
941 /* (non-Javadoc)
942 * @see eu.etaxonomy.cdm.model.common.IParsable#hasProblem()
943 */
944 @Override
945 public boolean hasProblem(){
946 return parsingProblem != 0;
947 }
948
949 /* (non-Javadoc)
950 * @see eu.etaxonomy.cdm.model.common.IParsable#hasProblem(eu.etaxonomy.cdm.strategy.parser.ParserProblem)
951 */
952 @Override
953 public boolean hasProblem(ParserProblem problem) {
954 return getParsingProblems().contains(problem);
955 }
956
957
958 /* (non-Javadoc)
959 * @see eu.etaxonomy.cdm.model.common.IParsable#problemStarts()
960 */
961 @Override
962 public int getProblemStarts(){
963 return this.problemStarts;
964 }
965
966 /* (non-Javadoc)
967 * @see eu.etaxonomy.cdm.model.common.IParsable#setProblemStarts(int)
968 */
969 @Override
970 public void setProblemStarts(int start) {
971 this.problemStarts = start;
972 }
973
974 /* (non-Javadoc)
975 * @see eu.etaxonomy.cdm.model.common.IParsable#problemEnds()
976 */
977 @Override
978 public int getProblemEnds(){
979 return this.problemEnds;
980 }
981
982 /* (non-Javadoc)
983 * @see eu.etaxonomy.cdm.model.common.IParsable#setProblemEnds(int)
984 */
985 @Override
986 public void setProblemEnds(int end) {
987 this.problemEnds = end;
988 }
989
990 /* (non-Javadoc)
991 * @see eu.etaxonomy.cdm.model.common.IParsable#addProblem(eu.etaxonomy.cdm.strategy.parser.NameParserWarning)
992 */
993 @Override
994 public void addParsingProblem(ParserProblem warning){
995 parsingProblem = ParserProblem.addProblem(parsingProblem, warning);
996 }
997
998 /* (non-Javadoc)
999 * @see eu.etaxonomy.cdm.model.common.IParsable#removeParsingProblem(eu.etaxonomy.cdm.strategy.parser.ParserProblem)
1000 */
1001 @Override
1002 public void removeParsingProblem(ParserProblem problem) {
1003 parsingProblem = ParserProblem.removeProblem(parsingProblem, problem);
1004 }
1005
1006 /* (non-Javadoc)
1007 * @see eu.etaxonomy.cdm.model.common.IParsable#getParsingProblems()
1008 */
1009 @Override
1010 @Transient
1011 public List<ParserProblem> getParsingProblems() {
1012 return ParserProblem.warningList(this.parsingProblem);
1013 }
1014
1015
1016 @Override
1017 @Transient
1018 public String getNomenclaturalCitation(String microReference) {
1019 rectifyCacheStrategy();
1020 String typeName = this.getType()== null ? "(no type defined)" : this.getType().getMessage();
1021 if (cacheStrategy == null){
1022 logger.warn("No CacheStrategy defined for "+ typeName + ": " + this.getUuid());
1023 return null;
1024 }else{
1025 if (cacheStrategy instanceof INomenclaturalReferenceCacheStrategy){
1026 return ((INomenclaturalReferenceCacheStrategy)cacheStrategy).getNomenclaturalCitation(this,microReference);
1027 }else {
1028 logger.warn("No INomenclaturalReferenceCacheStrategy defined for "+ typeName + ": " + this.getUuid());
1029 return null;
1030 }
1031 }
1032 }
1033
1034
1035 /**
1036 * Generates, according to the {@link eu.etaxonomy.cdm.strategy.strategy.cache.reference.IReferenceBaseCacheStrategy cache strategy}
1037 * assigned to <i>this</i> reference, a string that identifies <i>this</i>
1038 * reference and returns it. This string may be stored in the inherited
1039 * {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity#getTitleCache() titleCache} attribute.<BR>
1040 * This method overrides the generic and inherited generateTitle method
1041 * from {@link eu.etaxonomy.cdm.model.common.IdentifiableEntity IdentifiableEntity}.
1042 *
1043 * @return the string identifying <i>this</i> reference
1044 * @see #getCitation()
1045 * @see eu.etaxonomy.cdm.model.common.IdentifiableEntity#getTitleCache()
1046 * @see eu.etaxonomy.cdm.model.common.IdentifiableEntity#generateTitle()
1047 * @see eu.etaxonomy.cdm.strategy.strategy.cache.common.IIdentifiableEntityCacheStrategy#getTitleCache()
1048 */
1049 // @Override
1050 // public String generateTitle(){
1051 // if (cacheStrategy == null){
1052 // logger.warn("No CacheStrategy defined for Reference: " + this.getUuid());
1053 // return null;
1054 // }else{
1055 // return cacheStrategy.getTitleCache(this);
1056 // }
1057 // }
1058
1059
1060
1061 // /**
1062 // * Returns the reference identity object
1063 // * @return the referenceIdentity
1064 // */
1065 // public ReferenceIdentity getReferenceIdentity() {
1066 // return referenceIdentity;
1067 // }
1068 //
1069 // /**
1070 // * For bidirectional use only
1071 // * @param referenceIdentity the referenceIdentity to set
1072 // */
1073 // protected void setReferenceIdentity(ReferenceIdentity referenceIdentity) {
1074 // this.referenceIdentity = referenceIdentity;
1075 // }
1076 //
1077 // /**
1078 // * Returns the set of all identical references. Same as getReferenceIdentity().getReferences()
1079 // * @return
1080 // */
1081 // public Set<Reference> identicalReferences(){
1082 // return referenceIdentity.getReferences();
1083 // }
1084
1085
1086 //********** Casting methods ***********************************/
1087
1088 public IArticle castReferenceToArticle(){
1089 setType(ReferenceType.Article);
1090 return this;
1091 }
1092
1093 public IBook castReferenceToBook(){
1094 setType(ReferenceType.Book);
1095 return this;
1096 }
1097
1098 public IBookSection castReferenceToBookSection(){
1099 setType(ReferenceType.BookSection);
1100 return this;
1101 }
1102
1103 public ICdDvd castReferenceToCdDvd(){
1104 setType(ReferenceType.CdDvd);
1105 return this;
1106 }
1107
1108 public IDatabase castReferenceToDatabase(){
1109 setType(ReferenceType.Database);
1110 return this;
1111 }
1112
1113 public IGeneric castReferenceToGeneric(){
1114 setType(ReferenceType.Generic);
1115 return this;
1116 }
1117
1118 public IInProceedings castReferenceToInProceedings(){
1119 setType(ReferenceType.InProceedings);
1120 return this;
1121 }
1122
1123 public IJournal castReferenceToJournal(){
1124 setType(ReferenceType.Journal);
1125 return this;
1126 }
1127
1128 public IMap castReferenceToMap(){
1129 setType(ReferenceType.Map);
1130 return (IMap) this;
1131 }
1132
1133 public IPatent castReferenceToPatent(){
1134 setType(ReferenceType.Patent);
1135 return this;
1136 }
1137
1138 public IPersonalCommunication castReferenceToPersonalCommunication(){
1139 setType(ReferenceType.PersonalCommunication);
1140 return this;
1141 }
1142
1143 public IPrintSeries castReferenceToPrintSeries(){
1144 setType(ReferenceType.PrintSeries);
1145 return this;
1146 }
1147
1148 public IWebPage castReferenceToWebPage(){
1149 setType(ReferenceType.WebPage);
1150 return this;
1151 }
1152
1153 public IProceedings castReferenceToProceedings(){
1154 setType(ReferenceType.Proceedings);
1155 return this;
1156 }
1157
1158 public IReport castReferenceToReport(){
1159 setType(ReferenceType.Report);
1160 return this;
1161 }
1162
1163 public IThesis castReferenceToThesis(){
1164 setType(ReferenceType.Thesis);
1165 return this;
1166 }
1167
1168
1169 @Override
1170 @Transient // prevent from being serialized by webservice
1171 public IJournal getInJournal() {
1172 IJournal journal = this.inReference;
1173 return journal;
1174 }
1175
1176 @Override
1177 public void setInJournal(IJournal journal) {
1178 this.inReference = (Reference<JournalDefaultCacheStrategy<Reference>>) journal;
1179
1180 }
1181
1182 @Override
1183 @Transient // prevent from being serialized by webservice
1184 public IPrintSeries getInSeries() {
1185 IPrintSeries printSeries = this.inReference;
1186 return printSeries;
1187 }
1188
1189 @Override
1190 public void setInSeries(IPrintSeries inSeries) {
1191 this.inReference = (Reference<IReferenceBaseCacheStrategy<Reference>>) inSeries;
1192 }
1193
1194 @Override
1195 @Transient // prevent from being serialized by webservice
1196 public IBook getInBook() {
1197 IBook book = this.inReference;
1198 return book;
1199 }
1200
1201 //********************** In-References *****************************************
1202
1203 @Override
1204 public void setInBook(IBook book) {
1205 this.inReference = (Reference<BookDefaultCacheStrategy<Reference>>) book;
1206 }
1207
1208 @Override
1209 @Transient // prevent from being serialized by webservice
1210 public IProceedings getInProceedings() {
1211 IProceedings proceedings = this.inReference;
1212 return proceedings;
1213 }
1214
1215 @Override
1216 public void setInProceedings(IProceedings proceeding) {
1217 this.inReference = (Reference<BookDefaultCacheStrategy<Reference>>) proceeding;
1218 }
1219
1220 //*************************** CACHE STRATEGIES ******************************/
1221
1222 /**
1223 * The type property of this class is mapped on the field level to the data base column, so
1224 * Hibernate will consequently use the {@link org.hibernate.property.DirectPropertyAccessor}
1225 * to set the property. This PropertyAccessor directly sets the field instead of using the according setter so
1226 * the CacheStrategy is not correctly set after the initialization of the bean. Thus we need to
1227 * validate the CacheStrategy before it is to be used.
1228 */
1229 private void rectifyCacheStrategy() {
1230 if(!cacheStrategyRectified ){
1231 setType(getType());
1232 cacheStrategyRectified = true;
1233 }
1234 }
1235
1236
1237 //public void setCacheStrategy(S cacheStrategy){
1238 // this.cacheStrategy = cacheStrategy;
1239 //}
1240
1241 @Override
1242 public void setCacheStrategy(IReferenceBaseCacheStrategy iReferenceBaseCacheStrategy) {
1243 this.cacheStrategy = (S) iReferenceBaseCacheStrategy;
1244
1245 }
1246
1247 @Override
1248 public void setCacheStrategy(ArticleDefaultCacheStrategy cacheStrategy) {
1249 this.cacheStrategy = (S) cacheStrategy;
1250 }
1251
1252 @Override
1253 public void setCacheStrategy(BookDefaultCacheStrategy cacheStrategy) {
1254 this.cacheStrategy = (S) cacheStrategy;
1255 }
1256
1257 @Override
1258 public void setCacheStrategy(JournalDefaultCacheStrategy cacheStrategy) {
1259 this.cacheStrategy = (S) cacheStrategy;
1260 }
1261
1262 @Override
1263 public void setCacheStrategy(BookSectionDefaultCacheStrategy cacheStrategy) {
1264 this.cacheStrategy = (S) cacheStrategy;
1265 }
1266
1267 @Override
1268 public void setCacheStrategy(GenericDefaultCacheStrategy cacheStrategy) {
1269 this.cacheStrategy = (S) cacheStrategy;
1270 }
1271
1272 public void setCacheStrategy(ReferenceDefaultCacheStrategy cacheStrategy) {
1273 this.cacheStrategy = (S)cacheStrategy;
1274
1275 }
1276
1277
1278 //*********************** CLONE ********************************************************/
1279
1280 /**
1281 * Clones <i>this</i> reference. This is a shortcut that enables to create
1282 * a new instance that differs only slightly from <i>this</i> reference by
1283 * modifying only some of the attributes.
1284 *
1285 * @see eu.etaxonomy.cdm.model.media.IdentifiableMediaEntity#clone()
1286 * @see java.lang.Object#clone()
1287 */
1288 @Override
1289 public Object clone() {
1290 try {
1291 Reference result = (Reference)super.clone();
1292 result.setDatePublished(datePublished != null? (TimePeriod)datePublished.clone(): null);
1293 //no changes to: title, authorTeam, hasProblem, nomenclaturallyRelevant, uri
1294 return result;
1295 } catch (CloneNotSupportedException e) {
1296 logger.warn("Object does not implement cloneable");
1297 e.printStackTrace();
1298 return null;
1299 }
1300 }
1301
1302
1303 }
1304