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.ivy.plugins.repository.vfs;
019:
020: import java.io.IOException;
021: import java.io.InputStream;
022: import java.util.ArrayList;
023: import java.util.List;
024:
025: import org.apache.commons.vfs.FileContent;
026: import org.apache.commons.vfs.FileObject;
027: import org.apache.commons.vfs.FileSystemException;
028: import org.apache.commons.vfs.FileSystemManager;
029: import org.apache.commons.vfs.FileType;
030: import org.apache.ivy.plugins.repository.Resource;
031: import org.apache.ivy.plugins.resolver.VfsResolver;
032: import org.apache.ivy.util.Message;
033:
034: /**
035: * VFS implementation of the Resource interface
036: */
037: public class VfsResource implements Resource {
038: private String _vfsURI;
039:
040: private FileSystemManager _fsManager;
041:
042: private transient boolean _init = false;
043:
044: private transient boolean _exists;
045:
046: private transient long _lastModified;
047:
048: private transient long _contentLength;
049:
050: private transient FileContent _content = null;
051:
052: private transient FileObject _resourceImpl;
053:
054: // Constructor
055: public VfsResource(String vfsURI, FileSystemManager fsManager) {
056: this ._vfsURI = vfsURI;
057: this ._fsManager = fsManager;
058: this ._init = false;
059: }
060:
061: private void init() {
062: if (!_init) {
063: try {
064: _resourceImpl = _fsManager.resolveFile(_vfsURI);
065: _content = _resourceImpl.getContent();
066:
067: _exists = _resourceImpl.exists();
068: _lastModified = _content.getLastModifiedTime();
069: _contentLength = _content.getSize();
070: } catch (FileSystemException e) {
071: Message.verbose(e.getLocalizedMessage());
072: _exists = false;
073: _lastModified = 0;
074: _contentLength = 0;
075: }
076:
077: _init = true;
078: }
079: }
080:
081: /**
082: * Get a list of direct descendents of the given resource. Note that attempts to get a list of
083: * children does <emphasize>not</emphasize> result in an error. Instead an error message is
084: * logged and an empty ArrayList returned.
085: *
086: * @return A <code>ArrayList</code> of VFSResources
087: */
088: public List getChildren() {
089: init();
090: ArrayList list = new ArrayList();
091: try {
092: if ((_resourceImpl != null) && _resourceImpl.exists()
093: && (_resourceImpl.getType() == FileType.FOLDER)) {
094: FileObject[] children = _resourceImpl.getChildren();
095: for (int i = 0; i < children.length; i++) {
096: FileObject child = children[i];
097: list.add(normalize(child.getName().getURI()));
098: }
099: }
100: } catch (IOException e) {
101: Message.verbose(e.getLocalizedMessage());
102: }
103: return list;
104: }
105:
106: public FileContent getContent() {
107: init();
108: return _content;
109: }
110:
111: /**
112: * Get the name of the resource.
113: *
114: * @return a <code>String</code> representing the Resource URL.
115: */
116: public String getName() {
117: return normalize(_vfsURI);
118: }
119:
120: public Resource clone(String cloneName) {
121: return new VfsResource(cloneName, _fsManager);
122: }
123:
124: /**
125: * The VFS FileName getURI method seems to have a bug in it where file: URIs will have 4 forward
126: * slashes instead of 3.
127: *
128: * @param vfsURI
129: * @return a normalized <class>String</class> representing the VFS URI
130: */
131: public static String normalize(String vfsURI) {
132: if (vfsURI == null) {
133: return "";
134: }
135:
136: if (vfsURI.startsWith("file:////")) {
137: vfsURI = vfsURI.replaceFirst("////", "///");
138: }
139: return vfsURI;
140: }
141:
142: /**
143: * Get the last modification time of the resource.
144: *
145: * @return a <code>long</code> indicating last modified time.
146: */
147: public long getLastModified() {
148: init();
149: return _lastModified;
150: }
151:
152: /**
153: * Get the size of the resource
154: *
155: * @return a <code>long</code> representing the size of the resource (in bytes).
156: */
157: public long getContentLength() {
158: init();
159: return _contentLength;
160: }
161:
162: /**
163: * Flag indicating whether a resource is available for querying
164: *
165: * @return <code>true</code> if the resource is available for querying, <code>false</code>
166: * otherwise.
167: */
168: public boolean exists() {
169: init();
170: return _exists;
171: }
172:
173: /**
174: * Return a flag indicating whether a provided VFS resource physically exists
175: *
176: * @return <code>true</code> if the resource physically exists, <code>false</code>
177: * otherwise.
178: */
179: public boolean physicallyExists() {
180: // TODO: there is no need for this method anymore, replace it by calling exists();
181: init();
182:
183: try {
184: return _resourceImpl.exists();
185: // originally I only checked for a FileSystemException. I expanded it to
186: // include all exceptions when I found it would throw a NPE exception when the query was
187: // run on non-wellformed VFS URI.
188: } catch (Exception e) {
189: Message.verbose(e.getLocalizedMessage());
190: return false;
191: }
192: }
193:
194: public String toString() {
195: return VfsResolver.prepareForDisplay(getName());
196: }
197:
198: public boolean isLocal() {
199: return getName().startsWith("file:");
200: }
201:
202: public InputStream openStream() throws IOException {
203: return getContent().getInputStream();
204: }
205: }
|