1 17 18 package org.apache.james.mailrepository.filepair; 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.excalibur.io.ExtensionFileFilter; 31 import org.apache.avalon.framework.activity.Initializable; 32 import org.apache.avalon.framework.configuration.Configurable; 33 import org.apache.avalon.framework.configuration.Configuration; 34 import org.apache.avalon.framework.configuration.ConfigurationException; 35 import org.apache.avalon.framework.context.Context; 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 import org.apache.avalon.phoenix.BlockContext; 42 43 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 protected BlockContext m_context; 69 70 protected abstract String getExtensionDecorator(); 71 72 public void contextualize( final Context context ) 73 { 74 final BlockContext blockContext = (BlockContext) context; 75 m_baseDirectory = blockContext.getBaseDirectory(); 76 } 77 78 public void service( final ServiceManager serviceManager ) 79 throws ServiceException 80 { 81 m_serviceManager = serviceManager; 82 } 83 84 public void configure( final Configuration configuration ) 85 throws ConfigurationException 86 { 87 if( null == m_destination ) 88 { 89 final String destination = configuration.getAttribute( "destinationURL" ); 90 setDestination( destination ); 91 } 92 } 93 94 public void initialize() 95 throws Exception 96 { 97 getLogger().info( "Init " + getClass().getName() + " Store" ); 98 99 m_name = RepositoryManager.getName(); 100 String m_postfix = getExtensionDecorator(); 101 m_extension = "." + m_name + m_postfix; 102 m_filter = new ExtensionFileFilter(m_extension); 103 105 final File directory = new File ( m_path ); 106 directory.mkdirs(); 107 108 getLogger().info( getClass().getName() + " opened in " + m_path ); 109 110 114 FilenameFilter num_filter = new NumberedRepositoryFileFilter(getExtensionDecorator()); 115 final String [] names = directory.list( num_filter ); 116 117 try { 118 for( int i = 0; i < names.length; i++ ) { 119 String origFilename = names[i]; 120 121 int pos = origFilename.length() - m_postfix.length(); 123 while (pos >= 1 && Character.isDigit(origFilename.charAt(pos - 1))) { 124 pos--; 125 } 126 pos -= ".".length() + m_name.length(); 127 String newFilename = origFilename.substring(0, pos) + m_extension; 128 129 File origFile = new File (directory, origFilename); 130 File newFile = new File (directory, newFilename); 131 132 if (origFile.renameTo(newFile)) { 133 getLogger().info("Renamed " + origFile + " to " + newFile); 134 } else { 135 getLogger().info("Unable to rename " + origFile + " to " + newFile); 136 } 137 } 138 } catch (Exception e) { 139 throw e; 140 } 141 142 } 143 144 protected void setDestination( final String destination ) 145 throws ConfigurationException 146 { 147 if( !destination.startsWith( HANDLED_URL ) ) 148 { 149 throw new ConfigurationException( "cannot handle destination " + destination ); 150 } 151 152 m_path = destination.substring( HANDLED_URL.length() ); 153 154 File directory; 155 156 if( m_path.startsWith( "/" ) ) 158 { 159 directory = new File ( m_path ); 160 } 161 else 162 { 163 directory = new File ( m_baseDirectory, m_path ); 164 } 165 166 try 167 { 168 directory = directory.getCanonicalFile(); 169 } 170 catch( final IOException ioe ) 171 { 172 throw new ConfigurationException( "Unable to form canonical representation of " + 173 directory ); 174 } 175 176 m_path = directory.toString(); 177 178 m_destination = destination; 179 } 180 181 protected AbstractFileRepository createChildRepository() 182 throws Exception 183 { 184 return (AbstractFileRepository) getClass().newInstance(); 185 } 186 187 public Repository getChildRepository( final String childName ) 188 { 189 AbstractFileRepository child = null; 190 191 try 192 { 193 child = createChildRepository(); 194 } 195 catch( final Exception e ) 196 { 197 throw new RuntimeException ( "Cannot create child repository " + 198 childName + " : " + e ); 199 } 200 201 try 202 { 203 child.service( m_serviceManager ); 204 } 205 catch( final ServiceException cme ) 206 { 207 throw new RuntimeException ( "Cannot service child " + 208 "repository " + childName + 209 " : " + cme ); 210 } 211 212 try 213 { 214 child.setDestination( m_destination + File.pathSeparatorChar + 215 childName + File.pathSeparator ); 216 } 217 catch( final ConfigurationException ce ) 218 { 219 throw new RuntimeException ( "Cannot set destination for child child " + 220 "repository " + childName + 221 " : " + ce ); 222 } 223 224 try 225 { 226 child.initialize(); 227 } 228 catch( final Exception e ) 229 { 230 throw new RuntimeException ( "Cannot initialize child " + 231 "repository " + childName + 232 " : " + e ); 233 } 234 235 if( DEBUG ) 236 { 237 getLogger().debug( "Child repository of " + m_name + " created in " + 238 m_destination + File.pathSeparatorChar + 239 childName + File.pathSeparator ); 240 } 241 242 return child; 243 } 244 245 protected File getFile( final String key ) 246 throws IOException 247 { 248 return new File ( encode( key ) ); 249 } 250 251 protected InputStream getInputStream( final String key ) 252 throws IOException 253 { 254 return new FileInputStream ( getFile( key ) ); 255 } 256 257 protected OutputStream getOutputStream( final String key ) 258 throws IOException 259 { 260 return new FileOutputStream ( getFile( key ) ); 261 } 262 263 266 public synchronized void remove( final String key ) 267 { 268 try 269 { 270 final File file = getFile( key ); 271 file.delete(); 272 if( DEBUG ) getLogger().debug( "removed key " + key ); 273 } 274 catch( final Exception e ) 275 { 276 throw new RuntimeException ( "Exception caught while removing" + 277 " an object: " + e ); 278 } 279 } 280 281 284 public synchronized boolean containsKey( final String key ) 285 { 286 try 287 { 288 final File file = getFile( key ); 289 if( DEBUG ) getLogger().debug( "checking key " + key ); 290 return file.exists(); 291 } 292 catch( final Exception e ) 293 { 294 throw new RuntimeException ( "Exception caught while searching " + 295 "an object: " + e ); 296 } 297 } 298 299 302 public Iterator list() 303 { 304 final File storeDir = new File ( m_path ); 305 final String [] names = storeDir.list( m_filter ); 306 final ArrayList list = new ArrayList (); 307 308 for( int i = 0; i < names.length; i++ ) 309 { 310 String decoded = decode(names[i]); 311 list.add(decoded); 312 } 313 314 return list.iterator(); 315 } 316 317 325 protected String encode( final String key ) 326 { 327 final byte[] bytes = key.getBytes(); 328 final char[] buffer = new char[ bytes.length << 1 ]; 329 330 for( int i = 0, j = 0; i < bytes.length; i++ ) 331 { 332 final int k = bytes[ i ]; 333 buffer[ j++ ] = HEX_DIGITS[ ( k >>> 4 ) & BYTE_MASK ]; 334 buffer[ j++ ] = HEX_DIGITS[ k & BYTE_MASK ]; 335 } 336 337 StringBuffer result = new StringBuffer (); 338 result.append( m_path ); 339 result.append( File.separator ); 340 result.append( buffer ); 341 result.append( m_extension ); 342 return result.toString(); 343 } 344 345 351 protected String decode( String filename ) 352 { 353 filename = filename.substring( 0, filename.length() - m_extension.length() ); 354 final int size = filename.length(); 355 final byte[] bytes = new byte[ size >>> 1 ]; 356 357 for( int i = 0, j = 0; i < size; j++ ) 358 { 359 bytes[ j ] = Byte.parseByte( filename.substring( i, i + 2 ), 16 ); 360 i +=2; 361 } 362 363 return new String ( bytes ); 364 } 365 } 366 | Popular Tags |