/* * (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.utils; import java.io.File; import java.util.logging.Level; import java.util.logging.Logger; import org.openflexo.foundation.FlexoObject; import org.openflexo.foundation.rm.FlexoProject; import org.openflexo.foundation.rm.ProjectExternalRepository; import org.openflexo.toolbox.FileUtils; import org.openflexo.xmlcode.StringConvertable; import org.openflexo.xmlcode.StringEncoder; import org.openflexo.xmlcode.StringEncoder.Converter; /** * Represents a file relative to a project * * @author sguerin * */ public class FlexoProjectFile extends FlexoObject implements StringConvertable, Cloneable { private static final Logger logger = Logger.getLogger(FlexoProjectFile.class.getPackage().getName()); private static final char fileSeparator = File.separator.charAt(0); private static final char alternateFileSeparator = fileSeparator == '\\' ? '/' : '\\'; public static String transformIntoValidPath(String aRelativePath) { return aRelativePath.replace(alternateFileSeparator, fileSeparator); } public static final StringEncoder.Converter<FlexoProjectFile> converter = new Converter<FlexoProjectFile>(FlexoProjectFile.class) { @Override public FlexoProjectFile convertFromString(String value) { return new FlexoProjectFile(transformIntoValidPath(value)); } @Override public String convertToString(FlexoProjectFile value) { return value.toString(); } }; protected String relativePath; protected FlexoProject project; public FlexoProjectFile(File absoluteFile, File aProjectDirectory) { super(); File temp = absoluteFile; relativePath = null; while (!temp.equals(aProjectDirectory) && temp.getParentFile() != null) { if (relativePath == null) { relativePath = temp.getName(); } else { relativePath = temp.getName() + "/" + relativePath; } temp = temp.getParentFile(); } if (temp.getParentFile() == null) { if (logger.isLoggable(Level.WARNING)) { logger.warning("File " + absoluteFile.getAbsolutePath() + " is not contained in project " + aProjectDirectory); // TODO: try to look into external repository } } } public FlexoProjectFile(File absoluteFile, FlexoProject aProject) { this(absoluteFile, aProject.getProjectDirectory()); project = aProject; } public FlexoProjectFile(String relativePathToProject) { super(); if (relativePathToProject.indexOf(":") > -1) { repositoryName = relativePathToProject.substring(0, relativePathToProject.lastIndexOf(":")); relativePathToProject = relativePathToProject.substring(relativePathToProject.lastIndexOf(":") + 1); } relativePath = FileUtils.convertBackslashesToSlash(relativePathToProject); } public FlexoProjectFile(FlexoProject project, ProjectExternalRepository repository, String relativePathToRepository) { this(relativePathToRepository); setProject(project); setExternalRepository(repository); } public FlexoProjectFile(FlexoProject project, String relativePathToRepository) { this(relativePathToRepository); setProject(project); } private String repositoryName; // used as cache since getExternalRepositoryWithKey is very costly. private ProjectExternalRepository _externalRep; public ProjectExternalRepository getExternalRepository() { if (_externalRep != null) { return _externalRep; } if (getProject() != null && repositoryName != null) { return _externalRep = getProject().getExternalRepositoryWithKey(repositoryName); } return null; } public void setExternalRepository(ProjectExternalRepository repository) { this.repositoryName = repository.getIdentifier(); clearCachedFile(); } public FlexoProject getProject() { return project; } public void setProject(FlexoProject aProject) { project = aProject; clearCachedFile(); } private File _cachedFile; public void clearCachedFile() { _cachedFile = null; } public File getFile() { if (_cachedFile != null) { return _cachedFile; } if (project != null) { ProjectExternalRepository rep = getExternalRepository(); if (rep != null) { if (rep.getDirectory() != null) { return _cachedFile = new File(rep.getDirectory(), relativePath); } else { if (logger.isLoggable(Level.FINE)) { logger.fine("No directory defined for external repository"); } return null; } } else { return _cachedFile = new File(project.getProjectDirectory(), relativePath); } } else { if (logger.isLoggable(Level.WARNING)) { logger.warning("Project was not set for this FlexoProjectFile!"); } return null; } } public void setFile(File aFile) { _cachedFile = null; if (project != null) { File target = null; if (getExternalRepository() != null) { target = getExternalRepository().getDirectory(); } else { target = project.getProjectDirectory(); } File temp = aFile; String newRelativePath = null; while (!temp.equals(target) && temp.getParentFile() != null) { if (newRelativePath == null) { newRelativePath = temp.getName(); } else { newRelativePath = temp.getName() + "/" + newRelativePath; } temp = temp.getParentFile(); } if (temp.getParentFile() == null) { if (logger.isLoggable(Level.WARNING)) { logger.warning("File " + aFile.getAbsolutePath() + " is not contained in project " + project.getProjectDirectory() + " or repository (target is: " + target.getAbsolutePath() + ")"); } } else { relativePath = newRelativePath; } } else { if (logger.isLoggable(Level.WARNING)) { logger.warning("Project was not set for this FlexoProjectFile!"); } } } public File getFile(File directory) { return new File(directory, relativePath); } public String getRelativePath() { return relativePath; } public void setRelativePath(String relativePath) { this.relativePath = FileUtils.convertBackslashesToSlash(relativePath); } @Override public String toString() { return getStringRepresentation(); } public String getStringRepresentation() { ProjectExternalRepository rep = getExternalRepository(); if (rep != null) { return rep.getIdentifier() + ":" + getRelativePath(); } return getRelativePath(); } public boolean nameIsValid() { return FileUtils.isStringValidForFileName(relativePath); } public void fixName() { if (!nameIsValid() && relativePath != null) { relativePath = FileUtils.getValidFileName(relativePath); } } @Override public StringEncoder.Converter getConverter() { return converter; } @Override public Object clone() { return new FlexoProjectFile(getProject(), getExternalRepository(), getRelativePath()); } }