001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.geronimo.console.databasemanager.wizard;
017:
018: import java.io.BufferedOutputStream;
019: import java.io.File;
020: import java.io.FileOutputStream;
021: import java.io.IOException;
022: import java.io.InputStream;
023: import java.io.OutputStream;
024: import java.io.Serializable;
025: import java.net.MalformedURLException;
026: import java.net.URL;
027: import java.net.URLConnection;
028: import java.util.ArrayList;
029: import java.util.Collections;
030: import java.util.HashSet;
031: import java.util.Iterator;
032: import java.util.List;
033: import java.util.Properties;
034: import java.util.Random;
035: import java.util.Set;
036: import java.util.jar.JarEntry;
037: import java.util.jar.JarFile;
038: import org.apache.commons.logging.Log;
039: import org.apache.commons.logging.LogFactory;
040: import org.apache.geronimo.kernel.repository.Artifact;
041: import org.apache.geronimo.kernel.repository.FileWriteMonitor;
042: import org.apache.geronimo.kernel.repository.WriteableRepository;
043:
044: /**
045: * A utility that handles listing and downloading available JDBC driver JARs.
046: * It can handle straight JARs and also JARs in ZIP files.
047: *
048: * @version $Rev: 476061 $ $Date: 2006-11-16 22:36:50 -0800 (Thu, 16 Nov 2006) $
049: */
050: public class DriverDownloader {
051: private final static Log log = LogFactory
052: .getLog(DriverDownloader.class);
053: Random random;
054:
055: public Properties readDriverFile(URL url) {
056: try {
057: InputStream in = url.openStream();
058: Properties props = new Properties();
059: props.load(in);
060: in.close();
061: return props;
062: } catch (IOException e) {
063: log.error("Unable to download driver properties", e);
064: return null;
065: }
066: }
067:
068: public DriverInfo[] loadDriverInfo(URL driverInfoFile) {
069: List list = new ArrayList();
070: Properties props = readDriverFile(driverInfoFile);
071: if (props == null) {
072: return new DriverInfo[0];
073: }
074: Set drivers = new HashSet();
075: for (Iterator it = props.keySet().iterator(); it.hasNext();) {
076: String key = (String) it.next();
077: if (!key.startsWith("driver.")) {
078: continue;
079: }
080: int pos = key.indexOf('.', 7);
081: if (pos > -1) {
082: drivers.add(key.substring(7, pos));
083: }
084: }
085: List urls = new ArrayList();
086: for (Iterator it = drivers.iterator(); it.hasNext();) {
087: String driver = (String) it.next();
088: String name = props.getProperty("driver." + driver
089: + ".name");
090: String repository = props.getProperty("driver." + driver
091: + ".repository");
092: String unzip = props.getProperty("driver." + driver
093: + ".unzip");
094: urls.clear();
095: int index = 1;
096: while (true) {
097: String url = props.getProperty("driver." + driver
098: + ".url." + index);
099: if (url != null) {
100: ++index;
101: try {
102: urls.add(new URL(url));
103: } catch (MalformedURLException e) {
104: log
105: .error(
106: "Unable to process URL from driver list",
107: e);
108: }
109: } else {
110: break;
111: }
112: }
113: if (name != null && repository != null && urls.size() > 0) {
114: DriverInfo info = new DriverInfo(name, repository);
115: info.setUnzipPath(unzip);
116: info
117: .setUrls((URL[]) urls.toArray(new URL[urls
118: .size()]));
119: list.add(info);
120: }
121: }
122: Collections.sort(list);
123: return (DriverInfo[]) list.toArray(new DriverInfo[list.size()]);
124: }
125:
126: /**
127: * Downloads a driver and loads it into the local repository.
128: */
129: public void loadDriver(WriteableRepository repo, DriverInfo driver,
130: FileWriteMonitor monitor) throws IOException {
131: int urlIndex = 0;
132: if (driver.urls.length > 1) {
133: if (random == null) {
134: random = new Random();
135: }
136: urlIndex = random.nextInt(driver.urls.length);
137: }
138: URL url = driver.urls[urlIndex];
139: InputStream in;
140: String uri = driver.getRepositoryURI();
141: if (driver.unzipPath != null) {
142: byte[] buf = new byte[1024];
143: int size;
144: int total = 0;
145: int threshold = 10240;
146: URLConnection uc = url.openConnection();
147: int filesize = uc.getContentLength();
148: InputStream net = uc.getInputStream();
149: JarFile jar = null;
150: File download = null;
151: try {
152: download = File.createTempFile(
153: "geronimo-driver-download", ".zip");
154: OutputStream out = new BufferedOutputStream(
155: new FileOutputStream(download));
156: if (monitor != null) {
157: monitor.writeStarted("Download driver archive to "
158: + download, filesize);
159: }
160: try {
161: while ((size = net.read(buf)) > -1) {
162: out.write(buf, 0, size);
163: if (monitor != null) {
164: total += size;
165: if (total > threshold) {
166: monitor.writeProgress(total);
167: threshold += 10240;
168: }
169: }
170: }
171: out.flush();
172: out.close();
173: } finally {
174: if (monitor != null) {
175: monitor.writeComplete(total);
176: }
177: }
178: jar = new JarFile(download);
179: JarEntry entry = jar.getJarEntry(driver.unzipPath);
180: if (entry == null) {
181: log.error("Cannot extract driver JAR "
182: + driver.unzipPath + " from download file "
183: + url);
184: } else {
185: in = jar.getInputStream(entry);
186: repo.copyToRepository(in, (int) entry.getSize(),
187: Artifact.create(uri), monitor);
188: }
189: } finally {
190: if (jar != null)
191: try {
192: jar.close();
193: } catch (IOException e) {
194: log.error("Unable to close JAR file", e);
195: }
196: if (download != null) {
197: download.delete();
198: }
199: }
200: } else {
201: URLConnection con = url.openConnection();
202: in = con.getInputStream();
203: repo.copyToRepository(in, con.getContentLength(), Artifact
204: .create(uri), monitor);
205: }
206: }
207:
208: public static class DriverInfo implements Comparable, Serializable {
209: private final static long serialVersionUID = -1202452382992975449L;
210:
211: private String name;
212: private String repositoryURI;
213: private String unzipPath;
214: private URL[] urls;
215:
216: public DriverInfo(String name, String repositoryURI) {
217: this .name = name;
218: this .repositoryURI = repositoryURI;
219: }
220:
221: public String getName() {
222: return name;
223: }
224:
225: public void setName(String name) {
226: this .name = name;
227: }
228:
229: public String getRepositoryURI() {
230: return repositoryURI;
231: }
232:
233: public void setRepositoryURI(String repositoryURI) {
234: this .repositoryURI = repositoryURI;
235: }
236:
237: public String getUnzipPath() {
238: return unzipPath;
239: }
240:
241: public void setUnzipPath(String unzipPath) {
242: this .unzipPath = unzipPath;
243: }
244:
245: public URL[] getUrls() {
246: return urls;
247: }
248:
249: public void setUrls(URL[] urls) {
250: this .urls = urls;
251: }
252:
253: public int compareTo(Object o) {
254: return name.compareTo(((DriverInfo) o).name);
255: }
256: }
257: }
|