]> sjero.net Git - linphone/blob - p2pproxy/dependencies-src/jxse-src-2.5/api/src/net/jxta/endpoint/WireFormatMessageFactory.java
remove mediastreamer2 and add it as a submodule instead.
[linphone] / p2pproxy / dependencies-src / jxse-src-2.5 / api / src / net / jxta / endpoint / WireFormatMessageFactory.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.endpoint;
58
59
60 import net.jxta.document.MimeMediaType;
61 import net.jxta.logging.Logging;
62 import net.jxta.util.ClassFactory;
63
64 import java.io.IOException;
65 import java.io.InputStream;
66 import java.nio.ByteBuffer;
67 import java.util.Hashtable;
68 import java.util.Map;
69 import java.util.NoSuchElementException;
70 import java.util.logging.Level;
71 import java.util.logging.Logger;
72
73
74 /**
75  * This class is a class factory for Wire Format Messages. This class abstracts
76  * The implementation of Wire Format Messages and allows for construction based
77  * on the MimeType of InputStreams.
78  * <p/>
79  * The WireFormatMessageFactory extends the ClassFactory to register the
80  * various Message wire format implementations into a static hashtable. The
81  * factory is called with the Mime type requested to create the corresponding
82  * Wire Format type.
83  *
84  * @see net.jxta.endpoint.Message
85  * @see net.jxta.endpoint.WireFormatMessage
86  * @see net.jxta.util.ClassFactory
87  * @see net.jxta.document.MimeMediaType
88  */
89 public final class WireFormatMessageFactory extends ClassFactory<MimeMediaType, WireFormatMessageFactory.Instantiator> {
90
91     /**
92      * Logger
93      */
94     private static final Logger LOG = Logger.getLogger(WireFormatMessageFactory.class.getName());
95
96     /**
97      * The mime media type of preferred/default wire format.
98      */
99     public static final MimeMediaType DEFAULT_WIRE_MIME = new MimeMediaType("application/x-jxta-msg").intern();
100
101     /**
102      * Interface for instantiators of wire format messages.
103      */
104     public interface Instantiator {
105
106         /**
107          * Returns the list of mime types supported by this serialization. All of
108          * mimetypes in this list should have no mime type parameters.
109          *
110          * @return Returns the list of mime types supported by this serialization.
111          */
112         public MimeMediaType[] getSupportedMimeTypes();
113
114         /**
115          * Returns a list of the content encodings supported by this serialization.
116          * These content encodings apply to both the overall coding of the message
117          * and to the encoding of individual elements.
118          *
119          * @return a list of the content encodings supported by this serialization.
120          */
121         public MimeMediaType[] getSupportedContentEncodings();
122
123         /**
124          * Create a WireFormatMessage from an abstract message. It is an error
125          * (though lazily enforced) to modify the abstract message during the
126          * lifetime of the WireFormatMessage.
127          *
128          * @param msg                     the message for which a serialization is desired.
129          * @param type                    the the serialization form desired. This can include
130          *                                mime parameters to control options.
131          * @param preferedContentEncoding An array of acceptable message encodings
132          *                                in descending order of preference. any or none of these encoding options
133          *                                may be used. May be null for unencoded messages.
134          * @return a proxy object for the abstract message which is a
135          *         representation of the message in its serialized form.
136          */
137         public WireFormatMessage toWire(Message msg, MimeMediaType type, MimeMediaType[] preferedContentEncoding);
138
139         /**
140          * Create an abstract message from a serialization.
141          *
142          * @param is              The message stream. Message serializations must either use
143          *                        internal data or EOF to determine the length of the stream.
144          * @param type            Declared message type of the stream including any optional
145          *                        configuration parameters.
146          * @param contentEncoding Content encoding (including optional parameters)
147          *                        which has been applied to the message. May be null for unencoded messages.
148          * @return a proxy object for the abstract message which is a
149          *         representation of the message in its serialized form.
150          * @throws java.io.IOException if an io error occurs
151          */
152         public Message fromWire(InputStream is, MimeMediaType type, MimeMediaType contentEncoding) throws IOException;
153
154         /**
155          * Create an abstract message from a serialization.
156          *
157          * @param buffer          The byte buffer. Message serializations must either use
158          *                        internal data or EOF to determine the length of the stream.
159          * @param type            Declared message type of the stream including any optional
160          *                        configuration parameters.
161          * @param contentEncoding Content encoding (including optional parameters)
162          *                        which has been applied to the message. May be null for unencoded messages.
163          * @return a proxy object for the abstract message which is a
164          *         representation of the message in its serialized form.
165          * @throws java.io.IOException if an io error occurs
166          */
167         public Message fromBuffer(ByteBuffer buffer, MimeMediaType type, MimeMediaType contentEncoding) throws IOException;
168     }
169
170     /**
171      * This is the map of mime-types and constructors used by
172      * <CODE>newStructuredDocument</CODE>.
173      */
174     private Map<MimeMediaType,Instantiator> encodings = new Hashtable<MimeMediaType,Instantiator>();
175
176     /**
177      * If true then the pre-defined set of StructuredDocument sub-classes has
178      * been registered from the property containing them.
179      */
180     private volatile boolean loadedProperty = false;
181
182     /**
183      * This class is in fact a singleton. This is the instance that backs the
184      * static methods.
185      */
186     private static WireFormatMessageFactory factory = new WireFormatMessageFactory();
187
188     /**
189      * Private constructor. This class is not meant to be instantiated except
190      * by itself.
191      */
192     private WireFormatMessageFactory() {}
193
194     /**
195      *  Registers the pre-defined set of WireFormatMessage sub-classes so that
196      *  this factory can construct them.
197      *
198      *  @return true if at least one of the WireFormatMessage sub-classes could
199      *  be registered otherwise false.
200      */
201     private synchronized boolean loadProviders() {
202         if (!factory.loadedProperty) {
203             factory.loadedProperty = registerProviders(WireFormatMessage.class.getName());
204         }
205         
206         return factory.loadedProperty;
207     }
208     
209     /**
210      * {@inheritDoc}
211      */
212     @Override
213     protected Map<MimeMediaType,Instantiator> getAssocTable() {
214         return encodings;
215     }
216
217     /**
218      * {@inheritDoc}
219      */
220     @Override
221     public Class<Instantiator> getClassOfInstantiators() {
222         // our key is the doctype names.
223         return Instantiator.class;
224     }
225
226     /**
227      * {@inheritDoc}
228      */
229     @Override
230     public Class getClassForKey() {
231         // our key is the mime types.
232         return MimeMediaType.class;
233     }
234
235     /**
236      * {@inheritDoc}
237      */
238     @Override
239     protected boolean registerAssoc(String className) {
240         boolean registeredSomething = false;
241
242         if (Logging.SHOW_FINE && LOG.isLoggable(Level.FINE)) {
243             LOG.fine("Registering : " + className);
244         }
245
246         try {
247             Class msgClass = Class.forName(className);
248
249             Instantiator instantiator = (Instantiator) (msgClass.getField("INSTANTIATOR").get(null));
250
251             MimeMediaType[] mimeTypes = instantiator.getSupportedMimeTypes();
252
253             for (MimeMediaType mimeType : mimeTypes) {
254                 if (Logging.SHOW_FINER && LOG.isLoggable(Level.FINER)) {
255                     LOG.finer("   Registering Type : " + mimeType);
256                 }
257
258                 registeredSomething |= registerInstantiator(mimeType, instantiator);
259             }
260         } catch (Exception all) {
261             if (Logging.SHOW_WARNING && LOG.isLoggable(Level.WARNING)) {
262                 LOG.log(Level.WARNING, "Failed to register \'" + className + "\'", all);
263             }
264         }
265
266         return registeredSomething;
267     }
268
269     /**
270      * Register an instantiator object a mime-type of documents to be
271      * constructed.
272      *
273      * @param mimetype     the mime-type associated.
274      * @param instantiator the instantiator that wants to be registered..
275      * @return boolean true   if the instantiator for this mime-type is now
276      *         registered. If there was already an instantiator this mime-type then
277      *         false will be returned.
278      * @throws SecurityException there were permission problems registering
279      *                           the instantiator.
280      */
281     public static boolean registerInstantiator(MimeMediaType mimetype, Instantiator instantiator) {
282         boolean registered = factory.registerAssoc(mimetype, instantiator);
283
284         return registered;
285     }
286
287     /**
288      * Constructs an instance of {@link WireFormatMessage} matching the type
289      * specified by the <CODE>type</CODE> parameter.
290      *
291      * @param msg               the message for which a serialization is desired.
292      * @param type              the the serialization form desired. This can include
293      *                          mime parameters to control options.
294      * @param preferedEncodings An array of acceptable message encodings
295      *                          in descending order of preference. any or none of these encoding options
296      *                          may be used. May be null for unencoded messages.
297      * @return a proxy object for the abstract message which is a
298      *         representation of the message in its serialized form.
299      */
300     public static WireFormatMessage toWire(Message msg, MimeMediaType type, MimeMediaType[] preferedEncodings) {
301         factory.loadProviders();
302
303         Instantiator instantiator = factory.getInstantiator(type.getBaseMimeMediaType());
304
305         return instantiator.toWire(msg, type, preferedEncodings);
306     }
307
308     /**
309      * Constructs an instance of <CODE>Message</CODE> from matching the type
310      * specified by the <CODE>type</CODE> parameter.
311      *
312      * @param is              The message stream. Message serializations must either use
313      *                        internal data or EOF to determine the length of the stream.
314      * @param type            Declared message type of the stream including any optional
315      *                        configuration parameters.
316      * @param contentEncoding Content encoding (including optional parameters)
317      *                        which has been applied to the message. May be null for unencoded messages.
318      * @return the new abstract message.
319      * @throws java.io.IOException if an io error occurs
320      */
321     public static Message fromWire(InputStream is, MimeMediaType type, MimeMediaType contentEncoding) throws IOException {
322         factory.loadProviders();
323
324         Instantiator instantiator;
325
326         try {
327             instantiator = factory.getInstantiator(type.getBaseMimeMediaType());
328         } catch (NoSuchElementException badType) {
329             throw new IOException("Unable to deserialize message of type: " + type);
330         }
331
332         return instantiator.fromWire(is, type, contentEncoding);
333     }
334
335     /**
336      * Constructs an instance of <CODE>Message</CODE> from matching the type
337      * specified by the <CODE>type</CODE> parameter.
338      *
339      * @param buffer          The message buffer. Message serializations must either use
340      *                        internal data or EOF to determine the length of the stream.
341      * @param type            Declared message type of the stream including any optional
342      *                        configuration parameters.
343      * @param contentEncoding Content encoding (including optional parameters)
344      *                        which has been applied to the message. May be null for unencoded messages.
345      * @return the new abstract message.
346      * @throws java.io.IOException if an io error occurs
347      */
348     public static Message fromBuffer(ByteBuffer buffer, MimeMediaType type, MimeMediaType contentEncoding) throws IOException {
349         factory.loadProviders();
350
351         Instantiator instantiator;
352
353         try {
354             instantiator = factory.getInstantiator(type.getBaseMimeMediaType());
355         } catch (NoSuchElementException badType) {
356             throw new IOException("Unable to deserialize message of type: " + type);
357         }
358
359         return instantiator.fromBuffer(buffer, type, contentEncoding);
360     }
361 }