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:
019: package org.apache.tools.ant.taskdefs;
020:
021: import java.io.File;
022: import java.io.IOException;
023: import java.io.InputStream;
024: import java.io.OutputStream;
025: import org.apache.tools.ant.BuildException;
026: import org.apache.tools.ant.Task;
027: import org.apache.tools.ant.types.Resource;
028: import org.apache.tools.ant.types.ResourceCollection;
029: import org.apache.tools.ant.types.resources.FileResource;
030:
031: /**
032: * Abstract Base class for pack tasks.
033: *
034: * @since Ant 1.5
035: */
036:
037: public abstract class Pack extends Task {
038:
039: // CheckStyle:VisibilityModifier OFF - bc
040: protected File zipFile;
041: protected File source;
042: // CheckStyle:VisibilityModifier ON
043: private Resource src;
044:
045: /**
046: * the required destination file.
047: * @param zipFile the destination file
048: */
049: public void setZipfile(File zipFile) {
050: this .zipFile = zipFile;
051: }
052:
053: /**
054: * the required destination file.
055: * @param zipFile the destination file
056: */
057: public void setDestfile(File zipFile) {
058: setZipfile(zipFile);
059: }
060:
061: /**
062: * the file to compress; required.
063: * @param src the source file
064: */
065: public void setSrc(File src) {
066: setSrcResource(new FileResource(src));
067: }
068:
069: /**
070: * The resource to pack; required.
071: * @param src resource to expand
072: */
073: public void setSrcResource(Resource src) {
074: if (src.isDirectory()) {
075: throw new BuildException("the source can't be a directory");
076: }
077: if (src instanceof FileResource) {
078: source = ((FileResource) src).getFile();
079: } else if (!supportsNonFileResources()) {
080: throw new BuildException("Only FileSystem resources are"
081: + " supported.");
082: }
083: this .src = src;
084: }
085:
086: /**
087: * Set the source resource.
088: * @param a the resource to pack as a single element Resource collection.
089: */
090: public void addConfigured(ResourceCollection a) {
091: if (a.size() != 1) {
092: throw new BuildException(
093: "only single argument resource collections"
094: + " are supported as archives");
095: }
096: setSrcResource((Resource) a.iterator().next());
097: }
098:
099: /**
100: * validation routine
101: * @throws BuildException if anything is invalid
102: */
103: private void validate() throws BuildException {
104: if (zipFile == null) {
105: throw new BuildException("zipfile attribute is required",
106: getLocation());
107: }
108:
109: if (zipFile.isDirectory()) {
110: throw new BuildException("zipfile attribute must not "
111: + "represent a directory!", getLocation());
112: }
113:
114: if (getSrcResource() == null) {
115: throw new BuildException(
116: "src attribute or nested resource is" + " required",
117: getLocation());
118: }
119: }
120:
121: /**
122: * validate, then hand off to the subclass
123: * @throws BuildException on error
124: */
125: public void execute() throws BuildException {
126: validate();
127:
128: Resource s = getSrcResource();
129: if (!s.isExists()) {
130: log("Nothing to do: " + s.toString() + " doesn't exist.");
131: } else if (zipFile.lastModified() < s.getLastModified()) {
132: log("Building: " + zipFile.getAbsolutePath());
133: pack();
134: } else {
135: log("Nothing to do: " + zipFile.getAbsolutePath()
136: + " is up to date.");
137: }
138: }
139:
140: /**
141: * zip a stream to an output stream
142: * @param in the stream to zip
143: * @param zOut the output stream
144: * @throws IOException
145: */
146: private void zipFile(InputStream in, OutputStream zOut)
147: throws IOException {
148: byte[] buffer = new byte[8 * 1024];
149: int count = 0;
150: do {
151: zOut.write(buffer, 0, count);
152: count = in.read(buffer, 0, buffer.length);
153: } while (count != -1);
154: }
155:
156: /**
157: * zip a file to an output stream
158: * @param file the file to zip
159: * @param zOut the output stream
160: * @throws IOException on error
161: */
162: protected void zipFile(File file, OutputStream zOut)
163: throws IOException {
164: zipResource(new FileResource(file), zOut);
165: }
166:
167: /**
168: * zip a resource to an output stream
169: * @param resource the resource to zip
170: * @param zOut the output stream
171: * @throws IOException on error
172: */
173: protected void zipResource(Resource resource, OutputStream zOut)
174: throws IOException {
175: InputStream rIn = resource.getInputStream();
176: try {
177: zipFile(rIn, zOut);
178: } finally {
179: rIn.close();
180: }
181: }
182:
183: /**
184: * subclasses must implement this method to do their compression
185: */
186: protected abstract void pack();
187:
188: /**
189: * The source resource.
190: * @return the source.
191: * @since Ant 1.7
192: */
193: public Resource getSrcResource() {
194: return src;
195: }
196:
197: /**
198: * Whether this task can deal with non-file resources.
199: *
200: * <p>This implementation returns false.</p>
201: * @return false.
202: * @since Ant 1.7
203: */
204: protected boolean supportsNonFileResources() {
205: return false;
206: }
207: }
|