View Javadoc
1   /*
2    * Copyright (C) 2010-2014 Hamburg Sud and the contributors.
3    *
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.aludratest.service.file.impl;
17  
18  import org.aludratest.config.Preferences;
19  import org.aludratest.config.ValidatingPreferencesWrapper;
20  import org.aludratest.exception.AutomationException;
21  import org.aludratest.service.AludraCloseable;
22  import org.aludratest.service.file.FileService;
23  import org.apache.commons.vfs2.FileName;
24  import org.apache.commons.vfs2.FileObject;
25  import org.apache.commons.vfs2.FileSystemException;
26  import org.apache.commons.vfs2.FileSystemOptions;
27  import org.apache.commons.vfs2.UserAuthenticator;
28  import org.apache.commons.vfs2.auth.StaticUserAuthenticator;
29  import org.apache.commons.vfs2.impl.DefaultFileSystemConfigBuilder;
30  import org.apache.commons.vfs2.impl.StandardFileSystemManager;
31  import org.apache.commons.vfs2.provider.ftp.FtpFileSystemConfigBuilder;
32  
33  /**
34   * Provides configuration for the {@link FileService}.
35   * @author Volker Bergmann
36   */
37  public class FileServiceConfiguration implements AludraCloseable {
38  
39      static final int DEFAULT_WAIT_MAX_RETRIES = 15;
40  
41      static final int DEFAULT_WAIT_TIMEOUT = 30000;
42  
43      private ValidatingPreferencesWrapper configuration;
44  
45      /** Common-VFS' {@link StandardFileSystemManager}. */
46      private StandardFileSystemManager manager;
47  
48      /** The root folder used by this service instance. */
49      private FileObject rootFolder;
50  
51      /** Creates a new FileServiceConfiguration object which wraps the given Preferences object.
52       * 
53       * @param configuration Preferences configuration object to wrap.
54       * 
55       * @throws FileSystemException If an exception occurs when applying the configuration to the VFS Config Builders. */
56      public FileServiceConfiguration(Preferences configuration) throws FileSystemException {
57          this.configuration = new ValidatingPreferencesWrapper(configuration);
58  
59          // Configure secured access
60          FileSystemOptions fileSystemOptions = new FileSystemOptions();
61          String protocol = getProtocol();
62          String baseUrl = getBaseUrl();
63          String user = getUser();
64          String password = getPassword();
65  
66          if (user != null || password != null) {
67              UserAuthenticator authenticator = new StaticUserAuthenticator(protocol, user, password);
68              DefaultFileSystemConfigBuilder builder = DefaultFileSystemConfigBuilder.getInstance();
69              builder.setUserAuthenticator(fileSystemOptions, authenticator);
70          }
71          if ("ftp".equals(protocol)) {
72              FtpFileSystemConfigBuilder builder = FtpFileSystemConfigBuilder.getInstance();
73              builder.setUserDirIsRoot(fileSystemOptions, false);
74              builder.setDataTimeout(fileSystemOptions, getTimeout());
75              builder.setSoTimeout(fileSystemOptions, getTimeout());
76              builder.setPassiveMode(fileSystemOptions, true);
77          }
78  
79          // configure FileObject for root folder
80          this.manager = new StandardFileSystemManager();
81          // the setConfiguration() call prevents parsing of VFS-2.0's internal default configuration file
82          this.manager.setConfiguration(getClass().getResource("/META-INF/no-providers.xml"));
83          this.manager.init();
84          this.rootFolder = manager.resolveFile(protocol + "://" + baseUrl, fileSystemOptions);
85  
86          // access all configuration element in order to verify a complete configuration
87          getEncoding();
88          getLinefeed();
89          getPollingDelay();
90          getWaitMaxRetries();
91          getTimeout();
92          getRootFolder();
93          getFileObject("/");
94          getHost();
95          isWritingPermitted();
96  
97      }
98  
99      /** @return the name of the used protocol: file, ftp, sftp, http or https. */
100     public final String getProtocol() {
101         return configuration.getRequiredStringValue("protocol");
102     }
103 
104     /** @return the base URL of the service. */
105     public final String getBaseUrl() {
106         return configuration.getRequiredStringValue("base.url").replace('\\', '/');
107     }
108 
109     /** @return the file encoding used on the file system. */
110     public final String getEncoding() {
111         return configuration.getRequiredStringValue("encoding");
112     }
113 
114     /** @return the linefeed character(s) used on the file system. */
115     public final String getLinefeed() {
116         return Linefeed.valueOf(configuration.getRequiredStringValue("linefeed")).getChars();
117     }
118 
119     /** @return the user name for login. */
120     public final String getUser() {
121         return configuration.getStringValue("user");
122     }
123 
124     /** @return the password for login. */
125     public final String getPassword() {
126         return configuration.getStringValue("password");
127     }
128 
129     /** @return the delay to use between polls. */
130     public final int getPollingDelay() {
131         return getTimeout() / getWaitMaxRetries();
132     }
133 
134     /** @return the maximum number of polls to try. */
135     private final int getWaitMaxRetries() {
136         return configuration.getIntValue("wait.max.retries", DEFAULT_WAIT_MAX_RETRIES);
137     }
138 
139     /** @return the maximum time to wait when polling. */
140     public final int getTimeout() {
141         return configuration.getIntValue("wait.timeout", DEFAULT_WAIT_TIMEOUT);
142     }
143 
144     /** @return the root folder of the service. */
145     public final FileObject getRootFolder() {
146         return rootFolder;
147     }
148 
149     /** @return true if writing is permitted on the file system, otherwise false */
150     public final boolean isWritingPermitted() {
151         return configuration.getBooleanValue("writing.permitted", false);
152     }
153 
154     /** @return the host */
155     public final String getHost() {
156         String baseUrl = getBaseUrl();
157         int sep = baseUrl.indexOf('/');
158         String host = sep > 0 ? baseUrl.substring(0, sep) : "localhost";
159         return host;
160     }
161 
162     /** @return a commons-vfs {@link FileObject} for the given path.
163      *  @param filePath the path of the requested file
164      */
165     public final FileObject getFileObject(String filePath) {
166         try {
167             String path = (filePath.charAt(0) == '/' ? (filePath.length() == 1 ? "." : filePath.substring(1)) : filePath);
168             return manager.resolveFile(rootFolder, path);
169         } catch (FileSystemException e) {
170             throw new AutomationException("Error accessing file", e);
171         }
172     }
173 
174     /**
175      * @param file the file
176      * @return the full path
177      */
178     public final String pathFromRoot(FileObject file) {
179         FileName rootFolderName = rootFolder.getName();
180         FileName fileName = file.getName();
181         try {
182             return rootFolderName.getRelativeName(fileName);
183         } catch (FileSystemException e) {
184             throw new AutomationException("Error resolving relative path " +
185                     rootFolderName.getPath() + " -> " + fileName.getPath(), e);
186         }
187     }
188 
189     @Override
190     public void close() {
191         this.manager.close();
192     }
193 
194 }