class DigesterDefinitionsReader implements DefinitionsReader {

    public Map<String, Definition> read(Object source) {
        // This is an instance variable instead of a local variable because
        // we want to be able to call the addDefinition method to populate it.
        // But we reset the Map here, which, of course, has threading implications.
        definitions = new LinkedHashMap<String, Definition>();

        if (source == null) {
            // Perhaps we should throw an exception here.
            return null;
        }

        InputStream input;
        try {
            input = (InputStream) source;
        } catch (ClassCastException e) {
            throw new DefinitionsFactoryException(
                "Invalid source type.  Requires java.io.InputStream.", e);
        }

        try {
            // set first object in stack
            //digester.clear();
            digester.push(this);
            // parse
            digester.parse(input);

        } catch (SAXException e) {
            throw new DefinitionsFactoryException(
                "XML error reading definitions.", e);
        } catch (IOException e) {
            throw new DefinitionsFactoryException(
                "I/O Error reading definitions.", e);
        } finally {
            digester.clear();
        }

        return definitions;
    }

}

class TestDigesterDefinitionsReader {

    private final Logger log;
    private DigesterDefinitionsReader reader;

    @Test
    public void testBadXml() {

        try {
            URL configFile = this.getClass().getClassLoader().getResource(
                    "org/apache/tiles/config/malformed-defs.xml");
            assertNotNull("Config file not found", configFile);

            InputStream source = configFile.openStream();
            reader.read(source);
            fail("Should've thrown an exception.");
        } catch (DefinitionsFactoryException e) {
            // correct.
            if (log.isDebugEnabled()) {
                log.debug("Exception caught, it is OK", e);
            }
        } catch (Exception e) {
            fail("Exception reading configuration." + e);
        }
    }

}