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 org.codehaus.plexus.components.io.attributes.PlexusIoResourceAttributes;
20  import org.codehaus.plexus.components.io.functions.ContentSupplier;
21  import org.codehaus.plexus.components.io.functions.InputStreamTransformer;
22  import org.codehaus.plexus.components.io.functions.PlexusIoResourceConsumer;
23  
24  import javax.annotation.Nonnull;
25  import java.io.Closeable;
26  import java.io.File;
27  import java.io.IOException;
28  import java.io.InputStream;
29  import java.util.Collections;
30  import java.util.Iterator;
31  
32  
33  /**
34   * Abstract base class for compressed files, aka singleton
35   * resource collections.
36   */
37  public abstract class PlexusIoCompressedFileResourceCollection
38      implements PlexusIoArchivedResourceCollection, Iterable<PlexusIoResource>
39  {
40      private File file;
41  
42      private String path;
43  
44      private InputStreamTransformer streamTransformers = AbstractPlexusIoResourceCollection.identityTransformer;
45  
46  
47      public File getFile()
48      {
49          return file;
50      }
51  
52      public void setFile( File file )
53      {
54          this.file = file;
55  
56      }
57  
58      public String getPath()
59      {
60          return path;
61      }
62  
63      public void setPath( String path )
64      {
65          this.path = path;
66  
67      }
68  
69      // return the file attributes of the uncompressed file
70      // may be null.
71      protected abstract PlexusIoResourceAttributes getAttributes( File f )
72          throws IOException;
73  
74      public void setStreamTransformer( InputStreamTransformer streamTransformers )
75      {
76          this.streamTransformers = streamTransformers;
77      }
78  
79      public Stream stream()
80      {
81          return new Stream()
82          {
83              public void forEach( PlexusIoResourceConsumer resourceConsumer )
84                  throws IOException
85              {
86  
87                  final Iterator<PlexusIoResource> it = getResources();
88                  while ( it.hasNext() )
89                  {
90                      resourceConsumer.accept( it.next() );
91                  }
92                  if ( it instanceof Closeable )
93                  {
94                      ( (Closeable) it ).close();
95                  }
96              }
97          };
98      }
99  
100     public Iterator<PlexusIoResource> getResources()
101         throws IOException
102     {
103         final File f = getFile();
104         final String p = ( getPath() == null ? getName( f ) : getPath() ).replace( '\\', '/' );
105         if ( f == null )
106         {
107             throw new IOException( "No archive file is set." );
108         }
109         if ( !f.isFile() )
110         {
111             throw new IOException( "The archive file " + f.getPath() + " does not exist or is no file." );
112         }
113 
114         final PlexusIoResourceAttributes attributes = getAttributes( f );
115 
116         final ContentSupplier contentSupplier = new ContentSupplier()
117         {
118             @Nonnull
119             public InputStream getContents()
120                 throws IOException
121             {
122                 return getInputStream( f );
123             }
124         };
125 
126         final PlexusIoResource resource =
127             ResourceFactory.createResource( f, p, contentSupplier, attributes );
128 
129         return Collections.singleton( resource ).iterator();
130     }
131 
132     protected String getName( File file )
133         throws IOException
134     {
135         final String name = file.getPath();
136         final String ext = getDefaultExtension();
137         if ( ext != null && ext.length() > 0 && name.endsWith( ext ) )
138         {
139             return name.substring( 0, name.length() - ext.length() );
140         }
141         return name;
142     }
143 
144     protected abstract String getDefaultExtension();
145 
146     protected abstract @Nonnull InputStream getInputStream( File file )
147         throws IOException;
148 
149     public InputStream getInputStream( PlexusIoResource resource )
150         throws IOException
151     {
152         InputStream contents = resource.getContents();
153         return new ClosingInputStream( streamTransformers.transform( resource, contents ), contents );
154     }
155 
156     public PlexusIoResource resolve( final PlexusIoResource resource )
157         throws IOException
158     {
159         final Deferred deferred = new Deferred( resource, this, streamTransformers
160             != AbstractPlexusIoResourceCollection.identityTransformer );
161         return deferred.asResource();
162     }
163 
164 
165     public Iterator<PlexusIoResource> iterator()
166     {
167         try
168         {
169             return getResources();
170         }
171         catch ( IOException e )
172         {
173             throw new RuntimeException( e );
174         }
175     }
176 
177     public String getName( PlexusIoResource resource )
178     {
179         return resource.getName();
180     }
181 
182     public long getLastModified()
183         throws IOException
184     {
185         File f = getFile();
186         return f == null ? PlexusIoResource.UNKNOWN_MODIFICATION_DATE : f.lastModified();
187     }
188 
189     public boolean isConcurrentAccessSupported()
190     {
191         // There is a single resource in the collection so it is safe
192         return true;
193     }
194 }