001: /*
002: * Enhydra Java Application Server Project
003: *
004: * The contents of this file are subject to the Enhydra Public License
005: * Version 1.1 (the "License"); you may not use this file except in
006: * compliance with the License. You may obtain a copy of the License on
007: * the Enhydra web site ( http://www.enhydra.org/ ).
008: *
009: * Software distributed under the License is distributed on an "AS IS"
010: * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
011: * the License for the specific terms governing rights and limitations
012: * under the License.
013: *
014: * The Initial Developer of the Enhydra Application Server is Lutris
015: * Technologies, Inc. The Enhydra Application Server and portions created
016: * by Lutris Technologies, Inc. are Copyright Lutris Technologies, Inc.
017: * All Rights Reserved.
018: *
019: * Contributor(s):
020: *
021: * $Id: RemoteZipResource.java,v 1.2 2006-06-15 14:07:00 sinisa Exp $
022: */
023:
024: package com.lutris.classloader;
025:
026: // lutris packages
027: // v. strahinja, 27 sep 2002
028: import java.io.FileNotFoundException;
029: import java.io.IOException;
030: import java.io.InputStream;
031: import java.net.URL;
032: import java.util.zip.ZipEntry;
033: import java.util.zip.ZipInputStream;
034:
035: import com.lutris.logging.LogChannel;
036: import com.lutris.util.FatalExceptionError;
037:
038: /**
039: * <P>A <CODE>Resource</CODE> that is an entry in
040: * a specified zip file on a remote machine. The zip file is represented by a
041: * <CODE>ClassPathEntry</CODE>, and the filename is specified by a String.
042: *
043: * @author Kristen Pol, Lutris Technologies
044: * @version $Revision : 1.1 $
045: * @see com.lutris.classloader.MultiClassLoader
046: * @see com.lutris.classloader.ClassPathEntry
047: * @see com.lutris.classloader.Resource
048: * @see java.io.File
049: */
050: public class RemoteZipResource extends Resource {
051:
052: // data members
053:
054: URL zipFileURL = null;
055:
056: // constructors
057:
058: // FIXME: Test and change to protected and add javadoc. (kp)
059: private RemoteZipResource(String name, ClassPathEntry location,
060: // v. strahinja, 27 sep 2002
061: LogChannel loadLogChannel)
062: // Logger loadLogger)
063: throws FileNotFoundException {
064: // v. strahinja, 27 sep 2002
065: super (name, location, loadLogChannel);
066: // super(name, location, loadLogger);
067:
068: // Get location's URL
069: zipFileURL = location.getURL();
070: if (zipFileURL == null) {
071: String error = "The URL for location, " + location
072: + ", is null";
073: // v. strahinja, 27 sep 2002
074: logChannel.write(logLevel, error);
075: // logger.log(logLevel, error);
076: throw new FileNotFoundException(error);
077: }
078:
079: // Make sure the ZipEntry exists in the remote zip file
080: // FileNotFoundException will be thrown if it is not found
081: ZipInputStream zipStream = null;
082: try {
083: zipStream = getZipInputStream();
084: if (zipStream == null) {
085: String error = "URL \""
086: + zipFileURL
087: + "\" does not exist, "
088: + "can not be reached, or is not a zip file; or the "
089: + "resource \"" + name
090: + "\" is not in the zip file";
091: // v. strahinja, 27 sep 2002
092: logChannel.write(logLevel, error);
093: // logger.log(logLevel, error);
094: throw new FileNotFoundException(error);
095: }
096: } finally {
097: if (zipStream != null) {
098: try {
099: zipStream.close();
100: } catch (IOException ioe) {
101: // This should not happen because it was already checked
102: String error = ioe.toString() + ": URL zip file \""
103: + zipFileURL
104: + "\" is corrupt or the connection died";
105: // v. strahinja, 27 sep 2002
106: logChannel.write(logLevel, error);
107: // logger.log(logLevel, error);
108: throw new FatalExceptionError(
109: new IOException(error));
110: }
111: }
112: }
113: }
114:
115: // public methods
116:
117: /**
118: * Gets the specified resource as an input stream.
119: *
120: * @return an <CODE>InputStream</CODE> representing the specified resource.
121: * @exception an <CODE>IOException</CODE>
122: */
123: public InputStream getInputStream() throws IOException {
124: try {
125: return getZipInputStream();
126: } catch (FileNotFoundException fnfe) {
127: // This should not happen because it was already checked
128: String error = "URL zip file \""
129: + zipFileURL
130: + "\" has disappeared or can no longer be reached; or the "
131: + "resource \"" + name
132: + "\" is no longer in the zip file";
133: // v. strahinja, 27 sep 2002
134: logChannel.write(logLevel, error);
135: // logger.log(logLevel, error);
136: throw new FatalExceptionError(new FileNotFoundException(
137: error));
138: }
139: }
140:
141: // Get the input stream for the resource to if it exists.
142: private ZipInputStream getZipInputStream()
143: throws FileNotFoundException {
144: ZipInputStream zipStream;
145: try {
146: zipStream = new ZipInputStream(zipFileURL.openStream());
147: while (zipStream.available() > 0) {
148: ZipEntry entry = zipStream.getNextEntry();
149: if (entry == null) {
150: // v. strahinja, 27 sep 2002
151: logChannel.write(logLevel, "Null zip entry.");
152: // logger.log(logLevel, "Null zip entry.");
153: throw new IOException();
154: }
155: if (entry.getName().equals(name)) {
156: size = entry.getSize();
157: lastModifiedTime = entry.getTime();
158: return zipStream;
159: }
160: zipStream.closeEntry();
161: }
162: } catch (IOException e) {
163: String error = "URL, "
164: + zipFileURL
165: + ", does not exist, "
166: + "can not be reached, is not a zip file, or the resource, "
167: + name + ", is not in the zip file";
168: // v. strahinja, 27 sep 2002
169: logChannel.write(logLevel, error);
170: // logger.log(logLevel, error);
171: throw new FileNotFoundException(error);
172: }
173: return null;
174: }
175:
176: /**
177: * Get current last-modification time of resource. This is the
178: * time on the disk file the resource is associated with.
179: *
180: * @return the last-modified time of the permanent copy of the resource
181: * in milliseconds.
182: */
183: public long getCurrentLastModifiedTime() {
184: return -1; //FIXME: implement
185: }
186: }
|