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 java.net.URL;
028: import java.net.URLConnection;
029: import java.net.HttpURLConnection;
030: import java.util.HashMap;
031: import java.io.InputStream;
032:
033: import javax.xml.parsers.*;
034: import org.xml.sax.*;
035: import org.xml.sax.helpers.DefaultHandler;
036:
037: public class OTADiscovery {
038:
039: static final String htmlMime = "text/html";
040: static final String xmlMime = "text/xml";
041:
042: public HashMap discover(String url) {
043:
044: try {
045:
046: URL netUrl = new URL(url);
047: URLConnection conn = netUrl.openConnection();
048: conn.connect();
049:
050: if (DownloadModuleFactoryImpl.verbose) {
051: System.err.println("debug : discover mimetype is "
052: + conn.getContentType());
053: }
054:
055: String contentType = conn.getContentType().toLowerCase();
056: // Apache Web server adds encoding type to this field. So we have to look if it contains text/html...
057: if (contentType.indexOf(htmlMime.toLowerCase()) != -1)
058: return doHTMLDiscovery(url, netUrl, conn);
059: // ... or text/xml
060: else if (contentType.indexOf(xmlMime.toLowerCase()) != -1)
061: return doXMLDiscovery(url, netUrl, conn);
062: else
063: throw new Exception("Content type for the applist "
064: + "is neither " + htmlMime + " nor " + xmlMime);
065: } catch (Exception e) {
066: e.printStackTrace();
067: }
068: // Nothing was found. Return empty.
069: return new HashMap();
070: }
071:
072: private static HashMap doHTMLDiscovery(String url, URL netUrl,
073: URLConnection conn) {
074: try {
075: String rst = "";
076: InputStream in = conn.getInputStream();
077:
078: while (true) {
079:
080: byte[] data = new byte[16384];
081: int rd = in.read(data);
082: if (rd < 0) {
083: break;
084: }
085: rst = rst + new String(data, 0, rd);
086: }
087:
088: HashMap h = new HashMap();
089:
090: // parse
091:
092: String copy = rst.toLowerCase();
093:
094: while (true) {
095:
096: // require reference in enclosed into quotation marks
097: int idx = copy.indexOf("<a href=\"");
098:
099: if (idx < 0) {
100: break;
101: }
102:
103: try {
104:
105: rst = rst.substring(idx + 9);
106:
107: idx = rst.indexOf('"');
108: // get the reference
109:
110: String ref = rst.substring(0, idx);
111:
112: rst = rst.substring(idx);
113:
114: idx = rst.indexOf('>');
115: rst = rst.substring(idx + 1);
116:
117: // strictly, we should search to the next </a>,
118: // but we only will until first '<'
119: idx = rst.indexOf('<');
120: String name = rst.substring(0, idx);
121:
122: // let's use one helper function to get full URI
123: ref = ServerConfXMLHandler.getFullURI(netUrl, url,
124: ref);
125:
126: h.put(ref, name);
127:
128: } catch (Exception e) {
129: System.err.println("Parsing got an exception" + e);
130: break;
131: }
132: copy = rst.toLowerCase();
133: }
134:
135: return h;
136:
137: } catch (java.io.IOException e) {
138: System.err.println("Cannot read html content " + e);
139: }
140: return new HashMap();
141: }
142:
143: private static HashMap doXMLDiscovery(String url, URL netUrl,
144: URLConnection conn) {
145: try {
146: InputStream in = conn.getInputStream();
147:
148: SAXParserFactory factory = SAXParserFactory.newInstance();
149: SAXParser parser = factory.newSAXParser();
150:
151: ServerConfXMLHandler handler = new ServerConfXMLHandler(
152: url, netUrl);
153: parser.parse(in, handler);
154:
155: return handler.getMap();
156: } catch (org.xml.sax.SAXException saxExc) {
157: System.err.println("Cannot parse xml content " + saxExc);
158: } catch (javax.xml.parsers.ParserConfigurationException parserExc) {
159: System.err.println("Cannot create an xml parser "
160: + parserExc);
161: } catch (java.io.IOException ioExc) {
162: System.err.println("Cannot read xml content " + ioExc);
163: }
164: return new HashMap();
165: }
166: }
167:
168: class ServerConfXMLHandler extends DefaultHandler {
169:
170: private HashMap hmap;
171: private String state = "";
172: private String path = "";
173:
174: private String targetURI = "";
175: private String targetName = "";
176:
177: private String chars = "";
178: private String url = "";
179: private URL netUrl;
180:
181: public ServerConfXMLHandler(String url, URL netUrl) {
182: this .url = url;
183: this .netUrl = netUrl;
184: hmap = new HashMap();
185: }
186:
187: public HashMap getMap() {
188: return hmap;
189: }
190:
191: public void startElement(String uri, String localName,
192: String qName, Attributes attributes) throws SAXException {
193:
194: // building xml-path of the current tag
195: path = path.concat("/").concat(qName.toLowerCase());
196: }
197:
198: public void endElement(String uri, String localName, String qName)
199: throws SAXException {
200: // if we have got both the name and the uri of the target, put it into the map...
201: if (!"".equals(targetName) && !"".equals(targetURI)) {
202: hmap.put(targetURI, targetName);
203: // ... and clean it
204: targetName = "";
205: targetURI = "";
206: }
207: // if we get reached a name tag, save the name of the target
208: if ("/servercontent/dd:media/product/mediaobject/meta/name"
209: .equals(path)) {
210: targetName = chars.trim();
211: }
212: // if we get reached a server tag, save the the uri of the target
213: if ("/servercontent/dd:media/product/mediaobject/objecturi/server"
214: .equals(path)) {
215: String ref = targetURI.concat(chars.trim());
216: targetURI = getFullURI(netUrl, url, ref);
217: }
218: chars = "";
219:
220: // go back with the path
221: path = path.substring(0, path.lastIndexOf("/"));
222: }
223:
224: public void characters(char ch[], int start, int length)
225: throws SAXException {
226: chars = chars + new String(ch, start, length);
227: }
228:
229: /**
230: * Returns an absolute URI of the target object based on descriptor request URL.
231: * @param netUrl the URL of descriptor request.
232: * @param url the string representation of descriptor request.
233: * @param ref target object reference.
234: * @return a full URI of the target object
235: */
236: public static String getFullURI(URL netUrl, String url, String ref) {
237: if (ref.startsWith("/")) {
238: // relative to the hostname
239: String base = netUrl.getProtocol() + "://"
240: + netUrl.getHost();
241: if (netUrl.getPort() < 0)
242: ref = base + ref;
243: else
244: ref = base + ":" + netUrl.getPort() + ref;
245: }
246:
247: if (ref.indexOf(':') < 0) {
248: // relative to current directory
249: ref = url.substring(0, url.lastIndexOf('/') + 1) + ref;
250: }
251: return ref;
252: }
253: }
|