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.Serializable;
20  import java.util.ArrayList;
21  import java.util.Collection;
22  import java.util.Collections;
23  
24  import org.apache.commons.lang3.ArrayUtils;
25  import org.apache.commons.vfs2.FileName;
26  import org.apache.commons.vfs2.FileSystemException;
27  import org.apache.commons.vfs2.FileType;
28  
29  /**
30   * RAM File Object Data.
31   */
32  class RamFileData implements Serializable {
33  
34      /**
35       * serialVersionUID format is YYYYMMDD for the date of the last binary change.
36       */
37      private static final long serialVersionUID = 20101208L;
38  
39      /**
40       * File Name.
41       */
42      private FileName name;
43  
44      /**
45       * File Type.
46       */
47      private FileType type;
48  
49      /**
50       * Bytes.
51       */
52      private byte[] content;
53  
54      /**
55       * Last modified time
56       */
57      private long lastModifiedMillis;
58  
59      /**
60       * Children
61       */
62      private final Collection<RamFileData> children;
63  
64      /**
65       * Constructor.
66       *
67       * @param name The file name.
68       */
69      public RamFileData(final FileName name) {
70          this.children = Collections.synchronizedCollection(new ArrayList<>());
71          this.clear();
72          if (name == null) {
73              throw new IllegalArgumentException("name can not be null");
74          }
75          this.name = name;
76      }
77  
78      /**
79       * @return Returns the buffer.
80       */
81      byte[] getContent() {
82          return content;
83      }
84  
85      /**
86       * @param content The buffer.
87       */
88      void setContent(final byte[] content) {
89          updateLastModified();
90          this.content = content;
91      }
92  
93      /**
94       * @return Returns the lastModified.
95       */
96      long getLastModified() {
97          return lastModifiedMillis;
98      }
99  
100     /**
101      * @param lastModified The lastModified to set.
102      */
103     void setLastModified(final long lastModified) {
104         this.lastModifiedMillis = lastModified;
105     }
106 
107     /**
108      * @return Returns the type.
109      */
110     FileType getType() {
111         return type;
112     }
113 
114     /**
115      * @param type The type to set.
116      */
117     void setType(final FileType type) {
118         this.type = type;
119     }
120 
121     /**
122      */
123     void clear() {
124         this.content = ArrayUtils.EMPTY_BYTE_ARRAY;
125         updateLastModified();
126         this.type = FileType.IMAGINARY;
127         this.children.clear();
128         this.name = null;
129     }
130 
131     void updateLastModified() {
132         this.lastModifiedMillis = System.currentTimeMillis();
133     }
134 
135     /**
136      * @return Returns the name.
137      */
138     FileName getName() {
139         return name;
140     }
141 
142     /*
143      * (non-Javadoc)
144      *
145      * @see java.lang.Object#toString()
146      */
147     @Override
148     public String toString() {
149         return this.name.toString();
150     }
151 
152     /**
153      * Add a child.
154      *
155      * @param data The file data.
156      * @throws FileSystemException if an error occurs.
157      */
158     void addChild(final RamFileData data) throws FileSystemException {
159         if (!this.getType().hasChildren()) {
160             throw new FileSystemException("A child can only be added in a folder");
161         }
162 
163         FileSystemException.requireNonNull(data, "No child can be null");
164 
165         if (this.children.contains(data)) {
166             throw new FileSystemException("Child already exists. " + data);
167         }
168 
169         this.children.add(data);
170         updateLastModified();
171     }
172 
173     /**
174      * Remove a child.
175      *
176      * @param data The file data.
177      * @throws FileSystemException if an error occurs.
178      */
179     void removeChild(final RamFileData data) throws FileSystemException {
180         if (!this.getType().hasChildren()) {
181             throw new FileSystemException("A child can only be removed from a folder");
182         }
183         if (!this.children.contains(data)) {
184             throw new FileSystemException("Child not found. " + data);
185         }
186         this.children.remove(data);
187         updateLastModified();
188     }
189 
190     /**
191      * @return Returns the children.
192      */
193     Collection<RamFileData> getChildren() {
194         if (name == null) {
195             throw new IllegalStateException("Data is clear");
196         }
197         return children;
198     }
199 
200     /*
201      * (non-Javadoc)
202      *
203      * @see java.lang.Object#equals(java.lang.Object)
204      */
205     @Override
206     public boolean equals(final Object o) {
207         if (this == o) {
208             return true;
209         }
210         if (!(o instanceof RamFileData)) {
211             return false;
212         }
213         final RamFileData../../../../../org/apache/commons/vfs2/provider/ram/RamFileData.html#RamFileData">RamFileData data = (RamFileData) o;
214         return this.getName().equals(data.getName());
215     }
216 
217     /*
218      * (non-Javadoc)
219      *
220      * @see java.lang.Object#hashCode()
221      */
222     @Override
223     public int hashCode() {
224         return this.getName().hashCode();
225     }
226 
227     boolean hasChildren(final RamFileData data) {
228         return this.children.contains(data);
229     }
230 
231     /**
232      * @return Returns the size of the buffer
233      */
234     int size() {
235         return content.length;
236     }
237 
238     /**
239      * Resize the buffer
240      *
241      * @param newSize The new buffer size.
242      */
243     void resize(final long newSize) {
244         // A future implementation may allow longs/multiple buffer/and so on
245         if (newSize > Integer.MAX_VALUE) {
246             throw new IllegalArgumentException(
247                     String.format("newSize(%d) > Integer.MAX_VALUE(%d)", newSize, Integer.MAX_VALUE));
248         }
249         final int resize = (int) newSize;
250         final int size = this.size();
251         final byte[] newBuf = new byte[resize];
252         System.arraycopy(this.content, 0, newBuf, 0, Math.min(resize, size));
253         this.content = newBuf;
254         updateLastModified();
255     }
256 
257 }