ant-notifications mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From hi...@apache.org
Subject svn commit: r1056062 - in /ant/ivy/core/trunk/src/java/org/apache/ivy/osgi: obr/xml/OBRXMLParser.java obr/xml/OBRXMLWriter.java util/DelegetingHandler.java
Date Thu, 06 Jan 2011 20:39:13 GMT
Author: hibou
Date: Thu Jan  6 20:39:13 2011
New Revision: 1056062

URL: http://svn.apache.org/viewvc?rev=1056062&view=rev
Log:
Make the error handling more generic and put it into the utility class

Modified:
    ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/obr/xml/OBRXMLParser.java
    ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/obr/xml/OBRXMLWriter.java
    ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/util/DelegetingHandler.java

Modified: ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/obr/xml/OBRXMLParser.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/obr/xml/OBRXMLParser.java?rev=1056062&r1=1056061&r2=1056062&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/obr/xml/OBRXMLParser.java (original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/obr/xml/OBRXMLParser.java Thu Jan  6 20:39:13
2011
@@ -32,15 +32,15 @@ import org.apache.ivy.osgi.util.Version;
 import org.apache.ivy.util.Message;
 import org.apache.ivy.util.XMLHelper;
 import org.xml.sax.Attributes;
-import org.xml.sax.Locator;
+import org.xml.sax.InputSource;
 import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+import org.xml.sax.XMLReader;
+import org.xml.sax.ext.LexicalHandler;
+import org.xml.sax.helpers.XMLReaderFactory;
 
 public class OBRXMLParser {
 
-    static final String TRUE = "true";
-
-    static final String FALSE = "false";
-
     public static BundleRepoDescriptor parse(InputStream in) throws ParseException, IOException,
             SAXException {
         RepositoryHandler handler = new RepositoryHandler();
@@ -78,14 +78,11 @@ public class OBRXMLParser {
 
             repo.setName(atts.getValue(NAME));
 
-            String lastModified = atts.getValue(LASTMODIFIED);
-            if (lastModified != null) {
-                try {
-                    repo.setLastModified(Long.valueOf(lastModified));
-                } catch (NumberFormatException e) {
-                    printWarning(this, "Incorrect last modified timestamp : " + lastModified
-                            + ". It will be ignored.");
-                }
+            try {
+                Long lastModified = getOptionalLongAttribute(atts, LASTMODIFIED, null);
+                repo.setLastModified(lastModified);
+            } catch (SAXParseException e) {
+                log(Message.MSG_WARN, e.getMessage() + ". It will be ignored.");
             }
 
         }
@@ -93,6 +90,8 @@ public class OBRXMLParser {
 
     static class ResourceHandler extends DelegetingHandler {
 
+        private static final String DEFAULT_VERSION = "1.0.0";
+
         static final String RESOURCE = "resource";
 
         static final String ID = "id";
@@ -109,6 +108,10 @@ public class OBRXMLParser {
 
         public ResourceHandler() {
             super(RESOURCE);
+
+            setSkipOnError(true); // if anything bad happen in any children, just ignore
the
+                                  // resource
+
             addChild(new ResourceDescriptionHandler(), new ChildElementHandler() {
                 public void childHanlded(DelegetingHandler child) {
                     bundleInfo.setDescription(child.getBufferedChars().trim());
@@ -130,32 +133,35 @@ public class OBRXMLParser {
                     try {
                         bundleInfo.setSize(Integer.valueOf(size));
                     } catch (NumberFormatException e) {
-                        printWarning(child,
+                        log(Message.MSG_WARN,
                             "Invalid size for the bundle" + bundleInfo.getSymbolicName()
+ ": "
                                     + size + ". This size is then ignored.");
                     }
                 }
             });
             addChild(new CapabilityHandler(), new ChildElementHandler() {
-                public void childHanlded(DelegetingHandler child) {
+                public void childHanlded(DelegetingHandler child) throws SAXParseException
{
 
                     try {
                         CapabilityAdapter.adapt(bundleInfo, ((CapabilityHandler) child).capability);
                     } catch (ParseException e) {
-                        skipResourceOnError(child, "Invalid capability: " + e.getMessage());
+                        throw new SAXParseException("Invalid capability: " + e.getMessage(),
child
+                                .getLocator());
                     }
                 }
             });
             addChild(new RequireHandler(), new ChildElementHandler() {
-                public void childHanlded(DelegetingHandler child) {
+                public void childHanlded(DelegetingHandler child) throws SAXParseException
{
                     try {
                         RequirementAdapter.adapt(bundleInfo, ((RequireHandler) child).requirement);
                     } catch (UnsupportedFilterException e) {
-                        skipResourceOnError(child, "Unsupported requirement filter: "
-                                + ((RequireHandler) child).filter + " (" + e.getMessage()
+ ")");
+                        throw new SAXParseException("Unsupported requirement filter: "
+                                + ((RequireHandler) child).filter + " (" + e.getMessage()
+ ")",
+                                getLocator());
                     } catch (ParseException e) {
-                        skipResourceOnError(child,
-                            "Error in the requirement filter on the bundle: " + e.getMessage());
+                        throw new SAXParseException(
+                                "Error in the requirement filter on the bundle: " + e.getMessage(),
+                                getLocator());
                     }
                 }
             });
@@ -164,24 +170,20 @@ public class OBRXMLParser {
         protected void handleAttributes(Attributes atts) throws SAXException {
             String symbolicname = atts.getValue(SYMBOLIC_NAME);
             if (symbolicname == null) {
-                printError(this, "Resource with no symobilc name, skipping it.");
+                log(Message.MSG_ERR, "Resource with no symobilc name, skipping it.");
                 skip();
                 return;
             }
 
-            String v = atts.getValue(VERSION);
+            String v = getOptionalAttribute(atts, VERSION, DEFAULT_VERSION);
             Version version;
-            if (v == null) {
-                version = new Version(1, 0, 0, null);
-            } else {
-                try {
-                    version = new Version(v);
-                } catch (NumberFormatException e) {
-                    printError(this, "Incorrect resource version: " + v + ". The resource
"
-                            + symbolicname + " is then ignored.");
-                    skip();
-                    return;
-                }
+            try {
+                version = new Version(v);
+            } catch (NumberFormatException e) {
+                log(Message.MSG_ERR, "Incorrect resource version: " + v + ". The resource
"
+                        + symbolicname + " is then ignored.");
+                skip();
+                return;
             }
 
             bundleInfo = new BundleInfo(symbolicname, version);
@@ -190,12 +192,18 @@ public class OBRXMLParser {
             bundleInfo.setId(atts.getValue(ID));
         }
 
+        protected String getCurrentElementIdentifier() {
+            return bundleInfo.getSymbolicName() + "/" + bundleInfo.getVersion();
+        }
+
     }
 
     static class ResourceDescriptionHandler extends DelegetingHandler {
 
+        static final String DESCRIPTION = "description";
+
         public ResourceDescriptionHandler() {
-            super("description");
+            super(DESCRIPTION);
             setBufferingChar(true);
         }
 
@@ -203,16 +211,20 @@ public class OBRXMLParser {
 
     static class ResourceDocumentationHandler extends DelegetingHandler {
 
+        static final String DOCUMENTATION = "documentation";
+
         public ResourceDocumentationHandler() {
-            super("documentation");
+            super(DOCUMENTATION);
             setBufferingChar(true);
         }
     }
 
     static class ResourceLicenseHandler extends DelegetingHandler {
 
+        static final String LICENSE = "license";
+
         public ResourceLicenseHandler() {
-            super("license");
+            super(LICENSE);
             setBufferingChar(true);
         }
 
@@ -220,8 +232,10 @@ public class OBRXMLParser {
 
     static class ResourceSizeHandler extends DelegetingHandler {
 
+        static final String SIZE = "size";
+
         public ResourceSizeHandler() {
-            super("size");
+            super(SIZE);
             setBufferingChar(true);
         }
     }
@@ -239,21 +253,7 @@ public class OBRXMLParser {
             addChild(new CapabilityPropertyHandler(), new ChildElementHandler() {
                 public void childHanlded(DelegetingHandler child) {
                     String name = ((CapabilityPropertyHandler) child).name;
-                    if (name == null) {
-                        skipResourceOnError(
-                            child,
-                            "Capability property with no name on a capability "
-                                    + capability.getName());
-                        return;
-                    }
                     String value = ((CapabilityPropertyHandler) child).value;
-                    if (value == null) {
-                        skipResourceOnError(
-                            child,
-                            "Capability property with no value on a capability "
-                                    + capability.getName());
-                        return;
-                    }
                     String type = ((CapabilityPropertyHandler) child).type;
 
                     capability.addProperty(name, value, type);
@@ -262,12 +262,7 @@ public class OBRXMLParser {
         }
 
         protected void handleAttributes(Attributes atts) throws SAXException {
-            String name = atts.getValue(NAME);
-            if (name == null) {
-                skipResourceOnError(this, "Capability with no name");
-                return;
-            }
-
+            String name = getRequiredAttribute(atts, NAME);
             capability = new Capability(name);
         }
 
@@ -294,8 +289,8 @@ public class OBRXMLParser {
         }
 
         protected void handleAttributes(Attributes atts) throws SAXException {
-            name = atts.getValue(NAME);
-            value = atts.getValue(VALUE);
+            name = getRequiredAttribute(atts, NAME);
+            value = getRequiredAttribute(atts, VALUE);
             type = atts.getValue(TYPE);
         }
     }
@@ -323,11 +318,7 @@ public class OBRXMLParser {
         }
 
         protected void handleAttributes(Attributes atts) throws SAXException {
-            String name = atts.getValue(NAME);
-            if (name == null) {
-                skipResourceOnError(this, "Requirement with no name");
-                return;
-            }
+            String name = getRequiredAttribute(atts, NAME);
 
             String filterText = atts.getValue(FILTER);
             filter = null;
@@ -335,36 +326,14 @@ public class OBRXMLParser {
                 try {
                     filter = RequirementFilterParser.parse(filterText);
                 } catch (ParseException e) {
-                    skipResourceOnError(this, "Requirement with illformed filter: " + filterText);
-                    return;
+                    throw new SAXParseException("Requirement with illformed filter: " + filterText,
+                            getLocator());
                 }
             }
 
-            Boolean optional = null;
-            try {
-                optional = parseBoolean(atts, OPTIONAL);
-            } catch (ParseException e) {
-                skipResourceOnError(this,
-                    "Requirement with unrecognised optional: " + e.getMessage());
-                return;
-            }
-
-            Boolean multiple = null;
-            try {
-                multiple = parseBoolean(atts, MULTIPLE);
-            } catch (ParseException e) {
-                skipResourceOnError(this,
-                    "Requirement with unrecognised multiple: " + e.getMessage());
-                return;
-            }
-
-            Boolean extend = null;
-            try {
-                extend = parseBoolean(atts, EXTEND);
-            } catch (ParseException e) {
-                skipResourceOnError(this, "Requirement with unrecognised extend: " + e.getMessage());
-                return;
-            }
+            Boolean optional = getOptionalBooleanAttribute(atts, OPTIONAL, null);
+            Boolean multiple = getOptionalBooleanAttribute(atts, MULTIPLE, null);
+            Boolean extend = getOptionalBooleanAttribute(atts, EXTEND, null);
 
             requirement = new Requirement(name, filter);
             if (optional != null) {
@@ -380,43 +349,4 @@ public class OBRXMLParser {
 
     }
 
-    private static Boolean parseBoolean(Attributes atts, String name) throws ParseException
{
-        String v = atts.getValue(name);
-        if (v == null) {
-            return null;
-        }
-        if (TRUE.equalsIgnoreCase(v)) {
-            return Boolean.TRUE;
-        } else if (FALSE.equalsIgnoreCase(v)) {
-            return Boolean.FALSE;
-        } else {
-            throw new ParseException("Unparsable boolean value: " + v, 0);
-        }
-    }
-
-    private static void skipResourceOnError(DelegetingHandler/* <?> */handler, String
message) {
-        DelegetingHandler/* <?> */resourceHandler = handler;
-        while (!(resourceHandler instanceof ResourceHandler)) {
-            resourceHandler = resourceHandler.getParent();
-        }
-        BundleInfo bundleInfo = ((ResourceHandler) resourceHandler).bundleInfo;
-        printError(handler, message + ". The resource " + bundleInfo.getSymbolicName() +
"/"
-                + bundleInfo.getVersion() + " is then ignored.");
-        resourceHandler.skip();
-    }
-
-    private static void printError(DelegetingHandler/* <?> */handler, String message)
{
-        Message.error(getLocation(handler.getLocator()) + message);
-    }
-
-    private static void printWarning(DelegetingHandler/* <?> */handler, String message)
{
-        Message.warn(getLocation(handler.getLocator()) + message);
-    }
-
-    private static String getLocation(Locator locator) {
-        if (locator == null) {
-            return "";
-        }
-        return "[line " + locator.getLineNumber() + " col. " + locator.getColumnNumber()
+ "] ";
-    }
 }

Modified: ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/obr/xml/OBRXMLWriter.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/obr/xml/OBRXMLWriter.java?rev=1056062&r1=1056061&r2=1056062&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/obr/xml/OBRXMLWriter.java (original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/obr/xml/OBRXMLWriter.java Thu Jan  6 20:39:13
2011
@@ -196,7 +196,7 @@ public class OBRXMLWriter {
         AttributesImpl atts = new AttributesImpl();
         addAttr(atts, RequireHandler.NAME, requirement.getType());
         if ("optional".equals(requirement.getResolution())) {
-            addAttr(atts, RequireHandler.OPTIONAL, OBRXMLParser.TRUE);
+            addAttr(atts, RequireHandler.OPTIONAL, Boolean.TRUE.toString());
         }
         addAttr(atts, RequireHandler.FILTER, buildFilter(requirement));
         handler.startElement("", RequireHandler.REQUIRE, RequireHandler.REQUIRE, atts);

Modified: ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/util/DelegetingHandler.java
URL: http://svn.apache.org/viewvc/ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/util/DelegetingHandler.java?rev=1056062&r1=1056061&r2=1056062&view=diff
==============================================================================
--- ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/util/DelegetingHandler.java (original)
+++ ant/ivy/core/trunk/src/java/org/apache/ivy/osgi/util/DelegetingHandler.java Thu Jan  6
20:39:13 2011
@@ -19,8 +19,10 @@ package org.apache.ivy.osgi.util;
 
 import java.util.HashMap;
 import java.util.Iterator;
+import java.util.Locale;
 import java.util.Map;
 
+import org.apache.ivy.util.Message;
 import org.xml.sax.Attributes;
 import org.xml.sax.ContentHandler;
 import org.xml.sax.DTDHandler;
@@ -29,8 +31,10 @@ import org.xml.sax.Locator;
 import org.xml.sax.SAXException;
 import org.xml.sax.SAXParseException;
 import org.xml.sax.helpers.DefaultHandler;
+import com.sun.xml.internal.rngom.ast.util.LocatorImpl;
 
-public class DelegetingHandler extends DefaultHandler implements DTDHandler, ContentHandler,
ErrorHandler {
+
+public class DelegetingHandler implements DTDHandler, ContentHandler, ErrorHandler {
 
     private DelegetingHandler/* <?> */delegate = null;
 
@@ -46,6 +50,8 @@ public class DelegetingHandler extends D
 
     private boolean skip = false;
 
+    private boolean skipOnError = false;
+
     private StringBuffer charBuffer = new StringBuffer();
 
     private boolean bufferingChar = false;
@@ -75,6 +81,10 @@ public class DelegetingHandler extends D
         this.bufferingChar = bufferingChar;
     }
 
+    public void setSkipOnError(boolean skipOnError) {
+        this.skipOnError = skipOnError;
+    }
+
     public boolean isBufferingChar() {
         return bufferingChar;
     }
@@ -96,6 +106,16 @@ public class DelegetingHandler extends D
         return locator;
     }
 
+    /**
+     * Return an sort of identifier of the current element being parsed. It will only be
used for
+     * logging purpose.
+     * 
+     * @return an empty string by default
+     */
+    protected String getCurrentElementIdentifier() {
+        return "";
+    }
+
     public void skip() {
         skip = true;
         Iterator itHandler = saxHandlerMapping.values().iterator();
@@ -117,6 +137,30 @@ public class DelegetingHandler extends D
         }
     }
 
+    private interface SkipOnErrorCallback {
+        public void call() throws SAXException;
+    }
+
+    private void skipOnError(SkipOnErrorCallback callback) throws SAXException {
+        try {
+            callback.call();
+        } catch (SAXException e) {
+            if (skipOnError) {
+                skip();
+                Locator locator;
+                if (e instanceof SAXParseException) {
+                    locator = new LocatorImpl(null, ((SAXParseException) e).getLineNumber(),
+                            ((SAXParseException) e).getColumnNumber());
+                } else {
+                    locator = getLocator();
+                }
+                log(Message.MSG_ERR, locator, e.getMessage());
+            } else {
+                throw e;
+            }
+        }
+    }
+
     public final void startDocument() throws SAXException {
         if (skip) {
             return;
@@ -153,11 +197,15 @@ public class DelegetingHandler extends D
         // by default do nothing
     }
 
-    public final void startElement(String uri, String localName, String n, Attributes atts)
-            throws SAXException {
+    public final void startElement(final String uri, final String localName, final String
n,
+            final Attributes atts) throws SAXException {
         if (delegate != null) {
             // we are already delegating, let's continue
-            delegate.startElement(uri, localName, n, atts);
+            skipOnError(new SkipOnErrorCallback() {
+                public void call() throws SAXException {
+                    delegate.startElement(uri, localName, n, atts);
+                }
+            });
         } else {
             if (!started) { // first time called ?
                 // just for the root, check the expected element name
@@ -167,7 +215,11 @@ public class DelegetingHandler extends D
                     throw new SAXException("The root element of the parsed document '" +
localName
                             + "' didn't matched the expected one: '" + tagName + "'");
                 }
-                handleAttributes(atts);
+                skipOnError(new SkipOnErrorCallback() {
+                    public void call() throws SAXException {
+                        handleAttributes(atts);
+                    }
+                });
                 started = true;
             } else {
                 if (skip) {
@@ -177,7 +229,11 @@ public class DelegetingHandler extends D
                 // time now to delegate for a new element
                 delegate = (DelegetingHandler) saxHandlerMapping.get(localName);
                 if (delegate != null) {
-                    delegate.startElement(uri, localName, n, atts);
+                    skipOnError(new SkipOnErrorCallback() {
+                        public void call() throws SAXException {
+                            delegate.startElement(uri, localName, n, atts);
+                        }
+                    });
                 }
             }
         }
@@ -203,17 +259,26 @@ public class DelegetingHandler extends D
         // by default do nothing
     }
 
-    public final void endElement(String uri, String localName, String n) throws SAXException
{
+    public final void endElement(final String uri, final String localName, final String n)
+            throws SAXException {
         if (delegate != null) {
-            DelegetingHandler savedDelegate = delegate;
+            final DelegetingHandler savedDelegate = delegate;
             // we are already delegating, let's continue
-            delegate.endElement(uri, localName, n);
+            skipOnError(new SkipOnErrorCallback() {
+                public void call() throws SAXException {
+                    delegate.endElement(uri, localName, n);
+                }
+            });
             if (delegate == null) {
                 // we just stopped delegating, it means that the child has ended
-                ChildElementHandler childHandler = (ChildElementHandler) childHandlerMapping
+                final ChildElementHandler childHandler = (ChildElementHandler) childHandlerMapping
                         .get(localName);
                 if (childHandler != null) {
-                    childHandler.childHanlded(savedDelegate);
+                    skipOnError(new SkipOnErrorCallback() {
+                        public void call() throws SAXException {
+                            childHandler.childHanlded(savedDelegate);
+                        }
+                    });
                 }
             }
         } else {
@@ -236,7 +301,7 @@ public class DelegetingHandler extends D
 
     public static interface ChildElementHandler/* <DH extends DelegatingHandler> */{
 
-        public void childHanlded(/* DH */DelegetingHandler child);
+        public void childHanlded(/* DH */DelegetingHandler child) throws SAXParseException;
 
     }
 
@@ -449,4 +514,133 @@ public class DelegetingHandler extends D
         // by default do nothing
     }
 
+    // //////////////////////
+    // Functions related to error handling
+    // //////////////////////
+
+    protected void log(int logLevel, String message) {
+        log(logLevel, getLocator(), message);
+    }
+
+    protected void log(int logLevel, Locator/* <?> */locator, String message) {
+        Message.log(logLevel, getLocation(locator) + message);
+    }
+
+    protected static String getLocation(Locator locator) {
+        if (locator == null) {
+            return "";
+        }
+        return "[line " + locator.getLineNumber() + " col. " + locator.getColumnNumber()
+ "] ";
+    }
+
+    private void skipOnError(DelegetingHandler/* <?> */currentHandler, Class/*
+                                                                             * <? extends
+                                                                             * delegatingHandler>
+                                                                             */handlerClassToSkip,
+            String message) {
+        DelegetingHandler/* <?> */handlerToSkip = currentHandler;
+        while (!(handlerClassToSkip.isAssignableFrom(handlerToSkip.getClass()))) {
+            handlerToSkip = handlerToSkip.getParent();
+        }
+        log(Message.MSG_ERR, getLocator(), message + ". The '" + handlerToSkip.getName()
+                + "' element " + getCurrentElementIdentifier() + " is then ignored.");
+        handlerToSkip.skip();
+    }
+
+    // //////////////////////
+    // Helpers to parse the attributes
+    // //////////////////////
+
+    protected String getRequiredAttribute(Attributes atts, String name) throws SAXParseException
{
+        String value = atts.getValue(name);
+        if (value == null) {
+            throw new SAXParseException("Required attribute '" + name + "' not found", getLocator());
+        }
+        return value;
+    }
+
+    protected String getOptionalAttribute(Attributes atts, String name, String defaultValue)
{
+        String value = atts.getValue(name);
+        if (value == null) {
+            return defaultValue;
+        }
+        return value;
+    }
+
+    protected int getRequiredIntAttribute(Attributes atts, String name, Integer logLevel)
+            throws SAXParseException {
+        return parseInt(name, getRequiredAttribute(atts, name));
+    }
+
+    protected Integer getOptionalIntAttribute(Attributes atts, String name, Integer defaultValue)
+            throws SAXParseException {
+        String value = atts.getValue(name);
+        if (value == null) {
+            return defaultValue;
+        }
+        return Integer.valueOf(parseInt(name, value));
+    }
+
+    private int parseInt(String name, String value) throws SAXParseException {
+        try {
+            return Integer.parseInt(value);
+        } catch (NumberFormatException e) {
+            throw new SAXParseException("Attribute '" + name
+                    + "' is expected to be an integer but was '" + value + "' (" + e.getMessage()
+                    + ")", getLocator());
+        }
+    }
+
+    protected long getRequiredLongAttribute(Attributes atts, String name) throws SAXParseException
{
+        return parseLong(name, getRequiredAttribute(atts, name));
+    }
+
+    protected Long getOptionalLongAttribute(Attributes atts, String name, Long defaultValue)
+            throws SAXParseException {
+        String value = atts.getValue(name);
+        if (value == null) {
+            return defaultValue;
+        }
+        return Long.valueOf(parseLong(name, value));
+    }
+
+    private long parseLong(String name, String value) throws SAXParseException {
+        try {
+            return Long.parseLong(value);
+        } catch (NumberFormatException e) {
+            throw new SAXParseException("Attribute '" + name
+                    + "' is expected to be an long but was '" + value + "' (" + e.getMessage()
+                    + ")", getLocator());
+        }
+    }
+
+    protected boolean getRequiredBooleanAttribute(Attributes atts, String name)
+            throws SAXParseException {
+        return parseBoolean(name, getRequiredAttribute(atts, name));
+    }
+
+    protected Boolean getOptionalBooleanAttribute(Attributes atts, String name, Boolean defaultValue)
+            throws SAXParseException {
+        String value = atts.getValue(name);
+        if (value == null) {
+            return defaultValue;
+        }
+        return Boolean.valueOf(parseBoolean(name, value));
+    }
+
+    static final String TRUE = Boolean.TRUE.toString().toLowerCase(Locale.US);
+
+    static final String FALSE = Boolean.FALSE.toString().toLowerCase(Locale.US);
+
+    private boolean parseBoolean(String name, String value) throws SAXParseException {
+        String lowerValue = value.toLowerCase(Locale.US);
+        if (lowerValue.equals(TRUE)) {
+            return true;
+        }
+        if (lowerValue.equals(FALSE)) {
+            return false;
+        }
+        throw new SAXParseException("Attribute '" + name
+                + "' is expected to be a boolean but was '" + value + "'", getLocator());
+    }
 }



Mime
View raw message