View Javadoc

1   package org.astrogrid.registry.server.admin;
2   
3   import org.w3c.dom.Document;
4   import org.w3c.dom.Element;
5   import org.w3c.dom.Node;
6   import org.w3c.dom.DocumentFragment;
7   import org.w3c.dom.NodeList;
8   import org.w3c.dom.NamedNodeMap;
9   import org.w3c.dom.Attr;
10  import javax.xml.parsers.DocumentBuilderFactory;
11  import javax.xml.parsers.DocumentBuilder;
12  import org.astrogrid.registry.server.RegistryServerHelper;
13  import javax.xml.parsers.ParserConfigurationException;
14  import java.util.HashMap;
15  import java.util.Date;
16  import java.text.DateFormat;
17  import org.astrogrid.config.Config;
18  import org.astrogrid.registry.common.XSLHelper;
19  import org.astrogrid.registry.server.XQueryExecution;
20  import org.astrogrid.registry.common.RegistryValidator;
21  import org.astrogrid.util.DomHelper;
22  import java.util.ArrayList;
23  import org.astrogrid.registry.RegistryException;
24  import org.astrogrid.registry.server.query.RegistryQueryService;
25  import org.astrogrid.registry.server.harvest.RegistryHarvestService;
26  import org.xml.sax.helpers.DefaultHandler;
27  import java.io.ByteArrayInputStream;
28  import java.io.ByteArrayOutputStream;
29  import java.io.IOException;
30  import java.net.URL;
31  import java.net.HttpURLConnection;
32  import javax.xml.parsers.SAXParser;
33  import javax.xml.parsers.SAXParserFactory;
34  import org.xml.sax.SAXException;
35  import org.xml.sax.SAXNotRecognizedException;
36  import org.xml.sax.SAXNotSupportedException;
37  import javax.xml.parsers.ParserConfigurationException;
38  import java.net.MalformedURLException;
39  import org.apache.commons.logging.Log;
40  import org.apache.commons.logging.LogFactory;
41  import org.apache.axis.AxisFault;
42  import org.astrogrid.xmldb.eXist.server.UpdateDBService;
43  import junit.framework.AssertionFailedError;
44  import java.text.SimpleDateFormat;
45  
46  
47  /***
48   * Class Name: RegistryAdminService
49   * Description: This class represents the web service to the Administration
50   * piece of the registry.  This class will handle inserts/updates Ressources
51   * in the registry.
52   * 
53   * @see org.astrogrid.registry..common.RegistryAdminInterface
54   * @author Kevin Benson
55   * 
56   */
57  public class RegistryAdminService {
58                            
59      /***
60       * Logging variable for writing information to the logs
61       */
62     private static final Log log = 
63                                 LogFactory.getLog(RegistryAdminService.class);
64  
65     /***
66      * conf - Config variable to access the configuration for the server normally
67      * jndi to a config file.
68      * @see org.astrogrid.config.Config
69      */   
70     public static Config conf = null;
71  
72     /***
73      * final variable for the default AuthorityID associated to this registry.
74      */   
75     private static final String AUTHORITYID_PROPERTY = 
76                                 "org.astrogrid.registry.authorityid";
77  
78     /***
79      * Hashmap of the Authories managed by this registry, and the authority
80      * ids managed by other registries. Used for determining if things are valid
81      * for updating to this registry and verify it is not owned by another registry.
82      */   
83     private static HashMap manageAuths, otherAuths;
84  
85     /***
86      * Static to be used on the initiatian of this class for the config
87      */
88     static {
89        if(conf == null) {
90           conf = org.astrogrid.config.SimpleConfig.getSingleton();
91           manageAuths = new HashMap();
92           otherAuths = new HashMap();
93        }      
94     }
95     
96     
97     public Document harvestResource(Document resources)  throws AxisFault {
98         RegistryHarvestService rhs = new RegistryHarvestService();
99         try {   
100           rhs.harvestResource(resources,null);
101        }catch(IOException ioe) {
102           throw new AxisFault("IOE problem",ioe);
103        }catch(RegistryException re) {
104         throw new AxisFault("Registry exception", re);
105        }
106        return resources;      
107    }
108    
109    
110 
111    /***
112     * Update Web Service method, performs an update through all the Resources of
113     * a Registry.
114     * 
115     * @param update XML DOM containing Resource XML elements
116     * @return XML of identifiers that did not get updated otherwise nothing
117     * if all were successfull.
118     * @throws AxisFault if an error goes wrong trying to update into the
119     * XML database or parsing XML.
120     */
121    public Document Update(Document update) throws AxisFault {
122       log.debug("start update");
123       return updateResource(update);
124    }
125    
126    /***
127     * Takes an XML Document and will either update and insert the data in the
128     * registry.  If a client wants an insert, but the primarykey (AuthorityID
129     * and ResourceKey) are already in the registry an automatic update will 
130     * occur.  This method will only update XML Resource elements.
131     *  
132     * @param update Document a XML document dom object to be updated on the registry.
133     * @return the document updated on the registry is returned.
134     * @author Kevin Benson
135     * 
136     */   
137    public Document updateResource(Document update) throws AxisFault {
138       log.debug("start updateResource");
139       long beginUpdate = System.currentTimeMillis();
140 
141       String authorityID = conf.getString("org.astrogrid.registry.authorityid");
142       log.info("Default AuthorityID for this Registry = " + authorityID);
143       // Transform the xml document into a consistent way.
144       // xml can come in a few various forms.  This xsl will make it
145       // consistent in the db and throughout this registry.
146       XSLHelper xs = new XSLHelper();      
147       Document xsDoc = null;
148       
149       //Okay we need to get the vr attribute namespace.
150       //The confusing part is since we are using message style there is a chance it 
151       //could be in the root element (which might be the web service operation name)
152       //hence we need to look at the root element, its fist child, and lastly
153       //the child of that node
154       //ex of possible message style input: 
155       //<update><VoResource xmlns:vr=... ><Resource xmlns:vr=...>
156       //the vr attribute can live at either or both of those elments and we just need to get the first one.
157       //It is possible the <update> element will not be there hence we need to look at the root element
158       String defaultNS = null;
159             
160       boolean hasStyleSheet = false;
161       
162       
163       UpdateDBService udbService = new UpdateDBService();
164       
165       
166       if(update == null) {
167           throw new AxisFault("Nothing on request 'null sent'");
168       }
169       
170       SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'");
171       Date updateDate = new Date();
172       String updateDateString = sdf.format(updateDate);
173       
174       //Get all the Resource elements
175       NodeList nl = null;
176       
177       String attrVersion = null;
178       Element findVersionElement = null;
179       
180       if(update.getDocumentElement().hasChildNodes()) {
181           nl = update.getDocumentElement().getChildNodes();
182           for(int k = 0;k < nl.getLength() && findVersionElement == null;k++) {
183               if(Node.ELEMENT_NODE == nl.item(k).getNodeType())
184                   findVersionElement = (Element) nl.item(k);
185           }
186           //attrVersion = RegistryServerHelper.getRegistryVersionFromNode(update.getDocumentElement().getFirstChild());
187       }else {
188           findVersionElement = (Element)update.getDocumentElement();
189       }
190       attrVersion = RegistryServerHelper.getRegistryVersionFromNode(findVersionElement);
191       
192       log.info("Registry Version being updated = " + attrVersion);      
193       String vrNS = "http://www.ivoa.net/xml/VOResource/v" + attrVersion;
194       log.info("Registry namespace being updated = " + vrNS);
195       String versionNumber = attrVersion.replace('.','_');
196       String collectionName = "astrogridv" + versionNumber;
197       log.info("Collection Name = " + collectionName);
198       //String rootNodeString = RegistryServerHelper.getRootNodeLocalName(versionNumber);
199       hasStyleSheet = conf.getBoolean("org.astrogrid.registry.updatestylesheet." + versionNumber,false);
200       if(hasStyleSheet) {
201          //System.out.println("lets call transform update");
202          log.info("performing transformation before analysis of update for versionNumber = " + versionNumber);
203          xsDoc = xs.transformUpdate((Node)update.getDocumentElement(),versionNumber,false);
204       } else {
205          xsDoc = update;
206       }
207 
208       nl = xsDoc.getElementsByTagNameNS("*","Resource");
209       if(nl.getLength() == 0) {
210           throw new AxisFault("No Resources Found to be updated");
211       }
212       
213       boolean validateXML = conf.getBoolean("registry.validate.onupdates",false);
214       //log.info("Validate xml2 = " + validateXML);
215       if(validateXML) {
216           try {
217               
218               String rootElement = update.getDocumentElement().getFirstChild().getLocalName();
219               if(rootElement == null) {
220                   rootElement = update.getDocumentElement().getFirstChild().getNodeName();
221               }
222               log.info("try Validating for version = " + versionNumber +
223                        " with rootElement = " + rootElement);
224               RegistryValidator.isValid(xsDoc,rootElement);
225           }catch(AssertionFailedError afe) {
226               afe.printStackTrace();
227               log.error("Error invalid document = " + afe.getMessage());
228               if(conf.getBoolean("registry.quiton.invalid",false)) {
229                   throw new AxisFault("Invalid update, document not valid " + afe.getMessage());
230               }//if              
231           }//catch
232       }//if
233       
234       log.info("Number of Resources to be updated = " + nl.getLength());
235       
236       if(manageAuths.get(versionNumber) == null)
237           populateManagedMaps(collectionName, versionNumber);
238       
239       if(otherAuths.get(versionNumber) == null)
240           populateOtherManagedMaps(collectionName, versionNumber);
241       
242       if(manageAuths.get(versionNumber) == null) {
243           //okay this must be the very first time into the registry where
244           //registry is empty. So put a an empty entry for this version.
245           manageAuths.put(versionNumber,new HashMap());
246       }
247       if(otherAuths.get(versionNumber) == null) {
248           //okay this must be the very first time into the registry where
249           //registry is empty. So put a an empty entry for this version.
250           otherAuths.put(versionNumber,new HashMap());
251       }
252       
253       
254       ArrayList al = new ArrayList();
255       String xql = null;
256       DocumentFragment df = null;
257       Node root = null;
258       Document resultDoc = null;
259       String ident = null;
260       String resKey = null;
261       String tempIdent = null;
262       boolean addManageError = false;
263       String manageNodeVal = null;
264       
265       //log.info("here is the nl length = " + bhyxdtgdxdsnl.getLength());
266       
267       final int resourceNum = nl.getLength();
268       //go through the various resource entries.
269       for(int i = 0;i < resourceNum;i++) {
270          long beginQ = System.currentTimeMillis();
271          //Looks sort of odd always getting item at number 0
272          //this is because we append it to another element later
273          //hence the nodelist is like a queue and no longer
274          //has the current resource and moves everything up the queue
275          //get the iden and resource key elements.
276          ident = RegistryServerHelper.getAuthorityID((Element)nl.item(0));
277          log.info("here is the ident/authid = " + ident);         
278          resKey = RegistryServerHelper.getResourceKey((Element)nl.item(0));
279          log.info("here is the reskey = " + resKey);
280          //set the currentResource element.
281          Element currentResource = (Element)nl.item(0);
282          //Sometimes there are other elements defined above the
283          //Resource element so be sure this Resource element has a
284          //defined vr namespace if it does not have one already.
285          
286          Node parentNode = currentResource.getParentNode();
287          if(parentNode != null && Node.ELEMENT_NODE == parentNode.getNodeType()) {
288              NamedNodeMap attrNNM = parentNode.getAttributes();
289              //currentResource.setPrefix("vr");
290              for(int k= 0;k < attrNNM.getLength();k++) {
291                  Node attrNode = attrNNM.item(k);
292                  if(!currentResource.hasAttribute(attrNode.getNodeName()) && 
293                     !attrNode.getLocalName().equals(currentResource.getPrefix())) {
294                      //System.out.println("2ADDING THIS ATTRIBUTE: the localname = " + attrNode.getLocalName() + " node name = " + attrNode.getNodeName() + " node value = " + attrNode.getNodeValue() + " namespace uri = " + attrNode.getNamespaceURI());
295                      if(attrNode.getNodeName().indexOf("xmlns") != -1 && 
296                         attrNode.getNodeName().indexOf("xsi") == -1) {
297                          //System.out.println("adding xmlns");
298                          currentResource.setAttribute(attrNode.getNodeName(),
299                                                       attrNode.getNodeValue());
300                      }//else
301                  }//if
302              }//for
303          }//if
304          currentResource.setAttribute("updated",updateDateString);
305          
306 
307          //set a temporary identifier.
308          tempIdent = ident;
309          if(resKey != null && resKey.trim().length() > 0) tempIdent += "/" + resKey;
310       
311          log.info("serverside update ident = " + ident + " reskey = " + 
312                   resKey + " the nl getlenth here = " + nl.getLength());
313                   //see if we manage this authority id
314                   //if we do then update it in the db.
315          //doe we manage this authority id, if so then add the resource.
316          if(manageAuths.get(versionNumber) != null &&
317             ((HashMap)manageAuths.get(versionNumber)).containsKey(ident)) {
318             //Essentially chop off other elemens wrapping the Resource element, and put
319             //our own element. Would have been nice just to store the Resource element
320             //at the root level, but it seems the XQueries on the database have problems
321             //with that.
322             root = xsDoc.createElement("AstrogridResource");
323             root.appendChild(currentResource);
324 
325             RegistryServerHelper.addStatusMessage("Entering new entry: " + 
326                                                 tempIdent);
327             try {
328                //update the resource element.
329                udbService.updateQuery(tempIdent,"xml",collectionName,root);
330                //we want to keep a little bit of stats information on the
331                //Resources managed.
332                udbService.updateQuery(tempIdent,"xml","statv" + versionNumber,
333                                       createStats(tempIdent));
334             } catch(MalformedURLException mue) {
335                log.error(mue);
336                throw new AxisFault("Malformed URL on the update", mue);
337             } catch(IOException ioe) {
338                log.error(ioe);
339                throw new AxisFault("IO problem", ioe);
340             }
341 
342          }else {
343             // It is not one this registry manages, so check it's attributes
344             // and if it is a Registry type then go ahead and update it
345             // if it is an authoritytype
346             addManageError = true;
347             if(currentResource.hasAttributes()) {
348                 
349 //               NamedNodeMap nnm = currentResource.getAttributes();
350 //               for(int j = 0;j < nnm.getLength();j++) {
351 //                  Node attrNode = nnm.item(j);
352                   Node typeAttribute = currentResource.getAttributes().getNamedItem("xsi:type");
353                   String nodeVal = null;
354                   if(typeAttribute != null) {
355                       nodeVal = typeAttribute.getNodeValue();
356                   }
357                   log.info(
358                   "Checking xsi:type for a Registry or Authority: = " 
359                   + nodeVal);
360                   //check if it is a registry type.
361                   if(nodeVal != null && nodeVal.indexOf("Registry") != -1) {
362                      addManageError = false;
363                      log.info("This is an RegistryType");
364                      root = xsDoc.createElement("AstrogridResource");
365                      root.appendChild(currentResource);
366                      RegistryServerHelper.addStatusMessage(
367                               "Entering new entry: " + tempIdent);
368                      //update this registry resource into our registry.
369                      try {
370                         udbService.updateQuery(tempIdent,"xml",collectionName,root);
371                         if(authorityID.equals(ident)) {
372                             udbService.updateQuery(tempIdent,"xml","statv" + versionNumber,createStats(tempIdent));
373                         }else {
374                             udbService.updateQuery(tempIdent,"xml","statv" + versionNumber,createStats(tempIdent,false));
375                         }
376                      } catch(MalformedURLException mue) {
377                         log.error(mue);
378                         throw new AxisFault("Malformed URL on the update", mue);
379                      } catch(IOException ioe) {
380                         log.error(ioe);
381                         throw new AxisFault("IO problem", ioe);
382                      }
383                      NodeList manageList = getManagedAuthorities(currentResource);                     
384                      if(authorityID.equals(ident)) {
385                         log.info("authority id equaled to ident");
386                         ((HashMap)manageAuths.get(versionNumber)).put(ident,null);
387                         for(int k = 0;k < manageList.getLength();k++) {
388                             manageNodeVal = manageList.item(k).getFirstChild().getNodeValue();
389                             log.info("try adding new manage node for this registry = " + manageNodeVal);
390                             if(manageNodeVal != null && manageNodeVal.trim().length() > 0) {
391                                 ((HashMap)manageAuths.get(versionNumber)).put(manageNodeVal,null);
392                             }//if
393                         }//for
394                      }else {
395                         ((HashMap)otherAuths.get(versionNumber)).put(ident,null);
396                         for(int k = 0;k < manageList.getLength();k++) {
397                             manageNodeVal = manageList.item(k).getFirstChild().getNodeValue();
398                             if(manageNodeVal != null && manageNodeVal.trim().length() > 0) {
399                                 log.info("try adding a managed authority for another registry = " + manageNodeVal);
400                                 /*
401                                  Need to think about this a little more.
402                                 if(((HashMap)otherAuths.get(versionNumber)).containsKey(manageNodeVal)) {
403                                     log.error(
404                                     "Update Successfull, but when trying to update a Registry with authority id = " +
405                                     ident + "; Found an AuthorityID already owned by another Registry, " +
406                                     "the authority id in conflict is: " + manageNodeVal);
407                                     al.add(
408                                       "Update Successfull, but when trying to update a Registry with authority id = " +
409                                       ident + "; Found an AuthorityID already owned by another Registry, " +
410                                       "the authority id in conflict is: " + manageNodeVal);
411                                 }
412                                 */
413                                 ((HashMap)otherAuths.get(versionNumber)).put(manageNodeVal,null);
414                             }//if
415                         }//for
416                      }
417                   }else if(nodeVal != null && 
418                            nodeVal.indexOf("Authority") != -1)
419                   {
420                      // Okay it is an AuthorityType and if no other registries 
421                      // manage this authority then we can place it in this 
422                      // registry as a new managed authority.
423                      if((otherAuths.get(versionNumber) != null &&
424                         !((HashMap)otherAuths.get(versionNumber)).containsKey((String)ident))) {
425                         log.info(
426                         "This is an AuthorityType and not managed by other authorities");
427                         addManageError = false;
428                         // Grab our current Registry resource we need to add
429                         // a new managed authority tag.
430                         RegistryQueryService rs = new RegistryQueryService();
431                         Document loadedRegistry = rs.loadMainRegistry(versionNumber);
432                         log.info("THE LOADED REGISTRY before AUTHORITY = " + DomHelper.DocumentToString(loadedRegistry));
433                         // Get a ManagedAuthority Node region/area
434                         // so we can append a sibling to it, and
435                         // use its info for creating another ManagedAuthority
436                         // element.
437                         Node manageNode = 
438                                         getManagedAuthorityID(loadedRegistry);
439                         if(manageNode != null) {
440                            log.info(
441                              "creating new manage element for authorityid = " + ident);
442                            // Create a new ManagedAuthority element.
443                            Element newManage = loadedRegistry.
444                                                createElementNS(
445                                                  manageNode.getNamespaceURI(),
446                                                  manageNode.getNodeName());
447                            // Put in the text node the new ident.
448                            log.info("adding ident for managed authority = " + ident);
449                            newManage.appendChild(loadedRegistry.
450                                                  createTextNode(ident));
451                            
452                            //System.out.println("the loadedREgistry in admin service = " + DomHelper.DocumentToString(loadedRegistry));
453                            // For some reason the DOM model threw exceptions 
454                            // when I tried to insert it as a sibling after 
455                            // another existing ManagedAuthority tag, so just 
456                            // add it to the end for now.
457                            NodeList resListForAuth = loadedRegistry.getElementsByTagNameNS("*","Resource");
458                            resListForAuth.item(0).appendChild(newManage);
459                            ((HashMap)manageAuths.get(versionNumber)).put(ident,null);
460                            //System.out.println("the loadedREgistry in admin service2 = " + DomHelper.DocumentToString(loadedRegistry));
461                            //loadedRegistry.getDocumentElement().
462                            //             getFirstChild().appendChild(newManage);
463 
464                            // TODO: Need to check this next line I believe is 
465                            // useless.
466                            //df = xsDoc.createDocumentFragment();
467                            
468                            // Update our currentResource into the database
469                            root = xsDoc.createElement("AstrogridResource");
470                            root.appendChild(currentResource);
471                            log.info(
472                              "running query with new authorityentry = " + xql);
473                            RegistryServerHelper.addStatusMessage(
474                               "Entering new entry: " + tempIdent);
475                            try {
476                               udbService.updateQuery(tempIdent,"xml",collectionName,root);
477                               udbService.updateQuery(tempIdent,"xml","statv" + versionNumber,createStats(tempIdent));
478                            } catch(MalformedURLException mue) {
479                               log.error(mue);
480                               throw new AxisFault("Malformed URL on the update", mue);
481                            } catch(IOException ioe) {
482                               log.error(ioe);
483                               throw new AxisFault("IO problem", ioe);
484                            }
485 
486                            // Now get the information to re-update the
487                            // Registry Resource which is for this registry.
488                            ident = RegistryServerHelper.getAuthorityID(loadedRegistry.
489                                                   getDocumentElement());
490                            log.info("the ident form loaded registry right before update = " + ident);
491                            resKey = RegistryServerHelper.getResourceKey(loadedRegistry.
492                                                    getDocumentElement());
493                            log.info("the resKey form loaded registry right before update = " + resKey);
494                            tempIdent = ident;
495                            if(resKey != null) tempIdent += "/" + resKey;
496                            //TODO: again this next line should not be needed.
497                            //df = loadedRegistry.createDocumentFragment();
498                            resListForAuth = loadedRegistry.getElementsByTagNameNS("*","Resource");
499                            Element elem = loadedRegistry.
500                                           createElement("AstrogridResource");
501                            elem.appendChild(resListForAuth.item(0));
502                            log.info("THE LOADED REGISTRY after AUTHORITY = " + DomHelper.ElementToString(elem));                           
503                            try {
504                                log.info("updating the new registy");
505                               udbService.updateQuery(tempIdent,"xml",collectionName,elem);                                            
506                            } catch(MalformedURLException mue) {
507                               log.error(mue);
508                               throw new AxisFault("Malformed URL on the update", mue);
509                            } catch(IOException ioe) {
510                               log.error(ioe);
511                               throw new AxisFault("IO problem", ioe);
512                            }
513                            
514                            //XQueryExecution.updateQuery("xml","astrogridv" + 
515                            //                            versionNumber,tempIdent,
516                            //                            elem);
517                            // reset our hashmap of the managed authorities.
518                            ((HashMap)manageAuths.get(versionNumber)).put(ident,null);
519                         }else {
520                            log.error("Removing child - but somehow the Registries" +
521                                      " main RegistryType has no ManagedAuthority");
522                            // This resource is already owned by another 
523                            // Registry.
524                            log.error(
525                            "IN THE AUTO-INTEGRATION YOU SHOULD NOT GET HERE, " +
526                            "Removing Resource and not updating this Resource");
527                            //xsDoc.getDocumentElement().
528                            //      removeChild(currentResource);
529                         }                           
530                      }//if      
531                   }//elseif   
532 //               }//for
533             }//if
534             
535             if(addManageError) {
536                al.add("This AuthorityID is not managed by the Registry: " + 
537                       ident);
538                log.info("Found entry not managed by this Registry = " + ident);
539                //xsDoc.getDocumentElement().removeChild(currentResource);
540             }//if
541          }//else
542          log.info("Time taken to update an entry = " + 
543                   (System.currentTimeMillis() - beginQ) +
544                   " for ident  = " + tempIdent);
545       }//for
546       
547       Document returnDoc = null;      
548       // Constructgs a small RegistryError element with all the
549       // errored Resource that was not able to be updated in the db.
550       try {      
551           if(al != null && al.size() > 0) {
552               Document errorDoc = DomHelper.newDocument();
553               Element errorRoot = errorDoc.createElement("RegistryError");
554               errorDoc.appendChild(errorRoot);
555               for(int i = 0;i < al.size();i++) {
556                   Element errorElem = errorDoc.createElement("error");
557                   errorElem.appendChild(errorDoc.
558                                         createTextNode((String)al.get(i)));
559                   errorRoot.appendChild(errorElem);
560               }   
561               return errorDoc;
562           } else {
563               returnDoc = DomHelper.newDocument();
564               returnDoc.appendChild(returnDoc.createElement("UpdateResponse"));              
565           }          
566       }catch(ParserConfigurationException pce) {
567           pce.printStackTrace();
568           log.error(pce);   
569       }
570       
571       log.info("Time taken to complete update on server = " +
572                (System.currentTimeMillis() - beginUpdate) + "milliseconds");
573       log.debug("end updateResource");
574 
575       return returnDoc;
576    }
577    
578    public void clearManagedCache(String versionNumber) {
579        versionNumber = versionNumber.replace('.','_');
580        otherAuths.put(versionNumber,null);
581        manageAuths.put(versionNumber,null);
582    }
583    
584    private void populateOtherManagedMaps(String collectionName, String versionNumber) {
585        log.debug("start populateOtherManagedMaps");
586        HashMap versionOtherManaged = null;
587        //get All the Managed Authorities, the getOtherManagedAutories() does not
588        //perform a query every time only once.
589        try {
590           //otherAuths = RegistryServerHelper.getOtherManagedAuthorities(collectionName, versionNumber);
591            versionOtherManaged = RegistryServerHelper.getOtherManagedAuthorities(collectionName, versionNumber);
592            log.info("found other managed authorities size = " + 
593                    versionOtherManaged.size() + " for registry version = "
594                      + versionNumber);           
595            otherAuths.put(versionNumber,versionOtherManaged);
596        }catch(SAXException se) {
597            //hmmm need to relook the first time with an empty eXist db an
598            //exception is okay, but probably only IOException. 
599        }catch(MalformedURLException me) {
600            //hmmm need to relook the first time with an empty eXist db an
601            //exception is okay, but probably only IOException. 
602        }catch(ParserConfigurationException pce) {
603            //hmmm need to relook the first time with an empty eXist db an
604            //exception is okay, but probably only IOException.            
605        }catch(IOException ioe) {
606            //hmmm need to relook the first time with an empty eXist db an
607            //exception is okay, but probably only IOException.   
608        }
609        log.debug("end populateOtherManagedMaps");
610    }
611    
612    private void populateManagedMaps(String collectionName, String versionNumber) {
613        log.debug("start populateManagedMaps");       
614        //get All the Managed Authorities, the getManagedAutories() does not
615        //perform a query every time only once.
616        HashMap versionManaged = null;
617 
618        try {
619           //manageAuths = RegistryServerHelper.getManagedAuthorities(collectionName, versionNumber);
620            versionManaged = RegistryServerHelper.getManagedAuthorities(collectionName, versionNumber);
621            log.info("found managed authorities size = " + versionManaged.size()
622                     + " for registry version = " + versionNumber);
623            manageAuths.put(versionNumber,versionManaged);
624        }catch(SAXException se) {
625          //hmmm need to relook the first time with an empty eXist db an
626          //exception is okay, but probably only IOException. 
627        }catch(MalformedURLException me) {
628            //hmmm need to relook the first time with an empty eXist db an
629            //exception is okay, but probably only IOException. 
630        }catch(ParserConfigurationException pce) {
631            //hmmm need to relook the first time with an empty eXist db an
632            //exception is okay, but probably only IOException. 
633        }catch(IOException ioe) {
634            //hmmm need to relook the first time with an empty eXist db an
635            //exception is okay, but probably only IOException.    
636        }
637        log.debug("end populateManagedMaps");
638    }
639  
640   
641    /***
642     * Also an update method that updates into this Registry's db. But it does no
643     * special checking.  This is used internally by harvesting other registries to
644     * go ahead and place the Resources into our db.
645     * 
646     * @param update A DOM of XML of  one or more Resources.
647     */
648    public void updateNoCheck(Document update,String attrVersion) throws MalformedURLException, IOException {
649       log.debug("start updateNoCheck");
650 
651       //log.info("This is xsDoc = " + XMLUtils.DocumentToString(xsDoc));
652       //NodeList nl = xsDoc.getElementsByTagNameNS("vr","Resource" );
653 
654       ArrayList al = new ArrayList();
655       String xql = null;
656       DocumentFragment df = null;
657       Node root = null;
658       Document resultDoc = null;
659       String ident = null;
660       String resKey = null;
661       boolean addManageError = false;
662       String tempIdent = null;
663 
664       XSLHelper xs = new XSLHelper();
665       
666       if(update == null) {
667           throw new IOException("Error nothing to update 'null sent'");
668       }
669       
670       
671       //String attrVersion = null;
672       //the vr attribute can live at either or both of those elments and we just need to get the first one.
673       //It is possible the <update> element will not be there hence we need to look at the root element
674       //NodeList nl = DomHelper.getNodeListTags(update,"Resource","vr");
675       NodeList nl = update.getElementsByTagNameNS("*","Resource");
676       if(nl.getLength() == 0) {
677 
678           nl = update.getElementsByTagNameNS("*","resource");
679           System.out.println("the resource nl.getLength= " + nl.getLength());
680       }
681       
682       if(attrVersion == null) {
683           attrVersion = RegistryServerHelper.getRegistryVersionFromNode(nl.item(0));
684       }
685           
686       log.info("the nl length of resoruces = " + nl.getLength());      
687       /*
688       if(nl.getLength() > 0) {
689           log.info("NODE TYPE = " + nl.item(0).getNodeType() + " NODE NAME = " + nl.item(0).getNodeName() + " Local Name = " + nl.item(0).getLocalName());
690           attrVersion = RegistryServerHelper.getRegistryVersionFromNode((Element)nl.item(0)); 
691       }
692       */
693       String vrNS = "http://www.ivoa.net/xml/VOResource/v" + attrVersion;
694       String versionNumber = attrVersion.replace('.','_');      
695       String collectionName = "astrogridv" + versionNumber;
696       String defaultNS = null;
697       log.info("Collection Name = " + collectionName);
698       
699       boolean hasStyleSheet = conf.getBoolean("org.astrogrid.registry.updatestylesheet.onHarvest." + versionNumber,false);
700       Document xsDoc = null;
701       System.out.println("has stylesheet for " + "org.astrogrid.registry.updatestylesheet.onHarvest." + versionNumber);
702       log.info("Before the transform:::");
703       log.info(DomHelper.DocumentToString(update));
704       if(hasStyleSheet) {
705          //System.out.println("lets call transform update");
706          log.info("performing transformation before analysis of update for versionNumber = " + versionNumber);
707          xsDoc = xs.transformUpdate((Node)update.getDocumentElement(),versionNumber,true);
708       } else {
709          xsDoc = update;
710       }
711       log.info("the xsdoc = " + DomHelper.DocumentToString(xsDoc));
712       nl = xsDoc.getElementsByTagNameNS("*","Resource");            
713       
714       //System.out.println("the xsdoc in updateNocheck = " + DomHelper.DocumentToString(xsDoc));
715       log.info("Number of Resources = " + nl.getLength());
716       UpdateDBService udbService = new UpdateDBService();
717       
718       if(manageAuths.get(versionNumber) == null)
719           populateManagedMaps(collectionName, versionNumber);
720       
721       if(otherAuths.get(versionNumber) == null)
722           populateOtherManagedMaps(collectionName, versionNumber);
723       
724       //hmmm he is doing harvesting before he setup the registry, okay let it go.
725       if(manageAuths.get(versionNumber) == null) {
726           //okay this must be the very first time into the registry where
727           //registry is empty. So put a an empty entry for this version.
728           manageAuths.put(versionNumber,new HashMap());
729       }
730       //hmmm he is doing harvesting before he setup the registry, okay let it go.
731       if(otherAuths.get(versionNumber) == null) {
732           //okay this must be the very first time into the registry where
733           //registry is empty. So put a an empty entry for this version.
734           otherAuths.put(versionNumber,new HashMap());
735       }
736       
737       // This does seem a little strange as if an infinte loop,
738       // but later on an appendChild is performed which
739       // automatically reduced the length by one.
740       final int resourceNum = nl.getLength();
741       for(int i = 0;i < resourceNum;i++) {
742          ident = RegistryServerHelper.getAuthorityID( (Element)nl.item(0));
743          resKey = RegistryServerHelper.getResourceKey( (Element)nl.item(0));
744          Element currentResource = (Element)nl.item(0);
745 
746          tempIdent = ident;
747          if(resKey != null) tempIdent += "/" + resKey;
748          log.info("the ident in updateNoCheck = " + tempIdent);
749          
750          /*
751          if(!"vr".equals(currentResource.getPrefix())) {
752              currentResource.setAttribute("xmlns:vr",vrNS);
753          }
754          if(defaultNS == null) {
755              defaultNS = DomHelper.getNodeAttrValue((Element)currentResource,"xmlns");             
756          }
757          if((defaultNS == null || defaultNS.trim().length() == 0) && currentResource.getParentNode() != null) {
758              defaultNS = DomHelper.getNodeAttrValue((Element)currentResource.getParentNode(),"xmlns");
759          }
760          if(defaultNS != null && defaultNS.trim().length() > 0) {
761              currentResource.setAttribute("xmlns",defaultNS);
762          } 
763          */            
764          //root = update.createElement("AstrogridResource");
765          root = xsDoc.createElement("AstrogridResource");
766          root.appendChild(currentResource);
767          RegistryServerHelper.
768              addStatusMessage("Entering new entry: " + tempIdent);
769          udbService.updateQuery(tempIdent,"xml",collectionName,root);
770                           
771          if(currentResource.hasAttributes()) {
772              
773              Node typeAttribute = currentResource.getAttributes().getNamedItem("xsi:type");
774              String nodeVal = null;
775              if(typeAttribute != null) {
776                  nodeVal = typeAttribute.getNodeValue();
777              }
778              log.info(
779              "Checking xsi:type for a Registry: = " 
780              + nodeVal);
781                  //check if it is a registry type.
782                  if(nodeVal != null && nodeVal.indexOf("Registry") != -1)
783                  {
784                     log.info("A RegistryType in updateNoCheck add stats");
785                     //update this registry resource into our registry.
786                     try {
787                        log.info("UPDADING STATS FROM HARVEST = " + tempIdent);
788                        udbService.updateQuery(tempIdent,"xml","statv" + versionNumber,createStats(tempIdent));
789                     } catch(MalformedURLException mue) {
790                        log.error(mue);
791                        throw new AxisFault("Malformed URL on the update", mue);
792                     } catch(IOException ioe) {
793                        log.error(ioe);
794                        throw new AxisFault("IO problem", ioe);
795                     }//try
796                     if(otherAuths != null) {
797                        ((HashMap)otherAuths.get(versionNumber)).put(ident,null);
798                        NodeList manageList = getManagedAuthorities(currentResource);
799                        for(int k = 0;k < manageList.getLength();k++) {
800                            String manageNodeVal = manageList.item(k).getFirstChild().getNodeValue();
801                            if(manageNodeVal != null && manageNodeVal.trim().length() > 0) {
802                                ((HashMap)otherAuths.get(versionNumber)).put(manageNodeVal,null);
803                            }
804                        }
805                     }//if
806                  }//if
807          }//if
808       }//if
809       log.debug("end updateNoCheck");
810    }
811    
812    
813    private Node createStats( String tempIdent, boolean addMillis) {
814        log.debug("start createStats");
815        Date statsTimeMillis = new Date();
816        DateFormat shortDT = DateFormat.getDateTimeInstance();
817        String statsXML = "<ResourceStat><Identifier>" + tempIdent +
818                                 "</Identifier>";
819        if(addMillis) {
820            statsXML += "<StatsDateMillis>" +
821                        statsTimeMillis.getTime() +
822                        "</StatsDateMillis>";
823        }
824        statsXML += "<StatsDate>" +
825                         shortDT.format(statsTimeMillis) +
826                     "</StatsDate></ResourceStat>";
827        try {
828           log.debug("end createStats");
829           return DomHelper.newDocument(statsXML).getDocumentElement();
830        }
831        catch ( Exception e ) {
832        // This will be improved shortly with other Exception handling!
833           e.printStackTrace();
834           log.error(e);
835       }
836       return null;
837    }
838 
839    /***
840     * Create statistical data to store in the eXist database when each 
841     * managed or registry Resource entry is either created or updated. This
842     * will shortly be used to drive Harvesting so that only appropriate
843     * entries will be extracted.
844     *
845     * @param tempIdent The identifier for this Resource
846     * @return Node representing the <ResourceStat> Element
847     */     
848    private Node createStats( String tempIdent ) {
849        return createStats(tempIdent,true);
850    }
851 
852    /***
853     * Need to use RegistryServerHelper class to get the NodeList.
854     * But leave for the moment.
855     * @param doc
856     * @return
857     */
858    private Node getManagedAuthorityID(Document doc) {
859       log.debug("start getManagedAuthorityID");
860       //try {
861           NodeList nl = doc.getElementsByTagNameNS("*","ManagedAuthority");
862           
863           if(nl.getLength() == 0) {
864               nl = doc.getElementsByTagNameNS("*","managedAuthority");
865           }          
866           
867           //NodeList nl = DomHelper.getNodeListTags(doc,"ManagedAuthority","vg");
868           if(nl.getLength() > 0)
869              return nl.item(0);
870           log.debug("end getManagedAuthorityID");
871       //}catch(IOException ioe) {
872           //ioe.printStackTrace();
873           //log.error(ioe);
874       //}
875       return null;
876    }
877    
878    private NodeList getManagedAuthorities(Element regNode) {
879        log.debug("start getManagedAuthorityID");
880        //NodeList nl = null;
881        NodeList nl = regNode.getElementsByTagNameNS("*","ManagedAuthority");
882        if(nl.getLength() == 0) {
883            nl = regNode.getElementsByTagNameNS("*","managedAuthority");
884        }
885        /*
886        try {
887            
888            nl = DomHelper.getNodeListTags(regNode,"ManagedAuthority","vg");
889            log.debug("end getManagedAuthorityID");
890        }catch(IOException ioe) {
891            ioe.printStackTrace();
892            log.error(ioe);
893        }*/
894        return nl;
895     }
896    
897    
898  /***
899    * Takes an XML Document and will either update and insert the data in the
900    * registry.  If a client is intending for an insert, but the primarykey 
901    * (AuthorityID and ResourceKey) are already in the registry an automatic
902    * update will occur.  This method will only update main pieces of 
903    * data/elements conforming to the IVOA schema.
904    * 
905    * Main Pieces: Organisation, Authority, Registry, Resource, Service,
906    * SkyService, TabularSkyService, DataCollection 
907    * 
908    * @param status This DOM object really should be null each time.
909    * @return the document updated on the registry is returned.
910    * @author Kevin Benson
911    * 
912    */   
913    public Document getStatus(Document status) throws AxisFault {
914 
915       log.debug("start getStatus");
916    
917       Document doc = null;
918       try {
919          DocumentBuilder registryBuilder = null;
920          registryBuilder = DocumentBuilderFactory.newInstance().
921                                                  newDocumentBuilder();
922          doc = registryBuilder.newDocument();
923       
924          Element elem = doc.createElement("status");
925          elem.appendChild(doc.createTextNode(RegistryServerHelper.
926                                              getStatusMessage()));
927          doc.appendChild(elem);
928          log.info("Document returned for Status message = " +
929                    DomHelper.DocumentToString(doc));
930       } catch (ParserConfigurationException pce){
931          log.error(pce);
932          throw new AxisFault("Parser config problem", pce);
933       } catch (IOException ioe) {
934          log.error(ioe);
935          throw new AxisFault("IO problem", ioe);
936       }
937       log.debug("end getStatus");
938       return doc;
939    } 
940 }