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: ResourceOffering.java,v 1.2 2008/06/25 05:47:11 qcheng Exp $
026 *
027 */
028
029
030package com.sun.identity.liberty.ws.disco;
031
032
033import java.util.Iterator;
034import java.util.List;
035
036import org.w3c.dom.*;
037
038import com.sun.identity.liberty.ws.disco.common.DiscoConstants;
039import com.sun.identity.liberty.ws.disco.common.DiscoUtils;
040import com.sun.identity.shared.xml.XMLUtils;
041
042/**
043 * The class <code>ResourceOffering</code> associates a resource with a service
044 * instance that provides access to that resource.
045 * <p>The following schema fragment specifies the expected content within the
046 * <code>ResourceOffering</code> object.
047 * <p>
048 * <pre>
049 * &lt;complexType name="ResourceOfferingType">
050 *   &lt;complexContent>
051 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
052 *       &lt;sequence>
053 *         &lt;group ref="{urn:liberty:disco:2003-08}ResourceIDGroup"/>
054 *         &lt;element name="ServiceInstance" type="{urn:liberty:disco:2003-08}ServiceInstanceType"/>
055 *         &lt;element ref="{urn:liberty:disco:2003-08}Options" minOccurs="0"/>
056 *         &lt;element name="Abstract" type="{http://www.w3.org/2001/XMLSchema}string" minOccurs="0"/>
057 *       &lt;/sequence>
058 *       &lt;attribute name="entryID" type="{urn:liberty:disco:2003-08}IDType" />
059 *     &lt;/restriction>
060 *   &lt;/complexContent>
061 * &lt;/complexType>
062 * </pre>
063 * An example of the <code>ResourceOffering</code> is :
064 * <pre>
065 * &lt;ResourceOffering xmlns="urn:liberty:disco:2003-08">
066 *     &lt;ResourceID>http://profile-provider.com/profiles/l4m0B82k15csaUxs&lt;/ResourceID>
067 *     &lt;ServiceInstance xmlns="urn:liberty:disco:2003-08">
068 *         &lt;ServiceType>urn:liberty:idpp:2003-08&lt;/ServiceType>
069 *         &lt;ProviderID>http://profile-provider.com/&lt;/ProviderID>
070 *         &lt;Description>
071 *             &lt;SecurityMechID>urn:liberty:disco:2003-08:anonymous&lt;/SecurityMechID>
072 *             &lt;SecurityMechID>urn:liberty:security:2003-08:x509&lt;/SecurityMechID>
073 *             &lt;SecurityMechID>urn:liberty:security:2003-08:saml&lt;/SecurityMechID>
074 *             &lt;Endpoint>https://soap.profile-provider.com/soap/&lt;/Endpoint>
075 *         &lt;/Description>
076 *         &lt;Description>
077 *             &lt;SecurityMechID>urn:ietf:rfc:2246&lt;/SecurityMechID>
078 *             &lt;Endpoint>https://soap-auth.profile-provider.com/soap/&lt;/Endpoint>
079 *         &lt;/Description>
080 *      &lt;/ServiceInstance>
081 *      &lt;Options>
082 *          &lt;Option>urn:liberty:idpp&lt;/Option>
083 *          &lt;Option>urn:liberty:idpp:cn&lt;/Option>
084 *          &lt;Option>urn:liberty:idpp:can&lt;/Option>
085 *          &lt;Option>urn:liberty:idpp:can:cn&lt;/Option>
086 *      &lt;/Options>
087 *      &lt;Abstract>
088 *          This is a personal profile containing common name information. 
089 *      &lt;/Abstract>
090 * &lt;/ResourceOffering>
091 * </pre>
092 * 
093 * @supported.all.api
094 */
095public class ResourceOffering {
096
097    private String entryID = null;
098    private ResourceID resourceID = null;
099    private EncryptedResourceID encryptResID = null;
100    private ServiceInstance serviceInstance = null;
101    private List options = null;
102    private String abs = null;
103
104    /**
105     * Constructor.
106     * @param resourceID ID for the resource.
107     * @param serviceInstance service instance.
108     */
109    public ResourceOffering (ResourceID resourceID, 
110                             ServiceInstance serviceInstance)
111    {
112        this.resourceID = resourceID;
113        this.serviceInstance = serviceInstance;
114    }
115
116    /**
117     * Constructor.
118     *
119     * @param resourceID Encrypted Resource ID.
120     * @param serviceInstance service instance.
121     */
122    public ResourceOffering (EncryptedResourceID resourceID, 
123                             ServiceInstance serviceInstance)
124    {
125        encryptResID = resourceID;
126        this.serviceInstance = serviceInstance;
127    }
128
129    /**
130     * Constructor.
131     * @param elem <code>ResourceOffering</code> DOM element.
132     * @exception DiscoveryException if error occurs.
133     */
134    public ResourceOffering(Element elem) throws DiscoveryException {
135        if (elem == null) {
136            DiscoUtils.debug.message("ResourceOffering(Element): null input.");
137            throw new DiscoveryException(
138                DiscoUtils.bundle.getString("nullInput"));
139        }
140        String nodeName = null;
141        String nameSpaceURI = null;
142        if (((nodeName = elem.getLocalName()) == null) ||
143            (!nodeName.equals("ResourceOffering")) ||
144            ((nameSpaceURI = elem.getNamespaceURI()) == null) ||
145            (!nameSpaceURI.equals(DiscoConstants.DISCO_NS)))
146        {
147            DiscoUtils.debug.message("ResourceOffering(Element): wrong input");
148            throw new DiscoveryException(
149                DiscoUtils.bundle.getString("wrongInput"));
150        }
151
152        entryID = elem.getAttribute("entryID");
153
154        NodeList contentnl = elem.getChildNodes();
155        Node child;
156        for (int i = 0, length = contentnl.getLength(); i < length; i++) {
157            child = contentnl.item(i);
158            if ((nodeName = child.getLocalName()) != null) {
159                nameSpaceURI = ((Element) child).getNamespaceURI();
160                if ((nameSpaceURI == null) ||
161                    (!nameSpaceURI.equals(DiscoConstants.DISCO_NS)))
162                {
163                    if (DiscoUtils.debug.messageEnabled()) {
164                        DiscoUtils.debug.message("ResourceOffering(Element): "
165                            + "invalid namespace for node " + nodeName);
166                    }
167                    throw new DiscoveryException(
168                        DiscoUtils.bundle.getString("wrongInput"));
169                }
170                if (nodeName.equals("ResourceID")) {
171                    if ((resourceID != null) || (encryptResID != null)) {
172                        if (DiscoUtils.debug.messageEnabled()) {
173                            DiscoUtils.debug.message("ResourceOffering(Element)"
174                                + ": Included more than one ResourceIDGroup "
175                                + "element.");
176                        }
177                        throw new DiscoveryException(
178                            DiscoUtils.bundle.getString("moreResourceIDGroup"));
179                    }
180                    try {
181                        resourceID = new ResourceID((Element) child);
182                    } catch (DiscoveryException de) {
183                        DiscoUtils.debug.error("ResourceOffering(Element):",de);
184                    }
185                } else if (nodeName.equals("EncryptedResourceID")) {
186                    if ((resourceID != null) || (encryptResID != null)) {
187                        if (DiscoUtils.debug.messageEnabled()) {
188                            DiscoUtils.debug.message("ResourceOffering(Element)"
189                                + ": Included more than one ResourceIDGroup "
190                                + "element.");
191                        }
192                        throw new DiscoveryException(
193                            DiscoUtils.bundle.getString("moreResourceIDGroup"));
194                    }
195                    encryptResID = new EncryptedResourceID((Element) child);
196                } else if (nodeName.equals("ServiceInstance")) {
197                    if (serviceInstance != null) {
198                        if (DiscoUtils.debug.messageEnabled()) {
199                            DiscoUtils.debug.message("ResourceOffering(Element)"
200                                + ": Included more than one ServiceInstance.");
201                        }
202                        throw new DiscoveryException(
203                            DiscoUtils.bundle.getString("moreElement"));
204                    }
205                    serviceInstance = new ServiceInstance((Element) child);
206                } else if (nodeName.equals("Options")) {
207                    if (options != null) {
208                        if (DiscoUtils.debug.messageEnabled()) {
209                            DiscoUtils.debug.message("ResourceOffering(Element)"
210                                + ": Included more than one Options.");
211                        }
212                        throw new DiscoveryException(
213                            DiscoUtils.bundle.getString("moreElement"));
214                    }
215                    options = DiscoUtils.parseOptions((Element) child);
216                } else if (nodeName.equals("Abstract")) {
217                    if (abs != null) {
218                        if (DiscoUtils.debug.messageEnabled()) {
219                            DiscoUtils.debug.message("ResourceOffering(Element)"
220                                + ": Included more than one Abstract.");
221                        }
222                        throw new DiscoveryException(
223                            DiscoUtils.bundle.getString("moreElement"));
224                    }
225                    abs = XMLUtils.getElementValue((Element) child);
226                } else {
227                    if (DiscoUtils.debug.messageEnabled()) {
228                        DiscoUtils.debug.message("ResourceOffering(Element): "
229                            + "invalid node" + nodeName);
230                    }
231                    throw new DiscoveryException(
232                        DiscoUtils.bundle.getString("wrongInput"));
233                }
234            }
235        }            
236
237/*
238        if ((resourceID == null) && (encryptResID == null)) {
239            if (DiscoUtils.debug.messageEnabled()) {
240                DiscoUtils.debug.message("ResourceOffering(Element): missing "
241                    + "ResourceID or EncryptedResourceID element.");
242            }
243            throw new DiscoveryException(
244                DiscoUtils.bundle.getString("missingResourceIDGroup"));
245        }
246
247        if (serviceInstance == null) {
248            if (DiscoUtils.debug.messageEnabled()) {
249                DiscoUtils.debug.message("ResourceOffering(Element): missing "
250                    + "ServiceInstance element.");
251            }
252            throw new DiscoveryException(
253                DiscoUtils.bundle.getString("missingServiceInstance"));
254        }
255*/
256
257    }
258
259    /**
260     * Gets options of the resource offering, which expresses the options 
261     * available for the resource offering, that is provides hints to a
262     * potential requester whether certain data or operations may be available
263     * with a particular resource offering.
264     *
265     * @return List of options as String
266     * @see #setOptions(List)
267     */
268    public List getOptions() {
269        return options;
270    }
271
272    /**
273     * Sets options.
274     * @param options List of options as String 
275     * @see #getOptions()
276     */
277    public void setOptions(List options) {
278        this.options = options;
279    }
280
281    /**
282     * Gets encrypted resource ID.
283     *
284     * @return encrypted resource ID.
285     * @see #setEncryptedResourceID(EncryptedResourceID)
286     */
287    public EncryptedResourceID getEncryptedResourceID() {
288        return encryptResID;
289    }
290
291    /**
292     * Sets encrypted resource ID.
293     *
294     * @param resourceID <code>EncryptedResourceID</code> to be set
295     * @see #getEncryptedResourceID()
296     */
297    public void setEncryptedResourceID(EncryptedResourceID resourceID) {
298        encryptResID = resourceID;
299    }
300
301    /**
302     * Gets resource ID.
303     * @return resource ID.
304     * @see #setResourceID(ResourceID)
305     */
306    public ResourceID getResourceID() {
307        return resourceID;
308    }
309
310    /**
311     * Sets resource ID.
312     *
313     * @param resourceID resource ID. 
314     * @see #getResourceID()
315     */
316    public void setResourceID(ResourceID resourceID) {
317        this.resourceID = resourceID;
318    }
319
320    /**
321     * Gets entry ID.
322     *
323     * @return entry ID.
324     * @see #setEntryID(String)
325     */
326    public String getEntryID() {
327        return entryID;
328    }
329
330    /**
331     * Sets entry ID. 
332     * @param value of the id
333     * @see #getEntryID()
334     */
335    public void setEntryID(String value) {
336        entryID = value;
337    }
338
339    /**
340     * Gets service instance.
341     *
342     * @return service instance.
343     * @see #setServiceInstance(ServiceInstance)
344     */
345    public ServiceInstance getServiceInstance() {
346        return serviceInstance;
347    }
348
349    /**
350     * Sets service instance.
351     *
352     * @param value service instance.
353     * @see #getServiceInstance()
354     */
355    public void setServiceInstance(ServiceInstance value) {
356        serviceInstance = value;
357    }
358
359    /**
360     * Gets abstract of the resource offering 
361     *
362     * @return abstract of the resource offering.
363     * @see #setAbstract(String)
364     */
365    public String getAbstract() {
366        return abs;
367    }
368
369    /**
370     * Sets abstract.
371     *
372     * @param value abstract of the resource offering.
373     * @see #getAbstract()
374     */
375    public void setAbstract(String value) {
376        abs = value;
377    }
378
379    /**
380     * Returns string representation of object <code>ResourceOffering</code>.
381     *
382     * @return string representation
383     */
384    public String toString() {
385        // entryID, resIDgroup, service instance, options, Abstract
386        StringBuffer sb = new StringBuffer(1000);
387        sb.append("<ResourceOffering xmlns=\"").append(DiscoConstants.DISCO_NS).
388                append("\"");
389        if ((entryID != null) && entryID.length() != 0) {
390            sb.append(" entryID=\"").append(entryID).append("\"");
391        }
392        sb.append(">");
393        if (resourceID != null) {
394            sb.append(resourceID.toString());
395        } else if (encryptResID != null) {
396            sb.append(encryptResID.toString());
397        }
398        if (serviceInstance != null) {
399            sb.append(serviceInstance.toString());
400        }
401        if (options != null) {
402            sb.append("<Options>");
403            if (!options.isEmpty()) {
404                Iterator iter = options.iterator();
405                String option = null;
406                while (iter.hasNext()) {
407                    option = (String) iter.next();
408                    if ((option != null) && option.length() != 0) {
409                        sb.append("<Option>").append(option).
410                                append("</Option>");
411                    }
412                }
413            }
414            sb.append("</Options>");
415        }
416        if ((abs != null) && abs.length() != 0) {
417            sb.append("<Abstract>").append(abs).append("</Abstract>");
418        }
419        sb.append("</ResourceOffering>");
420        return sb.toString();
421    }
422}