001/**
002 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003 *
004 * Copyright (c) 2007 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: StatusImpl.java,v 1.3 2008/06/25 05:48:13 qcheng Exp $
026 *
027 */
028
029package com.sun.identity.xacml.context.impl;
030
031import com.sun.identity.shared.xml.XMLUtils;
032
033import com.sun.identity.xacml.common.XACMLConstants;
034import com.sun.identity.xacml.common.XACMLException;
035import com.sun.identity.xacml.common.XACMLSDKUtils;
036
037import com.sun.identity.xacml.context.ContextFactory;
038import com.sun.identity.xacml.context.Status;
039import com.sun.identity.xacml.context.StatusCode;
040import com.sun.identity.xacml.context.StatusMessage;
041import com.sun.identity.xacml.context.StatusDetail;
042
043import java.util.ArrayList;
044import java.util.List;
045
046import org.w3c.dom.Document;
047import org.w3c.dom.Element;
048import org.w3c.dom.Node;
049import org.w3c.dom.NodeList;
050
051/**
052 * The <code>Status</code> element is a container of 
053 * one or more <code>Status</code>s issuded by authorization authority.
054 * @supported.all.api
055 * <p/>
056 * <pre>
057 *
058 * Schema:
059 * &lt;xs:complexType name="StatusType">
060 *     &lt;xs:sequence>
061 *         &lt;xs:element ref="xacml-context:StatusCode"/>
062 *         &lt;xs:element ref="xacml-context:StatusMessage" minOccurs="0"/>
063 *         &lt;xs:element ref="xacml-context:StatusDetail" minOccurs="0"/>
064 *     &lt;xs:sequence>
065 * &lt;xs:complexType>
066 */
067public class StatusImpl implements Status {
068
069    private StatusCode statusCode;
070    private StatusMessage statusMessage;
071    private StatusDetail statusDetail;
072    private boolean mutable = true;
073
074    /** 
075     * Constructs a <code>Status</code> object
076     */
077    public StatusImpl() throws XACMLException {
078    }
079
080    /** 
081     * Constructs a <code>Status</code> object from an XML string
082     *
083     * @param xml string representing a <code>Status</code> object
084     * @throws SAMLException if the XML string could not be processed
085     */
086    public StatusImpl(String xml) throws XACMLException {
087        Document document = XMLUtils.toDOMDocument(xml, XACMLSDKUtils.debug);
088        if (document != null) {
089            Element rootElement = document.getDocumentElement();
090            processElement(rootElement);
091            makeImmutable();
092        } else {
093            XACMLSDKUtils.debug.error(
094                "StatusImpl.processElement(): invalid XML input");
095            throw new XACMLException(
096                XACMLSDKUtils.xacmlResourceBundle.getString(
097                "errorObtainingElement"));
098        }
099    }
100
101    /** 
102     * Constructs a <code>Status</code> object from an XML DOM element
103     *
104     * @param element XML DOM element representing a <code>Status</code> 
105     * object
106     *
107     * @throws SAMLException if the DOM element could not be processed
108     */
109    public StatusImpl(Element element) throws XACMLException {
110        processElement(element);
111        makeImmutable();
112    }
113
114
115    /**
116     * Returns the <code>StatusCode</code> of this object
117     *
118     * @return the <code>StatusCode</code> of this object
119     */
120    public StatusCode getStatusCode() {
121        return statusCode;
122    }
123
124    /**
125     * Sets the <code>StatusCode</code> of this object
126     *
127     * @exception XACMLException if the object is immutable
128     */
129    public void setStatusCode(StatusCode statusCode) throws XACMLException {
130        if (!mutable) {
131            throw new XACMLException(
132                XACMLSDKUtils.xacmlResourceBundle.getString("objectImmutable"));
133        }
134
135        if (statusCode == null) {
136            throw new XACMLException(
137                XACMLSDKUtils.xacmlResourceBundle.getString("null_not_valid"));
138        }
139        this.statusCode = statusCode;
140    }
141
142    /**
143     * Returns the <code>StatusMessage</code> of this object
144     *
145     * @return the <code>StatusMessage</code> of this object
146     */
147    public StatusMessage getStatusMessage() {
148        return statusMessage;
149    }
150
151    /**
152     * Sets the <code>StatusMessage</code> of this object
153     *
154     * @exception XACMLException if the object is immutable
155     */
156    public void setStatusMessage(StatusMessage statusMessage) throws XACMLException {
157        if (!mutable) {
158            throw new XACMLException(
159                XACMLSDKUtils.xacmlResourceBundle.getString("objectImmutable"));
160        }
161        this.statusMessage = statusMessage;
162    }
163
164    /**
165     * Returns the <code>StatusDetail</code> of this object
166     *
167     * @return the <code>StatusDetail</code> of this object
168     */
169    public StatusDetail getStatusDetail() {
170        return statusDetail;
171    }
172
173    /**
174     * Sets the <code>StatusDetail</code> of this object
175     *
176     * @exception XACMLException if the object is immutable
177     */
178    public void setStatusDetail(StatusDetail statusDetail) throws XACMLException {
179        if (!mutable) {
180            throw new XACMLException(
181                XACMLSDKUtils.xacmlResourceBundle.getString("objectImmutable"));
182        }
183        this.statusDetail = statusDetail;
184    }
185
186
187
188   /**
189    * Returns a string representation
190    *
191    * @return a string representation
192    * @exception XACMLException if conversion fails for any reason
193    */
194    public String toXMLString() throws XACMLException {
195        return toXMLString(true, false);
196    }
197
198   /**
199    * Returns a string representation
200    * @param includeNSPrefix Determines whether or not the namespace qualifier
201    *        is prepended to the Element when converted
202    * @param declareNS Determines whether or not the namespace is declared
203    *        within the Element.
204    * @return a string representation
205    * @exception XACMLException if conversion fails for any reason
206     */
207    public String toXMLString(boolean includeNSPrefix, boolean declareNS)
208            throws XACMLException {
209        StringBuffer sb = new StringBuffer(2000);
210        String nsPrefix = "";
211        String nsDeclaration = "";
212        if (includeNSPrefix) {
213            nsPrefix = XACMLConstants.CONTEXT_NS_PREFIX + ":";
214        }
215        if (declareNS) {
216            nsDeclaration = XACMLConstants.CONTEXT_NS_DECLARATION;
217        }
218        sb.append("<").append(nsPrefix).append(XACMLConstants.STATUS).
219                append(nsDeclaration).append(">\n");
220        if (statusCode != null) {
221            sb.append(statusCode.toXMLString(includeNSPrefix, false)); 
222        }
223        if (statusMessage != null) {
224            sb.append(statusMessage.toXMLString(includeNSPrefix, false)); 
225        }
226        if (statusDetail != null) {
227            sb.append(statusDetail.toXMLString(includeNSPrefix, false));
228        }
229        sb.append("</").append(nsPrefix).append(XACMLConstants.STATUS)
230                .append(">\n");
231        return sb.toString();
232    }
233
234   /**
235    * Checks if the object is mutable
236    *
237    * @return <code>true</code> if the object is mutable,
238    *         <code>false</code> otherwise
239    */
240    public boolean isMutable() {
241        return mutable;
242    }
243    
244   /**
245    * Makes the object immutable
246    */
247    public void makeImmutable() {
248        if (mutable) {
249            if (statusCode != null) {
250                statusCode.makeImmutable();
251            }
252            if (statusMessage != null) {
253                statusMessage.makeImmutable();
254            }
255            if (statusDetail != null) {
256                statusDetail.makeImmutable();
257            }
258            mutable = false;
259        }
260    }
261
262    private void processElement(Element element) throws XACMLException {
263        if (element == null) {
264            XACMLSDKUtils.debug.error(
265                "StatusImpl.processElement(): invalid root element");
266            throw new XACMLException(XACMLSDKUtils.xacmlResourceBundle.getString(
267                "invalid_element"));
268        }
269        String elemName = element.getLocalName();
270        if (elemName == null) {
271            XACMLSDKUtils.debug.error(
272                "StatusImpl.processElement(): local name missing");
273            throw new XACMLException(XACMLSDKUtils.xacmlResourceBundle.getString(
274                "missing_local_name"));
275        }
276
277        if (!elemName.equals(XACMLConstants.STATUS)) {
278            XACMLSDKUtils.debug.error(
279                "StatusImpl.processElement(): invalid local name " + elemName);
280            throw new XACMLException(XACMLSDKUtils.xacmlResourceBundle.getString(
281                "invalid_local_name"));
282        }
283
284        NodeList nodes = element.getChildNodes();
285        int numOfNodes = nodes.getLength();
286        List childElements = new ArrayList(); 
287        int i = 0;
288        while (i < numOfNodes) { 
289            Node child = (Node) nodes.item(i);
290            if (child.getNodeType() == Node.ELEMENT_NODE) {
291                childElements.add(child);
292            }
293           i++;
294        }
295        int childCount = childElements.size();
296        if (childCount < 1) {
297            XACMLSDKUtils.debug.error(
298                "StatusImpl.processElement(): invalid child element count: " 
299                        + childCount);
300            throw new XACMLException(XACMLSDKUtils.xacmlResourceBundle.getString(
301                "invalid_child_count")); //FIXME: add i18n key
302        } else if (childCount > 3) {
303            XACMLSDKUtils.debug.error(
304                "StatusImpl.processElement(): invalid child element count: " 
305                        + childCount);
306            throw new XACMLException(XACMLSDKUtils.xacmlResourceBundle.getString(
307                "invalid_child_count")); //FIXME: add i18n key
308        }
309        Element firstChild = (Element)childElements.get(0);
310        String firstChildName = firstChild.getLocalName();
311        if (firstChildName.equals(XACMLConstants.STATUS_CODE)) {
312            statusCode =  ContextFactory.getInstance()
313                    .createStatusCode(firstChild);
314        } else {
315            XACMLSDKUtils.debug.error(
316                "StatusImpl.processElement(): invalid first child element: " 
317                        + firstChildName);
318            throw new XACMLException(XACMLSDKUtils.xacmlResourceBundle.getString(
319                "invalid_first_child")); //FIXME: add i18n key
320        }
321        //process statusMessage element
322        if (childCount > 1) {
323            Element secondChild = (Element)childElements.get(1);
324            String secondChildName = secondChild.getLocalName();
325            if (secondChildName.equals(
326                        XACMLConstants.STATUS_MESSAGE)) {
327                statusMessage =  ContextFactory.getInstance()
328                        .createStatusMessage(secondChild);
329
330            } else if (secondChildName.equals(
331                    XACMLConstants.STATUS_DETAIL)) {
332                if (childCount == 2) {
333                    statusDetail =  ContextFactory.getInstance()
334                            .createStatusDetail(secondChild);
335                } else {
336                    XACMLSDKUtils.debug.error(
337                        "StatusImpl.processElement(): "
338                                + "invalid second child element: " 
339                                + secondChildName);
340                    throw new XACMLException(
341                        XACMLSDKUtils.xacmlResourceBundle.getString(
342                        "invalid_second_child")); //FIXME: add i18n key
343                }
344            }
345            if (childCount > 2) {
346                Element thirdChild = (Element)childElements.get(2);
347                String thirdChildName = thirdChild.getLocalName();
348                if (thirdChildName.equals(
349                            XACMLConstants.STATUS_DETAIL)) {
350                    statusDetail =  ContextFactory.getInstance()
351                            .createStatusDetail(thirdChild);
352                } else {
353                    XACMLSDKUtils.debug.error(
354                        "StatusImpl.processElement(): invalid third child element: " 
355                                + thirdChildName);
356                    throw new XACMLException(
357                        XACMLSDKUtils.xacmlResourceBundle.getString(
358                        "invalid_third_child")); //FIXME: add i18n key
359                }
360            }
361        }
362    }
363
364}




























































Copyright © 2010-2017, ForgeRock All Rights Reserved.