cleanup
[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.description.DescriptionBase;
32 import eu.etaxonomy.cdm.model.media.Media;
33 import eu.etaxonomy.cdm.model.name.HomotypicalGroup;
34 import eu.etaxonomy.cdm.model.name.TaxonName;
35 import eu.etaxonomy.cdm.model.occurrence.Collection;
36 import eu.etaxonomy.cdm.model.occurrence.SpecimenOrObservationBase;
37 import eu.etaxonomy.cdm.model.permission.User;
38 import eu.etaxonomy.cdm.model.reference.Reference;
39 import eu.etaxonomy.cdm.model.taxon.TaxonBase;
40 import eu.etaxonomy.cdm.model.term.DefinedTermBase;
41 import eu.etaxonomy.cdm.model.term.TermTree;
42 import eu.etaxonomy.cdm.model.term.TermVocabulary;
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<Object> resolve(final String id, final Class targetType) throws SAXException {
151 return new Callable<Object>() {
152 @Override
153 public Object call() throws Exception {
154 logger.info("Resolving " + id + " for class " + targetType);
155
156 if(idmap==null || !idmap.containsKey(id)) {
157
158 String uuidPart = id.substring(UUIDAdapter.UUID_URN_PREFIX.length());
159 UUID uuid = UUID.fromString(uuidPart);
160 logger.info(uuid + " not in idmap, looking in database");
161 if(targetType.equals(User.class)) {
162 return resolveObject(uuid, targetType, userService);
163 } else if(AgentBase.class.isAssignableFrom(targetType) || INomenclaturalAuthor.class.isAssignableFrom(targetType)) {
164 return resolveObject(uuid, targetType, agentService);
165 } else if(DefinedTermBase.class.isAssignableFrom(targetType)) {
166 return resolveObject(uuid, targetType, termService);
167 } else if(TermVocabulary.class.isAssignableFrom(targetType)) {
168 return resolveObject(uuid, targetType, vocabularyService);
169 } else if(DescriptionBase.class.isAssignableFrom(targetType)) {
170 return resolveObject(uuid, targetType, descriptionService);
171 } else if(TermTree.class.isAssignableFrom(targetType)) {
172 return resolveObject(uuid, targetType, featureTreeService);
173 } else if(Media.class.isAssignableFrom(targetType)) {
174 return resolveObject(uuid, targetType, mediaService);
175 } else if(TaxonName.class.isAssignableFrom(targetType)) {
176 return resolveObject(uuid, targetType, nameService);
177 } else if(SpecimenOrObservationBase.class.isAssignableFrom(targetType)) {
178 return resolveObject(uuid, targetType, occurrenceService);
179 } else if(Collection.class.isAssignableFrom(targetType)) {
180 return resolveObject(uuid, targetType, collectionService);
181 } else if(Reference.class.isAssignableFrom(targetType)) {
182 return resolveObject(uuid, targetType, referenceService);
183 } else if(TaxonBase.class.isAssignableFrom(targetType)) {
184 return resolveObject(uuid, targetType, taxonService);
185 } else if(HomotypicalGroup.class.isAssignableFrom(targetType)) {
186 Object object = nameService.findHomotypicalGroup(uuid);
187 if(object == null) {
188 throw new SAXException(targetType.getSimpleName() + " with " + uuid + " not found");
189 }
190 return object;
191 } else {
192 /**
193 * Collections of IDREFS do not have a type at runtime
194 * https://jaxb.dev.java.net/issues/show_bug.cgi?id=546
195 *
196 * Maybe in the future we'll be able to add targetType to IDREF
197 * but the spec has to be changed first so no fix is likely at the moment
198 *
199 */
200
201 AgentBase<?> agent = agentService.find(uuid);
202 if(agent != null) {
203 return agent;
204 }
205 DefinedTermBase<?> term = termService.find(uuid);
206 if(term != null) {
207 return term;
208 }
209 Media media = mediaService.find(uuid);
210 if(media != null) {
211 return media;
212 }
213 throw new SAXException(targetType.getSimpleName() + " with " + uuid + " not found");
214 }
215 } else {
216 return idmap.get(id);
217 }
218 }
219 };
220 }
221
222 private Object resolveObject(UUID uuid, Class targetType, IService service) throws SAXException {
223 Object object = service.find(uuid);
224 if(object == null) {
225 throw new SAXException(targetType.getSimpleName() + " with " + uuid + " not found");
226 }
227 return object;
228 }
229 }