001: /*
002: * Copyright 1990-2006 Sun Microsystems, Inc. All Rights Reserved.
003: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER
004: *
005: * This program is free software; you can redistribute it and/or
006: * modify it under the terms of the GNU General Public License version
007: * 2 only, as published by the Free Software Foundation.
008: *
009: * This program is distributed in the hope that it will be useful, but
010: * WITHOUT ANY WARRANTY; without even the implied warranty of
011: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012: * General Public License version 2 for more details (a copy is
013: * included at /legal/license.txt).
014: *
015: * You should have received a copy of the GNU General Public License
016: * version 2 along with this work; if not, write to the Free Software
017: * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
018: * 02110-1301 USA
019: *
020: * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
021: * Clara, CA 95054 or visit www.sun.com if you need additional
022: * information or have any questions.
023: */
024:
025: package com.sun.jumpimpl.module.download;
026:
027: import com.sun.jump.module.download.*;
028: import com.sun.jump.common.JUMPApplication;
029: import com.sun.jump.common.JUMPAppModel;
030:
031: import java.net.URL;
032: import java.net.URLConnection;
033: import java.net.HttpURLConnection;
034: import java.net.MalformedURLException;
035: import java.util.Iterator;
036: import java.util.Map;
037: import java.util.Properties;
038: import java.util.Vector;
039: import java.io.OutputStream;
040:
041: public class OMAOTADownloadModule //extends GenericDownloadModuleImpl
042: implements JUMPDownloadModule {
043:
044: // From the JUMPModule interface. Do initialization and uninitialization here.
045: public void load(Map config) {
046: }
047:
048: public void unload() {
049: }
050:
051: public JUMPDownloader createDownloader(
052: JUMPDownloadDescriptor descriptor)
053: throws JUMPDownloadException {
054:
055: return new DownloaderImpl(descriptor);
056: }
057:
058: static String ddMime = "application/vnd.oma.dd+xml";
059:
060: private String encode(String url) {
061: // Change spaces to %20
062: String encodedURL = "";
063: for (int i = 0; i < url.length(); i++) {
064: char c = url.charAt(i);
065: if (c == ' ') {
066: encodedURL += "%20";
067: } else {
068: encodedURL += c;
069: }
070: }
071: return encodedURL;
072: }
073:
074: public JUMPDownloadDescriptor createDescriptor(String url)
075: throws JUMPDownloadException {
076:
077: try {
078:
079: URL ddURL = new URL(encode(url));
080: URLConnection conn = ddURL.openConnection();
081: conn.setRequestProperty("User-Agent",
082: "CDC/FP 1.1 Appmanager");
083:
084: String mimeType = conn.getContentType();
085:
086: if (DownloadModuleFactoryImpl.verbose) {
087: System.err.println("debug : xlet mimetype is "
088: + mimeType);
089: }
090:
091: if (!ddURL.getProtocol().equals("file")
092: && (mimeType == null || !mimeType
093: .equalsIgnoreCase(ddMime))) {
094: throw new JUMPDownloadException(
095: "Content type for the DD URL" + " is not "
096: + ddMime + "\n" + url);
097: }
098:
099: // load the descriptor
100: Parser parser = new Parser();
101: parser.parse(ddURL);
102: Document dd = parser.getDocument();
103:
104: // parse the descriptor into Descriptor class.
105:
106: OMADownloadDescriptor d = new OMADownloadDescriptor(
107: getSchema(), url);
108:
109: Iterator i = dd.getIterator();
110:
111: while (i.hasNext()) {
112: DocumentElement de = (DocumentElement) i.next();
113:
114: String ename = de.getName();
115: String eval = de.getValue();
116:
117: if (DownloadModuleFactoryImpl.verbose) {
118: System.out.println("ename=" + ename + ", eval="
119: + eval);
120: }
121:
122: if ("type".equals(ename)) {
123: d.setType(eval);
124: } else if ("size".equals(ename)) {
125: d.setSize(Integer.parseInt(eval));
126: } else if ("objectURI".equals(ename)) {
127: d.setObjectURI(eval);
128: } else if ("installNotifyURI".equals(ename)) {
129: d.setInstallNotifyURI(eval);
130: } else if ("nextURL".equals(ename)) {
131: d.setNextURI(eval);
132: } else if ("name".equals(ename)) {
133: d.setName(eval);
134: } else if ("ddx:display".equals(ename)) {
135: d.setDisplayName(eval);
136: } else if ("description".equals(ename)) {
137: d.setDescription(eval);
138: } else if ("vendor".equals(ename)) {
139: d.setVendor(eval);
140: } else if ("infoURL".equals(ename)) {
141: d.setInfoURI(eval);
142: } else if ("iconURI".equals(ename)) {
143: d.setIconURI(eval);
144: } else if ("ddx:object".equals(ename)) {
145: extractObjects(d, de);
146: } else if ("ddx:dependencies".equals(ename)) {
147: // Currently no dependency support
148: } else if ("ddx:version".equals(ename)) {
149: d.setVersion(eval);
150: } else if ("ddx:security".equals(ename)) {
151: d.setSecurityLevel(eval);
152: } else {
153: if (DownloadModuleFactoryImpl.verbose) {
154: System.out
155: .println("Warning : unknown OMA tag : "
156: + ename);
157: }
158: }
159: }
160:
161: // Check the descriptor for internal consistency.
162: d.checkOut();
163:
164: return d;
165:
166: } catch (SyntaxException e) {
167: throw new JUMPDownloadException(
168: "The descriptor file is invalid");
169: } catch (JUMPDownloadException e) {
170: throw e;
171: } catch (Throwable e) {
172: throw new JUMPDownloadException("Unexpected error:"
173: + e.getMessage());
174: }
175: }
176:
177: private void extractObjects(OMADownloadDescriptor d,
178: DocumentElement de) throws Exception {
179:
180: if (de == null) {
181: throw new NullPointerException("null DocumentElement!");
182: }
183:
184: JUMPApplication ca = null;
185:
186: Vector elementVector = de.elements;
187: Vector applications = new Vector();
188:
189: for (int i = 0; i < elementVector.size(); i++) {
190: DocumentElement subElement = (DocumentElement) elementVector
191: .get(i);
192:
193: String name = subElement.getName();
194: if ("ddx:application".equals(name)) {
195:
196: d.setType(JUMPDownloadDescriptor.TYPE_APPLICATION);
197:
198: String iconpath = subElement.getAttribute("icon");
199:
200: // Set the propreties of this application
201: Properties props = new Properties();
202: props.setProperty("MAINApplication_initialClass",
203: subElement.getAttribute("classname"));
204: props.setProperty(JUMPApplication.TITLE_KEY, subElement
205: .getAttribute("name"));
206: props.setProperty(JUMPApplication.ICONPATH_KEY,
207: iconpath);
208: props.setProperty(JUMPApplication.APPMODEL_KEY,
209: JUMPAppModel.MAIN.getName());
210: applications.add(props);
211:
212: } else if ("ddx:xlet".equals(name)) {
213:
214: d.setType(JUMPDownloadDescriptor.TYPE_APPLICATION);
215:
216: String iconpath = subElement.getAttribute("icon");
217:
218: // Set the properites of this application
219: Properties props = new Properties();
220: props.setProperty("XLETApplication_initialClass",
221: subElement.getAttribute("classname"));
222: props.setProperty(JUMPApplication.TITLE_KEY, subElement
223: .getAttribute("name"));
224: props.setProperty(JUMPApplication.ICONPATH_KEY,
225: iconpath);
226: props.setProperty(JUMPApplication.APPMODEL_KEY,
227: JUMPAppModel.XLET.getName());
228: applications.add(props);
229:
230: } else if ("ddx:daemon".equals(name)) {
231:
232: // Currently unsupported
233:
234: } else if ("ddx:player".equals(name)) {
235:
236: // Currently unsupported
237:
238: } else if ("ddx:data".equals(name)) {
239:
240: d.setType(JUMPDownloadDescriptor.TYPE_DATA);
241: //d.setData( subElement.getAttribute( "mimetype" ),
242: // subElement.getAttribute( "name" ) );
243: ca = null;
244:
245: } else if ("ddx:library".equals(name)) {
246:
247: String type = subElement.getAttribute("type");
248: d.setType(JUMPDownloadDescriptor.TYPE_LIBRARY);
249: //d.addLibrary( type.equalsIgnoreCase( "java" ) );
250: ca = null;
251:
252: } else if ("ddx:property".equals(name)) {
253:
254: if (ca == null) {
255: throw new SyntaxException("property w/o "
256: + "application context");
257: }
258: ca.addProperty(subElement.getAttribute("name"),
259: subElement.getAttribute("value"));
260:
261: } else if ("ddx:mime".equals(name)) {
262: // This allows us to map a mimetype to a
263: // certain application, which will act as a
264: // "player." Currently unsupported.
265:
266: } else if ("action".equals(name)) {
267:
268: // Currently unsupported
269:
270: } else {
271: if (DownloadModuleFactoryImpl.verbose) {
272: System.out.println("Warning : unknown object tag "
273: + name);
274: }
275: ca = null;
276: }
277: }
278:
279: Object appsArray[] = applications.toArray();
280: Properties apps[] = new Properties[appsArray.length];
281: for (int i = 0; i < appsArray.length; i++) {
282: apps[i] = (Properties) appsArray[i];
283: }
284: d.setApplications(apps);
285: }
286:
287: public boolean sendNotify(String notifyURL, String statusCode,
288: String statusMsg) {
289:
290: try {
291: if ((notifyURL == null) || "".equals(notifyURL)) {
292: return false;
293: }
294:
295: if (DownloadModuleFactoryImpl.verbose) {
296: System.out.println("InstallNotifyURL: " + notifyURL);
297: }
298:
299: URL url = new URL(notifyURL);
300:
301: // Open a connection to the install-notify URL
302: HttpURLConnection huc = (HttpURLConnection) url
303: .openConnection();
304:
305: // This operation sends a POST request
306: huc.setDoOutput(true);
307:
308: if (DownloadModuleFactoryImpl.verbose) {
309: System.out.println("StatusCode=" + statusCode);
310: System.out.println("StatusMsg=" + statusMsg);
311: }
312:
313: // Write the status code and message to the URL
314: OutputStream os = huc.getOutputStream();
315: String content = statusCode + " " + statusMsg;
316: byte[] buf = content.getBytes();
317: os.write(buf);
318: os.flush();
319: os.close();
320:
321: if (huc.getResponseCode() != HttpURLConnection.HTTP_OK) {
322: throw new JUMPDownloadException(
323: "Http response is not OK "
324: + huc.getResponseCode());
325: }
326:
327: huc.disconnect();
328:
329: } catch (Exception e) {
330: e.printStackTrace();
331: return false;
332: }
333: return true;
334: }
335:
336: public String getSchema() {
337: return "oma";
338: }
339: }
|