View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.vfs2.provider.hdfs;
18  
19  import java.io.FileNotFoundException;
20  import java.io.IOException;
21  import java.io.InputStream;
22  import java.io.OutputStream;
23  import java.util.HashMap;
24  import java.util.Map;
25  import java.util.stream.Stream;
26  
27  import org.apache.commons.vfs2.FileNotFolderException;
28  import org.apache.commons.vfs2.FileObject;
29  import org.apache.commons.vfs2.FileSystemException;
30  import org.apache.commons.vfs2.FileType;
31  import org.apache.commons.vfs2.RandomAccessContent;
32  import org.apache.commons.vfs2.provider.AbstractFileName;
33  import org.apache.commons.vfs2.provider.AbstractFileObject;
34  import org.apache.commons.vfs2.util.RandomAccessMode;
35  import org.apache.hadoop.fs.FileStatus;
36  import org.apache.hadoop.fs.FileSystem;
37  import org.apache.hadoop.fs.Path;
38  
39  /**
40   * A VFS representation of an HDFS file.
41   *
42   * @since 2.1
43   */
44  public class HdfsFileObject extends AbstractFileObject<HdfsFileSystem> {
45  
46      private final HdfsFileSystem fs;
47      private final FileSystem hdfs;
48      private final Path path;
49      private FileStatus stat;
50  
51      /**
52       * Constructs a new HDFS FileObject
53       *
54       * @param name FileName
55       * @param fs HdfsFileSystem instance
56       * @param hdfs Hadoop FileSystem instance
57       * @param p Path to the file in HDFS
58       */
59      protected HdfsFileObject(final AbstractFileName name, final HdfsFileSystem fs, final FileSystem hdfs,
60              final Path p) {
61          super(name, fs);
62          this.fs = fs;
63          this.hdfs = hdfs;
64          this.path = p;
65      }
66  
67      /**
68       * @see org.apache.commons.vfs2.provider.AbstractFileObject#canRenameTo(org.apache.commons.vfs2.FileObject)
69       */
70      @Override
71      public boolean canRenameTo(final FileObject newfile) {
72          if (!super.canRenameTo(newfile)) {
73              return false;
74          }
75          try {
76              return this.hdfs.getFileStatus(new Path(newfile.getName().getPath())) == null;
77          } catch (final FileNotFoundException e) {
78              return false;
79          } catch (final IOException e) {
80              throw new IllegalStateException(e);
81          }
82      }
83  
84      /**
85       * @see org.apache.commons.vfs2.provider.AbstractFileObject#doAttach()
86       */
87      @Override
88      protected void doAttach() throws Exception {
89          try {
90              this.stat = this.hdfs.getFileStatus(this.path);
91          } catch (final FileNotFoundException e) {
92              this.stat = null;
93              return;
94          }
95      }
96  
97      /**
98       * @see org.apache.commons.vfs2.provider.AbstractFileObject#doCreateFolder()
99       * @since 2.7.0
100      */
101     @Override
102     protected void doCreateFolder() throws Exception {
103         hdfs.mkdirs(this.path);
104     }
105 
106     /**
107      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doDelete()
108      * @since 2.7.0
109      */
110     @Override
111     protected void doDelete() throws Exception {
112         hdfs.delete(this.path, true);
113     }
114 
115     /**
116      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doGetAttributes()
117      */
118     @Override
119     protected Map<String, Object> doGetAttributes() throws Exception {
120         if (null == this.stat) {
121             return super.doGetAttributes();
122         }
123         final Map<String, Object> attrs = new HashMap<>();
124         attrs.put(HdfsFileAttributes.LAST_ACCESS_TIME.toString(), this.stat.getAccessTime());
125         attrs.put(HdfsFileAttributes.BLOCK_SIZE.toString(), this.stat.getBlockSize());
126         attrs.put(HdfsFileAttributes.GROUP.toString(), this.stat.getGroup());
127         attrs.put(HdfsFileAttributes.OWNER.toString(), this.stat.getOwner());
128         attrs.put(HdfsFileAttributes.PERMISSIONS.toString(), this.stat.getPermission().toString());
129         attrs.put(HdfsFileAttributes.LENGTH.toString(), this.stat.getLen());
130         attrs.put(HdfsFileAttributes.MODIFICATION_TIME.toString(), this.stat.getModificationTime());
131         return attrs;
132     }
133 
134     /**
135      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doGetContentSize()
136      */
137     @Override
138     protected long doGetContentSize() throws Exception {
139         return stat.getLen();
140     }
141 
142     /**
143      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doGetInputStream(int)
144      */
145     @Override
146     protected InputStream doGetInputStream(final int bufferSize) throws Exception {
147         return this.hdfs.open(this.path, bufferSize);
148     }
149 
150     /**
151      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doGetLastModifiedTime()
152      */
153     @Override
154     protected long doGetLastModifiedTime() throws Exception {
155         doAttach();
156         if (null != this.stat) {
157             return this.stat.getModificationTime();
158         }
159         return -1;
160     }
161 
162     /**
163      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doGetOutputStream(boolean)
164      * @since 2.7.0
165      */
166     @Override
167     protected OutputStream doGetOutputStream(final boolean append) throws Exception {
168         if (append) {
169             throw new FileSystemException("vfs.provider/write-append-not-supported.error", this.path.getName());
170         }
171         return hdfs.create(this.path);
172     }
173 
174     /**
175      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doGetRandomAccessContent
176      *      (org.apache.commons.vfs2.util.RandomAccessMode)
177      */
178     @Override
179     protected RandomAccessContent doGetRandomAccessContent(final RandomAccessMode mode) throws Exception {
180         if (mode.equals(RandomAccessMode.READWRITE)) {
181             throw new UnsupportedOperationException();
182         }
183         return new HdfsRandomAccessContent(this.path, this.hdfs);
184     }
185 
186     /**
187      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doGetType()
188      */
189     @Override
190     protected FileType doGetType() throws Exception {
191         try {
192             doAttach();
193             if (null == stat) {
194                 return FileType.IMAGINARY;
195             }
196             if (stat.isDirectory()) {
197                 return FileType.FOLDER;
198             }
199             return FileType.FILE;
200         } catch (final FileNotFoundException fnfe) {
201             return FileType.IMAGINARY;
202         }
203     }
204 
205     /**
206      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doIsHidden()
207      */
208     @Override
209     protected boolean doIsHidden() throws Exception {
210         return false;
211     }
212 
213     /**
214      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doIsReadable()
215      */
216     @Override
217     protected boolean doIsReadable() throws Exception {
218         return true;
219     }
220 
221     /**
222      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doIsWriteable()
223      */
224     @Override
225     protected boolean doIsWriteable() throws Exception {
226         return true;
227     }
228 
229     /**
230      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doListChildren()
231      */
232     @Override
233     protected String[] doListChildren() throws Exception {
234         if (this.doGetType() != FileType.FOLDER) {
235             throw new FileNotFolderException(this);
236         }
237 
238         final FileStatus[] fileStatuses = this.hdfs.listStatus(this.path);
239         return Stream.of(fileStatuses).map(status -> status.getPath().getName()).toArray(String[]::new);
240     }
241 
242     /**
243      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doListChildrenResolved()
244      */
245     @Override
246     protected FileObject[] doListChildrenResolved() throws Exception {
247         if (this.doGetType() != FileType.FOLDER) {
248             return null;
249         }
250         final String[] children = doListChildren();
251         final FileObjectFileObject.html#FileObject">FileObject[] fo = new FileObject[children.length];
252         for (int i = 0; i < children.length; i++) {
253             final Path p = new Path(this.path, children[i]);
254             fo[i] = this.fs.resolveFile(p.toUri().toString());
255         }
256         return fo;
257     }
258 
259     /**
260      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doRemoveAttribute(java.lang.String)
261      */
262     @Override
263     protected void doRemoveAttribute(final String attrName) throws Exception {
264         throw new UnsupportedOperationException();
265     }
266 
267     /**
268      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doRename(FileObject)
269      * @since 2.7.0
270      */
271     @Override
272     protected void doRename(final FileObject newfile) throws Exception {
273         hdfs.rename(this.path, new Path(newfile.getName().getPath()));
274     }
275 
276     /**
277      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doSetAttribute(java.lang.String, java.lang.Object)
278      */
279     @Override
280     protected void doSetAttribute(final String attrName, final Object value) throws Exception {
281         throw new UnsupportedOperationException();
282     }
283 
284     /**
285      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doSetLastModifiedTime(long)
286      */
287     @Override
288     protected boolean doSetLastModifiedTime(final long modtime) throws Exception {
289         try {
290             hdfs.setTimes(this.path, modtime, System.currentTimeMillis());
291         } catch (final IOException ioe) {
292             throw new FileSystemException(ioe);
293         }
294         return true;
295     }
296 
297     /**
298      * @see org.apache.commons.vfs2.provider.AbstractFileObject#exists()
299      * @return boolean true if file exists, false if not
300      */
301     @Override
302     public boolean exists() throws FileSystemException {
303         try {
304             doAttach();
305             return this.stat != null;
306         } catch (final FileNotFoundException fne) {
307             return false;
308         } catch (final Exception e) {
309             throw new FileSystemException("Unable to check existance ", e);
310         }
311     }
312 
313 }