View Javadoc
1   package org.codehaus.plexus.components.io.resources;
2   
3   /*
4    * Copyright 2007 The Codehaus Foundation.
5    *
6    * Licensed under the Apache License, Version 2.0 (the "License");
7    * you may not use this file except in compliance with the License.
8    * You may obtain a copy of the License at
9    *
10   *      http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  
19  import java.io.ByteArrayInputStream;
20  import java.io.File;
21  import java.io.FileInputStream;
22  import java.io.IOException;
23  import java.io.InputStream;
24  import java.net.URL;
25  
26  import org.apache.commons.io.IOUtils;
27  import org.apache.commons.io.output.DeferredFileOutputStream;
28  import org.codehaus.plexus.components.io.attributes.AttributeUtils;
29  import org.codehaus.plexus.components.io.attributes.PlexusIoResourceAttributes;
30  import org.codehaus.plexus.components.io.functions.ContentSupplier;
31  import org.codehaus.plexus.components.io.functions.FileSupplier;
32  import org.codehaus.plexus.components.io.functions.InputStreamTransformer;
33  import org.codehaus.plexus.components.io.functions.ResourceAttributeSupplier;
34  
35  import javax.annotation.Nonnull;
36  
37  /**
38   * Implementation of {@link PlexusIoResource} for files.
39   */
40  public class PlexusIoFileResource
41      extends AbstractPlexusIoResource
42      implements ResourceAttributeSupplier, FileSupplier
43  
44  {
45      @Nonnull
46      private final File file;
47  
48      @Nonnull
49      private final PlexusIoResourceAttributes attributes;
50  
51      private final ContentSupplier contentSupplier;
52  
53      private final DeferredFileOutputStream dfos;
54  
55      protected PlexusIoFileResource( @Nonnull File file, @Nonnull String name,
56                                      @Nonnull PlexusIoResourceAttributes attrs )
57          throws IOException
58      {
59          this( file, name, attrs, null, null );
60      }
61  
62      @SuppressWarnings( "ConstantConditions" )
63      PlexusIoFileResource( @Nonnull final File file, @Nonnull String name, @Nonnull PlexusIoResourceAttributes attrs,
64                            final ContentSupplier contentSupplier, final InputStreamTransformer streamTransformer )
65          throws IOException
66      {
67          super( name, file.lastModified(), file.length(), file.isFile(), file.isDirectory(), file.exists() );
68          this.file = file;
69  
70          this.contentSupplier = contentSupplier != null ? contentSupplier : getRootContentSupplier( file );
71  
72          boolean hasTransformer = streamTransformer != null && streamTransformer != identityTransformer;
73          InputStreamTransformer transToUse = streamTransformer != null ? streamTransformer : identityTransformer;
74  
75          dfos = hasTransformer && file.isFile() ? asDeferredStream( this.contentSupplier, transToUse, this ) : null;
76          if ( attrs == null )
77              throw new IllegalArgumentException( "attrs is null for file " + file.getName() );
78          this.attributes = attrs;
79      }
80  
81      private static DeferredFileOutputStream asDeferredStream( @Nonnull ContentSupplier supplier,
82                                                                @Nonnull InputStreamTransformer transToUse,
83                                                                PlexusIoResource resource )
84          throws IOException
85      {
86          DeferredFileOutputStream dfos = new DeferredFileOutputStream( 5000000, "p-archiver", null, null );
87          InputStream inputStream = supplier.getContents();
88          InputStream transformed = transToUse.transform( resource, inputStream );
89          IOUtils.copy( transformed, dfos );
90          IOUtils.closeQuietly( inputStream );
91          IOUtils.closeQuietly( transformed );
92          return dfos;
93      }
94  
95      private static ContentSupplier getRootContentSupplier( final File file )
96      {
97          return new ContentSupplier()
98          {
99              public InputStream getContents()
100                 throws IOException
101             {
102                 return new FileInputStream( file );
103             }
104         };
105     }
106 
107     public static String getName( File file )
108     {
109         return file.getPath().replace( '\\', '/' );
110     }
111 
112     /**
113      * Returns the resources file.
114      */
115     @Nonnull
116     public File getFile()
117     {
118         return file;
119     }
120 
121     @Nonnull
122     public InputStream getContents()
123         throws IOException
124     {
125         if ( dfos == null )
126         {
127             return contentSupplier.getContents();
128         }
129         if ( dfos.isInMemory() )
130         {
131             return new ByteArrayInputStream( dfos.getData() );
132         }
133         else
134         {
135             return new FileInputStream( dfos.getFile() )
136             {
137                 @SuppressWarnings( "ResultOfMethodCallIgnored" )
138                 @Override
139                 public void close()
140                     throws IOException
141                 {
142                     super.close();
143                     dfos.getFile().delete();
144                 }
145             };
146         }
147     }
148 
149     @Nonnull
150     public URL getURL()
151         throws IOException
152     {
153         return getFile().toURI().toURL();
154     }
155 
156     public long getSize()
157     {
158         if ( dfos == null )
159         {
160             return getFile().length();
161         }
162         if ( dfos.isInMemory() )
163         {
164             return dfos.getByteCount();
165         }
166         else
167         {
168             return dfos.getFile().length();
169         }
170     }
171 
172     public boolean isDirectory()
173     {
174         return getFile().isDirectory();
175     }
176 
177     public boolean isExisting()
178     {
179         return getFile().exists();
180     }
181 
182     public boolean isFile()
183     {
184         return getFile().isFile();
185     }
186 
187     @Nonnull
188     public PlexusIoResourceAttributes getAttributes()
189     {
190         return attributes;
191     }
192 
193     public long getLastModified()
194     {
195         return AttributeUtils.getLastModified( getFile() );
196     }
197 
198     @Override public boolean isSymbolicLink() {
199         return getAttributes().isSymbolicLink();
200     }
201 
202     private static final InputStreamTransformer identityTransformer = AbstractPlexusIoResourceCollection.identityTransformer;
203 }