/* * Copyright 2001-2005 Internet2 * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package gov.nih.nci.cagrid.opensaml; import java.io.InputStream; import java.lang.reflect.Constructor; import java.util.Hashtable; import javax.xml.namespace.QName; import org.apache.log4j.Category; import org.apache.log4j.NDC; import org.w3c.dom.*; import org.xml.sax.SAXException; /** * Abstract base class for all SAML conditions * * @author Scott Cantor * @created March 30, 2002 */ public abstract class SAMLCondition extends SAMLObject implements Cloneable { /** Maps SAML condition types (as XML QNames) to Java class implementations */ protected static Hashtable conditionTypeMap = new Hashtable(); /** * Registers a class to handle a specific SAML condition type when parsing XML * * @param type The condition type or element name * @param className The Java class that handles this condition */ public static void regFactory(QName type, String className) { conditionTypeMap.put(type, className); } /** * Unregisters a class to handle a specific SAML condition type when parsing XML * * @param type The condition type or element name */ public static void unregFactory(QName type) { conditionTypeMap.remove(type); } /** * Locates an implementation class for a condition and constructs it based * on the DOM provided. * * @param e The root of a DOM containing the SAML condition * @return SAMLCondition A constructed condition object * * @throws SAMLException Thrown if an error occurs while constructing the object */ public static SAMLCondition getInstance(Element e) throws SAMLException { if (e == null) throw new MalformedException(SAMLException.RESPONDER, "SAMLCondition.getInstance() given an empty DOM"); try { if (XML.isElementNamed(e,XML.SAML_NS,"Condition")) { String className = (String)conditionTypeMap.get(XML.getQNameAttribute(e, XML.XSI_NS, "type")); if (className == null) throw new UnsupportedExtensionException(SAMLException.RESPONDER, "SAMLCondition.getInstance() unable to locate an implementation of specified condition type"); Class implementation = Class.forName(className); Class[] paramtypes = {Element.class}; Object[] params = {e}; Constructor ctor = implementation.getDeclaredConstructor(paramtypes); return (SAMLCondition)ctor.newInstance(params); } else { String className = (String)conditionTypeMap.get(new QName(e.getNamespaceURI(), e.getLocalName())); if (className == null) throw new UnsupportedExtensionException(SAMLException.RESPONDER, "SAMLCondition.getInstance() unable to locate an implementation of specified condition type"); Class implementation = Class.forName(className); Class[] paramtypes = {Element.class}; Object[] params = {e}; Constructor ctor = implementation.getDeclaredConstructor(paramtypes); return (SAMLCondition)ctor.newInstance(params); } } catch (ClassNotFoundException ex) { throw new SAMLException(SAMLException.REQUESTER, "SAMLCondition.getInstance() unable to locate implementation class for condition", ex); } catch (NoSuchMethodException ex) { throw new SAMLException(SAMLException.REQUESTER, "SAMLCondition.getInstance() unable to bind to constructor for condition", ex); } catch (InstantiationException ex) { throw new SAMLException(SAMLException.REQUESTER, "SAMLCondition.getInstance() unable to build implementation object for condition", ex); } catch (IllegalAccessException ex) { throw new SAMLException(SAMLException.REQUESTER, "SAMLCondition.getInstance() unable to access implementation of condition", ex); } catch (java.lang.reflect.InvocationTargetException ex) { ex.printStackTrace(); Throwable e2 = ex.getTargetException(); if (e2 instanceof SAMLException) throw (SAMLException)e2; else throw new SAMLException(SAMLException.REQUESTER, "SAMLCondition.getInstance() caught unknown exception while building condition object: " + e2.getMessage()); } } /** * Locates an implementation class for a condition and constructs it based * on the stream provided. * * @param in The stream to deserialize from * @return SAMLCondition A constructed condition object * * @throws SAMLException Thrown if an error occurs while constructing the object */ public static SAMLCondition getInstance(InputStream in) throws SAMLException { try { Document doc = XML.parserPool.parse(in); return getInstance(doc.getDocumentElement()); } catch (SAXException e) { NDC.push("getInstance"); Category.getInstance("SAMLCondition").error("caught an exception while parsing a stream:\n" + e.getMessage()); NDC.pop(); throw new MalformedException("SAMLCondition.getInstance() caught exception while parsing a stream",e); } catch (java.io.IOException e) { NDC.push("getInstance"); Category.getInstance("SAMLCondition").error("caught an exception while parsing a stream:\n" + e.getMessage()); NDC.pop(); throw new MalformedException("SAMLCondition.getInstance() caught exception while parsing a stream",e); } } }