1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21 package org.millscript.commons.vfs;
22
23 import org.millscript.commons.alert.Alert;
24 import org.millscript.commons.alert.AlertDecorator;
25 import org.millscript.commons.alert.alerts.Fault;
26 import org.millscript.commons.alert.alerts.IOAlert;
27 import org.millscript.commons.vfs.alerts.VEntryNotFoundAlert;
28 import org.millscript.commons.vfs.protocols.file.LocalFile;
29
30 import java.io.File;
31 import java.io.FileNotFoundException;
32 import java.io.IOException;
33 import java.io.InputStream;
34 import java.io.InputStreamReader;
35 import java.io.OutputStream;
36 import java.io.OutputStreamWriter;
37 import java.io.Reader;
38 import java.io.Writer;
39 import java.net.URI;
40
41 /**
42 * This class provides the skeletal implementation of a virtual filesystem
43 * file,
44 */
45 public abstract class AbstractVFile< V extends VVolume > extends AbstractVEntry< V > implements AlertDecorator, VFile {
46
47 /**
48 * Constructs a new virtual filesystem file with the specified name,
49 * parent folder and volume.
50 *
51 * @param vol the volume this entry is held on
52 * @param parent the parent folder for this file
53 * @param name the name of the file
54 */
55 public AbstractVFile( final V vol, final VFolder parent, final String name ) {
56 super( vol, parent, name );
57 }
58
59 /**
60 * @see org.millscript.commons.vfs.VEntry#appendRelativePath(java.lang.StringBuffer)
61 */
62 public final StringBuffer appendRelativePath( final StringBuffer buff ) {
63
64
65
66 if ( this.getParent() != null ) {
67 this.getParent().appendRelativePath( buff );
68 }
69 return buff.append( this.getName() );
70 }
71
72 /**
73 * @see org.millscript.commons.vfs.VEntry#appendRelativePathOnVolume(java.lang.StringBuffer)
74 */
75 public StringBuffer appendRelativePathOnVolume( final StringBuffer buff ) {
76
77
78
79
80
81
82
83 if ( this.getParent() == null ) {
84
85 return buff.append( this.getName() );
86 } else if ( this.getParent().getVolume() == this.getVolume() ) {
87
88
89 this.getParent().appendRelativePathOnVolume( buff );
90 }
91 return buff.append( this.getName() );
92 }
93
94 /**
95 * @see org.millscript.commons.vfs.VEntry#appendURI(java.lang.StringBuffer)
96 */
97 public final StringBuffer appendURI( final StringBuffer buffer ) {
98
99
100
101 if ( this.getParent() == null ) {
102
103 this.getVolume().appendBaseURI( buffer );
104 } else {
105
106 this.getParent().appendURI( buffer );
107 }
108 return buffer.append( this.getName() );
109 }
110
111 /**
112 * @see org.millscript.commons.alert.AlertDecorator#decorate(org.millscript.commons.alert.Alert)
113 */
114 public Alert decorate( final Alert alert ) {
115 return alert.culprit( "vfile", this );
116 }
117
118 /**
119 * @see org.millscript.commons.vfs.VFile#getAppendWriter()
120 */
121 public final Writer getAppendWriter() {
122 return new OutputStreamWriter(
123 this.getAppendOutputStream(),
124 this.getVolume().getParentVFS().getDefaultCharset()
125 );
126 }
127
128 /**
129 * @see org.millscript.commons.vfs.VFile#getContentMIMEType()
130 */
131 public String getContentMIMEType() {
132 return this.getMIMEType( this.getName() );
133 }
134
135 /**
136 * @see org.millscript.commons.vfs.VFile#getReader()
137 */
138 public final Reader getReader() {
139 return new InputStreamReader(
140 this.getInputStream(),
141 this.getVolume().getParentVFS().getDefaultCharset()
142 );
143 }
144
145 /**
146 * @see org.millscript.commons.vfs.VFile#getWriter()
147 */
148 public final Writer getWriter() {
149 return new OutputStreamWriter(
150 this.getOutputStream(),
151 this.getVolume().getParentVFS().getDefaultCharset()
152 );
153 }
154
155 /**
156 * @see org.millscript.commons.vfs.VFile#toLocal()
157 */
158 public LocalFile toLocal() {
159
160
161
162 final String originialFileName = this.getName();
163 LocalFile tempFile;
164 try {
165 final String name = originialFileName.substring( 0, originialFileName.indexOf( '.' ) );
166 final String extn = originialFileName.substring( originialFileName.indexOf( '.' ) );
167 final URI localFileURI = File.createTempFile( name, extn, null ).toURI();
168 tempFile = (LocalFile) this.getVolume().getParentVFS().resolveAsFile( localFileURI );
169 } catch ( IOException ex ) {
170 throw new IOAlert(
171 "Could not create a temporary copy of the virtual file"
172 ).culpritURI( this.getURI() ).setParentThrowable( ex ).mishap();
173 }
174 InputStream source = null;
175 OutputStream destination = null;
176 try {
177
178
179
180
181 source = this.getInputStream();
182 destination = tempFile.getOutputStream();
183
184 final byte[] buffer = new byte[1024];
185 int len = 0;
186
187 while ( ( len = source.read( buffer ) ) > 0 ) {
188 destination.write( buffer, 0, len );
189 }
190 source.close();
191 destination.close();
192 return tempFile;
193 } catch ( FileNotFoundException ex ) {
194
195 try {
196 if ( source != null ) {
197 source.close();
198 }
199 if ( destination != null ) {
200 destination.close();
201 }
202 } catch ( IOException ex2 ) {
203 throw new Fault(
204 "Failed to close input or output stream"
205 ).mishap();
206 }
207
208 throw new VEntryNotFoundAlert(
209 "Temporary file seems to have disappeared before we could open it!"
210 ).setParentThrowable( ex ).mishap();
211 } catch ( IOException ex ) {
212
213 try {
214 if ( source != null ) {
215 source.close();
216 }
217 if ( destination != null ) {
218 destination.close();
219 }
220 } catch ( IOException ex2 ) {
221 throw new Fault(
222 "Failed to close input or output stream"
223 ).mishap();
224 }
225 throw new IOAlert(
226 "A problem occured transfering data from the virtual file to the temporary copy"
227 ).culpritURI( this.getURI() ).setParentThrowable( ex ).mishap();
228 }
229 }
230
231 /**
232 * @see java.lang.Object#toString()
233 */
234 @Override
235 public String toString() {
236 final StringBuffer buff = new StringBuffer( "VFILE( " );
237 this.appendAbsolutePath( buff );
238 buff.append( " )" );
239 return buff.toString();
240 }
241
242 }