import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
-import java.net.URI;
import java.util.List;
import javax.persistence.Basic;
import javax.xml.bind.annotation.XmlType;
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter;
-import org.apache.commons.lang.StringUtils;
-import org.apache.log4j.Logger;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.LogManager;
+import org.apache.logging.log4j.Logger;
import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;
+import org.hibernate.annotations.Parameter;
import org.hibernate.annotations.Type;
import org.hibernate.envers.Audited;
import org.hibernate.search.annotations.Analyze;
import org.hibernate.search.annotations.FieldBridge;
import org.hibernate.search.annotations.IndexedEmbedded;
import org.joda.time.DateTime;
+import org.joda.time.Partial;
import eu.etaxonomy.cdm.common.DOI;
+import eu.etaxonomy.cdm.common.URI;
+import eu.etaxonomy.cdm.format.common.TimePeriodPartialFormatter;
+import eu.etaxonomy.cdm.format.reference.NomenclaturalSourceFormatter;
import eu.etaxonomy.cdm.hibernate.search.DateTimeBridge;
import eu.etaxonomy.cdm.hibernate.search.DoiBridge;
+import eu.etaxonomy.cdm.hibernate.search.UriBridge;
import eu.etaxonomy.cdm.jaxb.DateTimeAdapter;
import eu.etaxonomy.cdm.model.agent.Institution;
import eu.etaxonomy.cdm.model.agent.TeamOrPersonBase;
+import eu.etaxonomy.cdm.model.common.ExternallyManaged;
import eu.etaxonomy.cdm.model.common.IIntextReferenceTarget;
import eu.etaxonomy.cdm.model.common.TimePeriod;
import eu.etaxonomy.cdm.model.common.VerbatimTimePeriod;
import eu.etaxonomy.cdm.model.media.IdentifiableMediaEntity;
import eu.etaxonomy.cdm.model.name.TaxonName;
-import eu.etaxonomy.cdm.strategy.cache.reference.DefaultReferenceCacheStrategy;
-import eu.etaxonomy.cdm.strategy.cache.reference.INomenclaturalReferenceCacheStrategy;
+import eu.etaxonomy.cdm.strategy.cache.reference.IReferenceCacheStrategy;
+import eu.etaxonomy.cdm.strategy.cache.reference.ReferenceDefaultCacheStrategy;
import eu.etaxonomy.cdm.strategy.match.Match;
import eu.etaxonomy.cdm.strategy.match.MatchMode;
import eu.etaxonomy.cdm.strategy.merge.Merge;
/**
* The class for references (information sources). Originally
- * an abstract class with many subclasses. Not it is only
- * one class implementing many interfaces for safe use.
+ * an abstract class with many subclasses. Now it is only
+ * one class implementing many interfaces for safe use of different
+ * types of references. E.g. if you want to edit a journal
+ * you create a journal with {@link ReferenceFactory#newJournal()}
+ * which returns an IJournal. Though this instance is an ordinary instance
+ * of {@link Reference} by using IJournal you may not use attributes
+ * not allowed for journals.<p>
+ * References can be created via {@link ReferenceFactory} methods.
* <P>
* This class corresponds to: <ul>
* <li> PublicationCitation according to the TDWG ontology
"seriesPart",
"datePublished",
"publisher",
+ "publisher2",
"placePublished",
+ "placePublished2",
"institution",
"school",
"organization",
"inReference",
"accessed",
- "lastRetrieved",
- "externalId",
- "externalLink",
- "authorityType"
+ "externallyManaged",
})
@XmlRootElement(name = "Reference")
@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@Audited
-@Table(name="Reference", indexes = { @javax.persistence.Index(name = "ReferenceTitleCacheIndex", columnList = "titleCache") })
+@Table(name="Reference", indexes = { @javax.persistence.Index(name = "referenceTitleCacheIndex", columnList = "titleCache") })
//@InReference(groups=Level3.class)
@ReferenceCheck(groups=Level2.class)
@InReference(groups=Level3.class)
@NoRecursiveInReference(groups=Level3.class) //may become Level1 in future #
public class Reference
- extends IdentifiableMediaEntity<INomenclaturalReferenceCacheStrategy>
+ extends IdentifiableMediaEntity<IReferenceCacheStrategy>
implements IArticle, IBook, IPatent, IDatabase, IJournal, IBookSection,ICdDvd,
IGeneric,IInProceedings, IProceedings, IPrintSeries, IReport,
IThesis,IWebPage, IPersonalCommunication,
- INomenclaturalReference, IReference, IIntextReferenceTarget,
- Cloneable {
+ IIntextReferenceTarget {
private static final long serialVersionUID = -2034764545042691295L;
- private static final Logger logger = Logger.getLogger(Reference.class);
+ private static final Logger logger = LogManager.getLogger();
- @XmlAttribute(name ="type")
+// from E+M import (still needed?)
+// @Column(length=255)
+// private String refAuthorString;
+// public String getRefAuthorString() {return refAuthorString;}
+// public void setRefAuthorString(String refAuthorString) {this.refAuthorString = refAuthorString;}
+
+ @XmlAttribute(name ="type")
@Column(name="refType")
@NotNull
@Type(type = "eu.etaxonomy.cdm.hibernate.EnumUserType",
- parameters = {@org.hibernate.annotations.Parameter(name = "enumClass", value = "eu.etaxonomy.cdm.model.reference.ReferenceType")}
+ parameters = {@Parameter(name = "enumClass",
+ value = "eu.etaxonomy.cdm.model.reference.ReferenceType")}
)
@Audited
- protected ReferenceType type;
+ private ReferenceType type;
//Title of the reference
@XmlElement(name ="Title" )
@Column(length=4096, name="title")
@Lob
@Field
- @Match(MatchMode.EQUAL_REQUIRED) //TODO correct? was EQUAL_REQUIRED before, but with abbrevTitle this is not realistic anymore
+ @Match(MatchMode.EQUAL_REQUIRED) //TODO correct? was EQUAL_REQUIRED before, but with abbrevTitle this is not realistic anymore, see also #6427
//TODO Val #3379
// @NullOrNotEmpty
private String title;
//********************************************************/
-
@XmlElement(name = "Editor")
@Field
//TODO Val #3379
// @NullOrNotEmpty
@Column(length=255)
- protected String editor;
+ private String editor;
@XmlElement(name = "Volume")
@Field
//TODO Val #3379
// @NullOrNotEmpty
@Column(length=255)
- protected String volume;
+ private String volume;
@XmlElement(name = "Pages")
@Field
//TODO Val #3379
// @NullOrNotEmpty
@Column(length=255)
- protected String pages;
+ private String pages;
@XmlElement(name = "Edition")
@Field
//TODO Val #3379
// @NullOrNotEmpty
@Column(length=255)
- protected String edition;
+ private String edition;
@XmlElement(name = "ISBN")
@Field
// @NullOrNotEmpty
@Column(length=255)
@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}")
- protected String isbn;
+ private String isbn;
@XmlElement(name = "Doi")
@Field
@FieldBridge(impl = DoiBridge.class)
@Type(type="doiUserType")
@Column(length=DOI.MAX_LENGTH)
- protected DOI doi;
-
+ private DOI doi;
@XmlElement(name = "ISSN")
@Field
// @NullOrNotEmpty
@Column(length=255)
@Pattern(regexp = "(?=.{9}$)\\d{4}([- ])\\d{4} (\\d|X)$", groups = Level2.class, message = "{eu.etaxonomy.cdm.model.reference.Reference.issn.message}")
- protected String issn;
+ private String issn;
@XmlElement(name = "SeriesPart")
@Field
//TODO Val #3379
// @NullOrNotEmpty
@Column(length=255)
- protected String seriesPart;
+ private String seriesPart;
@XmlElement(name = "Organization")
@Field
//TODO Val #3379
// @NullOrNotEmpty
@Column(length=255)
- protected String organization;
+ private String organization;
@XmlElement(name = "Publisher")
@Field
//TODO Val #3379
// @NullOrNotEmpty
@Column(length=255)
- protected String publisher;
+ private String publisher;
+ @XmlElement(name = "Publisher2")
+ @Field
+ @Column(length=255)
+ private String publisher2;
@XmlElement(name = "PlacePublished")
@Field
//TODO Val #3379
// @NullOrNotEmpty
@Column(length=255)
- protected String placePublished;
+ private String placePublished;
+
+ @XmlElement(name = "PlacePublished2")
+ @Field
+ @Column(length=255)
+ private String placePublished2;
@XmlElement(name = "Institution")
@XmlIDREF
@ManyToOne(fetch = FetchType.LAZY)
@IndexedEmbedded
@Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
- protected Institution institution;
+ private Institution institution;
@XmlElement(name = "School")
@XmlIDREF
@ManyToOne(fetch = FetchType.LAZY)
@IndexedEmbedded
@Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
- protected Institution school;
+ private Institution school;
@XmlElement(name = "InReference")
@XmlIDREF
@ManyToOne(fetch = FetchType.LAZY)
@Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
// @InReference(groups=Level2.class)
- protected Reference inReference;
+ private Reference inReference;
//********************************************************/
private DateTime accessed;
@XmlElement(name ="Abstract" )
- @Column(length=65536, name="referenceAbstract")
+ @Column(length=CLOB_LENGTH, name="referenceAbstract")
@Lob
@Field
//TODO Val #3379
//URIs like DOIs, LSIDs or Handles for this reference
@XmlElement(name = "URI")
@Field(analyze = Analyze.NO)
+ @FieldBridge(impl = UriBridge.class)
@Type(type="uriUserType")
private URI uri;
@Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
private TeamOrPersonBase<?> authorship;
+ private ExternallyManaged externallyManaged;
+
@XmlAttribute
@Match(MatchMode.IGNORE)
private int parsingProblem = 0;
@Match(MatchMode.IGNORE)
private int problemEnds = -1;
- @Transient
- @XmlAttribute
- @Match(MatchMode.IGNORE)
- private boolean cacheStrategyRectified = false;
-
- //attributes for externally managed
-
-// @XmlElement (name = "LastRetrieved", type= String.class)
- @XmlJavaTypeAdapter(DateTimeAdapter.class)
- @Type(type="dateTimeUserType")
- //TODO needed??
- @Basic(fetch = FetchType.LAZY)
- private DateTime lastRetrieved;
-
- @XmlElement(name ="ExternalId" )
-// @Field
-// @Match(MatchMode.EQUAL) //TODO check if this is correct
- @NullOrNotEmpty
- @Column(length=255)
- private String externalId;
-
- //Actionable link on e.g. on a webservice
- @XmlElement(name = "ExternalLink")
- @Field(analyze = Analyze.NO)
- @Type(type="uriUserType")
- private URI externalLink;
-
- @XmlAttribute(name ="authority")
- @Column(name="authorityType", length=10)
- @Type(type = "eu.etaxonomy.cdm.hibernate.EnumUserType",
- parameters = {@org.hibernate.annotations.Parameter(name = "enumClass", value = "eu.etaxonomy.cdm.model.reference.AuthorityType")}
- )
-// @NotNull
- private AuthorityType authorityType;
// *********************** CONSTRUCTOR ************************/
+ //for hibernate use only, *packet* private required by bytebuddy
+ //TODO currenctly still protected as OpenUrlReference inherits from Reference
+ // this should be fixed
protected Reference(){
this(ReferenceType.Generic); //just in case someone uses constructor
}
} else{
this.type = type;
}
- this.setCacheStrategy(DefaultReferenceCacheStrategy.NewInstance());
}
// *********************** LISTENER ************************/
addPropertyChangeListener(listener);
}
-
//*************************** GETTER / SETTER ******************************************/
-
-
- // @Transient - must not be transient, since this property needs to to be included in all serializations produced by the remote layer
+ // @Transient - must not be transient, since this property needs to be included in all serializations produced by the remote layer
@Override
public String getTitleCache(){
String result = super.getTitleCache();
- if (isBlank(result)){
+ if (isBlank(result) && !isProtectedTitleCache()){
this.titleCache = this.getAbbrevTitleCache(true);
}
return titleCache;
@Override
public void setAbbrevTitle(String abbrevTitle) {
- this.abbrevTitle = StringUtils.isBlank(abbrevTitle) ? null : abbrevTitle;
+ this.abbrevTitle = isBlank(abbrevTitle) ? null : abbrevTitle;
}
@Override
public void setEditor(String editor) {
- this.editor = StringUtils.isBlank(editor)? null : editor;
+ this.editor = isBlank(editor)? null : editor;
}
@Override
@Override
public void setVolume(String volume) {
- this.volume = StringUtils.isBlank(volume)? null : volume;
+ this.volume = isBlank(volume)? null : volume;
}
@Override
@Override
public void setPages(String pages) {
- this.pages = StringUtils.isBlank(pages)? null : pages;
+ this.pages = isBlank(pages)? null : pages;
}
@Override
@Override
public void setEdition(String edition) {
- this.edition = StringUtils.isBlank(edition)? null : edition;
+ this.edition = isBlank(edition)? null : edition;
}
@Override
@Override
public void setIsbn(String isbn) {
- this.isbn = StringUtils.isBlank(isbn)? null : isbn;
+ this.isbn = isBlank(isbn)? null : isbn;
}
@Override
@Override
public void setIssn(String issn) {
- this.issn = StringUtils.isBlank(issn)? null : issn;
+ this.issn = isBlank(issn)? null : issn;
}
@Override
}
@Override
public void setSeriesPart(String seriesPart) {
- this.seriesPart = StringUtils.isBlank(seriesPart)? null : seriesPart;
+ this.seriesPart = isBlank(seriesPart)? null : seriesPart;
}
@Override
@Override
public void setOrganization(String organization) {
- this.organization = StringUtils.isBlank(organization)? null : organization;
+ this.organization = isBlank(organization)? null : organization;
}
@Override
public String getPublisher() {
return publisher;
}
-
@Override
public void setPublisher(String publisher) {
- this.publisher = StringUtils.isBlank(publisher)? null : publisher;
+ this.publisher = StringUtils.truncate(isBlank(publisher)? null : publisher, 255);
}
-
- @Override
+ @Override
public void setPublisher(String publisher, String placePublished){
- this.publisher = publisher;
- this.placePublished = placePublished;
- }
+ this.publisher = publisher;
+ this.placePublished = placePublished;
+ }
+
+ @Override
+ public String getPublisher2() {
+ return publisher2;
+ }
+ @Override
+ public void setPublisher2(String publisher2) {
+ this.publisher2 = StringUtils.truncate(isBlank(publisher2)? null : publisher2, 255);
+ }
+ @Override
+ public void setPublisher2(String publisher2, String placePublished2){
+ this.publisher2 = publisher2;
+ this.placePublished2 = placePublished2;
+ }
@Override
public String getPlacePublished() {
return placePublished;
}
-
@Override
public void setPlacePublished(String placePublished) {
- this.placePublished = StringUtils.isBlank(placePublished)? null: placePublished;
+ this.placePublished = isBlank(placePublished)? null: placePublished;
}
+ @Override
+ public String getPlacePublished2() {
+ return placePublished2;
+ }
+ @Override
+ public void setPlacePublished2(String placePublished2) {
+ this.placePublished2 = isBlank(placePublished2)? null: placePublished2;
+ }
+
@Override
public Institution getInstitution() {
return institution;
}
-
@Override
public void setInstitution(Institution institution) {
this.institution = institution;
public Institution getSchool() {
return school;
}
-
@Override
public void setSchool(Institution school) {
this.school = school;
public Reference getInReference() {
return inReference;
}
-
@Override
public void setInReference(Reference inReference) {
this.inReference = inReference;
/**
* Whether this reference is of the given type
- *
- * @param type
- * @return
*/
@Override
public boolean isOfType(ReferenceType type){
*/
@Override
public void setTitle(String title){
- this.title = StringUtils.isBlank(title)? null : title;
+ this.title = isBlank(title)? null : title;
}
/**
}
public boolean hasDatePublished(){
- boolean result = ! ( (this.datePublished == null) || StringUtils.isBlank(datePublished.toString()));
+ boolean result = !((this.datePublished == null) || isBlank(datePublished.toString()));
return result;
}
*/
@Override
public void setReferenceAbstract(String referenceAbstract) {
- this.referenceAbstract = StringUtils.isBlank(referenceAbstract)? null : referenceAbstract;
+ this.referenceAbstract = isBlank(referenceAbstract)? null : referenceAbstract;
}
* any longer using this reference as a nomenclatural reference. How does the
* reference get informed about the fact that it is not nomenclaturally relevant
* anymore?
+ * @deprecated currently not supported and not in use, may be removed in future
*/
- public boolean isNomenclaturallyRelevant(){
+ @Deprecated
+ public boolean isNomenclaturallyRelevant(){
return this.nomenclaturallyRelevant;
}
/**
* @see #isNomenclaturallyRelevant()
+ * @deprecated currently not supported and not in use, may be removed in future
*/
+ @Deprecated
public void setNomenclaturallyRelevant(boolean nomenclaturallyRelevant){
this.nomenclaturallyRelevant = nomenclaturallyRelevant;
}
// TODO implement
@Transient
public String getCitation(){
- if (getCacheStrategy() == null){
+ if (cacheStrategy() == null){
logger.warn("No CacheStrategy defined for "+ this.getClass() + ": " + this.getUuid());
return null;
}else{
- return getCacheStrategy().getTitleCache(this);
+ return cacheStrategy().getTitleCache(this);
}
}
}
public String generateAbbrevTitle() {
- return getCacheStrategy().getFullAbbrevTitleString(this);
+ return cacheStrategy().getNomenclaturalTitleCache(this);
}
/**
* Returns a string representation for the year of publication / creation
* of <i>this</i> reference. If the {@link #getDatePublished() datePublished}
- * of this reference contains more date information then (starting) year
+ * of this reference contains more date information than (starting) year
* only the year is returned.
- * than attribute.
*/
@Override
@Transient
}
}
+ /**
+ * Returns a sortable string of the datePublished.start attribute.<BR>
+ * If datePublished is null in-references are called recursively.
+ * Only structured publication data is considered, no freetext or
+ * verbatim date.
+ */
+ @Transient
+ public String getSortableDateString(){
+ VerbatimTimePeriod datePublished = this.getDatePublished();
+ if (datePublished != null ){
+ Partial partial = getDatePublished().getStart();
+ if (partial == null) {
+ partial = getDatePublished().getEnd();
+ }
+ if (partial != null ) {
+ return TimePeriodPartialFormatter.INSTANCE().printSortableDateString(partial);
+ }
+ }
+ if (this.inReference != null){
+ return this.inReference.getSortableDateString();
+ }else {
+ return "zzzz-zz-zz";
+ }
+ }
+
/**
* Convenience method that returns a string representation for the publication date / creation
* of <i>this</i> reference. The string is obtained by
}
}
-
-
@Override
public int getParsingProblem(){
return this.parsingProblem;
@Override
@Transient
public String getNomenclaturalCitation(String microReference) {
- String typeName = this.getType()== null ? "(no type defined)" : this.getType().getMessage();
- if (getCacheStrategy() == null){
- logger.warn("No CacheStrategy defined for "+ typeName + ": " + this.getUuid());
- return null;
+ String typeName = this.getType()== null ? "(no type defined)" : this.getType().getLabel();
+ if (cacheStrategy() == null){
+ throw new IllegalStateException("No CacheStrategy defined for "+ typeName + ": " + this.getUuid());
}else{
- if (getCacheStrategy() instanceof INomenclaturalReferenceCacheStrategy){
- return cacheStrategy.getNomenclaturalCitation(this, microReference);
- }else {
- logger.warn("No INomenclaturalReferenceCacheStrategy defined for "+ typeName + ": " + this.getUuid());
- return null;
- }
+ return NomenclaturalSourceFormatter.INSTANCE().format(this, microReference);
}
}
-
/**
* Generates, according to the {@link eu.etaxonomy.cdm.strategy.strategy.cache.reference.IReferenceBaseCacheStrategy cache strategy}
* assigned to <i>this</i> reference, a string that identifies <i>this</i>
setInReference((Reference)proceeding); //user setter to invoke aspect #1815
}
-//*************************** CACHE STRATEGIES ******************************/
+//**************************** Type *****************************************/
- @Override
- public INomenclaturalReferenceCacheStrategy getCacheStrategy() {
- return this.cacheStrategy;
+ public boolean isArticle() {
+ return this.getType().isArticle();
+ }
+ public boolean isBook() {
+ return this.getType().isBook();
+ }
+ public boolean isBookSection() {
+ return this.getType().isBookSection();
+ }
+ public boolean isWebPage() {
+ return this.getType().isWebPage();
+ }
+ public boolean isDatabase() {
+ return this.getType().isDatabase();
+ }
+ public boolean isMap() {
+ return this.getType().isMap();
+ }
+ public boolean isPatent() {
+ return this.getType().isPatent();
+ }
+ public boolean isGeneric() {
+ return this.getType().isGeneric();
+ }
+ public boolean isCdDvd() {
+ return this.getType().isCdDvd();
+ }
+ public boolean isProceedings() {
+ return this.getType().isProceedings();
+ }
+ public boolean isInProceedings() {
+ return this.getType().isInProceedings();
+ }
+ public boolean isJournal() {
+ return this.getType().isJournal();
+ }
+ public boolean isPersonalCommunication() {
+ return this.getType().isPersonalCommunication();
+ }
+ public boolean isThesis() {
+ return this.getType().isThesis();
+ }
+ public boolean isPrintSeries() {
+ return this.getType().isPrintSeries();
+ }
+ /**
+ * @return <code>true</code> if this type is exactly {@link ReferenceType#Section}
+ * @see ReferenceType#isSection()
+ */
+ public boolean isSectionOnly() {
+ return this.getType().isSectionOnly();
+ }
+ /**
+ * Returns <code>true</code> if this reference is part of another reference
+ * (inheriting from {@link ISection}) and therefore may have an in-reference and pages.
+ * @see ReferenceType#isSection()
+ */
+ public boolean isSection() {
+ return this.getType().isSection();
+ }
+ /**
+ * @see ReferenceType#isPrintedUnit()
+ */
+ public boolean isPrintedUnit() {
+ return this.getType().isPrintedUnit();
+ }
+ /**
+ * @return <code>true</code> if the type of this reference
+ * supports the {@link IDynamicReference} interface. Currently these are
+ * webpages, databases and maps.
+ */
+ public boolean isDynamic() {
+ return this.getType().isDynamic();
}
- @Override
- public void setCacheStrategy(INomenclaturalReferenceCacheStrategy referenceCacheStrategy) {
- this.cacheStrategy = referenceCacheStrategy;
- }
+//*************************** CACHE STRATEGIES ******************************/
+ @Override
+ protected void initDefaultCacheStrategy() {
+ this.setCacheStrategy(ReferenceDefaultCacheStrategy.NewInstance());
+ }
+ @Override
+ public boolean updateCaches(){
+ //TODO shouldn't this be moved to the cache strategy?
+ if (this.equals(this.getInReference())){
+ String message = "-- invalid inreference (self-referencing) --";
+ String oldTitleCache = this.titleCache;
+ this.titleCache = message;
+ return !message.equals(oldTitleCache);
+ }
+ boolean result = super.updateCaches();
+ if (this.protectedAbbrevTitleCache == false){
+ String oldAbbrevTitleCache = this.abbrevTitleCache;
+
+ String newAbbrevTitleCache = getTruncatedCache(cacheStrategy().getNomenclaturalTitleCache(this));
+ if (newAbbrevTitleCache.equals("")){
+ newAbbrevTitleCache = cacheStrategy().getTitleCache(this);
+ }
+
+ if ( oldAbbrevTitleCache == null || ! oldAbbrevTitleCache.equals(newAbbrevTitleCache) ){
+ this.setAbbrevTitleCache(null, false);
+ String newCache = this.getAbbrevTitleCache();
+
+ if (newCache == null){
+ logger.warn("New abbrevCache should never be null");
+ }
+ if (oldAbbrevTitleCache == null){
+ logger.info("oldAbbrevTitleCache was illegaly null and has been fixed");
+ }
+ result = true;
+ }
+ }
+ return result;
+ }
//*********************** CLONE ********************************************************/
* @see java.lang.Object#clone()
*/
@Override
- public Object clone() {
+ public Reference clone() {
try {
Reference result = (Reference)super.clone();
result.setDatePublished(datePublished != null? (VerbatimTimePeriod)datePublished.clone(): null);
return super.toString();
}
}
-
-
-
-
-}
-
+}
\ No newline at end of file