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.ivy.plugins.repository.vfs;
020:
021: import java.io.File;
022: import java.io.FileInputStream;
023: import java.io.IOException;
024: import java.util.ArrayList;
025: import java.util.Arrays;
026: import java.util.List;
027:
028: import org.apache.commons.vfs.FileContent;
029: import org.apache.commons.vfs.FileObject;
030: import org.apache.commons.vfs.FileSystemException;
031: import org.apache.commons.vfs.FileSystemManager;
032: import org.apache.commons.vfs.FileType;
033: import org.apache.commons.vfs.impl.StandardFileSystemManager;
034: import org.apache.ivy.plugins.repository.AbstractRepository;
035: import org.apache.ivy.plugins.repository.RepositoryCopyProgressListener;
036: import org.apache.ivy.plugins.repository.Resource;
037: import org.apache.ivy.plugins.repository.TransferEvent;
038: import org.apache.ivy.util.CopyProgressListener;
039: import org.apache.ivy.util.FileUtil;
040: import org.apache.ivy.util.Message;
041:
042: /**
043: * Implementation of a VFS repository
044: */
045: public class VfsRepository extends AbstractRepository {
046: /**
047: * Name of the resource defining the Ivy VFS Repo configuration.
048: */
049: private static final String IVY_VFS_CONFIG = "ivy_vfs.xml";
050:
051: private StandardFileSystemManager _manager = null;
052:
053: private final CopyProgressListener _progress = new RepositoryCopyProgressListener(
054: this );
055:
056: /**
057: * Create a new Ivy VFS Repository Instance
058: */
059: public VfsRepository() {
060: }
061:
062: private FileSystemManager getVFSManager() throws IOException {
063: synchronized (this ) {
064: if (_manager == null) {
065: _manager = createVFSManager();
066: }
067: }
068: return _manager;
069: }
070:
071: private StandardFileSystemManager createVFSManager()
072: throws IOException {
073: StandardFileSystemManager result = null;
074: try {
075: /*
076: * The DefaultFileSystemManager gets its configuration from the jakarta-vfs-common
077: * implementation which includes the res and tmp schemes which are of no use to use
078: * here. Using StandardFileSystemManager lets us specify which schemes to support as
079: * well as providing a mechanism to change this support without recompilation.
080: */
081: result = new StandardFileSystemManager() {
082: protected void configurePlugins()
083: throws FileSystemException {
084: // disable automatic loading potential unsupported extensions
085: }
086: };
087: result.setConfiguration(getClass().getResource(
088: IVY_VFS_CONFIG));
089: result.init();
090:
091: // Generate and print a list of available schemes
092: Message.verbose("Available VFS schemes...");
093: String[] schemes = result.getSchemes();
094: Arrays.sort(schemes);
095: for (int i = 0; i < schemes.length; i++) {
096: Message.verbose("VFS Supported Scheme: " + schemes[i]);
097: }
098: } catch (FileSystemException e) {
099: /*
100: * If our attempt to initialize a VFS Repository fails we log the failure but continue
101: * on. Given that an Ivy instance may involve numerous different repository types, it
102: * seems overly cautious to throw a runtime exception on the initialization failure of
103: * just one repository type.
104: */
105: Message
106: .error("Unable to initialize VFS repository manager!");
107: Message.error(e.getLocalizedMessage());
108: IOException error = new IOException(e.getLocalizedMessage());
109: error.initCause(e);
110: throw error;
111: }
112:
113: return result;
114: }
115:
116: protected void finalize() {
117: if (_manager != null) {
118: _manager.close();
119: _manager = null;
120: }
121: }
122:
123: /**
124: * Get a VfsResource
125: *
126: * @param source
127: * a <code>String</code> identifying a VFS Resource
128: * @throws <code>IOException</code> on failure
129: * @see "Supported File Systems in the jakarta-commons-vfs documentation"
130: */
131: public Resource getResource(String vfsURI) throws IOException {
132: return new VfsResource(vfsURI, getVFSManager());
133: }
134:
135: /**
136: * Transfer a VFS Resource from the repository to the local file system.
137: *
138: * @param srcVfsURI
139: * a <code>String</code> identifying the VFS resource to be fetched
140: * @param destination
141: * a <code>File</code> identifying the destination file
142: * @throws <code>IOException</code> on failure
143: * @see "Supported File Systems in the jakarta-commons-vfs documentation"
144: */
145: public void get(String srcVfsURI, File destination)
146: throws IOException {
147: VfsResource src = new VfsResource(srcVfsURI, getVFSManager());
148: fireTransferInitiated(src, TransferEvent.REQUEST_GET);
149: try {
150: FileContent content = src.getContent();
151: if (content == null) {
152: throw new IllegalArgumentException("invalid vfs uri "
153: + srcVfsURI + ": no content found");
154: }
155: FileUtil.copy(content.getInputStream(), destination,
156: _progress);
157: } catch (IOException ex) {
158: fireTransferError(ex);
159: throw ex;
160: } catch (RuntimeException ex) {
161: fireTransferError(ex);
162: throw ex;
163: }
164: }
165:
166: /**
167: * Return a listing of the contents of a parent directory. Listing is a set of strings
168: * representing VFS URIs.
169: *
170: * @param vfsURI
171: * providing identifying a VFS provided resource
172: * @throws IOException
173: * on failure.
174: * @see "Supported File Systems in the jakarta-commons-vfs documentation"
175: */
176: public List list(String vfsURI) throws IOException {
177: ArrayList list = new ArrayList();
178: Message.debug("list called for URI" + vfsURI);
179: FileObject resourceImpl = getVFSManager().resolveFile(vfsURI);
180: Message.debug("resourceImpl=" + resourceImpl.toString());
181: Message.debug("resourceImpl.exists()" + resourceImpl.exists());
182: Message
183: .debug("resourceImpl.getType()"
184: + resourceImpl.getType());
185: Message.debug("FileType.FOLDER" + FileType.FOLDER);
186: if ((resourceImpl != null) && resourceImpl.exists()
187: && (resourceImpl.getType() == FileType.FOLDER)) {
188: FileObject[] children = resourceImpl.getChildren();
189: for (int i = 0; i < children.length; i++) {
190: FileObject child = children[i];
191: Message.debug("child " + i + child.getName().getURI());
192: list.add(VfsResource
193: .normalize(child.getName().getURI()));
194: }
195: }
196: return list;
197: }
198:
199: /**
200: * Transfer an Ivy resource to a VFS repository
201: *
202: * @param source
203: * a <code>File</code> indentifying the local file to transfer to the repository
204: * @param vfsURI
205: * a <code>String</code> identifying the destination VFS Resource.
206: * @param overwrite
207: * whether to overwrite an existing resource.
208: * @throws <code>IOException</code> on failure.
209: * @see "Supported File Systems in the jakarta-commons-vfs documentation"
210: */
211: public void put(File source, String vfsURI, boolean overwrite)
212: throws IOException {
213: VfsResource dest = new VfsResource(vfsURI, getVFSManager());
214: fireTransferInitiated(dest, TransferEvent.REQUEST_PUT);
215: if (dest.physicallyExists() && !overwrite) {
216: throw new IOException("Cannot copy. Destination file: "
217: + dest.getName() + " exists and overwrite not set.");
218: }
219: if (dest.getContent() == null) {
220: throw new IllegalArgumentException("invalid vfs uri "
221: + vfsURI
222: + " to put data to: resource has no content");
223: }
224:
225: FileUtil.copy(new FileInputStream(source), dest.getContent()
226: .getOutputStream(), _progress);
227: }
228:
229: }
|