001: /*
002: *
003: *
004: * Copyright 1990-2007 Sun Microsystems, Inc. All Rights Reserved.
005: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
006: *
007: * This program is free software; you can redistribute it and/or
008: * modify it under the terms of the GNU General Public License version
009: * 2 only, as published by the Free Software Foundation.
010: *
011: * This program is distributed in the hope that it will be useful, but
012: * WITHOUT ANY WARRANTY; without even the implied warranty of
013: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
014: * General Public License version 2 for more details (a copy is
015: * included at /legal/license.txt).
016: *
017: * You should have received a copy of the GNU General Public License
018: * version 2 along with this work; if not, write to the Free Software
019: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA
021: *
022: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
023: * Clara, CA 95054 or visit www.sun.com if you need additional
024: * information or have any questions.
025: */
026:
027: package com.sun.midp.io.j2me.push;
028:
029: import com.sun.midp.midlet.MIDletSuite;
030: import java.io.IOException;
031: import javax.microedition.io.ConnectionNotFoundException;
032: import com.sun.midp.main.Configuration;
033: import com.sun.midp.io.HttpUrl;
034:
035: /**
036: * JSR's implementations will provide push behaviour.
037: */
038: public abstract class ProtocolPush {
039:
040: /**
041: * Number of delimiter characters in IP v4 address
042: */
043: protected static final int IP4_DELIMITER_COUNT = 3;
044:
045: /**
046: * Get instance of this class.
047: * @return class instance
048: */
049: protected abstract ProtocolPush getInstance();
050:
051: /**
052: * Get instance of class depends on protocol.
053: * @param connection generic connection <em>protocol</em>, <em>host</em>
054: * and <em>port number</em>
055: * (optional parameters may be included
056: * separated with semi-colons (;))
057: * @return class instance
058: * @exception IllegalArgumentException if the connection string is not
059: * valid
060: * @exception ConnectionNotFoundException if the protocol is not
061: * supported or invalid
062: */
063: public static ProtocolPush getInstance(String connection)
064: throws IllegalArgumentException,
065: ConnectionNotFoundException {
066:
067: /* Verify that the connection requested is valid. */
068: if (connection == null || connection.length() == 0) {
069: throw new IllegalArgumentException("Connection is empty");
070: }
071:
072: int index = connection.indexOf(':');
073: if (index == -1) {
074: throw new IllegalArgumentException(
075: "Protocol field is omitted");
076: }
077:
078: String className = Configuration.getProperty(connection
079: .substring(0, index).toLowerCase());
080:
081: if (className == null || className.length() == 0) {
082: throw new ConnectionNotFoundException(
083: "Protocol is invalid " + "or not supported");
084: }
085:
086: try {
087: ProtocolPush cl = (ProtocolPush) Class.forName(className)
088: .newInstance();
089: return cl.getInstance();
090: } catch (ClassNotFoundException exc) {
091: throw new ConnectionNotFoundException(
092: "Protocol is not supported");
093: } catch (ClassCastException exc) {
094: throw new RuntimeException("System error loading class "
095: + className + ": " + exc);
096: } catch (IllegalAccessException exc) {
097: throw new RuntimeException("System error loading class "
098: + className + ": " + exc);
099: } catch (InstantiationException exc) {
100: throw new RuntimeException("System error loading class "
101: + className + ": " + exc);
102: }
103: }
104:
105: /**
106: * Called when registration is checked.
107: * @param connection generic connection <em>protocol</em>, <em>host</em>
108: * and <em>port number</em>
109: * (optional parameters may be included
110: * separated with semi-colons (;))
111: * @param midlet class name of the <code>MIDlet</code> to be launched,
112: * when new external data is available
113: * @param filter a connection URL string indicating which senders
114: * are allowed to cause the MIDlet to be launched
115: * @exception IllegalArgumentException if the connection string is not
116: * valid
117: * @exception ClassNotFoundException if the <code>MIDlet</code> class
118: * name can not be found in the current
119: * <code>MIDlet</code> suite
120: */
121: public abstract void checkRegistration(String connection,
122: String midlet, String filter);
123:
124: /**
125: * Called when registration is established.
126: * @param midletSuite MIDlet suite for the suite registering,
127: * the suite only has to implement isRegistered,
128: * checkForPermission, and getID.
129: * @param connection generic connection <em>protocol</em>, <em>host</em>
130: * and <em>port number</em>
131: * (optional parameters may be included
132: * separated with semi-colons (;))
133: * @param midlet class name of the <code>MIDlet</code> to be launched,
134: * when new external data is available
135: * @param filter a connection URL string indicating which senders
136: * are allowed to cause the MIDlet to be launched
137: * @exception IllegalArgumentException if the connection string is not
138: * valid
139: * @exception IOException if the connection is already
140: * registered or if there are insufficient resources
141: * to handle the registration request
142: * @exception ClassNotFoundException if the <code>MIDlet</code> class
143: * name can not be found in the current
144: * <code>MIDlet</code> suite
145: */
146: public abstract void registerConnection(MIDletSuite midletSuite,
147: String connection, String midlet, String filter)
148: throws IllegalArgumentException, IOException,
149: ClassNotFoundException;
150:
151: /**
152: * Check if host is not present.
153: * @param connection generic connection <em>protocol</em>, <em>host</em>
154: * and <em>port number</em>
155: * (optional parameters may be included
156: * separated with semi-colons (;))
157: * @param checkPort check if the port is not omitted
158: * @exception IllegalArgumentException if the connection contains no port
159: * value
160: * @exception ConnectionNotFoundException if connection contains any host
161: * name
162: */
163: protected void checkIsNotHost(String connection, boolean checkPort)
164: throws IllegalArgumentException,
165: ConnectionNotFoundException {
166: HttpUrl url = new HttpUrl(connection);
167: // Server connections do not have a host
168: if (url.host != null) {
169: throw new ConnectionNotFoundException(
170: "Connection not supported");
171: }
172:
173: if (checkPort && url.port == -1) {
174: new IllegalArgumentException("Port missing");
175: }
176: }
177:
178: /**
179: * Check IP filter is valid.
180: * @param filter a connection URL string indicating which senders
181: * are allowed to cause the MIDlet to be launched
182: * @exception IllegalArgumentException if the connection contains no port
183: * value
184: */
185: protected void checkIIPFilter(String filter)
186: throws IllegalArgumentException {
187: int len = filter.length();
188: int dotCount = 0;
189: boolean dotUnexpected = true;
190: boolean failed = false;
191:
192: /* IP address characters only for other connections. */
193: /* Check for special case - single * char. This is valid filter. */
194: if (!"*".equals(filter)) {
195: /* All other filters shall be in IPv4 format. */
196: for (int i = 0; i < len && !failed; i++) {
197: char c = filter.charAt(i);
198:
199: if (c == '.') {
200: if (dotUnexpected || i == len - 1) {
201: failed = true;
202: } else {
203: dotCount++;
204: if (dotCount > IP4_DELIMITER_COUNT) {
205: failed = true;
206: }
207: dotUnexpected = true;
208: }
209: } else if (c != '?' && c != '*'
210: && !('0' <= c && c <= '9')) {
211: /* The only acceptable characters are [*?0-9] */
212: failed = true;
213: } else {
214: dotUnexpected = false;
215: }
216: }
217:
218: if (failed || dotCount < IP4_DELIMITER_COUNT) {
219: throw new IllegalArgumentException("IP Filter \""
220: + filter + "\" is invalid");
221: }
222: }
223: }
224: }
|