/* * (c) Copyright 2010-2011 AgileBirds * * This file is part of OpenFlexo. * * OpenFlexo is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * OpenFlexo is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with OpenFlexo. If not, see <http://www.gnu.org/licenses/>. * */ package org.openflexo.foundation.rm.cg; import java.io.File; import java.io.FilenameFilter; import java.io.IOException; import java.util.Collections; import java.util.Comparator; import java.util.Hashtable; import java.util.Vector; import java.util.logging.Level; import java.util.logging.Logger; import org.openflexo.foundation.cg.version.AbstractCGFileVersion; import org.openflexo.foundation.cg.version.CGFileIntermediateVersion; import org.openflexo.foundation.cg.version.CGFileReleaseVersion; import org.openflexo.foundation.cg.version.CGRelease; import org.openflexo.foundation.cg.version.CGVersionIdentifier; import org.openflexo.foundation.cg.version.CGVersionIdentifier.InvalidVersionFormatException; import org.openflexo.toolbox.FileResource; import org.openflexo.toolbox.FileUtils; public class FileHistory { private static final Logger logger = Logger.getLogger(FileHistory.class.getPackage().getName()); private CGRepositoryFileResource _resource; // private int lastWritingIndex = 0; public static final String HISTORY_DIR = ".history"; private Vector<CGFileReleaseVersion> _releasesVersion; private Hashtable<CGVersionIdentifier, AbstractCGFileVersion> _versions; public FileHistory(CGRepositoryFileResource resource) { _resource = resource; _releasesVersion = new Vector<CGFileReleaseVersion>(); _versions = new Hashtable<CGVersionIdentifier, AbstractCGFileVersion>(); update(); } public void update() { for (AbstractCGFileVersion fileVersion : _versions.values()) { fileVersion.delete(); } _releasesVersion.clear(); _versions.clear(); if (_resource == null || _resource.getResourceFile() == null || _resource.getResourceFile().getFile() == null) { return; } final File file = _resource.getResourceFile().getFile(); File directory = new File(file.getParentFile(), HISTORY_DIR); if (directory.exists()) { File[] candidates = directory.listFiles(new FilenameFilter() { @Override public boolean accept(File dir, String name) { return !name.equals(file.getName()) && name.indexOf(file.getName()) == 0; } }); for (File candidate : candidates) { String versionAsString = candidate.getName().substring(file.getName().length()); CGVersionIdentifier version; try { version = new CGVersionIdentifier(versionAsString); addVersion(candidate, version); } catch (InvalidVersionFormatException e) { // Forget this file } } Collections.sort(_releasesVersion, new Comparator<CGFileReleaseVersion>() { @Override public int compare(CGFileReleaseVersion o1, CGFileReleaseVersion o2) { return CGVersionIdentifier.COMPARATOR.compare(o1.getVersionId(), o2.getVersionId()); } }); } else { logger.fine("Directory " + directory.getAbsolutePath() + " does not exist"); } } private CGRelease releaseForVersion(CGVersionIdentifier versionId) { for (CGRelease release : _resource.getCGFile().getRepository().getReleases()) { if (release.getVersionIdentifier().major == versionId.major && release.getVersionIdentifier().minor == versionId.minor) { return release; } } return null; } private CGFileReleaseVersion releaseVersionForRelease(CGRelease release) { for (CGFileReleaseVersion releaseVersion : _releasesVersion) { if (release.getVersionIdentifier().major == releaseVersion.getVersionId().major && release.getVersionIdentifier().minor == releaseVersion.getVersionId().minor) { return releaseVersion; } } return null; } private CGFileReleaseVersion releaseVersionForBeforeFirstRelease() { for (CGFileReleaseVersion releaseVersion : _releasesVersion) { if (releaseVersion.getVersionId().major == 0 && releaseVersion.getVersionId().minor == 0) { return releaseVersion; } } CGFileReleaseVersion returned = new CGFileReleaseVersion.BeforeFirstRelease(_resource.getCGFile()); _releasesVersion.add(returned); return returned; } private void addVersion(File file, CGVersionIdentifier versionId) { if (logger.isLoggable(Level.FINE)) { logger.fine("Found " + file.getAbsolutePath() + " for version " + versionId); } CGRelease release = null; CGFileReleaseVersion fileReleaseVersion = null; if (versionId.major == 0 && versionId.minor == 0) { fileReleaseVersion = releaseVersionForBeforeFirstRelease(); } else { release = releaseForVersion(versionId); if (release != null) { fileReleaseVersion = releaseVersionForRelease(release); if (fileReleaseVersion == null) { fileReleaseVersion = new CGFileReleaseVersion(_resource.getCGFile(), release, null); _releasesVersion.add(fileReleaseVersion); } } } if (fileReleaseVersion == null) { logger.warning("Inconsistant data in versionning while handling " + versionId); return; } if (versionId.patch == 0) { fileReleaseVersion.setFile(file); _versions.put(versionId, fileReleaseVersion); } else { CGFileIntermediateVersion intermediateVersion = new CGFileIntermediateVersion(_resource.getCGFile(), versionId, file); fileReleaseVersion.addToIntermediateVersions(intermediateVersion); _versions.put(versionId, intermediateVersion); } } public AbstractCGFileVersion versionWithId(CGVersionIdentifier versionId) { if (versionId == null) { return null; } AbstractCGFileVersion returned = _versions.get(versionId); /*if (returned == null) { logger.info("I have:"); for (CGVersionIdentifier v : _versions.keySet()) { logger.info(" > "+v); } }*/ return returned; } public int getNextWritingIndex() { CGRelease release = _resource.getCGFile().getRepository().getLastRelease(); CGFileReleaseVersion fileReleaseVersion = null; if (release == null) { fileReleaseVersion = releaseVersionForBeforeFirstRelease(); } else { fileReleaseVersion = releaseVersionForRelease(release); if (fileReleaseVersion == null) { logger.warning("Some history files seems to have disappeared. Processing anyway."); return 1; } } if (fileReleaseVersion.getIntermediateVersions().size() == 0) { return 1; } return fileReleaseVersion.getIntermediateVersions().lastElement().getVersionId().patch + 1; } public void storeCurrentFileInHistory(CGVersionIdentifier.VersionType type) { if (_resource.getResourceFile().getFile().exists()) { CGVersionIdentifier newVersion = _resource.getCGFile().getRepository().getLastReleaseVersionIdentifier().clone(); newVersion.patch = getNextWritingIndex(); newVersion.type = type; storeCurrentFileInHistoryAs(newVersion); } else { logger.warning("File " + _resource.getResourceFile().getFile().getAbsolutePath() + " does not exist"); } } public void storeCurrentFileInHistoryAs(CGVersionIdentifier newVersion) { if (_resource.getResourceFile().getFile().exists()) { String newFileName = _resource.getResourceFile().getFile().getName() + "." + newVersion.toString(); File historyDir = new File(_resource.getResourceFile().getFile().getParentFile(), HISTORY_DIR); if (!historyDir.exists()) { historyDir.mkdirs(); } verifyAndCreateCVSIgnoreIfRequired(); File toCopy = _resource.getResourceFile().getFile(); File theCopy = new File(historyDir, newFileName); try { if (_resource instanceof WOFileResource) { String baseName = toCopy.getName().substring(0, toCopy.getName().indexOf(".wo")); theCopy.mkdirs(); File originalHTML = new File(toCopy, baseName + ".html"); File copiedHTML = new File(theCopy, baseName + ".html" + "." + newVersion.toString()); FileUtils.copyFileToFile(originalHTML, copiedHTML); File originalWOD = new File(toCopy, baseName + ".wod"); File copiedWOD = new File(theCopy, baseName + ".wod" + "." + newVersion.toString()); FileUtils.copyFileToFile(originalWOD, copiedWOD); File originalWOO = new File(toCopy, baseName + ".woo"); File copiedWOO = new File(theCopy, baseName + ".woo" + "." + newVersion.toString()); FileUtils.copyFileToFile(originalWOO, copiedWOO); } else { FileUtils.copyFileToFile(toCopy, theCopy); } addVersion(theCopy, newVersion); _resource.getCGFile().notifyHistoryRefreshed(); } catch (IOException e) { logger.warning("File " + theCopy.getAbsolutePath() + " cound not be written on disk"); e.printStackTrace(); } } else { logger.warning("File " + _resource.getResourceFile().getFile().getAbsolutePath() + " does not exist"); } } /** * */ private void verifyAndCreateCVSIgnoreIfRequired() { File cvsIgnore = new File(_resource.getResourceFile().getFile().getParentFile(), ".cvsignore"); if (!cvsIgnore.exists()) { try { FileUtils.copyFileToFile(new FileResource("Resources/dotCVSignore"), cvsIgnore); if (logger.isLoggable(Level.INFO)) { logger.info(".cvsignore file created at: " + cvsIgnore.getAbsolutePath()); } } catch (IOException e) { e.printStackTrace(); if (logger.isLoggable(Level.WARNING)) { logger.warning(".cvsignore file could not be generated"); } } } } public Vector<CGFileReleaseVersion> getReleasesVersion() { return _releasesVersion; } public void clean(boolean cleanBeforeFirstRelease, Vector<CGRelease> releasesToClean) { if (cleanBeforeFirstRelease) { releaseVersionForBeforeFirstRelease().clean(); } for (CGRelease release : releasesToClean) { CGFileReleaseVersion releaseVersion = releaseVersionForRelease(release); if (releaseVersion != null) { releaseVersion.clean(); } } } public void refresh() { update(); _resource.getCGFile().notifyHistoryRefreshed(); } }