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.vfs.provider;
18  
19  import org.apache.commons.vfs.FileChangeEvent;
20  import org.apache.commons.vfs.FileListener;
21  import org.apache.commons.vfs.FileName;
22  import org.apache.commons.vfs.FileObject;
23  import org.apache.commons.vfs.FileSystemException;
24  import org.apache.commons.vfs.FileType;
25  
26  import java.io.InputStream;
27  import java.io.OutputStream;
28  import java.security.cert.Certificate;
29  import java.util.HashSet;
30  import java.util.Map;
31  import java.util.Set;
32  
33  /***
34   * A file backed by another file.
35   *
36   * @author <a href="mailto:adammurdoch@apache.org">Adam Murdoch</a>
37   * @author Gary D. Gregory
38   * @version $Revision: 480428 $ $Date: 2006-11-29 07:15:24 +0100 (Mi, 29 Nov 2006) $
39   * @todo Extract subclass that overlays the children
40   */
41  public class DelegateFileObject
42      extends AbstractFileObject
43      implements FileListener
44  {
45      private FileObject file;
46      private final Set children = new HashSet();
47      private boolean ignoreEvent;
48  
49      public DelegateFileObject(final FileName name,
50                                final AbstractFileSystem fileSystem,
51                                final FileObject file) throws FileSystemException
52      {
53          super(name, fileSystem);
54          this.file = file;
55          if (file != null)
56          {
57              file.getFileSystem().addListener(file, this);
58          }
59      }
60  
61      /***
62       * Adds a child to this file.
63       */
64      public void attachChild(final FileName baseName, final FileType type) throws Exception
65      {
66          final FileType oldType = doGetType();
67          if (children.add(baseName.getBaseName()))
68          {
69              childrenChanged(baseName, type);
70          }
71          maybeTypeChanged(oldType);
72      }
73  
74      /***
75       * Attaches or detaches the target file.
76       */
77      public void setFile(final FileObject file) throws Exception
78      {
79          final FileType oldType = doGetType();
80  
81          if (file != null)
82          {
83              file.getFileSystem().addListener(file, this);
84          }
85          this.file = file;
86          maybeTypeChanged(oldType);
87      }
88  
89      /***
90       * Checks whether the file's type has changed, and fires the appropriate
91       * events.
92       */
93      private void maybeTypeChanged(final FileType oldType) throws Exception
94      {
95          final FileType newType = doGetType();
96          if (oldType == FileType.IMAGINARY && newType != FileType.IMAGINARY)
97          {
98              handleCreate(newType);
99          }
100         else if (oldType != FileType.IMAGINARY && newType == FileType.IMAGINARY)
101         {
102             handleDelete();
103         }
104     }
105 
106     /***
107      * Determines the type of the file, returns null if the file does not
108      * exist.
109      */
110     protected FileType doGetType() throws FileSystemException
111     {
112         if (file != null)
113         {
114             return file.getType();
115         }
116         else if (children.size() > 0)
117         {
118             return FileType.FOLDER;
119         }
120         else
121         {
122             return FileType.IMAGINARY;
123         }
124     }
125 
126     /***
127      * Determines if this file can be read.
128      */
129     protected boolean doIsReadable() throws FileSystemException
130     {
131         if (file != null)
132         {
133             return file.isReadable();
134         }
135         else
136         {
137             return true;
138         }
139     }
140 
141     /***
142      * Determines if this file can be written to.
143      */
144     protected boolean doIsWriteable() throws FileSystemException
145     {
146         if (file != null)
147         {
148             return file.isWriteable();
149         }
150         else
151         {
152             return false;
153         }
154     }
155 
156     /***
157      * Determines if this file is hidden.
158      */
159     protected boolean doIsHidden() throws FileSystemException
160     {
161         if (file != null)
162         {
163             return file.isHidden();
164         }
165         else
166         {
167             return false;
168         }
169     }
170 
171     /***
172      * Lists the children of the file.
173      */
174     protected String[] doListChildren() throws Exception
175     {
176         if (file != null)
177         {
178             final FileObject[] children = file.getChildren();
179             final String[] childNames = new String[children.length];
180             for (int i = 0; i < children.length; i++)
181             {
182                 childNames[i] = children[i].getName().getBaseName();
183             }
184             return childNames;
185         }
186         else
187         {
188             return (String[]) children.toArray(new String[children.size()]);
189         }
190     }
191 
192     /***
193      * Creates this file as a folder.
194      */
195     protected void doCreateFolder() throws Exception
196     {
197         ignoreEvent = true;
198         try
199         {
200             file.createFolder();
201         }
202         finally
203         {
204             ignoreEvent = false;
205         }
206     }
207 
208     /***
209      * Deletes the file.
210      */
211     protected void doDelete() throws Exception
212     {
213         ignoreEvent = true;
214         try
215         {
216             file.delete();
217         }
218         finally
219         {
220             ignoreEvent = false;
221         }
222     }
223 
224     /***
225      * Returns the size of the file content (in bytes).  Is only called if
226      * {@link #doGetType} returns {@link FileType#FILE}.
227      */
228     protected long doGetContentSize() throws Exception
229     {
230         return file.getContent().getSize();
231     }
232 
233     /***
234      * Returns the attributes of this file.
235      */
236     protected Map doGetAttributes()
237         throws Exception
238     {
239         return file.getContent().getAttributes();
240     }
241 
242     /***
243      * Sets an attribute of this file.
244      */
245     protected void doSetAttribute(final String atttrName,
246                                   final Object value)
247         throws Exception
248     {
249         file.getContent().setAttribute(atttrName, value);
250     }
251 
252     /***
253      * Returns the certificates of this file.
254      */
255     protected Certificate[] doGetCertificates() throws Exception
256     {
257         return file.getContent().getCertificates();
258     }
259 
260     /***
261      * Returns the last-modified time of this file.
262      */
263     protected long doGetLastModifiedTime() throws Exception
264     {
265         return file.getContent().getLastModifiedTime();
266     }
267 
268     /***
269      * Sets the last-modified time of this file.
270      */
271     protected void doSetLastModifiedTime(final long modtime)
272         throws Exception
273     {
274         file.getContent().setLastModifiedTime(modtime);
275     }
276 
277     /***
278      * Creates an input stream to read the file content from.
279      */
280     protected InputStream doGetInputStream() throws Exception
281     {
282         return file.getContent().getInputStream();
283     }
284 
285     /***
286      * Creates an output stream to write the file content to.
287      */
288     protected OutputStream doGetOutputStream(boolean bAppend) throws Exception
289     {
290         return file.getContent().getOutputStream(bAppend);
291     }
292 
293     /***
294      * Called when a file is created.
295      */
296     public void fileCreated(final FileChangeEvent event) throws Exception
297     {
298         if (!ignoreEvent)
299         {
300             handleCreate(file.getType());
301         }
302     }
303 
304     /***
305      * Called when a file is deleted.
306      */
307     public void fileDeleted(final FileChangeEvent event) throws Exception
308     {
309         if (!ignoreEvent)
310         {
311             handleDelete();
312         }
313     }
314 
315     /***
316      * Called when a file is changed.
317      * <p/>
318      * This will only happen if you monitor the file using {@link org.apache.commons.vfs.FileMonitor}.
319      */
320     public void fileChanged(FileChangeEvent event) throws Exception
321     {
322         if (!ignoreEvent)
323         {
324             handleChanged();
325         }
326     }
327 
328     /***
329      * Close the delegated file
330      */
331     public void close() throws FileSystemException
332     {
333         super.close();
334 
335         if (file != null)
336         {
337             file.close();
338         }
339     }
340 }