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: *
017: */
018: package org.apache.tools.ant.types.resources;
019:
020: import java.io.File;
021: import java.io.InputStream;
022: import java.io.OutputStream;
023: import java.io.IOException;
024: import java.io.FilterInputStream;
025:
026: import org.apache.tools.ant.Project;
027: import org.apache.tools.ant.BuildException;
028: import org.apache.tools.ant.types.Resource;
029: import org.apache.tools.ant.types.ResourceCollection;
030: import org.apache.tools.ant.types.Reference;
031: import org.apache.tools.ant.util.FileUtils;
032: import org.apache.tools.zip.ZipFile;
033: import org.apache.tools.zip.ZipEntry;
034:
035: /**
036: * A Resource representation of an entry in a zipfile.
037: * @since Ant 1.7
038: */
039: public class ZipResource extends ArchiveResource {
040:
041: private String encoding;
042:
043: /**
044: * Default constructor.
045: */
046: public ZipResource() {
047: }
048:
049: /**
050: * Construct a ZipResource representing the specified
051: * entry in the specified zipfile.
052: * @param z the zipfile as File.
053: * @param enc the encoding used for filenames.
054: * @param e the ZipEntry.
055: */
056: public ZipResource(File z, String enc, ZipEntry e) {
057: super (z, true);
058: setEncoding(enc);
059: setEntry(e);
060: }
061:
062: /**
063: * Set the zipfile that holds this ZipResource.
064: * @param z the zipfile as a File.
065: */
066: public void setZipfile(File z) {
067: setArchive(z);
068: }
069:
070: /**
071: * Get the zipfile that holds this ZipResource.
072: * @return the zipfile as a File.
073: */
074: public File getZipfile() {
075: FileResource r = (FileResource) getArchive();
076: return r.getFile();
077: }
078:
079: /**
080: * Sets the archive that holds this as a single element Resource
081: * collection.
082: * @param a the archive as a single element Resource collection.
083: */
084: public void addConfigured(ResourceCollection a) {
085: super .addConfigured(a);
086: if (!a.isFilesystemOnly()) {
087: throw new BuildException(
088: "only filesystem resources are supported");
089: }
090: }
091:
092: /**
093: * Set the encoding to use with the zipfile.
094: * @param enc the String encoding.
095: */
096: public void setEncoding(String enc) {
097: checkAttributesAllowed();
098: encoding = enc;
099: }
100:
101: /**
102: * Get the encoding to use with the zipfile.
103: * @return String encoding.
104: */
105: public String getEncoding() {
106: return isReference() ? ((ZipResource) getCheckedRef())
107: .getEncoding() : encoding;
108: }
109:
110: /**
111: * Overrides the super version.
112: * @param r the Reference to set.
113: */
114: public void setRefid(Reference r) {
115: if (encoding != null) {
116: throw tooManyAttributes();
117: }
118: super .setRefid(r);
119: }
120:
121: /**
122: * Return an InputStream for reading the contents of this Resource.
123: * @return an InputStream object.
124: * @throws IOException if the zip file cannot be opened,
125: * or the entry cannot be read.
126: */
127: public InputStream getInputStream() throws IOException {
128: if (isReference()) {
129: return ((Resource) getCheckedRef()).getInputStream();
130: }
131: final ZipFile z = new ZipFile(getZipfile(), getEncoding());
132: ZipEntry ze = z.getEntry(getName());
133: if (ze == null) {
134: z.close();
135: throw new BuildException("no entry " + getName() + " in "
136: + getArchive());
137: }
138: return new FilterInputStream(z.getInputStream(ze)) {
139: public void close() throws IOException {
140: FileUtils.close(in);
141: z.close();
142: }
143:
144: protected void finalize() throws Throwable {
145: try {
146: close();
147: } finally {
148: super .finalize();
149: }
150: }
151: };
152: }
153:
154: /**
155: * Get an OutputStream for the Resource.
156: * @return an OutputStream to which content can be written.
157: * @throws IOException if unable to provide the content of this
158: * Resource as a stream.
159: * @throws UnsupportedOperationException if OutputStreams are not
160: * supported for this Resource type.
161: */
162: public OutputStream getOutputStream() throws IOException {
163: if (isReference()) {
164: return ((Resource) getCheckedRef()).getOutputStream();
165: }
166: throw new UnsupportedOperationException(
167: "Use the zip task for zip output.");
168: }
169:
170: /**
171: * fetches information from the named entry inside the archive.
172: */
173: protected void fetchEntry() {
174: ZipFile z = null;
175: try {
176: z = new ZipFile(getZipfile(), getEncoding());
177: setEntry(z.getEntry(getName()));
178: } catch (IOException e) {
179: log(e.getMessage(), Project.MSG_DEBUG);
180: throw new BuildException(e);
181: } finally {
182: if (z != null) {
183: try {
184: z.close();
185: } catch (IOException e) {
186: //?
187: }
188: }
189: }
190: }
191:
192: private void setEntry(ZipEntry e) {
193: if (e == null) {
194: setExists(false);
195: return;
196: }
197: setName(e.getName());
198: setExists(true);
199: setLastModified(e.getTime());
200: setDirectory(e.isDirectory());
201: setSize(e.getSize());
202: setMode(e.getUnixMode());
203: }
204:
205: }
|