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:
022: import org.apache.tools.ant.BuildException;
023: import org.apache.tools.ant.types.Resource;
024: import org.apache.tools.ant.types.ResourceCollection;
025: import org.apache.tools.ant.types.Reference;
026:
027: /**
028: * A Resource representation of an entry inside an archive.
029: * @since Ant 1.7
030: */
031: public abstract class ArchiveResource extends Resource {
032: private static final int NULL_ARCHIVE = Resource
033: .getMagicNumber("null archive".getBytes());
034:
035: private Resource archive;
036: private boolean haveEntry = false;
037: private boolean modeSet = false;
038: private int mode = 0;
039:
040: /**
041: * Default constructor.
042: */
043: public ArchiveResource() {
044: }
045:
046: /**
047: * Construct a ArchiveResource representing the specified
048: * entry in the specified archive.
049: * @param a the archive as File.
050: */
051: public ArchiveResource(File a) {
052: this (a, false);
053: }
054:
055: /**
056: * Construct a ArchiveResource representing the specified
057: * entry in the specified archive.
058: * @param a the archive as File.
059: * @param withEntry if the entry has been specified.
060: */
061: public ArchiveResource(File a, boolean withEntry) {
062: setArchive(a);
063: haveEntry = withEntry;
064: }
065:
066: /**
067: * Construct a ArchiveResource representing the specified
068: * entry in the specified archive.
069: * @param a the archive as Resource.
070: * @param withEntry if the entry has been specified.
071: */
072: public ArchiveResource(Resource a, boolean withEntry) {
073: addConfigured(a);
074: haveEntry = withEntry;
075: }
076:
077: /**
078: * Set the archive that holds this Resource.
079: * @param a the archive as a File.
080: */
081: public void setArchive(File a) {
082: checkAttributesAllowed();
083: archive = new FileResource(a);
084: }
085:
086: /**
087: * Sets the file or dir mode for this resource.
088: * @param mode integer representation of Unix permission mask.
089: */
090: public void setMode(int mode) {
091: checkAttributesAllowed();
092: this .mode = mode;
093: modeSet = true;
094: }
095:
096: /**
097: * Sets the archive that holds this as a single element Resource
098: * collection.
099: * @param a the archive as a single element Resource collection.
100: */
101: public void addConfigured(ResourceCollection a) {
102: checkChildrenAllowed();
103: if (archive != null) {
104: throw new BuildException(
105: "you must not specify more than one" + " archive");
106: }
107: if (a.size() != 1) {
108: throw new BuildException(
109: "only single argument resource collections"
110: + " are supported as archives");
111: }
112: archive = (Resource) a.iterator().next();
113: }
114:
115: /**
116: * Get the archive that holds this Resource.
117: * @return the archive as a Resource.
118: */
119: public Resource getArchive() {
120: return isReference() ? ((ArchiveResource) getCheckedRef())
121: .getArchive() : archive;
122: }
123:
124: /**
125: * Get the last modified date of this Resource.
126: * @return the last modification date.
127: */
128: public long getLastModified() {
129: if (isReference()) {
130: return ((Resource) getCheckedRef()).getLastModified();
131: }
132: checkEntry();
133: return super .getLastModified();
134: }
135:
136: /**
137: * Get the size of this Resource.
138: * @return the long size of this Resource.
139: */
140: public long getSize() {
141: if (isReference()) {
142: return ((Resource) getCheckedRef()).getSize();
143: }
144: checkEntry();
145: return super .getSize();
146: }
147:
148: /**
149: * Learn whether this Resource represents a directory.
150: * @return boolean flag indicating whether the entry is a directory.
151: */
152: public boolean isDirectory() {
153: if (isReference()) {
154: return ((Resource) getCheckedRef()).isDirectory();
155: }
156: checkEntry();
157: return super .isDirectory();
158: }
159:
160: /**
161: * Find out whether this Resource represents an existing Resource.
162: * @return boolean existence flag.
163: */
164: public boolean isExists() {
165: if (isReference()) {
166: return ((Resource) getCheckedRef()).isExists();
167: }
168: checkEntry();
169: return super .isExists();
170: }
171:
172: /**
173: * Get the file or dir mode for this Resource.
174: * @return integer representation of Unix permission mask.
175: */
176: public int getMode() {
177: if (isReference()) {
178: return ((ArchiveResource) getCheckedRef()).getMode();
179: }
180: checkEntry();
181: return mode;
182: }
183:
184: /**
185: * Overrides the super version.
186: * @param r the Reference to set.
187: */
188: public void setRefid(Reference r) {
189: if (archive != null || modeSet) {
190: throw tooManyAttributes();
191: }
192: super .setRefid(r);
193: }
194:
195: /**
196: * Compare this ArchiveResource to another Resource.
197: * @param another the other Resource against which to compare.
198: * @return a negative integer, zero, or a positive integer as this Resource
199: * is less than, equal to, or greater than the specified Resource.
200: */
201: public int compareTo(Object another) {
202: return this .equals(another) ? 0 : super .compareTo(another);
203: }
204:
205: /**
206: * Compare another Object to this ArchiveResource for equality.
207: * @param another the other Object to compare.
208: * @return true if another is a Resource representing
209: * the same entry in the same archive.
210: */
211: public boolean equals(Object another) {
212: if (this == another) {
213: return true;
214: }
215: if (isReference()) {
216: return getCheckedRef().equals(another);
217: }
218: if (!(another.getClass().equals(getClass()))) {
219: return false;
220: }
221: ArchiveResource r = (ArchiveResource) another;
222: return getArchive().equals(r.getArchive())
223: && getName().equals(r.getName());
224: }
225:
226: /**
227: * Get the hash code for this Resource.
228: * @return hash code as int.
229: */
230: public int hashCode() {
231: return super .hashCode()
232: * (getArchive() == null ? NULL_ARCHIVE : getArchive()
233: .hashCode());
234: }
235:
236: /**
237: * Format this Resource as a String.
238: * @return String representatation of this Resource.
239: */
240: public String toString() {
241: return isReference() ? getCheckedRef().toString()
242: : getArchive().toString() + ':' + getName();
243: }
244:
245: private synchronized void checkEntry() throws BuildException {
246: if (haveEntry) {
247: return;
248: }
249: String name = getName();
250: if (name == null) {
251: throw new BuildException("entry name not set");
252: }
253: Resource r = getArchive();
254: if (r == null) {
255: throw new BuildException("archive attribute not set");
256: }
257: if (!r.isExists()) {
258: throw new BuildException(r.toString() + " does not exist.");
259: }
260: if (r.isDirectory()) {
261: throw new BuildException(r + " denotes a directory.");
262: }
263: fetchEntry();
264: haveEntry = true;
265: }
266:
267: /**
268: * fetches information from the named entry inside the archive.
269: */
270: protected abstract void fetchEntry();
271: }
|