KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > avalon > cornerstone > blocks > masterstore > AbstractFileRepository


1 /*
2  * Copyright 1999-2004 The Apache Software Foundation
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
12  * implied.
13  *
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */

17
18 package org.apache.avalon.cornerstone.blocks.masterstore;
19
20 import java.io.File JavaDoc;
21 import java.io.FileInputStream JavaDoc;
22 import java.io.FileOutputStream JavaDoc;
23 import java.io.FilenameFilter JavaDoc;
24 import java.io.IOException JavaDoc;
25 import java.io.InputStream JavaDoc;
26 import java.io.OutputStream JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import org.apache.avalon.cornerstone.services.store.Repository;
30 import org.apache.avalon.framework.activity.Initializable;
31 import org.apache.avalon.framework.configuration.Configurable;
32 import org.apache.avalon.framework.configuration.Configuration;
33 import org.apache.avalon.framework.configuration.ConfigurationException;
34 import org.apache.avalon.framework.context.Context;
35 import org.apache.avalon.framework.context.ContextException;
36 import org.apache.avalon.framework.context.Contextualizable;
37 import org.apache.avalon.framework.logger.AbstractLogEnabled;
38 import org.apache.avalon.framework.service.ServiceException;
39 import org.apache.avalon.framework.service.ServiceManager;
40 import org.apache.avalon.framework.service.Serviceable;
41
42 /**
43  * This an abstract class implementing functionality for creating a file-store.
44  *
45  * @author <a HREF="mailto:dev@avalon.apache.org">Avalon Development Team</a>
46  */

