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: ServiceInstance.java,v 1.2 2008/06/25 05:47:11 qcheng Exp $
026 *
027 */
028
029
030package com.sun.identity.liberty.ws.disco;
031
032import java.util.Iterator;
033import java.util.List;
034import java.util.ArrayList;
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>ServiceInstance</code> describes a web service at a 
044 * distinct protocol endpoint.
045 * <p>The following schema fragment specifies the expected content 
046 * within the <code>ServiceInstance</code> object.
047 * <p>
048 * <pre>
049 * &lt;xs:element name="ServiceInstance" type="ServiceInstanceType"/>
050 * &lt;complexType name="ServiceInstanceType">
051 *   &lt;complexContent>
052 *     &lt;restriction base="{http://www.w3.org/2001/XMLSchema}anyType">
053 *       &lt;sequence>
054 *         &lt;element ref="{urn:liberty:disco:2003-08}ServiceType"/>
055 *         &lt;element name="ProviderID" type="{urn:liberty:metadata:2003-08}entityIDType"/>
056 *         &lt;element name="Description" type="{urn:liberty:disco:2003-08}DescriptionType" maxOccurs="unbounded"/>
057 *       &lt;/sequence>
058 *     &lt;/restriction>
059 *   &lt;/complexContent>
060 * &lt;/complexType>
061 * </pre>
062 * 
063 * @supported.all.api
064 */
065public class ServiceInstance {
066
067    private String serviceType = null;
068    private String providerID = null;
069    private List descriptions = null;
070
071    /**
072     * Default Constructor.
073     */
074    public ServiceInstance (){}
075
076    /**
077     * Constructor
078     * @param serviceType service type
079     * @param providerID provider ID
080     * @param descriptions List of Description objects
081     */
082    public ServiceInstance (String serviceType,
083                            String providerID,
084                            java.util.List descriptions)
085    {
086        this.serviceType = serviceType;
087        this.providerID = providerID;
088        this.descriptions = descriptions;
089    }
090
091    /**
092     * Constructor.
093     * @param elem <code>ServiceInstance</code> DOM element.
094     * @exception DiscoveryException if error occurs.
095     */
096    public ServiceInstance(Element elem) throws DiscoveryException {
097        if (elem == null) {
098            DiscoUtils.debug.message("ServiceInstance(Element): null input.");
099            throw new DiscoveryException(
100                DiscoUtils.bundle.getString("nullInput"));
101        }
102        String nodeName;
103        String nameSpaceURI;
104        if (((nodeName = elem.getLocalName()) == null) ||
105            (!nodeName.equals("ServiceInstance")) ||
106            ((nameSpaceURI = elem.getNamespaceURI()) == null) ||
107            (!nameSpaceURI.equals(DiscoConstants.DISCO_NS)))
108        {
109            DiscoUtils.debug.message("ServiceInstance(Element): wrong input");
110            throw new DiscoveryException(
111                DiscoUtils.bundle.getString("wrongInput"));
112        }
113
114        NodeList contentnl = elem.getChildNodes();
115        Node child;
116        for (int i = 0, length = contentnl.getLength(); i < length; i++) {
117            child = contentnl.item(i);
118            if ((nodeName = child.getLocalName()) != null) {
119                nameSpaceURI = ((Element) child).getNamespaceURI();
120                if ((nameSpaceURI == null) ||
121                    (!nameSpaceURI.equals(DiscoConstants.DISCO_NS)))
122                {
123                    if (DiscoUtils.debug.messageEnabled()) {
124                        DiscoUtils.debug.message("ServiceInstance(Element): "
125                            + "invalid namespace for node " + nodeName);
126                    }
127                    throw new DiscoveryException(
128                        DiscoUtils.bundle.getString("wrongInput"));
129                }
130                if (nodeName.equals("ServiceType")) {
131                    if (serviceType != null) {
132                        if (DiscoUtils.debug.messageEnabled()) {
133                            DiscoUtils.debug.message("ServiceInstance(Element)"
134                                + ": Included more than one ServiceType "
135                                + "element.");
136                        }
137                        throw new DiscoveryException(
138                            DiscoUtils.bundle.getString("moreElement"));
139                    }
140                    serviceType = XMLUtils.getElementValue((Element) child);
141                    if ((serviceType == null) || (serviceType.length() == 0)) {
142                        if (DiscoUtils.debug.messageEnabled()) {
143                            DiscoUtils.debug.message("ServiceInstance(Element)"
144                                + ": missing ServiceType element value.");
145                        }
146                        throw new DiscoveryException(
147                            DiscoUtils.bundle.getString("emptyElement"));
148                    }
149                } else if (nodeName.equals("ProviderID")) {
150                    if (providerID != null) {
151                        if (DiscoUtils.debug.messageEnabled()) {
152                            DiscoUtils.debug.message("ServiceInstance(Element)"
153                                + ": Included more than one ProviderID.");
154                        }
155                        throw new DiscoveryException(
156                            DiscoUtils.bundle.getString("moreElement"));
157                    }
158                    providerID = XMLUtils.getElementValue((Element) child);
159                    if ((providerID == null) || (providerID.length() == 0)) {
160                        if (DiscoUtils.debug.messageEnabled()) {
161                            DiscoUtils.debug.message("ServiceInstance(Element)"
162                                + ": missing ProviderID element value.");
163                        }
164                        throw new DiscoveryException(
165                            DiscoUtils.bundle.getString("emptyElement"));
166                    }
167                } else if (nodeName.equals("Description")) {
168                    if (descriptions == null) {
169                        descriptions = new ArrayList();
170                    }
171                    descriptions.add(new Description((Element) child));
172                } else {
173                    if (DiscoUtils.debug.messageEnabled()) {
174                        DiscoUtils.debug.message("ServiceInstance(Element): "
175                            + "invalid node" + nodeName);
176                    }
177                    throw new DiscoveryException(
178                        DiscoUtils.bundle.getString("wrongInput"));
179                }
180            }
181        }
182
183        if (serviceType == null) {
184            if (DiscoUtils.debug.messageEnabled()) {
185                DiscoUtils.debug.message("ServiceInstance(Element): missing "
186                    + "ServiceInstance element.");
187            }
188            throw new DiscoveryException(
189                DiscoUtils.bundle.getString("missingServiceInstance"));
190        }
191
192        if (providerID == null) {
193            if (DiscoUtils.debug.messageEnabled()) {
194                DiscoUtils.debug.message("ServiceInstance(Element): missing "
195                    + "ProviderID element.");
196            }
197            throw new DiscoveryException(
198                DiscoUtils.bundle.getString("missingProviderID"));
199        }
200
201        if ((descriptions == null) || (descriptions.size() < 1)) {
202            if (DiscoUtils.debug.messageEnabled()) {
203                DiscoUtils.debug.message("ServiceInstance(Element): missing "
204                    + "Description element.");
205            }
206            throw new DiscoveryException(
207                DiscoUtils.bundle.getString("missingDescription"));
208        }
209    }
210
211    /**
212     * Gets provider ID of the service instance.
213     *
214     * @return provider ID of the service instance.
215     * @see #setProviderID(String)
216     */
217    public String getProviderID() {
218        return providerID;
219    }
220
221    /**
222     * Sets provider ID. 
223     *
224     * @param value provider ID.
225     * @see #getProviderID()
226     */
227    public void setProviderID(String value) {
228        providerID = value;
229    }
230
231    /**
232     * Gets the service descriptions.
233     * 
234     * @return List of Description objects
235     * @see #setDescription(List)
236     */
237    public List getDescription() {
238        return descriptions;
239    }
240
241    /**
242     * Sets the service descriptions.
243     * 
244     * @param desc List of Description objects.
245     * @see #getDescription()
246     */
247    public void setDescription(List desc) {
248        descriptions = desc;
249    }
250
251    /**
252     * Gets service type.
253     *
254     * @return service type.
255     * @see #setServiceType(String)
256     */
257    public String getServiceType() {
258        return serviceType;
259    }
260
261    /**
262     * Sets service type. 
263     *
264     * @param value service type.
265     * @see #getServiceType()
266     */
267    public void setServiceType(String value) {
268        serviceType = value;
269    }
270
271    /**
272     * Returns string format of object <code>ServiceInstance</code>.
273     *
274     * @return formatted string.
275     */ 
276    public String toString() {
277        StringBuffer sb = new StringBuffer(1000);
278        sb.append("<ServiceInstance xmlns=\"").append(DiscoConstants.DISCO_NS).
279                append("\"><ServiceType>").append(serviceType).
280                append("</ServiceType><ProviderID>").
281                append(providerID).append("</ProviderID>");
282        if (descriptions != null) {
283            Iterator iter = descriptions.iterator();
284            while (iter.hasNext()) {
285                sb.append(((Description) iter.next()).toString());
286            }
287        }
288        sb.append("</ServiceInstance>");
289        return sb.toString();
290    }
291}