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.ram;
18  
19  import java.io.ByteArrayInputStream;
20  import java.io.IOException;
21  import java.io.InputStream;
22  import java.io.OutputStream;
23  
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.FileType;
28  import org.apache.commons.vfs2.RandomAccessContent;
29  import org.apache.commons.vfs2.provider.AbstractFileName;
30  import org.apache.commons.vfs2.provider.AbstractFileObject;
31  import org.apache.commons.vfs2.util.FileObjectUtils;
32  import org.apache.commons.vfs2.util.RandomAccessMode;
33  
34  /**
35   * A RAM File contains a single RAM FileData instance, it provides methods to access the data by implementing FileObject
36   * interface.
37   */
38  public class RamFileObject extends AbstractFileObject<RamFileSystem>
39  {
40      /**
41       * RAM File Object Data.
42       */
43      private RamFileData data;
44  
45      /**
46       * @param name
47       *            The name of the file.
48       * @param fs
49       *            The FileSystem.
50       */
51      protected RamFileObject(final AbstractFileName name, final RamFileSystem fs)
52      {
53          super(name, fs);
54          this.getAbstractFileSystem().attach(this);
55      }
56  
57      private void save() throws FileSystemException
58      {
59          this.getAbstractFileSystem().save(this);
60      }
61  
62      /*
63       * (non-Javadoc)
64       *
65       * @see org.apache.commons.vfs2.provider.AbstractFileObject#doGetType()
66       */
67      @Override
68      protected FileType doGetType() throws Exception
69      {
70          return data.getType();
71      }
72  
73      /*
74       * (non-Javadoc)
75       *
76       * @see org.apache.commons.vfs2.provider.AbstractFileObject#doListChildren()
77       */
78      @Override
79      protected String[] doListChildren() throws Exception
80      {
81          return this.getAbstractFileSystem().listChildren(this.getName());
82      }
83  
84      /*
85       * (non-Javadoc)
86       *
87       * @see org.apache.commons.vfs2.provider.AbstractFileObject#doGetContentSize()
88       */
89      @Override
90      protected long doGetContentSize() throws Exception
91      {
92          return this.size();
93      }
94  
95      /*
96       * (non-Javadoc)
97       *
98       * @see org.apache.commons.vfs2.provider.AbstractFileObject#doGetInputStream()
99       */
100     @Override
101     protected InputStream doGetInputStream() throws Exception
102     {
103         // VFS-210: ram allows to gather an input stream even from a directory. So we need to check the type anyway.
104         if (!getType().hasContent())
105         {
106             throw new FileSystemException("vfs.provider/read-not-file.error", getName());
107         }
108 
109         return new ByteArrayInputStream(this.data.getContent());
110     }
111 
112     /*
113      * (non-Javadoc)
114      *
115      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doGetOutputStream(boolean)
116      */
117     @Override
118     protected OutputStream doGetOutputStream(final boolean bAppend) throws Exception
119     {
120         if (!bAppend)
121         {
122             this.data.setContent(RamFileData.EMPTY);
123         }
124         return new RamFileOutputStream(this);
125     }
126 
127     /*
128      * (non-Javadoc)
129      *
130      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doDelete()
131      */
132     @Override
133     protected void doDelete() throws Exception
134     {
135 
136         if (this.isContentOpen())
137         {
138             throw new FileSystemException(this.getName() + " cannot be deleted while the file is openg");
139         }
140         getAbstractFileSystem().delete(this);
141     }
142 
143     /*
144      * (non-Javadoc)
145      *
146      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doGetLastModifiedTime()
147      */
148     @Override
149     protected long doGetLastModifiedTime() throws Exception
150     {
151         return data.getLastModified();
152     }
153 
154     /*
155      * (non-Javadoc)
156      *
157      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doSetLastModifiedTime(long)
158      */
159     /** @since 2.0 */
160     @Override
161     protected boolean doSetLastModifiedTime(final long modtime) throws Exception
162     {
163         data.setLastModified(modtime);
164         return true;
165     }
166 
167     /*
168      * (non-Javadoc)
169      *
170      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doCreateFolder()
171      */
172     @Override
173     protected void doCreateFolder() throws Exception
174     {
175         this.injectType(FileType.FOLDER);
176         this.save();
177     }
178 
179     /*
180      * (non-Javadoc)
181      *
182      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doRename(org.apache.commons.vfs2.FileObject)
183      */
184     @Override
185     protected void doRename(final FileObject newFile) throws Exception
186     {
187         final RamFileObject newRamFileObject = (RamFileObject) FileObjectUtils.getAbstractFileObject(newFile);
188         getAbstractFileSystem().rename(this, newRamFileObject);
189     }
190 
191     /*
192      * (non-Javadoc)
193      *
194      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doGetRandomAccessContent(
195      * org.apache.commons.vfs2.util.RandomAccessMode)
196      */
197     @Override
198     protected RandomAccessContent doGetRandomAccessContent(final RandomAccessMode mode) throws Exception
199     {
200         return new RamFileRandomAccessContent(this, mode);
201     }
202 
203     /*
204      * (non-Javadoc)
205      *
206      * @see org.apache.commons.vfs2.provider.AbstractFileObject#doAttach()
207      */
208     @Override
209     protected void doAttach() throws Exception
210     {
211         this.getAbstractFileSystem().attach(this);
212     }
213 
214     /**
215      * @return Returns the data.
216      */
217     RamFileData getData()
218     {
219         return data;
220     }
221 
222     /**
223      * @param data
224      *            The data to set.
225      */
226     void setData(final RamFileData data)
227     {
228         this.data = data;
229     }
230 
231     /*
232      * (non-Javadoc)
233      *
234      * @see org.apache.commons.vfs2.provider.AbstractFileObject#injectType(org.apache.commons.vfs2.FileType)
235      */
236     @Override
237     protected void injectType(final FileType fileType)
238     {
239         this.data.setType(fileType);
240         super.injectType(fileType);
241     }
242 
243     /*
244      * (non-Javadoc)
245      *
246      * @see org.apache.commons.vfs2.provider.AbstractFileObject#endOutput()
247      */
248     @Override
249     protected void endOutput() throws Exception
250     {
251         super.endOutput();
252         this.save();
253     }
254 
255     /**
256      * @return Returns the size of the {@link RamFileData}.
257      */
258     int size()
259     {
260         return data == null ? 0 : data.size();
261     }
262 
263     /**
264      * @param newSize
265      * @throws IOException
266      *             if the new size exceeds the limit
267      */
268     synchronized void resize(final long newSize) throws IOException
269     {
270         final RamFileSystem afs = getAbstractFileSystem();
271         final FileSystemOptions afsOptions = afs.getFileSystemOptions();
272         if (afsOptions != null)
273         {
274             final long maxSize = RamFileSystemConfigBuilder.getInstance().getLongMaxSize(afsOptions);
275             if (afs.size() + newSize - this.size() > maxSize)
276             {
277                 throw new IOException("FileSystem capacity (" + maxSize + ") exceeded.");
278             }
279         }
280         this.data.resize(newSize);
281     }
282 
283 }