1 4 package org.openedit.repository.filesystem; 5 6 import java.io.File ; 7 import java.io.FilenameFilter ; 8 import java.util.List ; 9 10 import org.apache.commons.logging.Log; 11 import org.apache.commons.logging.LogFactory; 12 import org.openedit.repository.ContentItem; 13 import org.openedit.repository.RepositoryException; 14 15 18 public abstract class VersionedRepository extends FileRepository 19 { 20 static final String VERSIONS = ".versions"; 21 static final String META_DATA = ".metadata.xml"; 22 private static final Log log = LogFactory.getLog(VersionedRepository.class); 23 public VersionedRepository() 24 { 25 } 27 public VersionedRepository( File inRootDirectory ) 28 { 29 if ( !inRootDirectory.exists() ) 30 { 31 inRootDirectory.mkdirs(); 32 } 33 if ( inRootDirectory.isFile() ) 34 { 35 throw new IllegalArgumentException ( "The root directory must be a directory, not a file: " + inRootDirectory.getAbsolutePath() ); 36 } 37 fieldRootDirectory = inRootDirectory; 38 } 39 40 public ContentItem get( String inPath ) throws RepositoryException 41 { 42 File file = getFile( inPath); 43 checkVersion(file, inPath); 44 FileItem contentItem = new FileItem(); 45 contentItem.setPath( inPath ); 46 contentItem.setFile( file); 47 return contentItem; 48 } 49 public ContentItem getStub( String inPath ) throws RepositoryException 50 { 51 return createContentItem(inPath); 52 } 53 57 protected void checkVersion(File file, String inPath) throws RepositoryException 58 { 59 if (file.isDirectory()) 60 { 61 return; 62 } 63 File versionsDirectory = getVersionsDirectory( file ); 65 if( !versionsDirectory.exists() ) 66 { 67 return; 68 } 69 70 int m = maxVersionNumber(file); 71 if ( m == 0) 72 { 73 createInitialContentItem( inPath ); 74 } 75 else 76 { 77 String max = String.valueOf( m ); 78 File lastVersion = getVersionFile( file, max ); 79 if( file.lastModified() > lastVersion.lastModified() ) 80 { 81 ContentItem newItem = createContentItem(inPath); 82 newItem.setAuthor( "admin" ); 83 newItem.setMessage("edited version from disk"); 84 saveVersion( newItem ); 85 } 86 } 87 } 88 89 public void put( ContentItem inContentItem ) throws RepositoryException 90 { 91 String path = inContentItem.getPath(); 92 File file = getFile( path ); 93 if (file.isDirectory()) 94 { 95 throw new RepositoryException( "Error attempting to write content to a " 96 + "folder instead of a file for path " + path ); 97 } 98 checkReservedPaths( path ); 99 100 if (file.exists()) 101 { 102 if (inContentItem.getMessage() == null) 103 { 104 inContentItem.setMessage( inContentItem.getPath() + " modified" ); 105 } 106 inContentItem.setType( ContentItem.TYPE_EDITED ); 107 } 108 else 109 { 110 if (inContentItem.getMessage() == null) 111 { 112 inContentItem.setMessage( inContentItem.getPath() + " added" ); 113 } 114 inContentItem.setType( ContentItem.TYPE_ADDED ); 115 } 116 117 if (path.endsWith("/") && !file.exists()) 118 { 119 file.mkdirs(); 120 } 121 else 122 { 123 writeContent( inContentItem ); 124 } 125 126 if ( inContentItem.isMakeVersion() ) 127 { 128 saveVersion( inContentItem ); 129 } 130 131 } 132 protected String [] listFiles( final String inFileName, File versionsDirectory ) 133 { 134 FilenameFilter filenameFilter = new FilenameFilter () 135 { 136 public boolean accept( File dir, String name ) 137 { 138 return name.startsWith( inFileName ) && !name.endsWith( META_DATA ); 139 } 140 }; 141 String [] filesInDirectory = versionsDirectory.list( filenameFilter ); 142 return filesInDirectory; 143 } 144 145 protected void checkReservedPaths( String inPath ) throws RepositoryException 146 { 147 if (inPath.indexOf( VERSIONS ) > -1) 148 { 149 throw new RepositoryException( "The path \"" + inPath + "\" is a reserved path. " 150 + "Choose a different path or use a different repository." ); 151 } 152 } 153 154 protected int maxVersionNumber( File inFile ) 155 { 156 File versionsDirectory = getVersionsDirectory( inFile ); 157 String [] oldVersions = listFiles( inFile.getName(), versionsDirectory ); 158 int maxVersionNum = 0; 159 if ( oldVersions != null) 160 { 161 for ( int n = 0; n < oldVersions.length; n++ ) 162 { 163 int versionNum = extractVersionNumberFromFilename( oldVersions[n] ); 164 maxVersionNum = Math.max( maxVersionNum, versionNum ); 165 } 166 } 167 return maxVersionNum; 168 } 169 170 protected int extractVersionNumberFromFilename( String filename ) 171 { 172 int lastDotIndex = filename.lastIndexOf( '~' ); 173 if (lastDotIndex >= 0 && lastDotIndex < filename.length() - 1) 174 { 175 try 176 { 177 return Integer.parseInt( filename.substring( lastDotIndex + 1 ) ); 178 } 179 catch( NumberFormatException e ) 180 { 181 log.error("Should not get errors " + e); 182 return 0; 183 } 184 } 185 else 186 { 187 return 0; 188 } 189 } 190 public void move( ContentItem inSource, ContentItem inDestination ) throws RepositoryException 191 { 192 File sourceFile = getFile( inSource.getPath() ); 193 File destination = getFile( inDestination.getPath() ); 194 195 if ( inDestination.getMessage() == null) 196 { 197 inDestination.setMessage( inSource.getPath() + " moved to " + inDestination.getPath() ); 198 } 199 if ( inDestination.getType() == null) 200 { 201 inDestination.setType( ContentItem.TYPE_MOVED); 202 } 203 204 moveFiles( sourceFile, destination ); 205 206 if ( inDestination.isMakeVersion() ) 207 { 208 saveVersion( inDestination ); 209 } 210 211 } 212 213 public void copy( ContentItem inSource, ContentItem inDestination ) throws RepositoryException 214 { 215 File sourceFile = getFile( inSource ); 216 File destination = getFile( inDestination.getPath() ); 217 218 if ( inDestination.getMessage() == null) 219 { 220 inDestination.setMessage( inSource.getPath() + " copied to " + inDestination.getPath() ); 221 } 222 if ( inDestination.getType() == null) 223 { 224 inDestination.setType( ContentItem.TYPE_COPIED); 225 } 226 copyFiles(sourceFile, destination); 227 228 if ( inDestination.isMakeVersion() ) 229 { 230 saveVersion( inDestination ); 231 } 232 233 } 234 235 236 public void remove( ContentItem inContentItem ) throws RepositoryException 237 { 238 File todelete = getFile( inContentItem.getPath() ); 239 if ( inContentItem.getMessage() == null) 240 { 241 inContentItem.setMessage( inContentItem.getPath() + " removed"); 242 } 243 inContentItem.setType( ContentItem.TYPE_REMOVED ); 244 254 if( inContentItem.isMakeVersion() ) 255 { 256 saveVersion(inContentItem); 257 } 258 deleteAll(todelete); 259 } 260 261 public abstract List getVersions( String inPath ) throws RepositoryException; 262 263 protected ContentItem getContentItem( String inPath, ContentItem inContentItem ) 264 { 265 FileItem contentItem = new FileItem(); 266 contentItem.setPath( inPath ); 267 contentItem.setFile( getVersionFile( getFile( inPath ), inContentItem.getVersion() ) ); 268 return contentItem; 269 } 270 271 protected ContentItem createInitialContentItem( String inPath ) throws RepositoryException 272 { 273 ContentItem contentItem = createContentItem(inPath); 274 contentItem.setPath(inPath); 275 contentItem.setAuthor( "admin" ); 276 contentItem.setMessage( "automatic version" ); 277 contentItem.setVersion( "1" ); 278 contentItem.setType( ContentItem.TYPE_ADDED ); 279 if ( contentItem.exists() ) 280 { 281 saveVersion( contentItem ); 282 } 283 return contentItem; 284 } 285 286 protected File getVersionsDirectory( String inPath ) 287 { 288 return getVersionsDirectory( new File ( getRootDirectory(), inPath ) ); 289 } 290 291 protected File getVersionsDirectory( File inSourceFile ) 292 { 293 File reservedDirectory = new File ( inSourceFile.getParentFile(), VERSIONS ); 294 return reservedDirectory; 295 } 296 297 protected File getMetaDataFile( File file ) 298 { 299 File metadata = new File ( getVersionsDirectory( file ), file.getName() + META_DATA ); 300 return metadata; 301 } 302 303 protected abstract void saveVersion( ContentItem inContentItem ) throws RepositoryException; 304 305 310 protected File getVersionFile( File inSourceFile, String inVersionNumber ) 311 { 312 File versionFile = new File ( getVersionsDirectory( inSourceFile ), inSourceFile.getName() 313 + '~' + inVersionNumber ); 314 return versionFile; 315 } 316 } | Popular Tags |