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: StatusMessageImpl.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;
036import com.sun.identity.xacml.context.StatusMessage;
037
038import org.w3c.dom.Document;
039import org.w3c.dom.Element;
040import org.w3c.dom.Node;
041
042/**
043 * The <code>StatusMessage</code> element is a container of 
044 * one or more <code>StatusMessage</code>s issuded by authorization authority.
045 * @supported.all.api
046 * <p/>
047 * <pre>
048 *
049 * Schema:
050 *  &lt;xs:element name="StatusMessage" type="xs:string"/>
051 * </pre>
052 */
053public class StatusMessageImpl implements StatusMessage {
054
055    private boolean mutable = true;
056    private String value = null;
057
058    /** 
059     * Constructs a <code>StatusMessage</code> object
060     */
061    public StatusMessageImpl() throws XACMLException {
062    }
063
064    /** 
065     * Constructs a <code>StatusMessage</code> object from an XML string
066     *
067     * @param xml string representing a <code>StatusMessage</code> object
068     * @throws SAMLException if the XML string could not be processed
069     */
070    public StatusMessageImpl(String xml) throws XACMLException {
071        Document document = XMLUtils.toDOMDocument(xml, XACMLSDKUtils.debug);
072        if (document != null) {
073            Element rootElement = document.getDocumentElement();
074            processElement(rootElement);
075            makeImmutable();
076        } else {
077            XACMLSDKUtils.debug.error(
078                "StatusMessageImpl.processElement(): invalid XML input");
079            throw new XACMLException(XACMLSDKUtils.xacmlResourceBundle.getString(
080                "errorObtainingElement"));
081        }
082    }
083
084    /** 
085     * Constructs a <code>StatusMessage</code> object from an XML DOM element
086     *
087     * @param element XML DOM element representing a <code>StatusMessage</code> 
088     * object
089     *
090     * @throws SAMLException if the DOM element could not be processed
091     */
092    public StatusMessageImpl(Element element) throws XACMLException {
093        processElement(element);
094        makeImmutable();
095    }
096
097    /**
098     * Returns the <code>value</code> of this object
099     *
100     * @return the <code>value</code> of this object
101     */
102    public String getValue() {
103        return value;
104    }
105
106    /**
107     * Sets the <code>value</code> of this object
108     *
109     * @exception XACMLException if the object is immutable
110     */
111    public void setValue(String value) throws XACMLException {
112        if (!mutable) {
113            throw new XACMLException(
114                XACMLSDKUtils.xacmlResourceBundle.getString("objectImmutable"));
115        }
116
117        if (value == null) {
118            throw new XACMLException(
119                XACMLSDKUtils.xacmlResourceBundle.getString("null_not_valid")); //i18n
120        }
121
122        if (!XACMLSDKUtils.isValidStatusMessage(value)) {
123            throw new XACMLException(
124                XACMLSDKUtils.xacmlResourceBundle.getString("invalid_value")); //i18n
125        }
126        this.value = value;
127    }
128
129    /**
130    * Returns a string representation
131    *
132    * @return a string representation
133    * @exception XACMLException if conversion fails for any reason
134    */
135    public String toXMLString() throws XACMLException {
136        return toXMLString(true, false);
137    }
138
139   /**
140    * Returns a string representation
141    * @param includeNSPrefix Determines whether or not the namespace qualifier
142    *        is prepended to the Element when converted
143    * @param declareNS Determines whether or not the namespace is declared
144    *        within the Element.
145    * @return a string representation
146    * @exception XACMLException if conversion fails for any reason
147     */
148    public String toXMLString(boolean includeNSPrefix, boolean declareNS)
149            throws XACMLException {
150        StringBuffer sb = new StringBuffer(2000);
151        String nsDeclaration = "";
152        String nsPrefix = "";
153        if (declareNS) {
154            nsDeclaration = XACMLConstants.CONTEXT_NS_DECLARATION;
155        }
156        if (includeNSPrefix) {
157            nsPrefix = XACMLConstants.CONTEXT_NS_PREFIX + ":";
158        }
159        sb.append("<").append(nsPrefix)
160                .append(XACMLConstants.STATUS_MESSAGE)
161                .append(nsDeclaration).append(">")
162                .append(value)
163                .append("</").append(nsPrefix)
164                .append(XACMLConstants.STATUS_MESSAGE)
165                .append(">\n");
166        return sb.toString();
167    }
168
169   /**
170    * Checks if the object is mutable
171    *
172    * @return <code>true</code> if the object is mutable,
173    *         <code>false</code> otherwise
174    */
175    public boolean isMutable() {
176        return mutable;
177    }
178    
179   /**
180    * Makes the object immutable
181    */
182    public void makeImmutable() {
183        mutable = false;
184    }
185
186    private void processElement(Element element) throws XACMLException {
187        if (element == null) {
188            XACMLSDKUtils.debug.error(
189                "StatusMessageImpl.processElement(): invalid root element");
190            throw new XACMLException(XACMLSDKUtils.xacmlResourceBundle.getString(
191                "invalid_element"));
192        }
193        String elemName = element.getLocalName();
194        if (elemName == null) {
195            XACMLSDKUtils.debug.error(
196                "StatusMessageImpl.processElement(): local name missing");
197            throw new XACMLException(XACMLSDKUtils.xacmlResourceBundle.getString(
198                "missing_local_name"));
199        }
200
201        if (!elemName.equals(XACMLConstants.STATUS_MESSAGE)) {
202            XACMLSDKUtils.debug.error(
203                    "StatusMessageImpl.processElement(): invalid local name " 
204                    + elemName);
205            throw new XACMLException(XACMLSDKUtils.xacmlResourceBundle.getString(
206                    "invalid_local_name"));
207        }
208        String elementValue = element.getTextContent();
209        if (elementValue == null) {
210            throw new XACMLException(
211                    XACMLSDKUtils.xacmlResourceBundle.getString("null_not_valid"));
212        }
213        if (!XACMLSDKUtils.isValidStatusMessage(elementValue.trim())) {
214            throw new XACMLException(
215                    XACMLSDKUtils.xacmlResourceBundle.getString("invalid_value"));
216        } else {
217            this.value = elementValue;
218        }
219    }
220
221}