1 package org.astrogrid.registry.client.admin;
2
3 import org.apache.commons.logging.Log;
4 import org.apache.commons.logging.LogFactory;
5
6
7 import java.net.URL;
8 import java.util.Vector;
9 import javax.xml.parsers.DocumentBuilder;
10 import javax.xml.parsers.DocumentBuilderFactory;
11 import javax.xml.parsers.ParserConfigurationException;
12 import org.apache.axis.client.Call;
13 import org.apache.axis.client.Service;
14 import org.astrogrid.registry.common.RegistryValidator;
15 import org.apache.axis.message.SOAPBodyElement;
16 import org.apache.axis.utils.XMLUtils;
17 import org.w3c.dom.Document;
18 import org.w3c.dom.Element;
19 import org.w3c.dom.NodeList;
20 import org.w3c.dom.Node;
21 import java.io.Reader;
22 import java.io.StringReader;
23 import org.xml.sax.InputSource;
24
25 import javax.xml.rpc.ServiceException;
26 import org.xml.sax.SAXException;
27 import java.rmi.RemoteException;
28
29 import org.astrogrid.registry.RegistryException;
30
31 import java.io.File;
32 import java.io.IOException;
33 import org.astrogrid.util.DomHelper;
34 import org.astrogrid.config.Config;
35 import junit.framework.AssertionFailedError;
36
37 import org.astrogrid.registry.common.XSLHelper;
38
39 /***
40 * Class Name: RegistryAdminService
41 * Description: This class represents the client webservice delegate to the Administration piece of the
42 * web service. It uses the same Interface as the server side webservice so they both implement and handle
43 * the same web service method names. The primary goal of this class is to establish a Axis-Message style
44 * webservice call to the server.
45 *
46 * @see org.astrogrid.registry.common.RegistryAdminInterface
47 * @author Kevin Benson
48 * @todo document the method bodies
49 *
50 *
51 */
52 public class UpdateRegistry implements RegistryAdminService {
53 /***
54 * Commons Logger for this class
55 */
56 private static final Log logger = LogFactory.getLog(UpdateRegistry.class);
57
58
59 private static final String NAMESPACE_URI = "http://www.ivoa.net/schemas/services/UpdateRegistry/wsdl";
60
61 public static final String ADMIN_URL_PROPERTY = "org.astrogrid.registry.admin.endpoint";
62
63 private boolean validated = false;
64
65 /***
66 * target end point is the location of the webservice.
67 */
68 private URL endPoint = null;
69
70 public static Config conf = null;
71
72
73 /*** @todo shouldn't be necessary to take a local reference to this static - call simple config.getSingleton each time instead */
74 static {
75 if(conf == null) {
76 conf = org.astrogrid.config.SimpleConfig.getSingleton();
77 }
78 }
79
80
81 /***
82 * Empty constructor that defaults the end point to local host.
83 * @author Kevin Benson
84 */
85 public UpdateRegistry() {
86 this(conf.getUrl(ADMIN_URL_PROPERTY,null));
87 }
88
89 /***
90 * Main constructor to allocate the endPoint variable.
91 * @todo what happens with nulls?
92 * @param endPoint location to the web service.
93 * @author Kevin Benson
94 */
95 public UpdateRegistry(URL endPoint) {
96 this.endPoint = endPoint;
97 }
98
99 /***
100 * Method to establish a Service and a Call to the server side web service.
101 * @return Call object which has the necessary properties set for an Axis message style.
102 * @throws Exception
103 * @author Kevin Benson
104 */
105 private Call getCall() {
106 Call _call = null;
107 try {
108 Service service = new Service();
109 _call = (Call) service.createCall();
110 _call.setTargetEndpointAddress(this.endPoint);
111 _call.setSOAPActionURI("");
112 _call.setOperationStyle(org.apache.axis.enum.Style.MESSAGE);
113 _call.setOperationUse(org.apache.axis.enum.Use.LITERAL);
114 _call.setEncodingStyle(null);
115 } catch(ServiceException se) {
116 logger.error("getCall()", se);
117 _call = null;
118 }finally {
119
120 return _call;
121 }
122 }
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146 public void harvestResource(Document harvestDoc) throws RegistryException {
147
148 throw new RegistryException("Not implemented yet");
149 }
150
151 /***
152 * Takes an XML Document to send to the update server side web service call. Establishes
153 * a service and a call to the web service and call it's update method, using an Axis-Message
154 * style. Then updates this document onto the registry.
155 * @param query Document a XML document dom object to be updated on the registry.
156 * @return the document updated on the registry is returned.
157 * @author Kevin Benson
158 *
159 */
160 public Document update(Document update) throws RegistryException {
161
162 if(update == null) {
163 throw new RegistryException("Cannot update 'null' found as the document to update");
164 }
165
166 boolean validateXML = conf.getBoolean("registry.validate.onupdates",false);
167 if(validateXML) {
168 try {
169 RegistryValidator.isValid(update);
170 }catch(AssertionFailedError afe) {
171 logger.error("Error invalid document still attempting to process resources = " + afe.getMessage());
172 if(conf.getBoolean("registry.quiton.invalid",false)) {
173 throw new RegistryException("Quitting: Invalid document, Message: " + afe.getMessage());
174 }
175 }
176
177 }
178
179
180 DocumentBuilder registryBuilder = null;
181 Document doc = null;
182 Document resultDoc = null;
183
184 Element root = update.createElementNS(NAMESPACE_URI,"Update");
185 root.appendChild(update.getDocumentElement());
186 update.appendChild(root);
187
188
189 Call call = getCall();
190
191
192
193 logger
194 .info("update(Document) - the endpoint = "
195 + this.endPoint);
196 logger.info("update(Document) - okay calling update service with doc = "
197 + DomHelper.DocumentToString(update));
198
199 SOAPBodyElement sbeRequest = new SOAPBodyElement(update.getDocumentElement());
200 sbeRequest.setName("Update");
201 sbeRequest.setNamespaceURI(NAMESPACE_URI);
202
203 try {
204 Vector result = (Vector) call.invoke (new Object[] {sbeRequest});
205 if(result.size() > 0) {
206 SOAPBodyElement sbe = (SOAPBodyElement) result.get(0);
207 resultDoc = sbe.getAsDocument();
208 }
209 }catch(RemoteException re) {
210 resultDoc = null;
211
212 throw new RegistryException(re);
213 }catch (Exception e) {
214 resultDoc = null;
215 throw new RegistryException(e);
216 }
217 return resultDoc;
218 }
219
220 public Document updateFromFile(File fi) throws RegistryException {
221 try {
222 return update(DomHelper.newDocument(fi));
223 }catch(IOException ioe) {
224 throw new RegistryException(ioe);
225 }catch(SAXException sax) {
226 throw new RegistryException(sax);
227 }catch(ParserConfigurationException pce) {
228 throw new RegistryException(pce);
229 }
230 }
231
232 public Document updateFromURL(URL location) throws RegistryException {
233 try {
234 return update(DomHelper.newDocument(location));
235 }catch(IOException ioe) {
236 throw new RegistryException(ioe);
237 }catch(SAXException sax) {
238 throw new RegistryException(sax);
239 }catch(ParserConfigurationException pce) {
240 throw new RegistryException(pce);
241 }
242 }
243
244 public Document updateFromString(String voresources) throws RegistryException {
245 try {
246 return update(DomHelper.newDocument(voresources));
247 }catch(IOException ioe) {
248 throw new RegistryException(ioe);
249 }catch(SAXException sax) {
250 throw new RegistryException(sax);
251 }catch(ParserConfigurationException pce) {
252 throw new RegistryException(pce);
253 }
254 }
255
256 public String getCurrentStatus() {
257 String status = "";
258 try {
259 Document doc = getStatus();
260 NodeList nl = doc.getElementsByTagName("status");
261 for(int i = 0;i < nl.getLength();i++) {
262 Node nd = nl.item(i);
263 if(nd.hasChildNodes()) {
264 status += nd.getFirstChild().getNodeValue();
265 }
266 }
267 }catch(Exception e) {
268 logger.error("getCurrentStatus()", e);
269
270 }
271 return status;
272 }
273
274 public Document getStatus() {
275 Document doc = null;
276 Document resultDoc = null;
277 try {
278
279 DocumentBuilder registryBuilder = null;
280 registryBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
281 doc = registryBuilder.newDocument();
282 Element root = doc.createElementNS(NAMESPACE_URI,"getStatus");
283 doc.appendChild(root);
284 }catch(ParserConfigurationException pce){
285 doc = null;
286 logger.error("getStatus()", pce);
287
288 }
289
290 if(doc == null) {
291
292 return null;
293 }
294
295 Call call = getCall();
296 SOAPBodyElement sbeRequest = new SOAPBodyElement(doc.getDocumentElement());
297 sbeRequest.setName("getStatus");
298 sbeRequest.setNamespaceURI(NAMESPACE_URI);
299
300 try {
301 Vector result = (Vector) call.invoke (new Object[] {sbeRequest});
302 SOAPBodyElement sbe = null;
303 if(result.size() > 0) {
304 sbe = (SOAPBodyElement) result.get(0);
305 resultDoc = sbe.getAsDocument();
306 }
307 }catch(RemoteException re) {
308 resultDoc = null;
309 logger.error("getStatus()", re);
310 }catch (Exception e) {
311 resultDoc = null;
312 logger.error("getStatus()", e);
313 }finally {
314
315 return resultDoc;
316 }
317 }
318 }