47 public abstract class AbstractFileRepository
48     extends AbstractLogEnabled
49     implements Repository, Contextualizable, Serviceable, Configurable, Initializable
50 {
51     protected static final boolean DEBUG = false;
52
53     protected static final String JavaDoc HANDLED_URL = "file://";
54     protected static final int BYTE_MASK = 0x0f;
55     protected static final char[] HEX_DIGITS = new char[]
56     {
57         '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F'
58     };
59
60     protected String JavaDoc m_path;
61     protected String JavaDoc m_destination;
62     protected String JavaDoc m_extension;
63     protected String JavaDoc m_name;
64     protected FilenameFilter JavaDoc m_filter;
65     protected File JavaDoc m_baseDirectory;
66
67     protected ServiceManager m_serviceManager;
68
69     protected abstract String JavaDoc getExtensionDecorator();
70
71    /**
72     * Contextualization of the component by the container during
73     * which the working home directory will be provided.
74     *
75     * @param context the supplied context object
76     * @avalon.entry key="urn:avalon:home" type="java.io.File"
77     */

78     public void contextualize( final Context context ) throws ContextException
79     {
80         try
81         {
82             m_baseDirectory = (File JavaDoc)context.get( "urn:avalon:home" );
83         }
84         catch( ContextException e )
85         {
86             m_baseDirectory = (File JavaDoc)context.get( "app.home" );
87         }
88     }
89
90    /**
91     * Serviceing of the component by the container. This implementation
92     * is somewhat suspect in that it does not declare any servicable
93     * dependencies.
94     *
95     * @param serviceManager a service manager
96     */

97     public void service( final ServiceManager serviceManager )
98         throws ServiceException
99     {
100         m_serviceManager = serviceManager;
101     }
102
103    /**
104     * Configuration of the component by the container.
105     * @param configuration the configuration
106     * @exception ConfigurationException if a configuration error occurs
107     */

108     public void configure( final Configuration configuration )
109         throws ConfigurationException
110     {
111         if( null == m_destination )
112         {
113             final String JavaDoc destination = configuration.getAttribute( "destinationURL" );
114             setDestination( destination );
115         }
116     }
117
118    /**
119     * Initialization of the component by the container.
120     * @exception Exception if a initialization stage error occurs
121     */

122     public void initialize()
123         throws Exception JavaDoc
124     {
125         getLogger().info( "Init " + getClass().getName() + " Store" );
126
127         m_name = RepositoryManager.getName();
128         m_extension = "." + m_name + getExtensionDecorator();
129         m_filter = new ExtensionFileFilter( m_extension );
130
131         final File JavaDoc directory = new File JavaDoc( m_path );
132         directory.mkdirs();
133
134         getLogger().info( getClass().getName() + " opened in " + m_path );
135     }
136
137     protected void setDestination( final String JavaDoc destination )
138         throws ConfigurationException
139     {
140         if( !destination.startsWith( HANDLED_URL ) )
141         {
142             throw new ConfigurationException( "cannot handle destination " + destination );
143         }
144
145         m_path = destination.substring( HANDLED_URL.length() );
146
147         File JavaDoc directory;
148
149         // Check for absolute path
150
if( m_path.startsWith( "/" ) )
151         {
152             directory = new File JavaDoc( m_path );
153         }
154         else
155         {
156             directory = new File JavaDoc( m_baseDirectory, m_path );
157         }
158
159         try
160         {
161             directory = directory.getCanonicalFile();
162         }
163         catch( final IOException JavaDoc ioe )
164         {
165             throw new ConfigurationException( "Unable to form canonical representation of " +
166                                               directory );
167         }
168
169         m_path = directory.toString();
170
171         m_destination = destination;
172     }
173
174     protected AbstractFileRepository createChildRepository()
175         throws Exception JavaDoc
176     {
177         return (AbstractFileRepository)getClass().newInstance();
178     }
179
180     public Repository getChildRepository( final String JavaDoc childName )
181     {
182         AbstractFileRepository child = null;
183
184         try
185         {
186             child = createChildRepository();
187         }
188         catch( final Exception JavaDoc e )
189         {
190             throw new RuntimeException JavaDoc( "Cannot create child repository " +
191                                         childName + " : " + e );
192         }
193
194         try
195         {
196             child.service( m_serviceManager );
197         }
198         catch( final ServiceException cme )
199         {
200             throw new RuntimeException JavaDoc( "Cannot service child " +
201                                         "repository " + childName +
202                                         " : " + cme );
203         }
204
205         try
206         {
207             child.setDestination( m_destination + File.pathSeparatorChar +
208                                   childName + File.pathSeparator );
209         }
210         catch( final ConfigurationException ce )
211         {
212             throw new RuntimeException JavaDoc( "Cannot set destination for child child " +
213                                         "repository " + childName +
214                                         " : " + ce );
215         }
216
217         try
218         {
219             child.initialize();
220         }
221         catch( final Exception JavaDoc e )
222         {
223             throw new RuntimeException JavaDoc( "Cannot initialize child " +
224                                         "repository " + childName +
225                                         " : " + e );
226         }
227
228         if( DEBUG )
229         {
230             getLogger().debug( "Child repository of " + m_name + " created in " +
231                                m_destination + File.pathSeparatorChar +
232                                childName + File.pathSeparator );
233         }
234
235         return child;
236     }
237
238     protected File JavaDoc getFile( final String JavaDoc key )
239         throws IOException JavaDoc
240     {
241         return new File JavaDoc( encode( key ) );
242     }
243
244     protected InputStream JavaDoc getInputStream( final String JavaDoc key )
245         throws IOException JavaDoc
246     {
247         return new FileInputStream JavaDoc( getFile( key ) );
248     }
249
250     protected OutputStream JavaDoc getOutputStream( final String JavaDoc key )
251         throws IOException JavaDoc
252     {
253         return new FileOutputStream JavaDoc( getFile( key ) );
254     }
255
256     /**
257      * Remove the object associated to the given key.
258      */

259     public synchronized void remove( final String JavaDoc key )
260     {
261         try
262         {
263             final File JavaDoc file = getFile( key );
264             file.delete();
265             if( DEBUG ) getLogger().debug( "removed key " + key );
266         }
267         catch( final Exception JavaDoc e )
268         {
269             throw new RuntimeException JavaDoc( "Exception caught while removing" +
270                                         " an object: " + e );
271         }
272     }
273
274     /**
275      * Indicates if the given key is associated to a contained object.
276      */

277     public synchronized boolean containsKey( final String JavaDoc key )
278     {
279         try
280         {
281             final File JavaDoc file = getFile( key );
282             if( DEBUG ) getLogger().debug( "checking key " + key );
283             return file.exists();
284         }
285         catch( final Exception JavaDoc e )
286         {
287             throw new RuntimeException JavaDoc( "Exception caught while searching " +
288                                         "an object: " + e );
289         }
290     }
291
292     /**
293      * Returns the list of used keys.
294      */

295     public Iterator JavaDoc list()
296     {
297         final File JavaDoc storeDir = new File JavaDoc( m_path );
298         final String JavaDoc[] names = storeDir.list( m_filter );
299         final ArrayList JavaDoc list = new ArrayList JavaDoc();
300
301         for( int i = 0; i < names.length; i++ )
302         {
303             list.add( decode( names[ i ] ) );
304         }
305
306         return list.iterator();
307     }
308
309     /**
310      * Returns a String that uniquely identifies the object.
311      * <b>Note:</b> since this method uses the Object.toString()
312      * method, it's up to the caller to make sure that this method
313      * doesn't change between different JVM executions (like
314      * it may normally happen). For this reason, it's highly recommended
315      * (even if not mandated) that Strings be used as keys.
316      */

317     protected String JavaDoc encode( final String JavaDoc key )
318     {
319         final byte[] bytes = key.getBytes();
320         final char[] buffer = new char[ bytes.length << 1 ];
321
322         for( int i = 0, j = 0; i < bytes.length; i++ )
323         {
324             final int k = bytes[ i ];
325             buffer[ j++ ] = HEX_DIGITS[ ( k >>> 4 ) & BYTE_MASK ];
326             buffer[ j++ ] = HEX_DIGITS[ k & BYTE_MASK ];
327         }
328
329         StringBuffer JavaDoc result = new StringBuffer JavaDoc();
330         result.append( m_path );
331         result.append( File.separator );
332         result.append( buffer );
333         result.append( m_extension );
334         return result.toString();
335     }
336
337     /**
338      * Inverse of encode exept it do not use path.
339      * So decode(encode(s) - m_path) = s.
340      * In other words it returns a String that can be used as key to retive
341      * the record contained in the 'filename' file.
342      */

343     protected String JavaDoc decode( String JavaDoc filename )
344     {
345         filename = filename.substring( 0, filename.length() - m_extension.length() );
346         final int size = filename.length();
347         final byte[] bytes = new byte[ size >>> 1 ];
348
349         for( int i = 0, j = 0; i < size; j++ )
350         {
351             bytes[ j ] = Byte.parseByte( filename.substring( i, i + 2 ), 16 );
352             i += 2;
353         }
354
355         return new String JavaDoc( bytes );
356     }
357 }
358
Popular Tags