5e38a451c56f4ebd76d09c1e16f8ed5ecd54dc5d
[cdmlib.git] / cdmlib-model / src / main / java / eu / etaxonomy / cdm / model / common / IntextReference.java
1 /**
2 *
3 */
4 package eu.etaxonomy.cdm.model.common;
5
6 import javax.persistence.Entity;
7 import javax.persistence.FetchType;
8 import javax.persistence.ManyToOne;
9 import javax.xml.bind.annotation.XmlAccessType;
10 import javax.xml.bind.annotation.XmlAccessorType;
11 import javax.xml.bind.annotation.XmlElement;
12 import javax.xml.bind.annotation.XmlIDREF;
13 import javax.xml.bind.annotation.XmlSchemaType;
14 import javax.xml.bind.annotation.XmlType;
15
16 import org.apache.commons.lang.StringUtils;
17 import org.hibernate.annotations.Cascade;
18 import org.hibernate.annotations.CascadeType;
19 import org.hibernate.envers.Audited;
20
21 import eu.etaxonomy.cdm.model.agent.AgentBase;
22 import eu.etaxonomy.cdm.model.media.Media;
23 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
24 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
25 import eu.etaxonomy.cdm.model.reference.Reference;
26 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
27
28 /**
29 * This class represents a link to another CDM Base class from within a text.
30 * If a text, e.g. a LanguageString links parts of its text to an other CDM Base
31 * one may create a tag around the according text including id and uuid as attributes
32 * and adding an IntextReference to the LanguageString. The IntextReference then points
33 * to the according CdmBase.
34 * This way we may keep referential integrity and we may also support correct
35 * deduplication or deletion of the referenced objects.
36 *
37 * @see #4706
38 *
39 * @author a.mueller
40 *
41 */
42 @XmlAccessorType(XmlAccessType.FIELD)
43 @XmlType(name = "IntextReference", propOrder = {
44 "taxonName",
45 "taxon",
46 "occurrence",
47 "agent",
48 "reference",
49 "media",
50 "languageString",
51 "annotation",
52 "startPos",
53 "endPos"
54 })
55 @Entity
56 @Audited
57 public class IntextReference extends VersionableEntity {
58 private static final long serialVersionUID = -7002541566256975424L;
59
60 @XmlElement(name = "TaxonName")
61 @XmlIDREF
62 @XmlSchemaType(name = "IDREF")
63 @ManyToOne(fetch = FetchType.LAZY)
64 private TaxonNameBase<?,?> taxonName;
65
66 @XmlElement(name = "Taxon")
67 @XmlIDREF
68 @XmlSchemaType(name = "IDREF")
69 @ManyToOne(fetch = FetchType.LAZY)
70 private TaxonBase<?> taxon;
71
72 @XmlElement(name = "Occurrence")
73 @XmlIDREF
74 @XmlSchemaType(name = "IDREF")
75 @ManyToOne(fetch = FetchType.LAZY)
76 private SpecimenOrObservationBase<?> occurrence;
77
78 @XmlElement(name = "Agent")
79 @XmlIDREF
80 @XmlSchemaType(name = "IDREF")
81 @ManyToOne(fetch = FetchType.LAZY)
82 private AgentBase<?> agent;
83
84 @XmlElement(name = "Reference")
85 @XmlIDREF
86 @XmlSchemaType(name = "IDREF")
87 @ManyToOne(fetch = FetchType.LAZY)
88 @Cascade({CascadeType.SAVE_UPDATE,CascadeType.MERGE})
89 private Reference reference;
90
91 @XmlElement(name = "Media")
92 @XmlIDREF
93 @XmlSchemaType(name = "IDREF")
94 @ManyToOne(fetch = FetchType.LAZY)
95 private Media media;
96
97 //TODO or do we want to link to LanguageString Base??
98 @XmlElement(name = "LanguageString")
99 @XmlIDREF
100 @XmlSchemaType(name = "IDREF")
101 @ManyToOne(fetch = FetchType.LAZY)
102 private LanguageString languageString;
103
104 //TODO or do we want to link to LanguageString Base??
105 @XmlElement(name = "Annotation")
106 @XmlIDREF
107 @XmlSchemaType(name = "IDREF")
108 @ManyToOne(fetch = FetchType.LAZY)
109 private Annotation annotation;
110
111 private int startPos;
112
113 private int endPos;
114
115
116 private enum CDM_INTEXT_CLASS{
117 REFERENCE("reference"),
118 TAXONNAME("name"),
119 AGENT("agent"),
120 MEDIA("media"),
121 OCCURRENCE("occurrence"),
122 TAXON("taxon")
123 ;
124 String tag;
125
126 private CDM_INTEXT_CLASS(String tag) {
127 this.tag = tag;
128 }
129
130 public String tag(){
131 return this.tag;
132 }
133 }
134
135
136
137 // ***************** FACTORY METHOD ***********************************
138
139 public static IntextReference NewTaxonNameInstance(TaxonNameBase<?,?> taxonName, LanguageStringBase languageString, int start, int end){
140 return new IntextReference(taxonName, null, null, null, null, null, languageString, start, end);
141 }
142
143 public static IntextReference NewTaxonInstance(TaxonBase<?> taxon, LanguageStringBase languageString, int start, int end){
144 return new IntextReference(null, taxon, null, null, null, null, languageString, start, end);
145 }
146
147 public static IntextReference NewOccurrenceInstance(SpecimenOrObservationBase<?> occurrence, LanguageStringBase languageString, int start, int end){
148 return new IntextReference(null, null, occurrence, null, null, null, languageString, start, end);
149 }
150
151 public static IntextReference NewAgentInstance(AgentBase<?> agent, LanguageStringBase languageString, int start, int end){
152 return new IntextReference(null, null, null, agent, null, null, languageString, start, end);
153 }
154
155 public static IntextReference NewReferenceInstance(Reference reference, LanguageStringBase languageString, int start, int end){
156 return new IntextReference(null, null, null, null, reference, null, languageString, start, end);
157 }
158
159 public static IntextReference NewMediaInstance(Media media, LanguageStringBase languageString, int start, int end){
160 return new IntextReference(null, null, null, null, null, media, languageString, start, end);
161 }
162
163 //********************** CONSTRUCTOR ********************************************/
164
165 /**
166 * @deprecated for internal use only
167 */
168 @Deprecated //for hibernate use only
169 private IntextReference(){}
170
171 private IntextReference(TaxonNameBase<?, ?> taxonName, TaxonBase<?> taxon,
172 SpecimenOrObservationBase<?> occurrence, AgentBase<?> agent,
173 Reference reference, Media media, LanguageStringBase languageString, int start, int end) {
174 super();
175 this.taxonName = taxonName;
176 this.taxon = taxon;
177 this.occurrence = occurrence;
178 this.agent = agent;
179 this.reference = reference;
180 this.media = media;
181 if (languageString != null && languageString.isInstanceOf(LanguageString.class)){
182 this.languageString = CdmBase.deproxy(languageString, LanguageString.class);
183 this.languageString.addIntextReference(this);
184 }else if (languageString != null && languageString.isInstanceOf(Annotation.class)){
185 this.annotation = CdmBase.deproxy(languageString, Annotation.class);
186 this.annotation.addIntextReference(this);
187 }
188 this.startPos = start;
189 this.endPos = end;
190 }
191
192
193 private CDM_INTEXT_CLASS myClass(){
194 if (agent != null){
195 return CDM_INTEXT_CLASS.AGENT;
196 }else if (media != null){
197 return CDM_INTEXT_CLASS.MEDIA;
198 }else if (taxonName != null){
199 return CDM_INTEXT_CLASS.TAXONNAME;
200 }else if (taxon != null){
201 return CDM_INTEXT_CLASS.TAXON;
202 }else if (reference != null){
203 return CDM_INTEXT_CLASS.REFERENCE;
204 }else if (occurrence != null){
205 return CDM_INTEXT_CLASS.OCCURRENCE;
206 }else{
207 throw new IllegalStateException("Intext reference has no target object defined");
208 }
209 }
210
211 private IdentifiableEntity<?> myEntity(){
212 if (agent != null){
213 return agent;
214 }else if (media != null){
215 return media;
216 }else if (taxonName != null){
217 return taxonName;
218 }else if (taxon != null){
219 return taxon;
220 }else if (reference != null){
221 return reference;
222 }else if (occurrence != null){
223 return occurrence;
224 }else{
225 throw new IllegalStateException("Intext reference has no target object defined");
226 }
227 }
228
229 // **************** GETTER / SETTER ******************************************/
230
231 public TaxonNameBase<?, ?> getTaxonName() {
232 return taxonName;
233 }
234 public void setTaxonName(TaxonNameBase<?, ?> taxonName) {
235 this.taxonName = taxonName;
236 }
237
238
239 public TaxonBase<?> getTaxon() {
240 return taxon;
241 }
242 public void setTaxon(TaxonBase<?> taxon) {
243 this.taxon = taxon;
244 }
245
246 public SpecimenOrObservationBase<?> getOccurrence() {
247 return occurrence;
248 }
249 public void setOccurrence(SpecimenOrObservationBase<?> occurrence) {
250 this.occurrence = occurrence;
251 }
252
253 public AgentBase<?> getAgent() {
254 return agent;
255 }
256 public void setAgent(AgentBase<?> agent) {
257 this.agent = agent;
258 }
259
260 public Reference getReference() {
261 return reference;
262 }
263 public void setReference(Reference reference) {
264 this.reference = reference;
265 }
266
267
268
269 public Media getMedia() {
270 return media;
271 }
272 public void setMedia(Media media) {
273 this.media = media;
274 }
275
276 public LanguageString getLanguageString() {
277 return languageString;
278 }
279 public void setLanguageString(LanguageString languageString) {
280 this.languageString = languageString;
281 }
282
283 public Annotation getAnnotation() {
284 return annotation;
285 }
286
287 public void setAnnotation(Annotation annotation) {
288 this.annotation = annotation;
289 }
290
291 public int getStartPos() {
292 return startPos;
293 }
294 public void setStartPos(int startPos) {
295 this.startPos = startPos;
296 }
297
298 public int getEndPos() {
299 return endPos;
300 }
301 public void setEndPos(int endPos) {
302 this.endPos = endPos;
303 }
304
305 private static final String CDM_PREFIX = "cdm:";
306 public String toInlineString(String innerText){
307 String tag = CDM_PREFIX + myClass().tag();
308 IdentifiableEntity<?> entity = myEntity();
309 String attributes = " cdmId='" + entity.getUuid() + "' intextId='" + this.getUuid() + "'" + otherAttributes(entity);
310 String result;
311 if (StringUtils.isNotEmpty(innerText)){
312 result = "<" + tag + attributes + ">" + innerText + "</" + tag + ">";
313 }else{
314 result = "<" + tag + attributes + "/>";
315 }
316 return result;
317 }
318
319 /**
320 * Entity class dependent attributes
321 * @param entity
322 * @return
323 */
324 private String otherAttributes(IdentifiableEntity<?> entity) {
325 return "";
326 }
327
328
329 }