View Javadoc

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           //@todo never return null on error. throw the exception instead
120          return _call;   
121       }       
122     }
123     
124 /*   
125    public boolean validateDocument(Document validDocument) {
126       boolean valid = false;
127       try {
128          XSLHelper xs = new XSLHelper();
129          Document resultDoc = xs.transformDatabaseProcess((Node)validDocument);
130          Document castorXS = xs.transformCastorProcess((Node)resultDoc);            
131          VODescription vo = (VODescription)Unmarshaller.unmarshal(VODescription.class,castorXS);
132          valid = true;
133       }catch(MarshalException me) {
134          me.printStackTrace();
135          valid = false;   
136       }catch(ValidationException ve) {
137          ve.printStackTrace();
138          valid = false;   
139       }finally {
140          System.out.println("tried validating and results = " + valid);
141          return valid;   
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           //Element root = doc.createElementNS(NAMESPACE_URI,"update");
184           Element root = update.createElementNS(NAMESPACE_URI,"Update");
185           root.appendChild(update.getDocumentElement());
186           update.appendChild(root);
187        
188       //Get the CAll.  
189       Call call = getCall(); 
190       
191       //Build up a SoapBodyElement to be sent in a Axis message style.
192       //Go ahead and reset a name and namespace to this as well.
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       //SOAPBodyElement sbeRequest = new SOAPBodyElement(doc.getDocumentElement());      
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          //@todo shouldn't catch this one - let it through.
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          }//for
267       }catch(Exception e) {
268         logger.error("getCurrentStatus()", e);
269         //@todo should this throw again now? status can't be meaningful to return, can it.
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         //@todo not much point continuing is there?
288       }
289       
290       if(doc == null) {
291           //@todo don't return null - throw a sensible exception instead.
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           //@todo why return a null -just allow the previously caught exception to propagate upwards instead.
315          return resultDoc;
316       }
317    }
318 }