/*****************************************************************************
This file is part of Git-Starteam.
Git-Starteam 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.
Git-Starteam 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 Git-Starteam. If not, see <http://www.gnu.org/licenses/>.
******************************************************************************/
package org.sync;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.ossnoize.git.fastimport.Blob;
import org.ossnoize.git.fastimport.Checkpoint;
import org.ossnoize.git.fastimport.Commit;
import org.ossnoize.git.fastimport.Done;
import org.ossnoize.git.fastimport.Reset;
import org.ossnoize.git.fastimport.Tag;
import org.sync.util.LogEntry;
import org.sync.util.SmallRef;
import org.sync.util.StarteamFileInfo;
public abstract class RepositoryHelper {
protected final static long timeForEachCheckpoint = 1000L*60L*60L*3L; // 3 Hours
protected File fastExportOverrideToFile;
protected long lastCheckpointTime = 0;
protected Map<String, Map<String, StarteamFileInfo>> fileInformation;
protected String repositoryDir;
/**
* Return the full list of path to files that are tracked in the repository.
* @return a set of File path contained in the current version of the repository.
*/
public abstract Set<String> getListOfTrackedFile(String head);
/**
* Tell if the file is a special target repository type file.
* @return True if it is a special file, False otherwise.
*/
public abstract boolean isSpecialFile(String filename);
/**
* Do the repository garbage collection and the compression of it's database.
*/
public abstract int gc();
/**
* Tell if the "git fast-import" process is still running.
* @return True if it is running, False otherwise.
*/
public abstract boolean isFastImportRunning();
/**
* Inform the user that the repository is a bare one
* @return True if it is a bare repository
*/
public abstract boolean isBareRepository();
/**
* Create a fast-import process and dump all the repository information in the
* input stream of the process.
* @return The OutputStream representing the InputStream of the process.
*/
protected abstract OutputStream getFastImportStream();
/**
* Load the saved file information from the previous fast-export run.
* @return The file was found and loaded correctly
*/
protected abstract boolean loadFileInformation();
/**
* Save the file information into an hidden file inside the repository folder.
*/
protected abstract void saveFileInformation();
/**
* Register in file hidden inside the repository (.git, .bazaar, ...) the list
* of existing repository file and it's id.
* @param head reference name
* @param filename the full path of the file and its name inside the repository
* @param fileId the Starteam file id
* @param fileVersion the Starteam file version
*
* @return true if the file was correctly registered. False otherwise.
*/
public boolean registerFileId(String head, String filename, int fileId, int fileVersion) {
if(null == fileInformation) {
if(!loadFileInformation()) {
fileInformation = new HashMap<String, Map<String, StarteamFileInfo>>();
}
}
if(!fileInformation.containsKey(head)) {
fileInformation.put(head, new HashMap<String, StarteamFileInfo>());
}
if(!fileInformation.get(head).containsKey(filename)) {
fileInformation.get(head).put(filename, new StarteamFileInfo(filename, fileId, fileVersion, fileVersion));
return true;
}
return false;
}
/**
* Save in file hidden inside the repository (.git, .bazaar, ...) the version
* of an already registered file existing inside the repository.
*
* @param head
* the reference name
* @param filename
* the full path of the file and its name inside the repository
* @param fileVersion
* the Starteam version of this file.
*/
public boolean updateFileVersion(String head, String filename, int fileVersion) {
return updateFileVersion(head, filename, fileVersion, fileVersion);
}
/**
* Save in file hidden inside the repository (.git, .bazaar, ...) the version
* of an already registered file existing inside the repository.
*
* @param head
* the reference name
* @param filename
* the full path of the file and its name inside the repository
* @param fileVersion
* the Starteam version of this file.
* @param contentVersion
* The Starteam File Content version.
*/
public boolean updateFileVersion(String head, String filename, int fileVersion, int contentVersion) {
if(null != fileInformation) {
if(fileInformation.containsKey(head) && fileInformation.get(head).containsKey(filename)) {
StarteamFileInfo info = fileInformation.get(head).get(filename);
info.setVersion(fileVersion);
info.setContentVersion(contentVersion);
return true;
}
}
return false;
}
/**
* Remove the registered file from the repository.
* @param head the reference name
* @param filename the full path of the file and its name inside the repository
*/
public void unregisterFileId(String head, String filename) {
if(null != fileInformation) {
if(fileInformation.containsKey(head)) {
fileInformation.get(head).remove(filename);
}
}
}
/**
* Return the registered file id from the repository tracked file.
* @param head the name of the branch to check
* @param filename the full path of the file and its name inside the repository
*
* @return the id of the file or NULL if not found.
*/
public Integer getRegisteredFileId(String head, String filename) {
if(null != fileInformation) {
if(fileInformation.containsKey(head)) {
if(fileInformation.get(head).containsKey(filename)) {
return fileInformation.get(head).get(filename).getId();
}
}
} else if (loadFileInformation()) {
return getRegisteredFileId(head, filename);
}
return null;
}
/**
* Return the registered file version from the repository tracked file.
* @param head the name of the branch to check
* @param filename the full path of the file and its name inside the repository
*
* @return the id of the file or NULL if not found.
*/
public Integer getRegisteredFileVersion(String head, String filename) {
if(null != fileInformation) {
if(fileInformation.containsKey(head)) {
if(fileInformation.get(head).containsKey(filename)) {
return fileInformation.get(head).get(filename).getVersion();
}
}
} else if (loadFileInformation()) {
return getRegisteredFileVersion(head, filename);
}
return null;
}
/**
* Return the registered file version from the repository tracked file.
*
* @param head
* the name of the branch to check
* @param filename
* the full path of the file and its name inside the repository
*
* @return the id of the file or NULL if not found.
*/
public Integer getRegisteredFileContentVersion(String head, String filename) {
if (null != fileInformation) {
if (fileInformation.containsKey(head)) {
if (fileInformation.get(head).containsKey(filename)) {
return fileInformation.get(head).get(filename).getContentVersion();
}
}
} else if (loadFileInformation()) {
return getRegisteredFileVersion(head, filename);
}
return null;
}
/**
* Request that the stream be dumped into the following file
*
* @param file The file where is to be written the fast-export
**/
public void setFastExportDumpFile(File file) {
fastExportOverrideToFile = file;
}
/**
* Write a commit into the fast-import stream. After 3 hours of continuous
* commit, a checkpoint is done to preserve the history recorded so far.
* @param commit The commit to record.
* @throws IOException
*/
public void writeCommit(Commit commit) throws IOException {
OutputStream fastImportStream = getFastImportStream();
commit.writeTo(fastImportStream);
if(lastCheckpointTime <= 0) {
lastCheckpointTime = System.currentTimeMillis();
}
if((System.currentTimeMillis() - lastCheckpointTime) >= timeForEachCheckpoint) {
// if we are doing this process for 3 hours
writeCheckpoint();
}
}
/**
* Write a checkpoint into the fast-import stream.
*/
public void writeCheckpoint() throws IOException {
OutputStream fastImportStream = getFastImportStream();
Checkpoint checkpoint = new Checkpoint();
checkpoint.writeTo(fastImportStream);
lastCheckpointTime = System.currentTimeMillis();
Log.out("Checkpoint done");
}
/**
* Write a blob to the fast-import stream to be used by commit afterward.
* @param fileToStage The blob object representing a file or other markable
* data.
* @throws IOException
*/
public void writeBlob(Blob fileToStage) throws IOException {
OutputStream fastImportStream = getFastImportStream();
fileToStage.writeTo(fastImportStream);
}
/**
* Write a reset to the fast-import stream.
* @param reset Reset data.
* @throws IOException
*/
public void writeReset(Reset reset) throws IOException {
OutputStream fastImportStream = getFastImportStream();
reset.writeTo(fastImportStream);
}
/**
* Write a tag to the fast-import stream.
* @param tag Tag to create.
* @throws IOException
*/
public void writeTag(Tag tag) throws IOException {
OutputStream fastImportStream = getFastImportStream();
tag.writeTo(fastImportStream);
}
public abstract java.util.Date getLastCommitOfBranch(String branchName);
/**
* Return all log entry <code>from</code> the requested commit without
* including it <code>to</code> the requested commit marking it as the
* last on
* @param from Commit SmallRef to start logging from
* @param to The last commit SmallRef to mark the end of listing.
* @return The list of commit starting at the <code>from</code> to the
* last marked as <code>to</code>
*/
public abstract List<LogEntry> getCommitLog(SmallRef from, SmallRef to);
/**
* Return all commit from the first entry of the branch to the last marked
* as <code>to</code>
* @param to The last commit of the log
* @return The list of commit from the first entry to the last marked as
* <code>to</code>
*/
public abstract List<LogEntry> getCommitLog(SmallRef to);
/**
* Close the fast-import stream and do some house keeping for the tracked
* file version. Need to be called for the fast-import process to end.
*/
public void dispose() {
saveFileInformation();
try {
OutputStream out = getFastImportStream();
Done finishedImport = new Done();
finishedImport.writeTo(out);
out.close();
} catch (IOException e) {
Log.log(e.getMessage());
}
}
/**
* Set the working directory where the fast-import process and all other
* process will query the repository.
* @param dir Where to make the fast-import on disk
* @param create Ask to create the repository using an init command.
*/
public void setWorkingDirectory(String dir, boolean create) {
repositoryDir = dir;
}
/**
* Provide the repository directory where every internal files are located
* @return Directory where is located the internal files.
*/
public String getWorkingDirectory() {
return repositoryDir;
}
/**
* Extract the lastest version of the requested file from the current state
* of the fast-import process
*
* @param head which branch to look at
* @param path which file we should grab
* @param stream an output stream where we can store the extracted information
*/
public abstract void getFileContent(String head, String path, java.io.OutputStream stream);
}