001: /*
002: * Copyright (c) 1999-2002 Sun Microsystems, Inc., 901 San Antonio Road,
003: * Palo Alto, CA 94303, U.S.A. All Rights Reserved.
004: *
005: * Sun Microsystems, Inc. has intellectual property rights relating
006: * to the technology embodied in this software. In particular, and
007: * without limitation, these intellectual property rights may include
008: * one or more U.S. patents, foreign patents, or pending
009: * applications. Sun, Sun Microsystems, the Sun logo, Java, KJava,
010: * and all Sun-based and Java-based marks are trademarks or
011: * registered trademarks of Sun Microsystems, Inc. in the United
012: * States and other countries.
013: *
014: * This software is distributed under licenses restricting its use,
015: * copying, distribution, and decompilation. No part of this
016: * software may be reproduced in any form by any means without prior
017: * written authorization of Sun and its licensors, if any.
018: *
019: * FEDERAL ACQUISITIONS: Commercial Software -- Government Users
020: * Subject to Standard License Terms and Conditions
021: */
022:
023: package com.sun.portal.microedition.io;
024:
025: import java.io.*;
026: import com.sun.portal.cldc.io.*;
027:
028: /**
029: * This class is factory for creating new Connection objects.
030: * <p>
031: * The creation of Connections is performed dynamically by looking
032: * up a protocol implementation class whose name is formed from the
033: * platform name (read from a system property) and the protocol name
034: * of the requested connection (extracted from the parameter string
035: * supplied by the application programmer.)
036: *
037: * The parameter string that describes the target should conform
038: * to the URL format as described in RFC 2396.
039: * This takes the general form:
040: * <p>
041: * <code>{scheme}:[{target}][{parms}]</code>
042: * <p>
043: * where <code>{scheme}</code> is the name of a protocol such as
044: * <i>http</i>}.
045: * <p>
046: * The <code>{target}</code> is normally some kind of network
047: * address.
048: * <p>
049: * Any <code>{parms}</code> are formed as a series of equates
050: * of the form ";x=y". Example: ";type=a".
051: * <p>
052: * An optional second parameter may be specified to the open
053: * function. This is a mode flag that indicates to the protocol
054: * handler the intentions of the calling code. The options here
055: * specify if the connection is going to be read (READ), written
056: * (WRITE), or both (READ_WRITE). The validity of these flag
057: * settings is protocol dependent. For instance, a connection
058: * for a printer would not allow read access, and would throw
059: * an IllegalArgumentException. If the mode parameter is not
060: * specified, READ_WRITE is used by default.
061: * <p>
062: * An optional third parameter is a boolean flag that indicates
063: * if the calling code can handle timeout exceptions. If this
064: * flag is set, the protocol implementation may throw an
065: * InterruptedIOException when it detects a timeout condition.
066: * This flag is only a hint to the protocol handler, and it
067: * does not guarantee that such exceptions will actually be thrown.
068: * If this parameter is not set, no timeout exceptions will be
069: * thrown.
070: * <p>
071: * Because connections are frequently opened just to gain access
072: * to a specific input or output stream, four convenience
073: * functions are provided for this purpose.
074: *
075: * See also: {@link DatagramConnection DatagramConnection}
076: * for information relating to datagram addressing
077: *
078: * @author Nik Shaylor
079: * @version 1.2 12/8/2000 (comments revised)
080: * @since CLDC 1.0
081: */
082:
083: public class Connector {
084:
085: /*
086: * Implementation note: The open parameter is used for dynamically
087: * constructing a class name in the form:
088: * <p>
089: * <code>com.sun.cldc.io.{platform}.{protocol}.Protocol</code>
090: * <p>
091: * The platform name is derived from the system by looking for
092: * the system property "microedition.platform". If this property
093: * key is not found or the associated class is not present, then
094: * one of two default directories are used. These are called
095: * "j2me" and "j2se". If the property "microedition.configuration"
096: * is non-null, then "j2me" is used, otherwise "j2se" is assumed.
097: * <p>
098: * The system property "microedition.protocolpath" can be used to
099: * change the root of the class space that is used for looking
100: * up the protocol implementation classes.
101: * <p>
102: * The protocol name is derived from the parameter string
103: * describing the target of the connection. This takes the from:
104: * <p>
105: * <code> {protocol}:[{target}][ {parms}] </code>
106: * <p>
107: * The protocol name is used for dynamically finding the
108: * appropriate protocol implementation class. This information
109: * is stripped from the target name that is given as a parameter
110: * to the open() method.
111: */
112:
113: /**
114: * Access mode READ.
115: */
116: public final static int READ = 1;
117:
118: /**
119: * Access mode WRITE.
120: */
121: public final static int WRITE = 2;
122:
123: /**
124: * Access mode READ_WRITE.
125: */
126: public final static int READ_WRITE = (READ | WRITE);
127:
128: /**
129: * The platform name.
130: */
131: private static String platform;
132:
133: /**
134: * True if we are running on a J2ME system
135: */
136: private static boolean j2me = false;
137:
138: /**
139: * The root of the classes.
140: */
141: private static String classRoot;
142:
143: /**
144: * Class initializer.
145: */
146: static {
147: /* Find out if we are running on a J2ME system */
148: if (System.getProperty("microedition.configuration") != null) {
149: j2me = true;
150: }
151:
152: /* Set up the platform name */
153: platform = System.getProperty("microedition.platform");
154:
155: /* See if there is an alternate protocol class root path */
156: classRoot = System
157: .getProperty("com.sun.portal.microedition.io.Connector.protocolpath");
158: if (classRoot == null) {
159: classRoot = "com.sun.cldc.io";
160: }
161: }
162:
163: /**
164: * Prevent instantiation of this class.
165: */
166: private Connector() {
167: }
168:
169: /**
170: * Create and open a Connection.
171: *
172: * @param name The URL for the connection.
173: * @return A new Connection object.
174: *
175: * @exception IllegalArgumentException If a parameter is invalid.
176: * @exception ConnectionNotFoundException If the requested connection
177: * cannot be make, or the protocol type does not exist.
178: * @exception IOException If some other kind of I/O error occurs.
179: */
180: public static Connection open(String name) throws IOException {
181: return open(name, READ_WRITE);
182: }
183:
184: /**
185: * Create and open a Connection.
186: *
187: * @param name The URL for the connection.
188: * @param mode The access mode.
189: * @return A new Connection object.
190: *
191: * @exception IllegalArgumentException If a parameter is invalid.
192: * @exception ConnectionNotFoundException If the requested connection
193: * cannot be make, or the protocol type does not exist.
194: * @exception IOException If some other kind of I/O error occurs.
195: */
196: public static Connection open(String name, int mode)
197: throws IOException {
198:
199: return open(name, mode, false);
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: * @param timeouts A flag to indicate that the caller
208: * wants timeout exceptions
209: * @return A new Connection object
210: *
211: * @exception IllegalArgumentException If a parameter is invalid.
212: * @exception ConnectionNotFoundException if the requested connection
213: * cannot be make, or the protocol type does not exist.
214: * @exception IOException If some other kind of I/O error occurs.
215: */
216: public static Connection open(String name, int mode,
217: boolean timeouts) throws IOException {
218:
219: /* If the "microedition.platform" property was found */
220: /* then try to get the class from there */
221: if (platform != null) {
222: try {
223: return openPrim(name, mode, timeouts, platform);
224: } catch (ClassNotFoundException x) {
225: }
226: }
227:
228: /* Drop back to the default classes of "j2me" or "j2se" */
229: try {
230: return openPrim(name, mode, timeouts, j2me ? "j2me"
231: : "j2se");
232: } catch (ClassNotFoundException x) {
233: }
234:
235: throw new ConnectionNotFoundException(
236: "The requested protocol does not exist " + name);
237: }
238:
239: /**
240: * Create and open a Connection.
241: *
242: * @param string The URL for the connection
243: * @param mode The access mode
244: * @param timeouts A flag to indicate that the caller
245: * wants timeout exceptions
246: * @param platform Platform name
247: * @return A new Connection object
248: *
249: * @exception ClassNotFoundException If the protocol cannot be found.
250: * @exception IllegalArgumentException If a parameter is invalid.
251: * @exception ConnectionNotFoundException If the connection cannot
252: * be found.
253: * @exception IOException If some other kind of I/O error occurs.
254: * @exception IllegalArgumentException If a parameter is invalid.
255: */
256: private static Connection openPrim(String name, int mode,
257: boolean timeouts, String platform) throws IOException,
258: ClassNotFoundException {
259:
260: /* Test for null argument */
261: if (name == null) {
262: throw new IllegalArgumentException("Null URL");
263: }
264:
265: /* Look for : as in "http:", "file:", or whatever */
266: int colon = name.indexOf(':');
267:
268: /* Test for null argument */
269: if (colon < 1) {
270: throw new IllegalArgumentException("no ':' in URL");
271: }
272:
273: try {
274: String protocol;
275:
276: /* Strip off the protocol name */
277: protocol = name.substring(0, colon);
278:
279: /* Strip the protocol name from the rest of the string */
280: name = name.substring(colon + 1);
281:
282: /* Use the platform and protocol names to look up */
283: /* a class to implement the connection */
284: Class clazz = Class.forName(classRoot + "." + platform
285: + "." + protocol + ".Protocol");
286:
287: /* Construct a new instance */
288: ConnectionBaseInterface uc = (ConnectionBaseInterface) clazz
289: .newInstance();
290:
291: /* Open the connection, and return it */
292: return uc.openPrim(name, mode, timeouts);
293:
294: } catch (InstantiationException x) {
295: throw new IOException(x.toString());
296: } catch (IllegalAccessException x) {
297: throw new IOException(x.toString());
298: } catch (ClassCastException x) {
299: throw new IOException(x.toString());
300: }
301: }
302:
303: /**
304: * Create and open a connection input stream.
305: *
306: * @param name The URL for the connection.
307: * @return A DataInputStream.
308: *
309: * @exception IllegalArgumentException If a parameter is invalid.
310: * @exception ConnectionNotFoundException If the connection cannot
311: * be found.
312: * @exception IOException If some other kind of I/O error occurs.
313: */
314: public static DataInputStream openDataInputStream(String name)
315: throws IOException {
316:
317: InputConnection con = (InputConnection) Connector.open(name,
318: Connector.READ);
319:
320: try {
321: return con.openDataInputStream();
322: } finally {
323: con.close();
324: }
325: }
326:
327: /**
328: * Create and open a connection output stream.
329: *
330: * @param name The URL for the connection.
331: * @return A DataOutputStream.
332: *
333: * @exception IllegalArgumentException If a parameter is invalid.
334: * @exception ConnectionNotFoundException If the connection cannot
335: * be found.
336: * @exception IOException If some other kind of I/O error occurs.
337: */
338: public static DataOutputStream openDataOutputStream(String name)
339: throws IOException {
340:
341: OutputConnection con = (OutputConnection) Connector.open(name,
342: Connector.WRITE);
343:
344: try {
345: return con.openDataOutputStream();
346: } finally {
347: con.close();
348: }
349: }
350:
351: /**
352: * Create and open a connection input stream.
353: *
354: * @param name The URL for the connection.
355: * @return An InputStream.
356: *
357: * @exception IllegalArgumentException If a parameter is invalid.
358: * @exception ConnectionNotFoundException If the connection cannot
359: * be found.
360: * @exception IOException If some other kind of I/O error occurs.
361: */
362: public static InputStream openInputStream(String name)
363: throws IOException {
364:
365: return openDataInputStream(name);
366: }
367:
368: /**
369: * Create and open a connection output stream.
370: *
371: * @param name The URL for the connection.
372: * @return An OutputStream.
373: *
374: * @exception IllegalArgumentException If a parameter is invalid.
375: * @exception ConnectionNotFoundException If the connection cannot
376: * be found.
377: * @exception IOException If some other kind of I/O error occurs.
378: */
379: public static OutputStream openOutputStream(String name)
380: throws IOException {
381:
382: return openDataOutputStream(name);
383: }
384:
385: }
|