Clover coverage report - Ledge Container - SNAPSHOT
Coverage timestamp: Fri Nov 17 2006 05:16:03 CET
file stats: LOC: 158   Methods: 4
NCLOC: 88   Classes: 1
 
 Source file Conditionals Statements Methods TOTAL
LedgeContainerBuilder.java - 72% 75% 72.4%
coverage coverage
 1    //
 2    // Copyright (c) 2003,2004 , Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.
 3    // All rights reserved.
 4    //
 5    // Redistribution and use in source and binary forms, with or without modification,
 6    // are permitted provided that the following conditions are met:
 7    //
 8    // * Redistributions of source code must retain the above copyright notice,
 9    // this list of conditions and the following disclaimer.
 10    // * Redistributions in binary form must reproduce the above copyright notice,
 11    // this list of conditions and the following disclaimer in the documentation
 12    // and/or other materials provided with the distribution.
 13    // * Neither the name of the Caltha - Gajda, Krzewski, Mach, Potempski Sp.J.
 14    // nor the names of its contributors may be used to endorse or promote products
 15    // derived from this software without specific prior written permission.
 16    //
 17    // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 18    // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 19    // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
 20    // IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
 21    // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
 22    // BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
 23    // OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
 24    // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 25    // ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 26    // POSSIBILITY OF SUCH DAMAGE.
 27    //
 28    package org.objectledge.pico.xml;
 29   
 30    import java.io.IOException;
 31    import java.net.URL;
 32   
 33    import javax.xml.parsers.SAXParserFactory;
 34   
 35    import org.nanocontainer.integrationkit.PicoCompositionException;
 36    import org.nanocontainer.script.NanoContainerMarkupException;
 37    import org.nanocontainer.script.ScriptedContainerBuilder;
 38    import org.objectledge.filesystem.FileSystem;
 39    import org.objectledge.xml.XMLValidator;
 40    import org.picocontainer.PicoContainer;
 41    import org.xml.sax.EntityResolver;
 42    import org.xml.sax.InputSource;
 43    import org.xml.sax.SAXParseException;
 44    import org.xml.sax.XMLReader;
 45   
 46    /**
 47    * <code>LedgeContainerBuilder</code> has the same functionality as the Nano-provided
 48    * <code>XMLFrontEnd</code> but with a few changes and additions.
 49    *
 50    * <ul>
 51    * <li>{@link org.picocontainer.defaults.ComponentAdapterFactory}
 52    * may be declared for the top level container</li>
 53    * <li>{@link org.picocontainer.defaults.ComponentAdapterFactory}
 54    * may be declared using tags, with nesting (DecoratingComponentAdapterFactoryPatern)</li>
 55    * <li>for both components and component-parameters, both string and class keys may be used</li>
 56    * <li>{@link org.objectledge.pico.SequenceParameter}s are supported</li>
 57    * <li>The composition definition (file) is checked against a
 58    * <a href="http://relaxng.org/">RelaxNG schema</a>.</li>
 59    * </ul>
 60    *
 61    * <h3>Related</h3>
 62    * <ul>
 63    * <li>{@link ./container.rng}</li>
 64    * <li><a href="http://objectledge.org/viewcvs.cgi/ledge-container/src/test/resources/container1/config/container.xml?rev=HEAD&content-type=text/vnd.viewcvs-markup">Example configuration file</a></li>
 65    * </ul>
 66    *
 67    * @author <a href="mailto:rafal@caltha.pl">Rafal Krzewski </a>
 68    * @version $Id: LedgeContainerBuilder.java,v 1.2 2005/07/07 08:30:01 zwierzem Exp $
 69    */
 70    public class LedgeContainerBuilder
 71    extends ScriptedContainerBuilder
 72    {
 73    /** Location of the container composition schema. */
 74    public static final String SCHEMA_PATH = "org/objectledge/pico/xml/container.rng";
 75   
 76    private final URL scriptURL;
 77    private final ClassLoader classLoader;
 78    private final SAXParserFactory parserFactory;
 79   
 80    /**
 81    * Creates new LedgeContainerBuilder instance.
 82    *
 83    * @param configURL the URL of XML based container configuration file
 84    * @param classLoader the class loader.
 85    */
 86  258 public LedgeContainerBuilder(final URL configURL, final ClassLoader classLoader)
 87    {
 88  258 super(configURL, classLoader);
 89  258 this.scriptURL = configURL;
 90  258 this.classLoader = classLoader;
 91  258 try
 92    {
 93  258 parserFactory = SAXParserFactory.newInstance();
 94  258 parserFactory.setNamespaceAware(true);
 95    }
 96    catch(Exception e)
 97    {
 98  0 throw new NanoContainerMarkupException(e);
 99    }
 100    }
 101   
 102    /**
 103    * {@inheritDoc}
 104    */
 105  258 protected PicoContainer createContainerFromScript(PicoContainer parentContainer,
 106    Object assemblyScope)
 107    {
 108  258 validate(scriptURL, parentContainer);
 109  258 CompositionContentHandler handler = new CompositionContentHandler(
 110    parentContainer, classLoader, assemblyScope);
 111  258 try
 112    {
 113  258 XMLReader reader = parserFactory.newSAXParser().getXMLReader();
 114  258 reader.setEntityResolver(new EntityResolver()
 115    {
 116  0 public InputSource resolveEntity(String publicId, String systemId)
 117    throws IOException
 118    {
 119  0 URL url = new URL(scriptURL, systemId);
 120  0 return new InputSource(url.openStream());
 121    }
 122    });
 123  258 reader.setContentHandler(handler);
 124  258 reader.parse(new InputSource(scriptURL.toString()));
 125  258 return handler.getResult();
 126    }
 127    catch(SAXParseException e)
 128    {
 129  0 throw new PicoCompositionException("parse error " + e.getMessage() + " in " +
 130    e.getSystemId() + " at line " + e.getLineNumber(), e);
 131    }
 132    catch(Exception e)
 133    {
 134  0 throw new PicoCompositionException("error processing " + scriptURL, e);
 135    }
 136    }
 137   
 138  258 private void validate(URL scriptURL, PicoContainer container)
 139    {
 140  258 XMLValidator validator = (XMLValidator)container.getComponentInstance(XMLValidator.class);
 141  258 FileSystem fileSystem = (FileSystem)container.getComponentInstance(FileSystem.class);
 142   
 143  258 try
 144    {
 145  258 validator.validate(scriptURL, fileSystem.getResource(SCHEMA_PATH));
 146    }
 147    catch(SAXParseException e)
 148    {
 149  0 throw new PicoCompositionException("parse error " + e.getMessage() + " in " +
 150    e.getSystemId() + " at line " + e.getLineNumber(), e);
 151    }
 152    catch(Exception e)
 153    {
 154  0 throw new PicoCompositionException("composition file " + scriptURL +
 155    " is missing or invalid", e);
 156    }
 157    }
 158    }