Clover coverage report - Code Coverage for hivemind release 1.0-rc-1
Coverage timestamp: Wed Aug 25 2004 13:06:02 EDT
file stats: LOC: 411   Methods: 20
NCLOC: 272   Classes: 1
30 day Evaluation Version distributed via the Maven Jar Repository. Clover is not free. You have 30 days to evaluate it. Please visit http://www.thecortex.net/clover to obtain a licensed version of Clover
 
 Source file Conditionals Statements Methods TOTAL
ConstructRegistry.java 86.2% 90.6% 95% 89.8%
coverage coverage
 1   
 //  Copyright 2004 The Apache Software Foundation
 2   
 //
 3   
 // Licensed under the Apache License, Version 2.0 (the "License");
 4   
 // you may not use this file except in compliance with the License.
 5   
 // You may obtain a copy of the License at
 6   
 //
 7   
 //     http://www.apache.org/licenses/LICENSE-2.0
 8   
 //
 9   
 // Unless required by applicable law or agreed to in writing, software
 10   
 // distributed under the License is distributed on an "AS IS" BASIS,
 11   
 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 12   
 // See the License for the specific language governing permissions and
 13   
 // limitations under the License.
 14   
 
 15   
 package org.apache.hivemind.ant;
 16   
 
 17   
 import java.io.BufferedInputStream;
 18   
 import java.io.BufferedOutputStream;
 19   
 import java.io.File;
 20   
 import java.io.FileOutputStream;
 21   
 import java.io.IOException;
 22   
 import java.io.InputStream;
 23   
 import java.io.OutputStream;
 24   
 import java.net.URL;
 25   
 import java.util.ArrayList;
 26   
 import java.util.List;
 27   
 
 28   
 import javax.xml.parsers.DocumentBuilder;
 29   
 import javax.xml.parsers.DocumentBuilderFactory;
 30   
 import javax.xml.parsers.ParserConfigurationException;
 31   
 
 32   
 import org.apache.hivemind.Resource;
 33   
 import org.apache.hivemind.impl.RegistryBuilder;
 34   
 import org.apache.hivemind.util.FileResource;
 35   
 import org.apache.hivemind.util.URLResource;
 36   
 import org.apache.tools.ant.BuildException;
 37   
 import org.apache.tools.ant.Task;
 38   
 import org.apache.tools.ant.types.Path;
 39   
 import org.apache.xml.serialize.OutputFormat;
 40   
 import org.apache.xml.serialize.XMLSerializer;
 41   
 import org.w3c.dom.Document;
 42   
 import org.w3c.dom.Element;
 43   
 import org.w3c.dom.NamedNodeMap;
 44   
 import org.w3c.dom.Node;
 45   
 import org.xml.sax.InputSource;
 46   
 import org.xml.sax.SAXException;
 47   
 
 48   
 /**
 49   
  * Reads some number of hivemodule deployment descriptors (specified as a fileset)
 50   
  * and builds a composite registry by simply concatinating them all. The resulting
 51   
  * file is suitable for passing through an XSLT processor to create documentation.
 52   
  * 
 53   
  * <p>
 54   
  * The resulting XML file does not conform to the hivemind module deployment
 55   
  * descriptor schema.  The following changes occur:
 56   
  * <ul>
 57   
  * <li>The outermost element is &lt;registry&gt; (which contains a list of &lt;module&gt;)
 58   
  * <li>A unique id (unique within the file) is assigned to each &lt;module&gt;, 
 59   
  * &lt;configuration-point&gt;, 
 60   
  * &lt;service-point&gt;, &lt;contribution&gt;, &tl;schema&gt; and &lt;implementation&gt; (this is
 61   
  * to make it easier to generate links and anchors)
 62   
  * <li>Unqualified ids are converted to qualified ids (whereever possible).
 63   
  * </ul>
 64   
  *
 65   
  * 
 66   
  * @author Howard Lewis Ship
 67   
  */
 68   
 public class ConstructRegistry extends Task
 69   
 {
 70   
     private int _uid = 1;
 71   
 
 72   
     private File _output;
 73   
     private Path _descriptorsPath;
 74   
 
 75   
     /**
 76   
      * List of {@link org.apache.hivemind.Resource} of additional
 77   
      * descriptors to parse.
 78   
      */
 79   
     private List _resourceQueue = new ArrayList();
 80   
     private List processedModules = new ArrayList();
 81   
 
 82  7
     public void execute() throws BuildException
 83   
     {
 84  7
         if (_output == null)
 85  1
             throw new BuildException("You must specify an output file");
 86   
 
 87  6
         if (_descriptorsPath == null)
 88  1
             throw new BuildException("You must specify a set of module descriptors");
 89   
 
 90  5
         long outputStamp = _output.lastModified();
 91   
 
 92  5
         String[] paths = _descriptorsPath.list();
 93  5
         int count = paths.length;
 94   
 
 95  5
         boolean needsUpdate = false;
 96   
 
 97  5
         File[] descriptors = new File[count];
 98   
 
 99  5
         for (int i = 0; i < count; i++)
 100   
         {
 101  10
             File f = new File(paths[i]);
 102   
 
 103  10
             if (f.isDirectory())
 104  0
                 continue;
 105   
 
 106  10
             if (f.lastModified() > outputStamp)
 107  8
                 needsUpdate = true;
 108   
 
 109  10
             descriptors[i] = f;
 110   
         }
 111   
 
 112  5
         if (needsUpdate)
 113   
         {
 114  4
             Document registry = constructRegistry(descriptors);
 115   
 
 116  4
             log("Writing registry to " + _output);
 117   
 
 118  4
             writeDocument(registry, _output);
 119   
         }
 120   
 
 121   
     }
 122   
 
 123  4
     private DocumentBuilder getBuilder() throws ParserConfigurationException
 124   
     {
 125  4
         DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
 126   
 
 127  4
         factory.setIgnoringComments(true);
 128   
 
 129  4
         return factory.newDocumentBuilder();
 130   
     }
 131   
 
 132  4
     private Document constructRegistry(File[] moduleDescriptors) throws BuildException
 133   
     {
 134  4
         try
 135   
         {
 136  4
             DocumentBuilder builder = getBuilder();
 137   
 
 138  4
             Document result = builder.newDocument();
 139   
 
 140  4
             Element registry = result.createElement("registry");
 141   
 
 142  4
             result.appendChild(registry);
 143   
 
 144  4
             enqueue(moduleDescriptors);
 145   
 
 146  4
             while (!_resourceQueue.isEmpty())
 147   
             {
 148  7
                 Resource r = (Resource) _resourceQueue.remove(0);
 149   
 
 150  7
                 processResource(r, builder, registry);
 151   
             }
 152   
 
 153  4
             return result;
 154   
         }
 155   
         catch (Exception ex)
 156   
         {
 157  0
             throw new BuildException(ex);
 158   
         }
 159   
     }
 160   
 
 161  4
     private void enqueue(File[] descriptors) throws IOException
 162   
     {
 163  4
         for (int i = 0; i < descriptors.length; i++)
 164  8
             enqueue(descriptors[i]);
 165   
     }
 166   
 
 167   
     /**
 168   
      * Queues up a single descriptor which may be a raw XML file, or a JAR (containing the XML file).
 169   
      */
 170  8
     private void enqueue(File file) throws IOException
 171   
     {
 172   
         // This occurs when a bare directory is part of the classpath.
 173   
 
 174  8
         if (file == null)
 175  0
             return;
 176   
 
 177  8
         if (file.getName().endsWith(".jar"))
 178   
         {
 179  2
             enqueueJar(file);
 180  2
             return;
 181   
         }
 182   
 
 183  6
         String path = file.getPath().replace('\\', '/');
 184   
 
 185  6
         Resource r = new FileResource(path);
 186   
 
 187  6
         enqueue(r);
 188   
     }
 189   
 
 190  7
     private void enqueue(Resource resource)
 191   
     {
 192  7
         _resourceQueue.add(resource);
 193   
     }
 194   
 
 195  2
     private void enqueueJar(File jarFile) throws IOException
 196   
     {
 197  2
         URL jarRootURL = new URL("jar:" + jarFile.toURL() + "!/");
 198   
 
 199  2
         Resource jarResource = new URLResource(jarRootURL);
 200   
 
 201  2
         enqueueIfExists(jarResource, RegistryBuilder.HIVE_MODULE_XML);
 202   
     }
 203   
 
 204  2
     private void enqueueIfExists(Resource jarResource, String path)
 205   
     {
 206  2
         Resource r = jarResource.getRelativeResource(path);
 207   
 
 208  2
         if (r.getResourceURL() != null)
 209  1
             enqueue(r);
 210   
     }
 211   
 
 212  7
     private void processResource(
 213   
         Resource descriptor,
 214   
         DocumentBuilder builder,
 215   
         Element registryElement)
 216   
         throws SAXException, IOException
 217   
     {
 218  7
         log("Reading " + descriptor);
 219   
 
 220  7
         Document module = parse(builder, descriptor);
 221   
 
 222  7
         Element e = module.getDocumentElement();
 223   
 
 224  7
         if (prepareModuleForInclusion(descriptor, e))
 225   
         {
 226  7
             Document d = (Document) registryElement.getParentNode();
 227  7
             Node eCopy = d.importNode(e, true);
 228  7
             registryElement.appendChild(eCopy);
 229   
         }
 230   
 
 231   
     }
 232   
 
 233  7
     private Document parse(DocumentBuilder builder, Resource descriptor)
 234   
         throws SAXException, IOException
 235   
     {
 236  7
         return parseXML(builder, descriptor);
 237   
     }
 238   
 
 239  7
     private Document parseXML(DocumentBuilder builder, Resource descriptor)
 240   
         throws SAXException, IOException
 241   
     {
 242  7
         URL resourceURL = descriptor.getResourceURL();
 243   
 
 244  7
         InputStream rawStream = resourceURL.openStream();
 245  7
         InputStream stream = new BufferedInputStream(rawStream);
 246   
 
 247  7
         try
 248   
         {
 249  7
             InputSource source = new InputSource(stream);
 250   
 
 251  7
             return builder.parse(source);
 252   
         }
 253   
         finally
 254   
         {
 255  7
             stream.close();
 256   
         }
 257   
     }
 258   
 
 259  4
     private void writeDocument(Document document, File file) throws BuildException
 260   
     {
 261  4
         try
 262   
         {
 263  4
             OutputStream out = new FileOutputStream(file);
 264  4
             BufferedOutputStream buffered = new BufferedOutputStream(out);
 265   
 
 266  4
             writeDocument(document, buffered);
 267   
 
 268  4
             buffered.close();
 269   
         }
 270   
         catch (IOException ex)
 271   
         {
 272  0
             throw new BuildException(
 273   
                 "Unable to write registry to " + file + ": " + ex.getMessage(),
 274   
                 ex);
 275   
         }
 276   
     }
 277   
 
 278  7
     private boolean prepareModuleForInclusion(Resource currentResource, Element module)
 279   
     {
 280  7
         NamedNodeMap attributes = module.getAttributes();
 281   
 
 282  7
         String moduleId = attributes.getNamedItem("id").getNodeValue();
 283   
 
 284  7
         if (processedModules.contains(moduleId))
 285   
         {
 286  0
            log("Not including already processed module: " + moduleId);
 287  0
             return false;
 288   
         }
 289  7
         processedModules.add(moduleId);
 290   
 
 291  7
         for (int i = attributes.getLength() - 1; i >= 0; i--)
 292   
         {
 293  14
             Node attr = attributes.item(i);
 294   
 
 295  14
             String name = attr.getNodeName();
 296   
 
 297  14
             if (name.indexOf(':') > 0)
 298  0
                 attributes.removeNamedItem(name);
 299   
         }
 300   
 
 301  7
         module.setAttribute("uid", Integer.toString(_uid++));
 302   
 
 303  7
         Node node = module.getFirstChild();
 304   
 
 305  7
         while (node != null)
 306   
         {
 307  203
             if (node instanceof Element)
 308   
             {
 309  98
                 Element e = (Element) node;
 310   
 
 311  98
                 e.setAttribute("uid", Integer.toString(_uid++));
 312   
 
 313  98
                 String name = e.getTagName();
 314   
 
 315  98
                 if (name.equals("service-point")
 316   
                     || name.equals("configuration-point")
 317   
                     || name.equals("schema"))
 318  81
                     qualify(moduleId, e, "id");
 319   
 
 320  98
                 if (name.equals("configuration-point"))
 321  26
                     qualify(moduleId, e, "schema-id");
 322   
 
 323  98
                 if (name.equals("service-point"))
 324  47
                     qualify(moduleId, e, "parameters-schema-id");
 325   
 
 326   
                 // Expand local ids to fully qualified ids in extension and extend-service
 327   
 
 328  98
                 if (name.equals("contribution"))
 329  17
                     qualify(moduleId, e, "configuration-id");
 330   
 
 331  98
                 if (name.equals("implementation"))
 332  0
                     qualify(moduleId, e, "service-id");
 333   
 
 334  98
                 if (name.equals("service-point") || name.equals("implementation"))
 335  47
                     qualifyServiceIds(moduleId, e);
 336   
 
 337  98
                 if (name.equals("sub-module"))
 338  0
                     enqueueSubmodule(currentResource, e);
 339   
 
 340   
             }
 341   
 
 342  203
             node = node.getNextSibling();
 343   
         }
 344  7
         return true;
 345   
     }
 346   
 
 347  197
     private void qualify(String moduleId, Element element, String attributeName)
 348   
     {
 349  197
         String id = element.getAttribute(attributeName);
 350   
 
 351  197
         if (id == null || id.trim().length() == 0)
 352  62
             return;
 353   
 
 354  135
         if (id.indexOf('.') < 0)
 355  135
             element.setAttribute(attributeName, moduleId + "." + id);
 356   
     }
 357   
 
 358  47
     private void qualifyServiceIds(String moduleId, Element element)
 359   
     {
 360  47
         Node node = element.getFirstChild();
 361   
 
 362  47
         while (node != null)
 363   
         {
 364  149
             if (node instanceof Element)
 365   
             {
 366  51
                 Element e = (Element) node;
 367   
 
 368  51
                 String name = e.getTagName();
 369   
 
 370  51
                 if (name.equals("invoke-factory") || name.equals("interceptor"))
 371  26
                     qualify(moduleId, e, "service-id");
 372   
 
 373   
             }
 374   
 
 375  149
             node = node.getNextSibling();
 376   
         }
 377   
     }
 378   
 
 379  0
     private void enqueueSubmodule(Resource currentResource, Element e)
 380   
     {
 381  0
         String descriptor = e.getAttribute("descriptor");
 382   
 
 383  0
         Resource sub = currentResource.getRelativeResource(descriptor);
 384   
 
 385  0
         enqueue(sub);
 386   
     }
 387   
 
 388  4
     private void writeDocument(Document document, OutputStream out) throws IOException
 389   
     {
 390  4
         XMLSerializer serializer = new XMLSerializer(out, new OutputFormat(document, null, true));
 391  4
         serializer.serialize(document);
 392   
     }
 393   
 
 394  4
     public Path createDescriptors()
 395   
     {
 396  4
         _descriptorsPath = new Path(project);
 397  4
         return _descriptorsPath;
 398   
     }
 399   
 
 400  1
     public File getOutput()
 401   
     {
 402  1
         return _output;
 403   
     }
 404   
 
 405  5
     public void setOutput(File file)
 406   
     {
 407  5
         _output = file;
 408   
     }
 409   
 
 410   
 }
 411