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 }