1 17 18 package org.apache.avalon.cornerstone.blocks.masterstore; 19 20 import java.io.File ; 21 import java.io.FileInputStream ; 22 import java.io.FileOutputStream ; 23 import java.io.FilenameFilter ; 24 import java.io.IOException ; 25 import java.io.InputStream ; 26 import java.io.OutputStream ; 27 import java.util.ArrayList ; 28 import java.util.Iterator ; 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 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 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 m_path; 61 protected String m_destination; 62 protected String m_extension; 63 protected String m_name; 64 protected FilenameFilter m_filter; 65 protected File m_baseDirectory; 66 67 protected ServiceManager m_serviceManager; 68 69 protected abstract String getExtensionDecorator(); 70 71 78 public void contextualize( final Context context ) throws ContextException 79 { 80 try 81 { 82 m_baseDirectory = (File )context.get( "urn:avalon:home" ); 83 } 84 catch( ContextException e ) 85 { 86 m_baseDirectory = (File )context.get( "app.home" ); 87 } 88 } 89 90 97 public void service( final ServiceManager serviceManager ) 98 throws ServiceException 99 { 100 m_serviceManager = serviceManager; 101 } 102 103 108 public void configure( final Configuration configuration ) 109 throws ConfigurationException 110 { 111 if( null == m_destination ) 112 { 113 final String destination = configuration.getAttribute( "destinationURL" ); 114 setDestination( destination ); 115 } 116 } 117 118 122 public void initialize() 123 throws Exception 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 directory = new File ( m_path ); 132 directory.mkdirs(); 133 134 getLogger().info( getClass().getName() + " opened in " + m_path ); 135 } 136 137 protected void setDestination( final String 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 directory; 148 149 if( m_path.startsWith( "/" ) ) 151 { 152 directory = new File ( m_path ); 153 } 154 else 155 { 156 directory = new File ( m_baseDirectory, m_path ); 157 } 158 159 try 160 { 161 directory = directory.getCanonicalFile(); 162 } 163 catch( final IOException 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 176 { 177 return (AbstractFileRepository)getClass().newInstance(); 178 } 179 180 public Repository getChildRepository( final String childName ) 181 { 182 AbstractFileRepository child = null; 183 184 try 185 { 186 child = createChildRepository(); 187 } 188 catch( final Exception e ) 189 { 190 throw new RuntimeException ( "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 ( "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 ( "Cannot set destination for child child " + 213 "repository " + childName + 214 " : " + ce ); 215 } 216 217 try 218 { 219 child.initialize(); 220 } 221 catch( final Exception e ) 222 { 223 throw new RuntimeException ( "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 getFile( final String key ) 239 throws IOException 240 { 241 return new File ( encode( key ) ); 242 } 243 244 protected InputStream getInputStream( final String key ) 245 throws IOException 246 { 247 return new FileInputStream ( getFile( key ) ); 248 } 249 250 protected OutputStream getOutputStream( final String key ) 251 throws IOException 252 { 253 return new FileOutputStream ( getFile( key ) ); 254 } 255 256 259 public synchronized void remove( final String key ) 260 { 261 try 262 { 263 final File file = getFile( key ); 264 file.delete(); 265 if( DEBUG ) getLogger().debug( "removed key " + key ); 266 } 267 catch( final Exception e ) 268 { 269 throw new RuntimeException ( "Exception caught while removing" + 270 " an object: " + e ); 271 } 272 } 273 274 277 public synchronized boolean containsKey( final String key ) 278 { 279 try 280 { 281 final File file = getFile( key ); 282 if( DEBUG ) getLogger().debug( "checking key " + key ); 283 return file.exists(); 284 } 285 catch( final Exception e ) 286 { 287 throw new RuntimeException ( "Exception caught while searching " + 288 "an object: " + e ); 289 } 290 } 291 292 295 public Iterator list() 296 { 297 final File storeDir = new File ( m_path ); 298 final String [] names = storeDir.list( m_filter ); 299 final ArrayList list = new ArrayList (); 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 317 protected String encode( final String 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 result = new StringBuffer (); 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 343 protected String decode( String 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 ( bytes ); 356 } 357 } 358 | Popular Tags |