remove ReferencedMediaBase and Figure, let PhylogeneticTree inherit from Media, remov...
[cdmlib.git] / cdmlib-io / src / main / java / eu / etaxonomy / cdm / io / jaxb / CdmIDResolver.java
1 package eu.etaxonomy.cdm.io.jaxb;
2
3 import java.util.HashMap;
4 import java.util.UUID;
5 import java.util.concurrent.Callable;
6
7 import javax.xml.bind.ValidationEventHandler;
8
9 import org.apache.log4j.Logger;
10 import org.springframework.beans.factory.annotation.Autowired;
11 import org.xml.sax.SAXException;
12
13 import com.sun.xml.bind.IDResolver;
14
15 import eu.etaxonomy.cdm.api.service.IAgentService;
16 import eu.etaxonomy.cdm.api.service.ICollectionService;
17 import eu.etaxonomy.cdm.api.service.IDescriptionService;
18 import eu.etaxonomy.cdm.api.service.IFeatureTreeService;
19 import eu.etaxonomy.cdm.api.service.IMediaService;
20 import eu.etaxonomy.cdm.api.service.INameService;
21 import eu.etaxonomy.cdm.api.service.IOccurrenceService;
22 import eu.etaxonomy.cdm.api.service.IReferenceService;
23 import eu.etaxonomy.cdm.api.service.IService;
24 import eu.etaxonomy.cdm.api.service.ITaxonService;
25 import eu.etaxonomy.cdm.api.service.ITermService;
26 import eu.etaxonomy.cdm.api.service.IUserService;
27 import eu.etaxonomy.cdm.api.service.IVocabularyService;
28 import eu.etaxonomy.cdm.jaxb.UUIDAdapter;
29 import eu.etaxonomy.cdm.model.agent.AgentBase;
30 import eu.etaxonomy.cdm.model.agent.INomenclaturalAuthor;
31 import eu.etaxonomy.cdm.model.common.DefinedTermBase;
32 import eu.etaxonomy.cdm.model.common.TermVocabulary;
33 import eu.etaxonomy.cdm.model.common.User;
34 import eu.etaxonomy.cdm.model.description.DescriptionBase;
35 import eu.etaxonomy.cdm.model.description.FeatureTree;
36 import eu.etaxonomy.cdm.model.media.Media;
37 import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
38 import eu.etaxonomy.cdm.model.name.TaxonNameBase;
39 import eu.etaxonomy.cdm.model.occurrence.Collection;
40 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
41 import eu.etaxonomy.cdm.model.reference.Reference;
42 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
43
44 public class CdmIDResolver extends IDResolver {
45 private static final Logger logger = Logger.getLogger(CdmIDResolver.class);
46
47 IUserService userService;
48
49 IAgentService agentService;
50
51 ITermService termService;
52
53 IVocabularyService vocabularyService;
54
55 IDescriptionService descriptionService;
56
57 IFeatureTreeService featureTreeService;
58
59 IMediaService mediaService;
60
61 INameService nameService;
62
63 IOccurrenceService occurrenceService;
64
65 ICollectionService collectionService;
66
67 IReferenceService referenceService;
68
69 ITaxonService taxonService;
70
71 @Autowired
72 public void setUserService(IUserService userService) {
73 this.userService = userService;
74 }
75
76 @Autowired
77 public void setAgentService(IAgentService agentService) {
78 this.agentService = agentService;
79 }
80
81 @Autowired
82 public void setTermService(ITermService termService) {
83 this.termService = termService;
84 }
85
86 @Autowired
87 public void setVocabularyService(IVocabularyService vocabularyService) {
88 this.vocabularyService = vocabularyService;
89 }
90
91 @Autowired
92 public void setDescriptionService(IDescriptionService descriptionService) {
93 this.descriptionService = descriptionService;
94 }
95
96 @Autowired
97 public void setFeatureTreeService(IFeatureTreeService featureTreeService) {
98 this.featureTreeService = featureTreeService;
99 }
100
101 @Autowired
102 public void setMediaService(IMediaService mediaService) {
103 this.mediaService = mediaService;
104 }
105
106 @Autowired
107 public void setNameService(INameService nameService) {
108 this.nameService = nameService;
109 }
110
111 @Autowired
112 public void setOccurrenceService(IOccurrenceService occurrenceService) {
113 this.occurrenceService = occurrenceService;
114 }
115
116 @Autowired
117 public void setCollectionService(ICollectionService collectionService) {
118 this.collectionService = collectionService;
119 }
120
121 @Autowired
122 public void setReferenceService(IReferenceService referenceService) {
123 this.referenceService = referenceService;
124 }
125
126 @Autowired
127 public void setTaxonService(ITaxonService taxonService) {
128 this.taxonService = taxonService;
129 }
130
131 private HashMap<String,Object> idmap = null;
132
133 @Override
134 public void startDocument(ValidationEventHandler eventHandler) throws SAXException {
135 if(idmap!=null) {
136 idmap.clear();
137 }
138 }
139
140 @Override
141 public void bind(String id, Object obj) throws SAXException {
142 if(idmap==null) {
143 idmap = new HashMap<String,Object>();
144 }
145 idmap.put(id,obj);
146 }
147
148
149 @Override
150 public Callable<?> resolve(final String id, final Class targetType) throws SAXException {
151 return new Callable() {
152 public Object call() throws Exception {
153 logger.info("Resolving " + id + " for class " + targetType);
154
155 if(idmap==null || !idmap.containsKey(id)) {
156
157 String uuidPart = id.substring(UUIDAdapter.UUID_URN_PREFIX.length());
158 UUID uuid = UUID.fromString(uuidPart);
159 logger.info(uuid + " not in idmap, looking in database");
160 if(targetType.equals(User.class)) {
161 return resolveObject(uuid, targetType, userService);
162 } else if(AgentBase.class.isAssignableFrom(targetType) || INomenclaturalAuthor.class.isAssignableFrom(targetType)) {
163 return resolveObject(uuid, targetType, agentService);
164 } else if(DefinedTermBase.class.isAssignableFrom(targetType)) {
165 return resolveObject(uuid, targetType, termService);
166 } else if(TermVocabulary.class.isAssignableFrom(targetType)) {
167 return resolveObject(uuid, targetType, vocabularyService);
168 } else if(DescriptionBase.class.isAssignableFrom(targetType)) {
169 return resolveObject(uuid, targetType, descriptionService);
170 } else if(FeatureTree.class.isAssignableFrom(targetType)) {
171 return resolveObject(uuid, targetType, featureTreeService);
172 } else if(Media.class.isAssignableFrom(targetType)) {
173 return resolveObject(uuid, targetType, mediaService);
174 } else if(TaxonNameBase.class.isAssignableFrom(targetType)) {
175 return resolveObject(uuid, targetType, nameService);
176 } else if(SpecimenOrObservationBase.class.isAssignableFrom(targetType)) {
177 return resolveObject(uuid, targetType, occurrenceService);
178 } else if(Collection.class.isAssignableFrom(targetType)) {
179 return resolveObject(uuid, targetType, collectionService);
180 } else if(Reference.class.isAssignableFrom(targetType)) {
181 return resolveObject(uuid, targetType, referenceService);
182 } else if(TaxonBase.class.isAssignableFrom(targetType)) {
183 return resolveObject(uuid, targetType, taxonService);
184 } else if(HomotypicalGroup.class.isAssignableFrom(targetType)) {
185 Object object = nameService.findHomotypicalGroup(uuid);
186 if(object == null) {
187 throw new SAXException(targetType.getSimpleName() + " with " + uuid + " not found");
188 }
189 return object;
190 } else {
191 /**
192 * Collections of IDREFS do not have a type at runtime
193 * https://jaxb.dev.java.net/issues/show_bug.cgi?id=546
194 *
195 * Maybe in the future we'll be able to add targetType to IDREF
196 * but the spec has to be changed first so no fix is likely at the moment
197 *
198 */
199
200 AgentBase agent = agentService.find(uuid);
201 if(agent != null) {
202 return agent;
203 }
204 DefinedTermBase term = termService.find(uuid);
205 if(term != null) {
206 return term;
207 }
208 Media media = mediaService.find(uuid);
209 if(media != null) {
210 return media;
211 }
212 throw new SAXException(targetType.getSimpleName() + " with " + uuid + " not found");
213 }
214 } else {
215 return idmap.get(id);
216 }
217 }
218 };
219 }
220
221 private Object resolveObject(UUID uuid, Class targetType, IService service) throws SAXException {
222 Object object = service.find(uuid);
223 if(object == null) {
224 throw new SAXException(targetType.getSimpleName() + " with " + uuid + " not found");
225 }
226 return object;
227 }
228 }