/* * Created on Jan 4, 2005 */ package org.openedit.repository.filesystem; import java.io.File; import java.util.ArrayList; import java.util.Collections; import java.util.Date; import java.util.Iterator; import java.util.List; import org.dom4j.Document; import org.dom4j.DocumentHelper; import org.dom4j.Element; import org.dom4j.io.SAXReader; import org.openedit.repository.ContentItem; import org.openedit.repository.RepositoryException; import com.openedit.util.PathUtilities; import com.openedit.util.XmlUtil; /** * We need to move more stuff out of the Base Repository into here so that * one day we can implement a Macromedia Contribute version of this * @author cburkey * */ public class XmlVersionRepository extends VersionedRepository { protected XmlUtil fieldXmlUtil; public XmlVersionRepository() { } public XmlVersionRepository(String inPath, File inRoot) { setPath( inPath); setExternalPath(inRoot.getAbsolutePath()); } protected SAXReader fieldReader; /** * @param inPath * @param version * @return */ protected ContentItem populateRevision(String inPath, String inVersionsDir, Element version) { // <version number="1" author="admin" date="2323525233" type="added">Some message</version> String rootDir = PathUtilities.extractDirectoryPath(inPath); String filename = PathUtilities.extractFileName(inPath); String versionPath = rootDir + "/" + inVersionsDir + "/" + version.attributeValue("number") + "~" + filename ; ContentItem item = createContentItem(versionPath); item.setActualPath(versionPath); if(!item.exists()) { //check older version format also versionPath = rootDir + "/" + inVersionsDir + "/"+ filename + "~" + version.attributeValue("number") ; item = createContentItem(versionPath); item.setActualPath(versionPath); } item.setPath(inPath); //We dont need the date here since we use a FileItem that points to the date on the disk //This should be changed if we ever have problems with it. item.setAuthor(version.attributeValue("author")); item.setVersion(version.attributeValue("number")); String comment = version.getTextTrim(); item.setMessage(comment); item.setType(version.attributeValue("type")); return item; } public List readAll(String inPath, File inMetadata) throws RepositoryException { if ( !inMetadata.exists()) { return Collections.EMPTY_LIST; } Element root = getXmlUtil().getXml(inMetadata, "UTF-8"); List all = new ArrayList(); String versionsDir = inMetadata.getParentFile().getName(); for (Iterator versions = root.elementIterator("version"); versions.hasNext();) { Element version = (Element) versions.next(); ContentItem item = populateRevision(inPath,versionsDir, version); all.add(item); } Collections.reverse(all); //put oldest on bottom return all; } public void append(ContentItem inRevision, File inMetadata) throws RepositoryException { Document document = null; if ( !inMetadata.exists() ) { document = DocumentHelper.createDocument(); Element root = document.addElement("versions"); //root.addAttribute("path", inRevision.getPath()); } else { document = getXmlUtil().getXml(inMetadata, "UTF-8").getDocument(); } //TODO check that its not in there already Element version = document.getRootElement().addElement("version"); version.addAttribute("number",inRevision.getVersion()); Date date = inRevision.lastModified(); if ( date == null) { date = new Date(); } version.addAttribute("date",String.valueOf( date.getTime())); version.addAttribute("author",inRevision.getAuthor()); version.addAttribute("type",inRevision.getType()); version.setText(inRevision.getMessage()); inMetadata.getParentFile().mkdirs(); getXmlUtil().saveXml(document, inMetadata ); } /* (non-javadoc) * @see com.einnovation.repository.filesystem.BaseRepository#getContentItems(java.lang.String) */ public List getVersions(String inPath) throws RepositoryException { File file = getFile( inPath ); if (file.isDirectory()) { return Collections.EMPTY_LIST; } File versionsDirectory = getVersionsDirectory( file ); if( !versionsDirectory.exists() ) { versionsDirectory.mkdirs(); } checkVersion(file, inPath); File metadata = getMetaDataFile( file ); List knownContentItems = readAll( inPath, metadata ); return knownContentItems; } public ContentItem getLastVersion(String inPath) { File file = getFile( inPath ); File metadata = getMetaDataFile( file ); if ( !metadata.exists() ) { return null; } Element root = getXmlUtil().getXml(metadata, "UTF-8"); String versionsDir = metadata.getParentFile().getName(); List all = root.elements("version"); if( all.size() == 0) { return null; } Element last = (Element)all.get(all.size() - 1); ContentItem item = populateRevision(inPath, versionsDir, last); return item; } protected void saveVersion( ContentItem inContentItem ) throws RepositoryException { File file = getFile( inContentItem.getPath() ); if ( file.isDirectory() ) { return; } int maxVersionNum = maxVersionNumber( file ); //check that this is not the same content as last version if ( maxVersionNum > 0) { File oldversion = getVersionFile(file,String.valueOf(maxVersionNum ) ); if ( oldversion.length() == file.length()) { //these might be the same //TODO: Do a string comparison on them return; } } inContentItem.setVersion( String.valueOf( maxVersionNum + 1 ) ); File newversion = getVersionFile( file, inContentItem.getVersion() ); try { newversion.getParentFile().mkdirs(); if ( file.exists() ) { getFileUtils().copyFiles( file, newversion ); } File metadata = getMetaDataFile( file ); append( inContentItem, metadata ); } catch( Exception e ) { throw new RepositoryException( "Error saving ContentItem " + inContentItem.getVersion() + " for path " + inContentItem.getPath(), e ); } } public XmlUtil getXmlUtil() { if( fieldXmlUtil == null) { fieldXmlUtil = new XmlUtil(); } return fieldXmlUtil; } public void setXmlUtil(XmlUtil inXmlUtil) { fieldXmlUtil = inXmlUtil; } public void deleteOldVersions(String inPath) throws RepositoryException { File file = getFile( inPath ); if ( file.isDirectory() ) { return; } File metadata = getMetaDataFile( file ); List knownContentItems = readAll( inPath, metadata ); for (Iterator iterator = knownContentItems.iterator(); iterator.hasNext();) { FileItem item = (FileItem) iterator.next(); item.getFile().delete(); } metadata.delete(); } }