001: /*
002: * Portions Copyright 2000-2007 Sun Microsystems, Inc. All Rights
003: * Reserved. Use is subject to license terms.
004: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
005: *
006: * This program is free software; you can redistribute it and/or
007: * modify it under the terms of the GNU General Public License version
008: * 2 only, as published by the Free Software Foundation.
009: *
010: * This program is distributed in the hope that it will be useful, but
011: * WITHOUT ANY WARRANTY; without even the implied warranty of
012: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
013: * General Public License version 2 for more details (a copy is
014: * included at /legal/license.txt).
015: *
016: * You should have received a copy of the GNU General Public License
017: * version 2 along with this work; if not, write to the Free Software
018: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
019: * 02110-1301 USA
020: *
021: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
022: * Clara, CA 95054 or visit www.sun.com if you need additional
023: * information or have any questions.
024: */
025: /*
026: * Created on Jan 29, 2004
027: *
028: */
029: package gov.nist.microedition.sip;
030:
031: import java.io.DataInputStream;
032: import java.io.DataOutputStream;
033: import java.io.IOException;
034: import java.io.InputStream;
035: import java.io.OutputStream;
036:
037: import javax.microedition.io.Connection;
038: import javax.microedition.io.ConnectionNotFoundException;
039: import javax.microedition.io.InputConnection;
040: import javax.microedition.io.OutputConnection;
041:
042: import javax.microedition.io.DatagramConnection;
043:
044: import com.sun.cldc.io.ConnectionBaseInterface;
045:
046: /**
047: * This class is factory for creating new Connection objects.
048: * <p>
049: * The creation of Connections is performed dynamically by looking
050: * up a protocol implementation class whose name is formed from the
051: * platform name (read from a system property) and the protocol name
052: * of the requested connection (extracted from the parameter string
053: * supplied by the application programmer.)
054: *
055: * The parameter string that describes the target should conform
056: * to the URL format as described in RFC 2396.
057: * This takes the general form:
058: * <p>
059: * <code>{scheme}:[{target}][{params}]</code>
060: * <p>
061: * where <code>{scheme}</code> is the name of a protocol such as
062: * <i>http</i>}.
063: * <p>
064: * The <code>{target}</code> is normally some kind of network
065: * address.
066: * <p>
067: * Any <code>{params}</code> are formed as a series of equates
068: * of the form ";x=y". Example: ";type=a".
069: * <p>
070: * An optional second parameter may be specified to the open
071: * function. This is a mode flag that indicates to the protocol
072: * handler the intentions of the calling code. The options here
073: * specify if the connection is going to be read (READ), written
074: * (WRITE), or both (READ_WRITE). The validity of these flag
075: * settings is protocol dependent. For instance, a connection
076: * for a printer would not allow read access, and would throw
077: * an IllegalArgumentException. If the mode parameter is not
078: * specified, READ_WRITE is used by default.
079: * <p>
080: * An optional third parameter is a boolean flag that indicates
081: * if the calling code can handle timeout exceptions. If this
082: * flag is set, the protocol implementation may throw an
083: * InterruptedIOException when it detects a timeout condition.
084: * This flag is only a hint to the protocol handler, and it
085: * does not guarantee that such exceptions will actually be thrown.
086: * If this parameter is not set, no timeout exceptions will be
087: * thrown.
088: * <p>
089: * Because connections are frequently opened just to gain access
090: * to a specific input or output stream, four convenience
091: * functions are provided for this purpose.
092: *
093: * See also: {@link DatagramConnection DatagramConnection}
094: * for information relating to datagram addressing
095: *
096: * @version 12/17/01 (CLDC 1.1)
097: * @since CLDC 1.0
098: */
099:
100: public class SipConnector {
101:
102: /*
103: * Implementation notes: The open parameter is used for
104: * dynamically constructing a class name in the form:
105: * <p>
106: * <code>com.sun.cldc.io.{platform}.{protocol}.Protocol</code>
107: * <p>
108: * The platform name is derived from the system by looking for
109: * the system property "microedition.platform". If this property
110: * key is not found or the associated class is not present, then
111: * "j2me" is used by default.
112: * <p>
113: * The protocol name is derived from the parameter string
114: * describing the target of the connection. This takes the from:
115: * <p>
116: * <code> {protocol}:[{target}][ {params}] </code>
117: * <p>
118: * The protocol name is used for dynamically finding the
119: * appropriate protocol implementation class. This information
120: * is stripped from the target name that is given as a parameter
121: * to the open() method. In order to avoid problems with illegal
122: * class file names, all the '-' characters in the protocol name
123: * are automatically converted into '_' characters.
124: */
125:
126: /**
127: * Access mode READ.
128: */
129: public final static int READ = 1;
130:
131: /**
132: * Access mode WRITE.
133: */
134: public final static int WRITE = 2;
135:
136: /**
137: * Access mode READ_WRITE.
138: */
139: public final static int READ_WRITE = (READ | WRITE);
140:
141: /**
142: * The platform name.
143: */
144: private static String platform;
145:
146: /**
147: * True if we are running on a J2ME system
148: */
149: private static boolean j2me = true;
150:
151: /**
152: * The root of the classes.
153: */
154: private static String classRoot;
155:
156: /**
157: * Class initializer.
158: */
159: static {
160: /* Find out if we are running on a J2ME system */
161: if (System.getProperty("microedition.configuration") != null) {
162: j2me = true;
163: }
164:
165: /* Set up the platform name */
166: platform = System.getProperty("microedition.platform");
167:
168: /* Set up the library class root path */
169: /* This may vary from one CLDC implementation to another */
170: classRoot = System
171: .getProperty("javax.microedition.io.Connector.protocolpath");
172: if (classRoot == null) {
173: classRoot = "com.sun.cldc.io";
174: }
175: classRoot = "gov.nist.microedition.io";
176: }
177:
178: /**
179: * Prevent instantiation of this class.
180: */
181: private SipConnector() {
182: }
183:
184: /**
185: * Create and open a Connection.
186: *
187: * @param name The URL for the connection.
188: * @return A new Connection object.
189: *
190: * @exception IllegalArgumentException If a parameter is invalid.
191: * @exception ConnectionNotFoundException If the target of the
192: * name cannot be found, or if the requested protocol type
193: * is not supported.
194: * @exception IOException If some other kind of I/O error occurs.
195: * @exception SecurityException May be thrown if access to the
196: * protocol handler is prohibited.
197: */
198: public static Connection open(String name) throws IOException {
199: return open(name, READ_WRITE);
200: }
201:
202: /**
203: * Create and open a Connection.
204: *
205: * @param name The URL for the connection.
206: * @param mode The access mode.
207: * @return A new Connection object.
208: *
209: * @exception IllegalArgumentException If a parameter is invalid.
210: * @exception ConnectionNotFoundException If the target of the
211: * name cannot be found, or if the requested protocol type
212: * is not supported.
213: * @exception IOException If some other kind of I/O error occurs.
214: * @exception SecurityException May be thrown if access to the
215: * protocol handler is prohibited.
216: */
217: public static Connection open(String name, int mode)
218: throws IOException {
219: return open(name, mode, false);
220: }
221:
222: /**
223: * Create and open a Connection.
224: *
225: * @param name The URL for the connection
226: * @param mode The access mode
227: * @param timeouts A flag to indicate that the caller
228: * wants timeout exceptions
229: * @return A new Connection object
230: *
231: * @exception IllegalArgumentException If a parameter is invalid.
232: * @exception ConnectionNotFoundException If the target of the
233: * name cannot be found, or if the requested protocol type
234: * is not supported.
235: * @exception IOException If some other kind of I/O error occurs.
236: * @exception SecurityException May be thrown if access to the
237: * protocol handler is prohibited.
238: */
239: public static Connection open(String name, int mode,
240: boolean timeouts) throws IOException {
241:
242: /* If the "microedition.platform" property is defined, */
243: /* use that as the platform name for opening a connection */
244: if (platform != null) {
245: try {
246: return openPrim(name, mode, timeouts, platform);
247: } catch (ClassNotFoundException x) {
248: }
249: }
250:
251: /* If the "microedition.platform" property is not defined, */
252: /* use one of the default values */
253: try {
254: return openPrim(name, mode, timeouts, j2me ? "j2me"
255: : "j2se");
256: } catch (ClassNotFoundException x) {
257: }
258:
259: throw new ConnectionNotFoundException(
260: "The requested protocol does not exist " + name);
261: }
262:
263: /**
264: * Create and open a Connection.
265: *
266: * @param name The URL for the connection
267: * @param mode The access mode
268: * @param timeouts A flag to indicate that the caller
269: * wants timeout exceptions
270: * @param platform Platform name
271: * @return A new Connection object
272: *
273: * @exception ClassNotFoundException If the protocol cannot be found.
274: * @exception IllegalArgumentException If a parameter is invalid.
275: * @exception ConnectionNotFoundException If the target of the
276: * name cannot be found, or if the requested protocol type
277: * is not supported.
278: * @exception IOException If some other kind of I/O error occurs.
279: * @exception IllegalArgumentException If a parameter is invalid.
280: */
281: private static Connection openPrim(String name, int mode,
282: boolean timeouts, String platform) throws IOException,
283: ClassNotFoundException, IllegalArgumentException {
284:
285: /* Test for null argument */
286: if (name == null) {
287: throw new IllegalArgumentException("Null URL");
288: }
289:
290: /* Look for : as in "http:", "file:", or whatever */
291: int colon = name.indexOf(':');
292:
293: /* Test for null argument */
294: if (colon < 1) {
295: throw new IllegalArgumentException("no ':' in URL");
296: }
297:
298: try {
299: String protocol;
300:
301: /* Strip off the protocol name */
302: protocol = name.substring(0, colon);
303:
304: /* Strip off the rest of the string */
305: name = name.substring(colon + 1);
306:
307: /* Convert all the '-' characters in the protocol */
308: /* name to '_' characters (dashes are not allowed */
309: /* in class names). This operation creates garbage */
310: /* only if the protocol name actually contains dashes */
311: protocol = protocol.replace('-', '_');
312:
313: /* Use the platform and protocol names to look up */
314: /* a class to implement the connection */
315: Class clazz = Class.forName(classRoot + "." + platform
316: + "." + protocol + ".Protocol");
317:
318: /* Construct a new instance of the protocol */
319: ConnectionBaseInterface uc = (ConnectionBaseInterface) clazz
320: .newInstance();
321:
322: /* Open the connection, and return it */
323: return uc.openPrim(name, mode, timeouts);
324:
325: } catch (InstantiationException x) {
326: throw new IOException(x.toString());
327: } catch (IllegalAccessException x) {
328: throw new IOException(x.toString());
329: } catch (ClassCastException x) {
330: throw new IOException(x.toString());
331: }
332: }
333:
334: /**
335: * Create and open a connection input stream.
336: *
337: * @param name The URL for the connection.
338: * @return A DataInputStream.
339: *
340: * @exception IllegalArgumentException If a parameter is invalid.
341: * @exception ConnectionNotFoundException If the target of the
342: * name cannot be found, or if the requested protocol type
343: * is not supported.
344: * @exception IOException If some other kind of I/O error occurs.
345: * @exception SecurityException May be thrown if access to the
346: * protocol handler is prohibited.
347: */
348: public static DataInputStream openDataInputStream(String name)
349: throws IOException {
350: /* Look for : as in "http:", "file:", or whatever */
351: int colon = name.indexOf(':');
352:
353: /* Test for null argument */
354: if (colon < 1) {
355: throw new IOException(
356: "This method is not authorized for this protocol");
357: }
358:
359: String protocol = name.substring(0, colon);
360: if (protocol.equals("sip"))
361: throw new IOException(
362: "This method is not authorized for this protocol");
363: InputConnection con = (InputConnection) SipConnector.open(name,
364: SipConnector.READ);
365:
366: try {
367: return con.openDataInputStream();
368: } finally {
369: con.close();
370: }
371: }
372:
373: /**
374: * Create and open a connection output stream.
375: *
376: * @param name The URL for the connection.
377: * @return A DataOutputStream.
378: *
379: * @exception IllegalArgumentException If a parameter is invalid.
380: * @exception ConnectionNotFoundException If the target of the
381: * name cannot be found, or if the requested protocol type
382: * is not supported.
383: * @exception IOException If some other kind of I/O error occurs.
384: * @exception SecurityException May be thrown if access to the
385: * protocol handler is prohibited.
386: */
387: public static DataOutputStream openDataOutputStream(String name)
388: throws IOException {
389: /* Look for : as in "http:", "file:", or whatever */
390: int colon = name.indexOf(':');
391:
392: /* Test for null argument */
393: if (colon < 1) {
394: throw new IOException(
395: "This method is not authorized for this protocol");
396: }
397:
398: String protocol = name.substring(0, colon);
399: if (protocol.equals("sip"))
400: throw new IOException(
401: "This method is not authorized for this protocol");
402: OutputConnection con = (OutputConnection) SipConnector.open(
403: name, SipConnector.WRITE);
404:
405: try {
406: return con.openDataOutputStream();
407: } finally {
408: con.close();
409: }
410: }
411:
412: /**
413: * Create and open a connection input stream.
414: *
415: * @param name The URL for the connection.
416: * @return An InputStream.
417: *
418: * @exception IllegalArgumentException If a parameter is invalid.
419: * @exception ConnectionNotFoundException If the target of the
420: * name cannot be found, or if the requested protocol type
421: * is not supported.
422: * @exception IOException If some other kind of I/O error occurs.
423: * @exception SecurityException May be thrown if access to the
424: * protocol handler is prohibited.
425: */
426: public static InputStream openInputStream(String name)
427: throws IOException {
428: /* Look for : as in "http:", "file:", or whatever */
429: int colon = name.indexOf(':');
430:
431: /* Test for null argument */
432: if (colon < 1) {
433: throw new IOException(
434: "This method is not authorized for this protocol");
435: }
436:
437: String protocol = name.substring(0, colon);
438: if (protocol.equals("sip"))
439: throw new IOException(
440: "This method is not authorized for this protocol");
441: return openDataInputStream(name);
442: }
443:
444: /**
445: * Create and open a connection output stream.
446: *
447: * @param name The URL for the connection.
448: * @return An OutputStream.
449: *
450: * @exception IllegalArgumentException If a parameter is invalid.
451: * @exception ConnectionNotFoundException If the target of the
452: * name cannot be found, or if the requested protocol type
453: * is not supported.
454: * @exception IOException If some other kind of I/O error occurs.
455: * @exception SecurityException May be thrown if access to the
456: * protocol handler is prohibited.
457: */
458: public static OutputStream openOutputStream(String name)
459: throws IOException {
460: /* Look for : as in "http:", "file:", or whatever */
461: int colon = name.indexOf(':');
462:
463: /* Test for null argument */
464: if (colon < 1) {
465: throw new IOException(
466: "This method is not authorized for this protocol");
467: }
468:
469: String protocol = name.substring(0, colon);
470: if (protocol.equals("sip"))
471: throw new IOException(
472: "This method is not authorized for this protocol");
473:
474: return openDataOutputStream(name);
475: }
476:
477: }
|