View Javadoc

1   /**
2      This file is part of GoldenGate Project (named also GoldenGate or GG).
3   
4      Copyright 2009, Frederic Bregier, and individual contributors by the @author
5      tags. See the COPYRIGHT.txt in the distribution for a full listing of
6      individual contributors.
7   
8      All GoldenGate Project is free software: you can redistribute it and/or 
9      modify it under the terms of the GNU General Public License as published 
10     by the Free Software Foundation, either version 3 of the License, or
11     (at your option) any later version.
12  
13     GoldenGate is distributed in the hope that it will be useful,
14     but WITHOUT ANY WARRANTY; without even the implied warranty of
15     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16     GNU General Public License for more details.
17  
18     You should have received a copy of the GNU General Public License
19     along with GoldenGate .  If not, see <http://www.gnu.org/licenses/>.
20   */
21  package goldengate.common.file.passthrough;
22  
23  import goldengate.common.command.exception.CommandAbstractException;
24  import goldengate.common.command.exception.Reply550Exception;
25  import goldengate.common.command.exception.Reply553Exception;
26  import goldengate.common.file.AbstractDir;
27  import goldengate.common.file.FileInterface;
28  import goldengate.common.file.OptsMLSxInterface;
29  import goldengate.common.file.SessionInterface;
30  import goldengate.common.logging.GgInternalLogger;
31  import goldengate.common.logging.GgInternalLoggerFactory;
32  
33  import java.io.File;
34  import java.util.ArrayList;
35  import java.util.List;
36  
37  /**
38   * Directory implementation for Passthrough Based.
39   * It is just an empty shell since in pass through mode, no directories or files really exist.
40   *
41   * If one wants to implement special actions, he/she just has to extend this class and override
42   * the default empty implementation.
43   *
44   * @author Frederic Bregier
45   *
46   */
47  public abstract class PassthroughBasedDirImpl extends AbstractDir {
48      /**
49       * Factory for PassthroughFile
50       */
51      public static PassthroughFileFactory factory = null;
52  
53      /**
54       * Passthrough object
55       */
56      protected PassthroughFile pdir = null;
57      /**
58       * Internal Logger
59       */
60      private static final GgInternalLogger logger = GgInternalLoggerFactory
61              .getLogger(PassthroughBasedDirImpl.class);
62  
63      /**
64       * @param session
65       * @param optsMLSx
66       */
67      public PassthroughBasedDirImpl(SessionInterface session,
68              OptsMLSxInterface optsMLSx) {
69          this.session = session;
70          this.optsMLSx = optsMLSx;
71          this.optsMLSx.setOptsModify((byte) -1);
72          this.optsMLSx.setOptsPerm((byte) -1);
73          this.optsMLSx.setOptsSize((byte) 1);
74          this.optsMLSx.setOptsType((byte) 1);
75          try {
76              pdir = factory.create(null, "/");
77          } catch (PassthroughException e) {
78          }
79      }
80  
81      /**
82       * Finds all files matching a wildcard expression (based on '?', '~' or
83       * '*').
84       *
85       * @param pathWithWildcard
86       *            The wildcard expression with a business path.
87       * @return List of String as relative paths matching the wildcard
88       *         expression. Those files are tested as valid from business point
89       *         of view. If Wildcard support is not active, if the path contains
90       *         any wildcards, it will throw an error.
91       * @throws CommandAbstractException
92       */
93      protected List<String> wildcardFiles(String pathWithWildcard)
94              throws CommandAbstractException {
95          List<String> resultPaths = new ArrayList<String>();
96          // First check if pathWithWildcard contains wildcards
97          if (!(pathWithWildcard.contains("*") || pathWithWildcard.contains("?") || pathWithWildcard
98                  .contains("~"))) {
99              // No so simply return the list containing this path after
100             // validating it
101             if (getSession().getAuth().isBusinessPathValid(pathWithWildcard)) {
102                 resultPaths.add(pathWithWildcard);
103             }
104             return resultPaths;
105         }
106         // FIXME could support Wildcard path
107         PassthroughFile file;
108         try {
109             file = factory.create(null, pathWithWildcard);
110         } catch (PassthroughException e) {
111             throw new Reply553Exception("Error while creating a wildcard PassthroughFile: "+
112                     e.getMessage());
113         }
114         try {
115             return file.wildcard(null);
116         } catch (PassthroughException e) {
117             throw new Reply553Exception("Error while getting a wildcard PassthroughFile: "+
118                     e.getMessage());
119         }
120 
121     }
122 
123     /**
124      * Get the File from this path, checking first its validity
125      *
126      * @param path
127      * @return the FileInterface
128      * @throws CommandAbstractException
129      */
130     protected File getFileFromPath(String path) throws CommandAbstractException {
131         String newdir = validatePath(path);
132         if (isAbsoluteWindows(newdir)) {
133             return new File(newdir);
134         }
135         String truedir = ((PassthroughBasedAuthImpl) getSession().getAuth())
136                 .getAbsolutePath(newdir);
137         return new File(truedir);
138     }
139 
140     /**
141      * Get the true file from the path
142      *
143      * @param path
144      * @return the true File from the path
145      * @throws CommandAbstractException
146      */
147     protected File getTrueFile(String path) throws CommandAbstractException {
148         checkIdentify();
149         String newpath = consolidatePath(path);
150         List<String> paths = wildcardFiles(normalizePath(newpath));
151         if (paths.size() != 1) {
152             throw new Reply550Exception("File not found: " + paths.size() +
153                     " founds");
154         }
155         String extDir = paths.get(0);
156         extDir = this.validatePath(extDir);
157         File file = getFileFromPath(extDir);
158         return file;
159     }
160 
161     /**
162      * Get the relative path (without mount point)
163      *
164      * @param file
165      * @return the relative path
166      */
167     protected String getRelativePath(File file) {
168         return ((PassthroughBasedAuthImpl) getSession().getAuth())
169                 .getRelativePath(normalizePath(file.getAbsolutePath()));
170     }
171 
172     public boolean changeDirectory(String path) throws CommandAbstractException {
173         checkIdentify();
174         String newpath = consolidatePath(path);
175         List<String> paths = wildcardFiles(newpath);
176         if (paths.size() != 1) {
177             logger.warn("CD error: {}", newpath);
178             throw new Reply550Exception("Directory not found: " + paths.size() +
179                     " founds");
180         }
181         String extDir = paths.get(0);
182         extDir = this.validatePath(extDir);
183         if (isDirectory(extDir)) {
184             try {
185                 pdir.changeDirectory(extDir);
186             } catch (PassthroughException e) {
187                 throw new Reply550Exception("Directory not found");
188             }
189             currentDir = extDir;
190             return true;
191         }
192         throw new Reply550Exception("Directory not found");
193     }
194 
195     public String mkdir(String directory) throws CommandAbstractException {
196         checkIdentify();
197         String newdirectory = consolidatePath(directory);
198         File dir = new File(newdirectory);
199         String parent = dir.getParentFile().getPath();
200         List<String> paths = wildcardFiles(normalizePath(parent));
201         if (paths.size() != 1) {
202             throw new Reply550Exception("Base Directory not found: " +
203                     paths.size() + " founds");
204         }
205         String newDir = paths.get(0) + SEPARATOR + dir.getName();
206         newDir = this.validatePath(newDir);
207         PassthroughFile newdir;
208         try {
209             newdir = factory.create(null, newDir);
210         } catch (PassthroughException e) {
211             throw new Reply550Exception("Cannot create directory " + newDir);
212         }
213         try {
214             if (newdir.mkdir()) {
215                 return newDir;
216             }
217         } catch (PassthroughException e) {
218             throw new Reply550Exception("Cannot create directory " + newDir);
219         }
220         throw new Reply550Exception("Cannot create directory " + newDir);
221     }
222 
223     public String rmdir(String directory) throws CommandAbstractException {
224         checkIdentify();
225         String newdirectory = consolidatePath(directory);
226         List<String> paths = wildcardFiles(normalizePath(newdirectory));
227         if (paths.size() != 1) {
228             throw new Reply550Exception("Directory not found: " + paths.size() +
229                     " founds");
230         }
231         String extDir = paths.get(0);
232         extDir = this.validatePath(extDir);
233         PassthroughFile dir;
234         try {
235             dir = factory.create(null, extDir);
236         } catch (PassthroughException e) {
237             throw new Reply550Exception("Cannot delete directory " + extDir);
238         }
239         try {
240             if (dir.delete()) {
241                 return extDir;
242             }
243         } catch (PassthroughException e) {
244             throw new Reply550Exception("Cannot delete directory " + extDir);
245         }
246         throw new Reply550Exception("Cannot delete directory " + extDir);
247     }
248 
249     public boolean isDirectory(String path) throws CommandAbstractException {
250         checkIdentify();
251         PassthroughFile dir;
252         try {
253             dir = factory.create(pdir, path);
254         } catch (PassthroughException e) {
255             throw new Reply550Exception("Cannot get isDirectory " + path);
256         }
257         return dir.isDirectory();
258     }
259 
260     public boolean isFile(String path) throws CommandAbstractException {
261         checkIdentify();
262         PassthroughFile file;
263         try {
264             file = factory.create(pdir, path);
265         } catch (PassthroughException e) {
266             throw new Reply550Exception("Cannot get File " + path);
267         }
268         return file.isFile();
269     }
270 
271     public String getModificationTime(String path)
272             throws CommandAbstractException {
273         checkIdentify();
274         PassthroughFile file;
275         try {
276             file = factory.create(pdir, path);
277         } catch (PassthroughException e) {
278             throw new Reply550Exception("Cannot get File " + path);
279         }
280         try {
281             return file.getModificationTime();
282         } catch (PassthroughException e) {
283             throw new Reply550Exception("Cannot get ModificationTime " + path);
284         }
285     }
286 
287     public List<String> list(String path) throws CommandAbstractException {
288         checkIdentify();
289         PassthroughFile file;
290         try {
291             file = factory.create(pdir, path);
292         } catch (PassthroughException e) {
293             throw new Reply550Exception("Cannot get File " + path);
294         }
295         try {
296             return file.list();
297         } catch (PassthroughException e) {
298             throw new Reply550Exception("List error "+e.getMessage());
299         }
300     }
301 
302     public List<String> listFull(String path, boolean lsFormat)
303             throws CommandAbstractException {
304         checkIdentify();
305         PassthroughFile file;
306         try {
307             file = factory.create(pdir, path);
308         } catch (PassthroughException e) {
309             throw new Reply550Exception("Cannot get File " + path);
310         }
311         try {
312             return file.listFull(lsFormat);
313         } catch (PassthroughException e) {
314             throw new Reply550Exception("List error "+e.getMessage());
315         }
316     }
317 
318     public String fileFull(String path, boolean lsFormat)
319             throws CommandAbstractException {
320         checkIdentify();
321         PassthroughFile file;
322         try {
323             file = factory.create(pdir, path);
324         } catch (PassthroughException e) {
325             throw new Reply550Exception("Cannot get File " + path);
326         }
327         try {
328             return file.fileFull(lsFormat);
329         } catch (PassthroughException e) {
330             throw new Reply550Exception("FileFull error "+e.getMessage());
331         }
332     }
333 
334     /**
335      * Decide if Full time or partial time as in 'ls' command
336      *
337      * @return True if Full Time, False is Default (as in 'ls' command)
338      */
339     protected boolean isFullTime() {
340         // FIXME should be it the default ?
341         return false;
342     }
343 
344     public long getFreeSpace() throws CommandAbstractException {
345         checkIdentify();
346         try {
347             return pdir.getFreeSpace();
348         } catch (PassthroughException e) {
349             throw new Reply550Exception("FileFull error "+e.getMessage());
350         }
351     }
352 
353     public FileInterface setUniqueFile()
354             throws CommandAbstractException {
355         checkIdentify();
356         // FIXME file: create a virtual unique file
357         String filename =
358             getFileFromPath(currentDir)+SEPARATOR+
359             getSession().getAuth().getUser()+
360             Long.toHexString(System.currentTimeMillis())+
361             this.session.getUniqueExtension();
362         File file = new File(filename);
363         String currentFile = getRelativePath(file);
364         return newFile(normalizePath(currentFile), false);
365     }
366 
367     public boolean canRead() throws CommandAbstractException {
368         checkIdentify();
369         return pdir.canRead();
370     }
371 
372     public boolean canWrite() throws CommandAbstractException {
373         checkIdentify();
374         return pdir.canWrite();
375     }
376 
377     public boolean exists() throws CommandAbstractException {
378         checkIdentify();
379         return pdir.exists();
380     }
381 
382     public long getCRC(String path) throws CommandAbstractException {
383         PassthroughFile file;
384         try {
385             file = factory.create(pdir, path);
386         } catch (PassthroughException e) {
387             throw new Reply550Exception("Cannot get File " + path);
388         }
389         try {
390             return file.getCRC();
391         } catch (PassthroughException e) {
392             throw new Reply550Exception("CRC error "+e.getMessage());
393         }
394     }
395 
396     public byte[] getMD5(String path) throws CommandAbstractException {
397         PassthroughFile file;
398         try {
399             file = factory.create(pdir, path);
400         } catch (PassthroughException e) {
401             throw new Reply550Exception("Cannot get File " + path);
402         }
403         try {
404             return file.getMD5();
405         } catch (PassthroughException e) {
406             throw new Reply550Exception("CRC error "+e.getMessage());
407         }
408     }
409 
410     public byte[] getSHA1(String path) throws CommandAbstractException {
411         PassthroughFile file;
412         try {
413             file = factory.create(pdir, path);
414         } catch (PassthroughException e) {
415             throw new Reply550Exception("Cannot get File " + path);
416         }
417         try {
418             return file.getSHA1();
419         } catch (PassthroughException e) {
420             throw new Reply550Exception("CRC error "+e.getMessage());
421         }
422     }
423 }