001/**
002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003 *
004 * Copyright (c) 2006 Sun Microsystems Inc. All Rights Reserved
005 *
006 * The contents of this file are subject to the terms
007 * of the Common Development and Distribution License
008 * (the License). You may not use this file except in
009 * compliance with the License.
010 *
011 * You can obtain a copy of the License at
012 * https://opensso.dev.java.net/public/CDDLv1.0.html or
013 * opensso/legal/CDDLv1.0.txt
014 * See the License for the specific language governing
015 * permission and limitations under the License.
016 *
017 * When distributing Covered Code, include this CDDL
018 * Header Notice in each file and include the License file
019 * at opensso/legal/CDDLv1.0.txt.
020 * If applicable, add the following below the CDDL Header,
021 * with the fields enclosed by brackets [] replaced by
022 * your own identifying information:
023 * "Portions Copyrighted [year] [name of copyright owner]"
024 *
025 * $Id: AdviceBase.java,v 1.2 2008/06/25 05:47:31 qcheng Exp $
026 *
027 */
028
029
030package com.sun.identity.saml.assertion;
031
032import java.util.*; 
033import org.w3c.dom.*; 
034import com.sun.identity.saml.common.SAMLUtilsCommon;
035import com.sun.identity.saml.common.SAMLConstants;
036import com.sun.identity.saml.common.SAMLException;
037import com.sun.identity.saml.common.SAMLRequesterException;
038import com.sun.identity.shared.xml.XMLUtils;
039
040/**
041 *The <code>Advice</code> element contains additional information  
042 *that the issuer wish to provide.
043 *This information MAY be ignored by applications without affecting
044 *either the semantics or validity. Advice elements MAY be specified in 
045 *an extension schema. 
046 *
047 * This class is an abstract base class for all Advice implementations and
048 * encapsulates common functionality.
049 *
050 *@supported.all.api
051 */
052public abstract class AdviceBase {
053    protected List _assertionIDRef       = null; 
054    protected List _assertion            = null; 
055    protected List _otherElements        = null; 
056    
057    /**
058     * Constructs an Advice element from an existing XML block.
059     *
060     * @param element representing a DOM tree element 
061     * @exception SAMLException if there is an error in the sender or in the
062     *            element definition.
063     */
064    public AdviceBase(Element element) throws SAMLException {
065        // Make sure the input is not null.
066        if (element == null) {
067            SAMLUtilsCommon.debug.message("Advice: null input.");
068            throw new SAMLRequesterException(
069                      SAMLUtilsCommon.bundle.getString("nullInput"));
070        }
071        // Make sure this element is an Advice element. 
072        String tag = null;
073        tag = element.getLocalName(); 
074        if ((tag == null) || (!tag.equals("Advice"))) {
075            SAMLUtilsCommon.debug.message("Advice: wrong input");
076            throw new SAMLRequesterException(
077                      SAMLUtilsCommon.bundle.getString("wrongInput"));
078        }
079        NodeList  nodes = element.getChildNodes();
080        int nodeCount = nodes.getLength();      
081        if (nodeCount > 0) {
082            for (int i = 0; i < nodeCount; i++) {
083                Node currentNode = nodes.item(i);               
084                if (currentNode.getNodeType() == Node.ELEMENT_NODE) {
085                    String tagName = currentNode.getLocalName();
086                    String tagNS = currentNode.getNamespaceURI(); 
087                    if ((tagName == null) || tagName.length() == 0 ||
088                        tagNS == null || tagNS.length() == 0) {
089                        if (SAMLUtilsCommon.debug.messageEnabled()) {
090                            SAMLUtilsCommon.debug.message("Advice: " +
091                                "The tag name or tag namespace of child" + 
092                                " element is either null or empty.");
093                        }
094                        throw new SAMLRequesterException(
095                             SAMLUtilsCommon.bundle.getString("nullInput"));
096                    }
097                    if (tagName.equals("AssertionIDReference") &&
098                        tagNS.equals(SAMLConstants.assertionSAMLNameSpaceURI)) {
099                        AssertionIDReference  assertionid = 
100                            createAssertionIDReference((Element)currentNode); 
101                        if (_assertionIDRef == null) {
102                            _assertionIDRef = new ArrayList(); 
103                        }
104                        if ((_assertionIDRef.add(assertionid))== false) {
105                            if (SAMLUtilsCommon.debug.messageEnabled()) {
106                                SAMLUtilsCommon.debug.message(
107                                              "Advice:failed to add" +
108                                              " to AssertionIDReference List.");
109                            }
110                            throw new SAMLRequesterException(
111                                  SAMLUtilsCommon.bundle.getString(
112                                  "addListError"));
113                        }
114                    } else if (tagName.equals("Assertion") &&
115                        tagNS.equals(SAMLConstants.assertionSAMLNameSpaceURI)) {
116                        AssertionBase assertion = 
117                                       createAssertion((Element)currentNode); 
118
119                        if (_assertion == null) {
120                            _assertion = new ArrayList(); 
121                        }
122                        if ((_assertion.add(assertion))== false) {
123                            if (SAMLUtilsCommon.debug.messageEnabled()) {
124                                SAMLUtilsCommon.debug.message(
125                                        "Advice:failed to add" +
126                                        " to Assertion List.");
127                            }
128                            throw new SAMLRequesterException(
129                                    SAMLUtilsCommon.bundle.getString(
130                                        "addListError"));
131                        }
132                    } else {
133                        if (_otherElements == null) 
134                            _otherElements = new ArrayList(); 
135                        if (( _otherElements.add(
136                            (Element)currentNode))==false) {
137                            if (SAMLUtilsCommon.debug.messageEnabled()) {
138                                SAMLUtilsCommon.debug.message("Advice: failed "
139                                        + "to add to other elements list.");
140                            }
141                            throw new SAMLRequesterException(
142                                SAMLUtilsCommon.bundle.getString(
143                                                 "addListError"));
144                        }
145                    }
146                }
147            } // end of for loop 
148        } // end of if (nodeCount > 0) 
149    }
150    
151    /**
152     * Constructor
153     *
154     * @param assertionidreference A List of <code>AssertionIDReference</code>.
155     * @param assertion A List of Assertion
156     * @param otherelement A List of any element defined as 
157     *        <code>any namespace="##other" processContents="lax"</code>; 
158     */
159    public AdviceBase(List assertionidreference, List assertion,
160        List otherelement) { 
161        if (assertionidreference != null && !assertionidreference.isEmpty()) {
162            if (_assertionIDRef == null) {
163                _assertionIDRef = new ArrayList(); 
164            }
165            _assertionIDRef = assertionidreference; 
166        }
167        if (assertion != null && !assertion.isEmpty()) {
168            if (_assertion == null) {
169                _assertion = new ArrayList(); 
170            }
171            _assertion = assertion; 
172        }
173        if (otherelement != null) {
174            if (_otherElements == null) {
175                _otherElements = new ArrayList(); 
176            }
177            _otherElements = otherelement; 
178        }
179    }
180
181    /**
182     * Creates appropriate Assertion Instance
183     * @param assertionElement the assertion Element
184     * @return the assertion instance
185     */
186    protected abstract AssertionBase
187        createAssertion(Element assertionElement) throws SAMLException;
188    
189    /**
190     * Creates appropriate AssertionIDReference Instance
191     * @param assertionIDRefElement the assertion ID reference Element
192     * @return the assertion ID reference instance
193     */
194    protected abstract AssertionIDReference
195        createAssertionIDReference(Element assertionIDRefElement) 
196        throws SAMLException;
197     
198    /**
199     * Returns access to the <code>AssertionIDReference</code> in this
200     * Advice element.
201     *
202     * @return A list of <code>AssertionIDReference</code> in this Advice
203     * element.
204     */
205    public List getAssertionIDReference() {
206        return _assertionIDRef; 
207    }
208    
209    /**
210     *Gets access to the Assertion in this Advice element
211     *@return A list of Assertion in this Advice element
212     */
213    public List getAssertion() {
214        return _assertion; 
215    }
216    
217    /**
218     *Gets other element contained within the Advice element  
219     *@return A list of other elements.
220     */
221    public List getOtherElement() {
222        return _otherElements; 
223    }
224   
225    /** 
226     *Creates a String representation of the <code>Advice</code> element
227     *@return A String representing the valid XML for this element
228     */
229    public String toString() {
230        return toString(true, false); 
231    }
232    
233    /**
234     * Returns a String representation of the
235     *         <code>&lt;saml:Advice&gt;</code> element.
236     *
237     * @param includeNS Determines whether or not the namespace qualifier
238     *        is prepended to the Element when converted
239     * @param declareNS Determines whether or not the namespace is declared
240     *        within the Element.
241     * @return A string containing the valid XML for this element
242     */
243    public String toString(boolean includeNS, boolean declareNS) {
244        StringBuffer result = new StringBuffer(1000);
245        Iterator iter = null; 
246        String prefix = "";
247        String uri = "";
248        if (includeNS) {
249            prefix = SAMLConstants.ASSERTION_PREFIX;
250        }
251        if (declareNS) {
252            uri = SAMLConstants.assertionDeclareStr;
253        }
254        
255        result.append("<").append(prefix).append("Advice").append(uri).
256               append(">\n");
257        if (_assertionIDRef != null && (!_assertionIDRef.isEmpty())) {
258            iter = _assertionIDRef.iterator();
259            while (iter.hasNext()) {
260                result.append(((AssertionIDReference)iter.next()).
261                              toString(includeNS, false));
262            }
263        }
264        if (_assertion != null && (!_assertion.isEmpty())) {
265            iter = _assertion.iterator();
266            while (iter.hasNext()) {
267                result.append(((AssertionBase)iter.next()).
268                                toString(includeNS, false));
269            }
270        }
271        if (_otherElements != null && !(_otherElements.isEmpty())) {
272            iter = _otherElements.iterator();  
273            while (iter.hasNext()) {
274                result.append(XMLUtils.print((Element)iter.next()));
275            }
276        }
277        result.append("</").append(prefix).append("Advice>\n");
278        return result.toString();
279    }                                                                 
280
281}