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: DSTModification.java,v 1.2 2008/06/25 05:47:13 qcheng Exp $
026 *
027 */
028
029
030package com.sun.identity.liberty.ws.dst;
031
032import java.text.ParseException;
033import java.util.Date;
034import java.util.List;
035import java.util.Iterator;
036import java.util.ArrayList;
037import java.util.StringTokenizer;
038import org.w3c.dom.Node;
039import org.w3c.dom.Element;
040import org.w3c.dom.NodeList;
041import com.sun.identity.shared.xml.XMLUtils;
042import com.sun.identity.shared.DateUtils;
043
044/**
045 * The <code>DSTModification</code> class represents a <code>DST</code>
046 * modification operation. 
047 * 
048 * <p>The following schema fragment specifies the expected content within
049 * the <code>DSTModification</code> object.
050 * <p>
051 * <pre>
052 * &lt;complexType>
053 *   &lt;complexContent>
054 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
055 *       &lt;sequence>
056 *         &lt;element name="Select"
057 *         type="{urn:liberty:idpp:2003-08}SelectType"/>
058 *         &lt;element name="NewData" minOccurs="0">
059 *           &lt;complexType>
060 *             &lt;complexContent>
061 *               &lt;restriction base="{http://www.w3.org/2001/XMLSchema}
062 *               anyType">
063 *                 &lt;sequence>
064 *                   &lt;any/>
065 *                 &lt;/sequence>
066 *               &lt;/restriction>
067 *             &lt;/complexContent>
068 *           &lt;/complexType>
069 *         &lt;/element>
070 *       &lt;/sequence>
071 *       &lt;attribute name="overrideAllowed"
072 *       type="{http://www.w3.org/2001/XMLSchema}boolean" />
073 *       &lt;attribute name="id" type="{http://www.w3.org/2001/XMLSchema}ID" />
074 *     &lt;/restriction>
075 *   &lt;/complexContent>
076 * &lt;/complexType>
077 * </pre>
078 * 
079 * @supported.all.api
080 */
081public class DSTModification {
082    private String id;
083    private String select;
084    private Date notChangedSince;
085    private boolean overrideAllowed = false;
086    private List newData = new ArrayList();
087    private String nameSpaceURI = null;
088    private String prefix = null;
089
090    /**
091     * Default constructor
092     */
093    public DSTModification() {}
094
095 
096    /**
097     * Constructor
098     * @param select identifies the data service to be modified
099     * @param notChangedSince  match only entries that are not changed 
100     *        after the specified date.
101     * @param serviceNS service namespace
102     */
103    public DSTModification(String select, 
104                           Date notChangedSince,
105                           String serviceNS) {
106        this.select = select;
107        this.notChangedSince = notChangedSince;
108        nameSpaceURI = serviceNS;
109    }
110
111    /**
112     * Constructor
113     *
114     * @param element <code>DOM</code> Element.
115     * @throws DSTException
116     */
117    public DSTModification(org.w3c.dom.Element element) throws DSTException{
118        if(element == null) {
119           DSTUtils.debug.error("DSTModification(element):null input");
120           throw new DSTException(DSTUtils.bundle.getString("nullInputParams"));
121        }
122        String elementName = element.getLocalName();
123        if(elementName == null || !elementName.equals("Modification")) {
124           DSTUtils.debug.error("DSTModification(element):Invalid elementName");
125           throw new DSTException(DSTUtils.bundle.getString("invalidElement"));
126        }
127        nameSpaceURI = element.getNamespaceURI();
128        prefix = element.getPrefix();
129        if(nameSpaceURI == null) {
130           DSTUtils.debug.error("DSTModification(element): Namespace is null");
131           throw new DSTException(DSTUtils.bundle.getString("noNameSpace"));
132        }
133        id = element.getAttribute("id");
134        String attr = element.getAttribute("overrideAllowed");
135        if(attr != null) {
136           overrideAllowed = Boolean.valueOf(attr).booleanValue();
137        }
138        attr = element.getAttribute("notChangedSince");
139
140        if(attr != null && attr.length() != 0) {
141            try {
142                notChangedSince = DateUtils.stringToDate(attr);
143            } catch(ParseException ex) {
144                DSTUtils.debug.error(
145                    "DSTModification(element): date can not be parsed.", ex); 
146            }
147        }
148
149        NodeList list = element.getElementsByTagNameNS(
150                        nameSpaceURI, "Select");
151
152        if((list.getLength() != 1)) {
153           DSTUtils.debug.error("DSTModification(element): Select is null" +
154           " or more than one select found.");
155           throw new DSTException(
156           DSTUtils.bundle.getString("invalidSelect"));
157        }
158        select = XMLUtils.getElementValue((Element)list.item(0));
159        if(select == null) {
160           DSTUtils.debug.error("DSTModification(element): Select is null" );
161           throw new DSTException(
162           DSTUtils.bundle.getString("invalidSelect"));
163        }
164        NodeList newDataElements = element.getElementsByTagNameNS(
165                 nameSpaceURI, "NewData"); 
166        if(newDataElements.getLength() != 1) {
167           DSTUtils.debug.error("DSTModification(element): Modification can"+
168           "not have more than one new data elements.");
169           throw new DSTException(
170           DSTUtils.bundle.getString("invalidNewData"));
171        }
172        Node newDataElement = newDataElements.item(0);
173        NodeList dataElements = newDataElement.getChildNodes();
174        int size = dataElements.getLength();
175        for(int i=0; i < size; i++) {
176           Node node = dataElements.item(0);
177           if(node.getNodeType() == Node.ELEMENT_NODE) {
178              newData.add((Element)node); 
179           }
180        }
181    }
182
183    /**
184     * Gets id attribute 
185     * @return 
186     * {@link java.lang.String}
187     */
188    public java.lang.String getId() {
189        return id;
190    } 
191
192    /**
193     * Sets id attribute
194     * @param id id attribute value to be set.
195     */
196    public void  setId(java.lang.String id) {
197        this.id = id;
198    }
199
200
201    /**
202     * Gets new data value 
203     * @return  
204     * {@link java.util.List}
205     */
206    public java.util.List getNewDataValue() {
207        return newData;
208    }
209
210    /**
211     * Sets new data value 
212     * @param value list of Data XML DOM Elements 
213     * 
214     */
215    public void setNewDataValue(java.util.List value) {
216        if(value != null && !value.isEmpty()) {
217           newData.addAll(value);
218        }
219    }
220
221    /**
222     * Checks if override is allowed
223     * @return if true, means override is allowed, false otherwise
224     */
225    public boolean isOverrideAllowed() {
226        return overrideAllowed;
227    }
228
229    /**
230     * Sets if override is allowed
231     * @param value if true, means override is allowed, false otherwise
232     */
233    public void setOverrideAllowed(boolean value) {
234        this.overrideAllowed = value;
235    }
236
237    /**
238     * Gets select element 
239     * @return the select element as string
240     */
241    public java.lang.String getSelect() {
242        return select;
243    }
244
245    /**
246     * Sets select element 
247     * @param value select value to be set  
248     */
249    public void setSelect(java.lang.String value) {
250        this.select = value;
251    }
252
253    /**
254     * Gets the <code>NotChangedSince</code> attribute.
255     * @return Date for the <code>NotChangedSince</code> attribute 
256     */
257    public Date getNotChangedSince() {
258        return notChangedSince;
259    }
260
261    /**
262     * Sets <code>NotChangedSince</code> attribute.
263     * @param value value of the <code>NotChangedSince</code> attribute to be
264     *        set.
265     */
266    public void setNotChangedSince(java.util.Date value) {
267        this.notChangedSince = value;
268    }
269
270    /**
271     * Gets the name space.
272     * @return String NameSpace String
273     */
274    public java.lang.String getNameSpaceURI() {
275        return nameSpaceURI;
276    }
277
278    /**
279     * Sets the name space.
280     * @param nameSpace NameSpace URI
281     */
282    public void setNameSpaceURI(String nameSpace) {
283        this.nameSpaceURI = nameSpace;
284    }
285
286    /**
287     * Sets the name space prefix.
288     * @param prefix NameSpace prefix.
289     */
290    public void setNameSpacePrefix(String prefix) {
291        this.prefix = prefix;
292    }
293
294    /**
295     * Gets the name space prefix.
296     * @return String NameSpace prefix.
297     */
298    public java.lang.String getNameSpacePrefix() {
299        return prefix;
300    }
301
302    /**
303     * Creates a String representation of this object.
304     * By default name space name is prepended to the element name
305     * @return String A string containing the valid XML for this element
306     */
307    public java.lang.String toString() {
308        return toString(true, false);
309    }
310
311    /**
312     * Creates a String representation of this object.
313     * @param includeNS if true prepends all elements by their Namespace prefix
314     * @param declareNS if true includes the namespace within the
315     *                  generated.
316     * @return String A string containing the valid XML for this element
317     */
318    public java.lang.String toString(boolean includeNS, boolean declareNS) {
319
320        String tempPrefix = "";
321        if(includeNS) {
322           if(prefix == null) {
323              prefix = DSTConstants.DEFAULT_NS_PREFIX;
324           }
325           tempPrefix = prefix + ":";
326        }
327        if(declareNS) {
328           if(nameSpaceURI == null) {
329              DSTUtils.debug.error("DSTModification.toString: Name Space is " +
330              "not defined");
331              return "";
332           }
333        }
334        StringBuffer sb = new StringBuffer(300);
335        sb.append("<").append(tempPrefix).append("Modification");
336        if(id != null && id.length() != 0) {
337           sb.append(" id=\"").append(id).append("\"");
338        }
339        sb.append(" overrideAllowed=\"");
340        if(overrideAllowed) {
341           sb.append("true").append("\"");
342        } else {
343           sb.append("false").append("\"");
344        }
345
346        if(notChangedSince != null) {
347            sb.append(" notChangedSince=\"")
348                .append(DateUtils.toUTCDateFormat(notChangedSince))
349                .append("\"");
350        }
351
352        if(declareNS) {
353           sb.append(" xmlns:").append(prefix).append("=\"")
354             .append(nameSpaceURI).append("\"")
355             .append(" xmlns=\"").append(nameSpaceURI).append("\"");
356        }
357        sb.append(">")
358          .append("<").append(tempPrefix).append("Select").append(">")
359          .append(appendPrefix(select, prefix)).append("</")
360          .append(tempPrefix).append("Select").append(">")
361          .append("<").append(tempPrefix).append("NewData").append(">");
362        Iterator iter = newData.iterator();
363        while(iter.hasNext()) {
364           Node node = (Node)iter.next();
365           sb.append(XMLUtils.print(node));
366        }
367        sb.append("</").append(tempPrefix).append("NewData").append(">")
368          .append("</").append(tempPrefix).append("Modification").append(">");
369
370        return sb.toString();
371    }
372
373    private String appendPrefix(String select, String prefix) {
374        if(select.indexOf(":") != -1) {
375           // prefix is already defined.
376           return select;
377        }
378        StringBuffer sb = new StringBuffer(100);
379        StringTokenizer st = new StringTokenizer(select, "/");
380        while(st.hasMoreTokens()) {
381           String temp = (String)st.nextToken();
382           temp = "/" + prefix + ":" + temp;
383           sb.append(temp);
384        }
385        return sb.toString();
386    }
387
388}