]> sjero.net Git - linphone/blob - p2pproxy/dependencies-src/jxse-src-2.5/impl/src/net/jxta/impl/protocol/DiscoveryQuery.java
remove mediastreamer2 and add it as a submodule instead.
[linphone] / p2pproxy / dependencies-src / jxse-src-2.5 / impl / src / net / jxta / impl / protocol / DiscoveryQuery.java
1 /*
2  * Copyright (c) 2001-2007 Sun Microsystems, Inc.  All rights reserved.
3  *  
4  *  The Sun Project JXTA(TM) Software License
5  *  
6  *  Redistribution and use in source and binary forms, with or without 
7  *  modification, are permitted provided that the following conditions are met:
8  *  
9  *  1. Redistributions of source code must retain the above copyright notice,
10  *     this list of conditions and the following disclaimer.
11  *  
12  *  2. Redistributions in binary form must reproduce the above copyright notice, 
13  *     this list of conditions and the following disclaimer in the documentation 
14  *     and/or other materials provided with the distribution.
15  *  
16  *  3. The end-user documentation included with the redistribution, if any, must 
17  *     include the following acknowledgment: "This product includes software 
18  *     developed by Sun Microsystems, Inc. for JXTA(TM) technology." 
19  *     Alternately, this acknowledgment may appear in the software itself, if 
20  *     and wherever such third-party acknowledgments normally appear.
21  *  
22  *  4. The names "Sun", "Sun Microsystems, Inc.", "JXTA" and "Project JXTA" must 
23  *     not be used to endorse or promote products derived from this software 
24  *     without prior written permission. For written permission, please contact 
25  *     Project JXTA at http://www.jxta.org.
26  *  
27  *  5. Products derived from this software may not be called "JXTA", nor may 
28  *     "JXTA" appear in their name, without prior written permission of Sun.
29  *  
30  *  THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES,
31  *  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 
32  *  FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SUN 
33  *  MICROSYSTEMS OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 
34  *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
35  *  LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, 
36  *  OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF 
37  *  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING 
38  *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, 
39  *  EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40  *  
41  *  JXTA is a registered trademark of Sun Microsystems, Inc. in the United 
42  *  States and other countries.
43  *  
44  *  Please see the license information page at :
45  *  <http://www.jxta.org/project/www/license.html> for instructions on use of 
46  *  the license in source files.
47  *  
48  *  ====================================================================
49  *  
50  *  This software consists of voluntary contributions made by many individuals 
51  *  on behalf of Project JXTA. For more information on Project JXTA, please see 
52  *  http://www.jxta.org.
53  *  
54  *  This license is based on the BSD license adopted by the Apache Foundation. 
55  */
56
57 package net.jxta.impl.protocol;
58
59
60 import java.io.IOException;
61 import net.jxta.discovery.DiscoveryService;
62 import net.jxta.document.*;
63 import net.jxta.protocol.DiscoveryQueryMsg;
64 import net.jxta.protocol.PeerAdvertisement;
65 import java.util.logging.Level;
66 import net.jxta.logging.Logging;
67 import java.util.logging.Logger;
68
69 import java.io.StringReader;
70 import java.lang.reflect.UndeclaredThrowableException;
71 import java.util.Enumeration;
72
73
74 /**
75  * Implements the Discovery Query Message according to the schema defined by the
76  * standard JXTA Peer Discovery Protocol (PDP).
77  * <p/>
78  * <p/><pre>
79  * &lt;xs:element name="DiscoveryQuery" type="jxta:DiscoveryQuery"/>
80  * <p/>
81  * &lt;xsd:simpleType name="DiscoveryQueryType">
82  *   &lt;xsd:restriction base="xsd:string">
83  *     &lt;!-- peer -->
84  *     &lt;xsd:enumeration value="0"/>
85  *     &lt;!-- group -->
86  *     &lt;xsd:enumeration value="1"/>
87  *     &lt;!-- adv -->
88  *     &lt;xsd:enumeration value="2"/>
89  *   &lt;/xsd:restriction>
90  * &lt;/xsd:simpleType>
91  * <p/>
92  * &lt;xs:complexType name="DiscoveryQuery">
93  *   &lt;xs:sequence>
94  *     &lt;xs:element name="Type" type="jxta:DiscoveryQueryType"/>
95  *     &lt;xs:element name="Threshold" type="xs:unsignedInt" minOccurs="0"/>
96  *     &lt;xs:element name="Attr" type="xs:string" minOccurs="0"/>
97  *     &lt;xs:element name="Value" type="xs:string" minOccurs="0"/>
98  *     &lt;!-- The following should refer to a peer adv, but is instead a whole doc for historical reasons -->
99  *     &lt;xs:element name="PeerAdv" type="xs:string" minOccurs="0"/>
100  *   &lt;/xs:sequence>
101  * &lt;/xs:complexType>
102  * </pre>
103  *
104  * @see net.jxta.discovery.DiscoveryService
105  * @see net.jxta.impl.discovery.DiscoveryServiceImpl
106  * @see <a href="https://jxta-spec.dev.java.net/nonav/JXTAProtocols.html#proto-pdp" target="_blank">JXTA Protocols Specification : Peer Discovery Protocol</a>
107  */
108 public class DiscoveryQuery extends DiscoveryQueryMsg {
109
110     private static final Logger LOG = Logger.getLogger(DiscoveryQuery.class.getName());
111
112     private static final String typeTag = "Type";
113     private static final String peerAdvTag = "PeerAdv";
114     private static final String thresholdTag = "Threshold";
115     private static final String queryAttrTag = "Attr";
116     private static final String queryValueTag = "Value";
117
118     /**
119      * Default constructor
120      */
121     public DiscoveryQuery() {}
122
123     /**
124      * Construct from a StructuredDocument
125      *
126      * @param doc the element
127      */
128     public DiscoveryQuery(Element doc) {
129         initialize(doc);
130     }
131
132     /**
133      * Process an individual element from the document during parse. Normally,
134      * implementations will allow the base advertisments a chance to handle the
135      * element before attempting ot handle the element themselves. ie.
136      * <p/>
137      * <p/><pre><code>
138      *  protected boolean handleElement(Element elem) {
139      * <p/>
140      *      if (super.handleElement()) {
141      *           // it's been handled.
142      *           return true;
143      *           }
144      * <p/>
145      *      <i>... handle elements here ...</i>
146      * <p/>
147      *      // we don't know how to handle the element
148      *      return false;
149      *      }
150      *  </code></pre>
151      *
152      * @param elem the element to be processed.
153      * @return true if the element was recognized, otherwise false.
154      */
155     protected boolean handleElement(XMLElement elem) {
156         
157         String value = elem.getTextValue();
158         
159         if(null == value) {
160             return false;
161         }
162         
163         value = value.trim();
164         
165         if(0 == value.length()) {
166             return false;
167         }
168
169         if (elem.getName().equals(typeTag)) {
170             setDiscoveryType(Integer.parseInt(value));
171             return true;
172         }
173         if (elem.getName().equals(thresholdTag)) {
174             setThreshold(Integer.parseInt(value));
175             return true;
176         }
177         if (elem.getName().equals(peerAdvTag)) {
178             try {
179                 XMLDocument asDoc = (XMLDocument) StructuredDocumentFactory.newStructuredDocument(MimeMediaType.XMLUTF8, new StringReader(value));
180                 PeerAdvertisement adv = (PeerAdvertisement) AdvertisementFactory.newAdvertisement(asDoc);
181                 setPeerAdvertisement(adv);
182                 return true;
183             } catch(IOException failed) {
184                 IllegalArgumentException failure = new IllegalArgumentException("Bad Peer Advertisement");
185                 failure.initCause(failed);
186                 
187                 throw failure;
188             }
189         }
190         if (elem.getName().equals(queryAttrTag)) {
191             setAttr(value);
192             return true;
193         }
194         if (elem.getName().equals(queryValueTag)) {
195             setValue(value);
196             return true;
197         }
198
199         // element was not handled
200         return false;
201     }
202
203     /**
204      * Intialize a Discovery Query from a portion of a structured document.
205      *
206      * @param root document to intialize from
207      */
208     protected void initialize(Element root) {
209
210         if (!XMLElement.class.isInstance(root)) {
211             throw new IllegalArgumentException(getClass().getName() + " only supports XMLElement");
212         }
213
214         XMLElement doc = (XMLElement) root;
215
216         if (!doc.getName().equals(getAdvertisementType())) {
217             throw new IllegalArgumentException(
218                     "Could not construct : " + getClass().getName() + "from doc containing a " + doc.getName());
219         }
220
221         setDiscoveryType(-1); // force illegal value;
222
223         Enumeration<XMLElement> elements = doc.getChildren();
224
225         while (elements.hasMoreElements()) {
226             XMLElement elem = elements.nextElement();
227
228             if (!handleElement(elem)) {
229                 if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
230                     LOG.fine("Unhandled Element : " + elem.toString());
231                 }
232             }
233         }
234
235         // sanity check time!
236
237         if ((DiscoveryService.PEER != getDiscoveryType()) && (DiscoveryService.GROUP != getDiscoveryType())
238                 && (DiscoveryService.ADV != getDiscoveryType())) {
239             throw new IllegalArgumentException("Type is not one of the required values.");
240         }
241         if (getThreshold() < 0) {
242             throw new IllegalArgumentException("Threshold must not be less than zero.");
243         }
244         if ((getDiscoveryType() != DiscoveryService.PEER) && (getThreshold() == 0)) {
245             throw new IllegalArgumentException("Threshold may not be zero.");
246         }
247         if ((null == getAttr()) && (null != getValue())) {
248             throw new IllegalArgumentException("Value specified without attribute.");
249         }
250     }
251
252     /**
253      * {@inheritDoc}
254      */
255     @Override
256     public Document getDocument(MimeMediaType asMimeType) {
257         StructuredDocument adv = StructuredDocumentFactory.newStructuredDocument(asMimeType, getAdvertisementType());
258
259         if (adv instanceof XMLDocument) {
260             XMLDocument xmlDoc = (XMLDocument) adv;
261
262             xmlDoc.addAttribute("xmlns:jxta", "http://jxta.org");
263             xmlDoc.addAttribute("xml:space", "preserve");
264         }
265
266         Element e;
267
268         e = adv.createElement(typeTag, Integer.toString(getDiscoveryType()));
269         adv.appendChild(e);
270
271         int threshold = getThreshold();
272
273         if (threshold < 0) {
274             throw new IllegalStateException("threshold must be >= 0");
275         }
276         e = adv.createElement(thresholdTag, Integer.toString(threshold));
277         adv.appendChild(e);
278
279         PeerAdvertisement peerAdv = getPeerAdvertisement();
280
281         if ((peerAdv != null)) {
282             e = adv.createElement(peerAdvTag, peerAdv.toString());
283             adv.appendChild(e);
284         }
285
286         String attr = getAttr();
287
288         if ((attr != null) && (attr.length() > 0)) {
289             e = adv.createElement(queryAttrTag, attr.trim());
290             adv.appendChild(e);
291
292             String value = getValue();
293
294             if ((value != null) && (value.length() > 0)) {
295                 e = adv.createElement(queryValueTag, value.trim());
296                 adv.appendChild(e);
297             } else {
298                 if (threshold < 0) {
299                     throw new IllegalStateException("Attribute specified, but no value was specified.");
300                 }
301             }
302         }
303         return adv;
304     }
305
306     /**
307      * return the string representaion of this doc
308      *
309      * @deprecated should not be used. use getDocument().toString() instead.
310      */
311     @Override
312     @Deprecated
313     public String toString() {
314
315         try {
316             StructuredTextDocument doc = (StructuredTextDocument) getDocument(MimeMediaType.XMLUTF8);
317
318             return doc.toString();
319         } catch (Exception e) {
320             if (e instanceof RuntimeException) {
321                 throw (RuntimeException) e;
322             } else {
323                 throw new UndeclaredThrowableException(e);
324             }
325         }
326     }
327 }