Author: anil.saldhana(a)jboss.com
Date: 2011-06-29 16:14:53 -0400 (Wed, 29 Jun 2011)
New Revision: 1043
Modified:
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/parsers/util/SecurityActions.java
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/parsers/util/StaxParserUtil.java
Log:
PLFED-188: add validator construction in StaxParserUtil
Modified:
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/parsers/util/SecurityActions.java
===================================================================
---
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/parsers/util/SecurityActions.java 2011-06-29
18:59:42 UTC (rev 1042)
+++
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/parsers/util/SecurityActions.java 2011-06-29
20:14:53 UTC (rev 1043)
@@ -21,6 +21,7 @@
*/
package org.picketlink.identity.federation.core.parsers.util;
+import java.net.URL;
import java.security.AccessController;
import java.security.PrivilegedAction;
@@ -37,14 +38,42 @@
* @param defaultValue
* @return
*/
- static String getSystemProperty( final String key, final String defaultValue )
+ static String getSystemProperty(final String key, final String defaultValue)
{
- return AccessController.doPrivileged( new PrivilegedAction<String>()
+ return AccessController.doPrivileged(new PrivilegedAction<String>()
{
public String run()
{
- return System.getProperty( key, defaultValue );
+ return System.getProperty(key, defaultValue);
}
- } );
+ });
}
+
+ /**
+ * Load a resource based on the passed {@link Class} classloader.
+ * Failing which try with the Thread Context CL
+ * @param clazz
+ * @param resourceName
+ * @return
+ */
+ static URL loadResource(final Class<?> clazz, final String resourceName)
+ {
+ return AccessController.doPrivileged(new PrivilegedAction<URL>()
+ {
+ public URL run()
+ {
+ URL url = null;
+ ClassLoader clazzLoader = clazz.getClassLoader();
+ url = clazzLoader.getResource(resourceName);
+
+ if (url == null)
+ {
+ clazzLoader = Thread.currentThread().getContextClassLoader();
+ url = clazzLoader.getResource(resourceName);
+ }
+
+ return url;
+ }
+ });
+ }
}
\ No newline at end of file
Modified:
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/parsers/util/StaxParserUtil.java
===================================================================
---
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/parsers/util/StaxParserUtil.java 2011-06-29
18:59:42 UTC (rev 1042)
+++
federation/trunk/picketlink-fed-core/src/main/java/org/picketlink/identity/federation/core/parsers/util/StaxParserUtil.java 2011-06-29
20:14:53 UTC (rev 1043)
@@ -22,6 +22,7 @@
package org.picketlink.identity.federation.core.parsers.util;
import java.io.InputStream;
+import java.net.URL;
import javax.xml.namespace.QName;
import javax.xml.stream.Location;
@@ -32,12 +33,18 @@
import javax.xml.stream.events.EndElement;
import javax.xml.stream.events.StartElement;
import javax.xml.stream.events.XMLEvent;
+import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.dom.DOMResult;
import javax.xml.transform.stax.StAXSource;
+import javax.xml.transform.stream.StreamSource;
+import javax.xml.validation.Schema;
+import javax.xml.validation.SchemaFactory;
+import javax.xml.validation.Validator;
+import org.apache.log4j.Logger;
import org.picketlink.identity.federation.core.exceptions.ConfigurationException;
-import org.picketlink.identity.federation.core.exceptions.ParsingException;
+import org.picketlink.identity.federation.core.exceptions.ParsingException;
import org.picketlink.identity.federation.core.saml.v2.constants.JBossSAMLConstants;
import org.picketlink.identity.federation.core.saml.v2.constants.JBossSAMLURIConstants;
import org.picketlink.identity.federation.core.saml.v2.util.DocumentUtil;
@@ -45,7 +52,9 @@
import org.picketlink.identity.federation.core.util.TransformerUtil;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
-
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
/**
* Utility for the stax based parser
@@ -53,26 +62,32 @@
* @since Feb 8, 2010
*/
public class StaxParserUtil
-{
+{
+ protected static Logger log = Logger.getLogger(StaxParserUtil.class);
+
+ protected static boolean trace = log.isTraceEnabled();
+
+ protected static Validator validator = null;
+
/**
* Bypass an entire XML element block from startElement to endElement
* @param xmlEventReader
* @param tag Tag of the XML element that we need to bypass
* @throws ParsingException
*/
- public static void bypassElementBlock( XMLEventReader xmlEventReader, String tag )
throws ParsingException
+ public static void bypassElementBlock(XMLEventReader xmlEventReader, String tag)
throws ParsingException
{
- while ( xmlEventReader.hasNext() )
+ while (xmlEventReader.hasNext())
{
- EndElement endElement = getNextEndElement( xmlEventReader );
- if( endElement == null )
+ EndElement endElement = getNextEndElement(xmlEventReader);
+ if (endElement == null)
return;
- if( StaxParserUtil.matches( endElement , tag ) )
+ if (StaxParserUtil.matches(endElement, tag))
return;
}
}
-
+
/**
* Given an {@code Attribute}, get its trimmed value
* @param attribute
@@ -84,22 +99,22 @@
str = StringUtil.getSystemPropertyAsString(str);
return str;
}
-
+
/**
* Get the Attribute value
* @param startElement
* @param tag localpart of the qname of the attribute
* @return
*/
- public static String getAttributeValue( StartElement startElement, String tag )
+ public static String getAttributeValue(StartElement startElement, String tag)
{
String result = null;
- Attribute attr = startElement.getAttributeByName( new QName( tag ));
- if( attr != null )
+ Attribute attr = startElement.getAttributeByName(new QName(tag));
+ if (attr != null)
result = getAttributeValue(attr);
return result;
}
-
+
/**
* Given that the {@code XMLEventReader} is in {@code
XMLStreamConstants.START_ELEMENT}
* mode, we parse into a DOM Element
@@ -107,44 +122,45 @@
* @return
* @throws ParsingException
*/
- public static Element getDOMElement( XMLEventReader xmlEventReader ) throws
ParsingException
+ public static Element getDOMElement(XMLEventReader xmlEventReader) throws
ParsingException
{
Transformer transformer = null;
final String JDK_TRANSFORMER_PROPERTY = "picketlink.jdk.transformer";
-
- boolean useJDKTransformer = Boolean.parseBoolean(
SecurityActions.getSystemProperty(JDK_TRANSFORMER_PROPERTY, "false" ));
+ boolean useJDKTransformer =
Boolean.parseBoolean(SecurityActions.getSystemProperty(JDK_TRANSFORMER_PROPERTY,
+ "false"));
+
try
- {
- if( useJDKTransformer )
+ {
+ if (useJDKTransformer)
{
transformer = TransformerUtil.getTransformer();
}
else
{
transformer = TransformerUtil.getStaxSourceToDomResultTransformer();
- }
+ }
Document resultDocument = DocumentUtil.createDocument();
- DOMResult domResult = new DOMResult( resultDocument );
-
- StAXSource source = new StAXSource( xmlEventReader );
+ DOMResult domResult = new DOMResult(resultDocument);
- TransformerUtil.transform( transformer, source, domResult );
+ StAXSource source = new StAXSource(xmlEventReader);
- Document doc = ( Document ) domResult.getNode();
+ TransformerUtil.transform(transformer, source, domResult);
+
+ Document doc = (Document) domResult.getNode();
return doc.getDocumentElement();
}
- catch ( ConfigurationException e )
+ catch (ConfigurationException e)
{
- throw new ParsingException( e );
+ throw new ParsingException(e);
}
- catch ( XMLStreamException e )
+ catch (XMLStreamException e)
{
- throw new ParsingException( e );
+ throw new ParsingException(e);
}
- }
+ }
/**
* Get the element text.
@@ -152,47 +168,47 @@
* @return A <b>trimmed</b> string value
* @throws ParsingException
*/
- public static String getElementText( XMLEventReader xmlEventReader ) throws
ParsingException
- {
+ public static String getElementText(XMLEventReader xmlEventReader) throws
ParsingException
+ {
String str = null;
try
{
- str = xmlEventReader.getElementText().trim();
+ str = xmlEventReader.getElementText().trim();
str = StringUtil.getSystemPropertyAsString(str);
}
catch (XMLStreamException e)
{
- throw new ParsingException( e );
+ throw new ParsingException(e);
}
return str;
}
-
+
/**
* Get the XML event reader
* @param is
* @return
*/
- public static XMLEventReader getXMLEventReader( InputStream is )
+ public static XMLEventReader getXMLEventReader(InputStream is)
{
XMLInputFactory xmlInputFactory = null;
XMLEventReader xmlEventReader = null;
- try
+ try
{
- xmlInputFactory = XMLInputFactory.newInstance();
- xmlInputFactory.setProperty( XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES,
Boolean.TRUE );
- xmlInputFactory.setProperty( XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES,
Boolean.FALSE );
- xmlInputFactory.setProperty( XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.TRUE );
- xmlInputFactory.setProperty( XMLInputFactory.IS_COALESCING, Boolean.TRUE );
-
- xmlEventReader = xmlInputFactory.createXMLEventReader(is);
- }
- catch (Exception ex)
+ xmlInputFactory = XMLInputFactory.newInstance();
+ xmlInputFactory.setProperty(XMLInputFactory.IS_REPLACING_ENTITY_REFERENCES,
Boolean.TRUE);
+ xmlInputFactory.setProperty(XMLInputFactory.IS_SUPPORTING_EXTERNAL_ENTITIES,
Boolean.FALSE);
+ xmlInputFactory.setProperty(XMLInputFactory.IS_NAMESPACE_AWARE, Boolean.TRUE);
+ xmlInputFactory.setProperty(XMLInputFactory.IS_COALESCING, Boolean.TRUE);
+
+ xmlEventReader = xmlInputFactory.createXMLEventReader(is);
+ }
+ catch (Exception ex)
{
- throw new RuntimeException(ex);
+ throw new RuntimeException(ex);
}
return xmlEventReader;
- }
-
+ }
+
/**
* Given a {@code Location}, return a formatted string
* [lineNum,colNum]
@@ -201,79 +217,79 @@
*/
public static String getLineColumnNumber(Location location)
{
- StringBuilder builder = new StringBuilder("[");
-
builder.append(location.getLineNumber()).append(",").append(location.getColumnNumber()).append("]");
- return builder.toString();
+ StringBuilder builder = new StringBuilder("[");
+
builder.append(location.getLineNumber()).append(",").append(location.getColumnNumber()).append("]");
+ return builder.toString();
}
-
+
/**
* Get the next xml event
* @param xmlEventReader
* @return
* @throws ParsingException
*/
- public static XMLEvent getNextEvent( XMLEventReader xmlEventReader ) throws
ParsingException
+ public static XMLEvent getNextEvent(XMLEventReader xmlEventReader) throws
ParsingException
{
try
{
return xmlEventReader.nextEvent();
}
- catch ( XMLStreamException e)
+ catch (XMLStreamException e)
{
- throw new ParsingException( e );
- }
+ throw new ParsingException(e);
+ }
}
-
+
/**
* Get the next {@code StartElement }
* @param xmlEventReader
* @return
* @throws ParsingException
*/
- public static StartElement getNextStartElement( XMLEventReader xmlEventReader ) throws
ParsingException
+ public static StartElement getNextStartElement(XMLEventReader xmlEventReader) throws
ParsingException
{
try
{
- while( xmlEventReader.hasNext() )
+ while (xmlEventReader.hasNext())
{
- XMLEvent xmlEvent = xmlEventReader.nextEvent();
-
- if( xmlEvent == null || xmlEvent.isStartElement() )
- return ( StartElement ) xmlEvent;
+ XMLEvent xmlEvent = xmlEventReader.nextEvent();
+
+ if (xmlEvent == null || xmlEvent.isStartElement())
+ return (StartElement) xmlEvent;
}
}
catch (XMLStreamException e)
{
- throw new ParsingException( e );
+ throw new ParsingException(e);
}
return null;
}
-
+
/**
* Get the next {@code EndElement}
* @param xmlEventReader
* @return
* @throws ParsingException
*/
- public static EndElement getNextEndElement( XMLEventReader xmlEventReader ) throws
ParsingException
+ public static EndElement getNextEndElement(XMLEventReader xmlEventReader) throws
ParsingException
{
try
{
- while( xmlEventReader.hasNext() )
+ while (xmlEventReader.hasNext())
{
- XMLEvent xmlEvent = xmlEventReader.nextEvent();
-
- if( xmlEvent == null || xmlEvent.isEndElement() )
- return ( EndElement ) xmlEvent;
+ XMLEvent xmlEvent = xmlEventReader.nextEvent();
+
+ if (xmlEvent == null || xmlEvent.isEndElement())
+ return (EndElement) xmlEvent;
}
}
catch (XMLStreamException e)
{
- throw new ParsingException( e );
+ throw new ParsingException(e);
}
return null;
}
-
+
/**
* Return the name of the start element
* @param startElement
@@ -283,76 +299,75 @@
{
return trim(startElement.getName().getLocalPart());
}
-
+
/**
* Return the name of the end element
* @param endElement
* @return
*/
- public static String getEndElementName( EndElement endElement )
+ public static String getEndElementName(EndElement endElement)
{
- return trim( endElement.getName().getLocalPart() );
+ return trim(endElement.getName().getLocalPart());
}
-
+
/**
* Given a start element, obtain the xsi:type defined
* @param startElement
* @return
* @throws RuntimeException if xsi:type is missing
*/
- public static String getXSITypeValue( StartElement startElement )
+ public static String getXSITypeValue(StartElement startElement)
{
- Attribute xsiType = startElement.getAttributeByName( new QName(
JBossSAMLURIConstants.XSI_NSURI.get(),
- JBossSAMLConstants.TYPE.get() ));
- if( xsiType == null )
- throw new RuntimeException( "xsi:type expected" );
- return StaxParserUtil.getAttributeValue( xsiType );
+ Attribute xsiType = startElement.getAttributeByName(new
QName(JBossSAMLURIConstants.XSI_NSURI.get(),
+ JBossSAMLConstants.TYPE.get()));
+ if (xsiType == null)
+ throw new RuntimeException("xsi:type expected");
+ return StaxParserUtil.getAttributeValue(xsiType);
}
-
+
/**
* Return whether the next event is going to be text
* @param xmlEventReader
* @return
* @throws ParsingException
*/
- public static boolean hasTextAhead( XMLEventReader xmlEventReader ) throws
ParsingException
+ public static boolean hasTextAhead(XMLEventReader xmlEventReader) throws
ParsingException
{
- XMLEvent event = peek( xmlEventReader );
- return event.getEventType() == XMLEvent.CHARACTERS;
+ XMLEvent event = peek(xmlEventReader);
+ return event.getEventType() == XMLEvent.CHARACTERS;
}
-
-
+
/**
* Match that the start element with the expected tag
* @param startElement
* @param tag
* @return boolean if the tags match
*/
- public static boolean matches( StartElement startElement, String tag )
+ public static boolean matches(StartElement startElement, String tag)
{
- String elementTag = getStartElementName( startElement );
- return tag.equals( elementTag );
+ String elementTag = getStartElementName(startElement);
+ return tag.equals(elementTag);
}
-
+
/**
* Match that the end element with the expected tag
* @param endElement
* @param tag
* @return boolean if the tags match
*/
- public static boolean matches( EndElement endElement, String tag )
+ public static boolean matches(EndElement endElement, String tag)
{
- String elementTag = getEndElementName( endElement );
- return tag.equals( elementTag );
+ String elementTag = getEndElementName(endElement);
+ return tag.equals(elementTag);
}
-
+
/**
* Peek at the next event
* @param xmlEventReader
* @return
* @throws ParsingException
*/
- public static XMLEvent peek( XMLEventReader xmlEventReader ) throws ParsingException
+ public static XMLEvent peek(XMLEventReader xmlEventReader) throws ParsingException
{
try
{
@@ -360,62 +375,62 @@
}
catch (XMLStreamException e)
{
- throw new ParsingException( e );
+ throw new ParsingException(e);
}
}
-
+
/**
* Peek the next {@code StartElement }
* @param xmlEventReader
* @return
* @throws ParsingException
*/
- public static StartElement peekNextStartElement( XMLEventReader xmlEventReader )
throws ParsingException
+ public static StartElement peekNextStartElement(XMLEventReader xmlEventReader) throws
ParsingException
{
try
{
- while( true )
+ while (true)
{
- XMLEvent xmlEvent = xmlEventReader.peek();
-
- if( xmlEvent == null || xmlEvent.isStartElement() )
- return ( StartElement ) xmlEvent;
- else
+ XMLEvent xmlEvent = xmlEventReader.peek();
+
+ if (xmlEvent == null || xmlEvent.isStartElement())
+ return (StartElement) xmlEvent;
+ else
xmlEvent = xmlEventReader.nextEvent();
}
}
catch (XMLStreamException e)
{
- throw new ParsingException( e );
+ throw new ParsingException(e);
}
}
-
+
/**
* Peek the next {@code EndElement}
* @param xmlEventReader
* @return
* @throws ParsingException
*/
- public static EndElement peekNextEndElement( XMLEventReader xmlEventReader ) throws
ParsingException
+ public static EndElement peekNextEndElement(XMLEventReader xmlEventReader) throws
ParsingException
{
try
{
- while( true )
+ while (true)
{
- XMLEvent xmlEvent = xmlEventReader.peek();
-
- if( xmlEvent == null || xmlEvent.isEndElement() )
- return ( EndElement ) xmlEvent;
- else
+ XMLEvent xmlEvent = xmlEventReader.peek();
+
+ if (xmlEvent == null || xmlEvent.isEndElement())
+ return (EndElement) xmlEvent;
+ else
xmlEvent = xmlEventReader.nextEvent();
}
}
catch (XMLStreamException e)
{
- throw new ParsingException( e );
+ throw new ParsingException(e);
}
}
-
+
/**
* Given a string, trim it
* @param str
@@ -424,34 +439,113 @@
*/
public static final String trim(String str)
{
- if(str == null || str.length() == 0)
+ if (str == null || str.length() == 0)
throw new IllegalArgumentException("Input str is null");
return str.trim();
}
-
+
/**
* Validate that the start element has the expected tag
* @param startElement
* @param tag
* @throws RuntimeException mismatch
*/
- public static void validate( StartElement startElement, String tag )
+ public static void validate(StartElement startElement, String tag)
{
- String elementTag = getStartElementName( startElement );
- if( !tag.equals( elementTag ))
- throw new RuntimeException( "Expecting <" + tag + ">.
Found <" + elementTag + ">" );
+ String elementTag = getStartElementName(startElement);
+ if (!tag.equals(elementTag))
+ throw new RuntimeException("Expecting <" + tag + ">. Found
<" + elementTag + ">");
}
-
+
/**
* Validate that the end element has the expected tag
* @param endElement
* @param tag
* @throws RuntimeException mismatch
*/
- public static void validate( EndElement endElement, String tag )
+ public static void validate(EndElement endElement, String tag)
{
- String elementTag = getEndElementName( endElement );
- if( !tag.equals( elementTag ))
- throw new RuntimeException( "Expecting </" + tag + ">.
Found </" + elementTag + ">" );
+ String elementTag = getEndElementName(endElement);
+ if (!tag.equals(elementTag))
+ throw new RuntimeException("Expecting </" + tag + ">.
Found </" + elementTag + ">");
}
+
+ public static Validator getSchemaValidator()
+ {
+ if (validator == null)
+ {
+ try
+ {
+ final Class<?> clazz = StaxParserUtil.class;
+
+ URL saml1Assertion = SecurityActions.loadResource(clazz,
"schema/saml/v1/saml-schema-assertion-1.0.xsd");
+ URL saml1Protocol = SecurityActions.loadResource(clazz,
"schema/saml/v1/saml-schema-protocol-1.1.xsd");
+ URL dsig = SecurityActions.loadResource(clazz,
"schema/w3c/xmldsig/xmldsig-core-schema.xsd");
+ URL xmlenc = SecurityActions.loadResource(clazz,
"schema/w3c/xmlenc/xenc-schema.xsd");
+
+ if (saml1Assertion == null)
+ throw new RuntimeException("SAML11 Assertion Schema not
found");
+
+ if (saml1Protocol == null)
+ throw new RuntimeException("SAML11 Protocol Schema not found");
+
+ if (dsig == null)
+ throw new RuntimeException("XML DSIG Schema not found");
+
+ if (xmlenc == null)
+ throw new RuntimeException("XML Enc Schema not found");
+
+ Source[] sources = new Source[]
+ {new StreamSource(dsig.openStream()), new StreamSource(xmlenc.openStream()),
+ new StreamSource(saml1Assertion.openStream()), new
StreamSource(saml1Protocol.openStream())};
+
+ /* URL schemaURL = tcl.getResource(schemaFile);
+ if (schemaURL == null)
+ throw new RuntimeException("Cannot find schema :" +
schemaFile);*/
+ SchemaFactory schemaFactory =
SchemaFactory.newInstance("http://www.w3.org/2001/XMLSchema");
+ Schema schemaGrammar = schemaFactory.newSchema(sources);
+
+ validator = schemaGrammar.newValidator();
+ validator.setErrorHandler(new ErrorHandler()
+ {
+
+ public void error(SAXParseException ex) throws SAXException
+ {
+ logException(ex);
+ throw ex;
+ }
+
+ public void fatalError(SAXParseException ex) throws SAXException
+ {
+ logException(ex);
+ throw ex;
+ }
+
+ public void warning(SAXParseException ex) throws SAXException
+ {
+ logException(ex);
+ }
+
+ private void logException(SAXParseException sax)
+ {
+ StringBuilder builder = new StringBuilder();
+
+ if (trace)
+ {
+
builder.append("[").append(sax.getLineNumber()).append(",").append(sax.getColumnNumber())
+ .append("]");
+ builder.append(":").append(sax.getLocalizedMessage());
+ log.trace(builder.toString());
+ }
+ }
+ });
+ }
+ catch (Exception e)
+ {
+ throw new RuntimeException(e);
+ }
+ }
+
+ return validator;
+ }
}
\ No newline at end of file