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: FSSubject.java,v 1.2 2008/06/25 05:46:45 qcheng Exp $
026 *
027 */
028
029
030package com.sun.identity.federation.message;
031
032import org.w3c.dom.Element;
033import org.w3c.dom.Node;
034import org.w3c.dom.NodeList;
035
036import com.sun.identity.saml.common.SAMLConstants;
037import com.sun.identity.saml.common.SAMLUtils;
038import com.sun.identity.saml.common.SAMLException;
039import com.sun.identity.saml.assertion.NameIdentifier;
040import com.sun.identity.saml.assertion.Subject;
041import com.sun.identity.saml.assertion.SubjectConfirmation;
042
043import com.sun.identity.federation.message.common.IDPProvidedNameIdentifier;
044import com.sun.identity.federation.common.IFSConstants;
045import com.sun.identity.federation.message.common.FSMsgException;
046import com.sun.identity.federation.common.FSUtils;
047
048/**
049 * This class has methods to create <code>Subject</code> object.
050 *
051 * @supported.all.api
052 */
053
054public class FSSubject extends Subject {
055    protected IDPProvidedNameIdentifier _idpNameIdentifier;
056    
057    /**
058     * Default Constructor.
059     */
060    protected FSSubject() {}
061    
062    /**
063     * Constructor creates <code>FSSubject</code> object.
064     *
065     * @param nameIdentifier the <code>NameIdentifier</code> of
066     *        the subject.
067     * @param subjectConfirmation the <code>SubjectConfirmation</code>
068     *        object.
069     * @param idpNameIdentifier the <code>IDPProvidedNameIdentifier</code>
070     *         object.
071     * @throws FSMsgException if there is an error creating this object.
072     * @throws SAMLException if there is an error creating this object.
073     */
074    public FSSubject(NameIdentifier nameIdentifier,
075            SubjectConfirmation subjectConfirmation,
076            IDPProvidedNameIdentifier idpNameIdentifier)
077            throws FSMsgException, SAMLException {
078        super(nameIdentifier, subjectConfirmation);
079        _idpNameIdentifier = idpNameIdentifier;
080    }
081    
082    
083    /**
084     * Constructor creates <code>FSSubject</code> object.
085     *
086     * @param nameIdentifier the <code>NameIdentifier</code> of
087     *        the subject.
088     * @param idpNameIdentifier the <code>IDPProvidedNameIdentifier</code>
089     *         object.
090     * @throws FSMsgException if there is an error creating this object.
091     * @throws SAMLException if there is an error creating this object.
092     */
093    public FSSubject(NameIdentifier nameIdentifier,
094            IDPProvidedNameIdentifier idpNameIdentifier)
095            throws FSMsgException, SAMLException {
096        super(nameIdentifier);
097        _idpNameIdentifier = idpNameIdentifier;
098    }
099    
100    /**
101     * Constructor creates <code>FSSubject</code> object from
102     * the Document Element.
103     *
104     * @param subjectElement the Document Element
105     * @throws FSMsgException if there is an error creating this object.
106     * @throws SAMLException if there is an error creating this object.
107     */
108    public FSSubject(Element subjectElement)
109    throws FSMsgException, SAMLException {
110        FSUtils.debug.message("FSSubject(Element): Called");
111        int elementCount=0;
112        Element elt = (Element)subjectElement;
113        String rootTagName = elt.getLocalName();
114        if (rootTagName == null) {
115            if (FSUtils.debug.messageEnabled()) {
116                FSUtils.debug.message("FSSubject: local name missing");
117            }
118            throw new FSMsgException("nullInput",null) ;
119        }
120        if (!(rootTagName.equals("Subject")))  {
121            if (FSUtils.debug.messageEnabled()) {
122                FSUtils.debug.message("FSSubject: invalid root element");
123            }
124            throw new FSMsgException("invalidElement",null) ;
125        }
126        NodeList nl = subjectElement.getChildNodes();
127        int length = nl.getLength();
128        if (length == 0 ) {
129            if (FSUtils.debug.messageEnabled()) {
130                FSUtils.debug.message("FSSubject: No sub elements found");
131            }
132            throw new FSMsgException("emptyElement",null) ;
133        }
134        for (int n=0; n < length; n++) {
135            Node child = (Node)nl.item(n);
136            if (child.getNodeType() != Node.ELEMENT_NODE) {
137                continue;
138            }
139            String childName = child.getLocalName();
140            if (childName.equals("NameIdentifier"))  {
141                setNameIdentifier(new NameIdentifier((Element)child));
142                elementCount++;
143            } else if (childName.equals("SubjectConfirmation"))  {
144                setSubjectConfirmation(new SubjectConfirmation((Element)child));
145                elementCount++;
146            }else if (childName.equals("IDPProvidedNameIdentifier"))  {
147                _idpNameIdentifier =
148                        new IDPProvidedNameIdentifier((Element)child);
149                elementCount++;
150            } else {
151                if (FSUtils.debug.messageEnabled()) {
152                    FSUtils.debug.message("FSSubject: Invalid element "
153                            + "encountered.");
154                }
155                throw new FSMsgException("invalidElement",null) ;
156            }
157        }
158        if (elementCount > 3 ) {
159            if (FSUtils.debug.messageEnabled()) {
160                FSUtils.debug.message("FSSubject: more than allowed elements "
161                        + "passed");
162            }
163            throw new FSMsgException("moreElement",null) ;
164        }
165        FSUtils.debug.message("FSSubject(Element): leaving");
166    }
167    
168    /**
169     * Constructor creates <code>FSSubject</code> object.
170     *
171     * @param subjectConfirmation the <code>SubjectConfirmation</code> object.
172     * @throws SAMLException if there is an error creating this object.
173     */
174    public FSSubject(SubjectConfirmation subjectConfirmation)
175    throws SAMLException {
176        super(subjectConfirmation);
177    }
178    
179    /**
180     * Sets the Identity Provider's <code>NameIdentifier</code>.
181     *
182     * @param idpNameIdentifier the Identity Provider's
183     *        <code>NameIdentifier</code>.
184     */
185    public boolean setIDPProvidedNameIdentifier(
186            IDPProvidedNameIdentifier idpNameIdentifier) {
187        if (idpNameIdentifier == null)  {
188            if (FSUtils.debug.messageEnabled())  {
189                FSUtils.debug.message("FSSubject:null IDPProvidedNameIdentifier"
190                        + "specified");
191            }
192            return false;
193        }
194        _idpNameIdentifier = idpNameIdentifier;
195        return true;
196    }
197    
198    /**
199     * Returns the Identity Provider's <code>NameIdentifier</code>.
200     *
201     * @return the Identity Provider's <code>NameIdentifier</code>.
202     */
203    public IDPProvidedNameIdentifier getIDPProvidedNameIdentifier() {
204        return _idpNameIdentifier;
205    }
206    
207    /**
208     * Returns a String representation of this object.
209     *
210     * @return a string containing the valid XML for this element
211     * @throws FSMsgException if there is an error converting
212     *         this object ot a string.
213     */
214    public String toXMLString() throws FSMsgException {
215        String xml = this.toXMLString(true, false);
216        return xml;
217    }
218    
219    /**
220     * Returns a String representation of the Logout Response.
221     *
222     * @param includeNS : Determines whether or not the namespace qualifier
223     *        is prepended to the Element when converted
224     * @param declareNS : Determines whether or not the namespace is declared
225     *        within the Element.
226     * @return a string containing the valid XML for this element
227     * @throws FSMsgException if there is an error converting
228     *         this object ot a string.
229     */
230    public String toXMLString(boolean includeNS, boolean declareNS)
231    throws FSMsgException {
232        StringBuffer xml = new StringBuffer(3000);
233        String prefix = "";
234        String libprefix = "";
235        String uri = "";
236        String liburi = "";
237        if (includeNS) {
238            prefix = SAMLConstants.ASSERTION_PREFIX;
239            libprefix = IFSConstants.LIB_PREFIX;
240            
241        }
242        if (declareNS) {
243            uri = SAMLConstants.assertionDeclareStr;
244            liburi = IFSConstants.LIB_NAMESPACE_STRING;
245        }
246        
247        xml.append("<").append(prefix).append("Subject").append(" ").
248                append(uri).append(" ").append(liburi).append(" ").
249                append("xsi:type").
250                append("=\"").append(libprefix).append("SubjectType").
251                append("\"").
252                append(">");
253        
254        if (getNameIdentifier() != null ) {
255            xml.append(getNameIdentifier().toString(includeNS, false));
256        }
257        if (getSubjectConfirmation() != null)  {
258            xml.append(getSubjectConfirmation().toString(includeNS, false));
259        }
260        if (_idpNameIdentifier != null ) {
261            xml.append(_idpNameIdentifier.toXMLString(includeNS, false));
262        }
263        xml.append("</").append(prefix).append("Subject").append(">");
264        return xml.toString();
265    }
266}