blob: 0468fd34de922a0d876f3747191eb08a66791ad5 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2011, 2012 Ericsson
*
* All rights reserved. This program and the accompanying materials are
* made available under the terms of the Eclipse Public License v1.0 which
* accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Description:
*
* Contributors:
* Alvaro Sanchez-Leon - Initial API
*******************************************************************************/
package org.eclipse.mylyn.reviews.r4e.core.rfs;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import org.eclipse.core.resources.IStorage;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.core.runtime.Status;
import org.eclipse.egit.core.RepositoryUtil;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectInserter;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryCache.FileKey;
import org.eclipse.jgit.storage.file.FileRepository;
import org.eclipse.jgit.util.FS;
import org.eclipse.mylyn.reviews.r4e.core.Activator;
import org.eclipse.mylyn.reviews.r4e.core.model.R4EFileVersion;
import org.eclipse.mylyn.reviews.r4e.core.rfs.spi.IRFSRegistry;
import org.eclipse.mylyn.reviews.r4e.core.rfs.spi.ReviewsFileStorageException;
import org.eclipse.mylyn.reviews.r4e.core.utils.IOUtils;
import org.eclipse.mylyn.reviews.r4e.core.utils.filePermission.FileSupportCommandFactory;
import org.eclipse.team.core.history.IFileRevision;
import org.eclipse.team.core.history.provider.FileRevision;
/**
* @author Alvaro Sanchez-Leon
*
*/
public class ReviewsRFSProxy implements IRFSRegistry {
// ------------------------------------------------------------------------
// Constants
// ------------------------------------------------------------------------
private static final String DEFAULT_REPO_NAME = "ReviewsRepo.git";
private ObjectInserter fInserter = null;
protected Repository fRepository = null;
protected final RepositoryUtil fRepositoryUtil;
// ------------------------------------------------------------------------
// Constructors
// ------------------------------------------------------------------------
/**
* @param aParentDir
* @throws IOException
*/
public ReviewsRFSProxy(File aReviewGroupDir, boolean create) throws ReviewsFileStorageException {
File repoLoc = new File(aReviewGroupDir, DEFAULT_REPO_NAME);
if (create) {
fRepository = initializeRepo(repoLoc);
// Set writing permissions to the shared location
try {
FileSupportCommandFactory.getInstance().grantWritePermission(aReviewGroupDir.getAbsolutePath());
} catch (IOException e) {
throw new ReviewsFileStorageException(e);
}
} else {
// permissions must have been already set
fRepository = openRepository(repoLoc);
}
fInserter = fRepository.newObjectInserter();
fRepositoryUtil = org.eclipse.egit.core.Activator.getDefault().getRepositoryUtil();
}
// ------------------------------------------------------------------------
// Methods
// ------------------------------------------------------------------------
/**
* Validate if the given directory is a valid repository
*
* @param dir
* @return
*/
public static boolean isValidRepo(File dir) {
File repoDir = new File(dir, DEFAULT_REPO_NAME);
return FileKey.isGitRepository(repoDir, FS.DETECTED);
}
/**
* @param aReviewGroupDir
* @return
* @throws ReviewsFileStorageException
*/
private Repository initializeRepo(File aReviewGroupDir) throws ReviewsFileStorageException {
try {
Repository newRepo = new FileRepository(aReviewGroupDir);
newRepo.create(true);
newRepo.getConfig().setString("core", null, "sharedrepository", "0666");
newRepo.getConfig().save();
return newRepo;
} catch (IOException e) {
throw new ReviewsFileStorageException(e);
}
}
/**
* @param aReviewGroupDir
* @throws ReviewsFileStorageException
*/
private Repository openRepository(File aReviewGroupDir) throws ReviewsFileStorageException {
Repository r;
try {
r = FileKey.exact(aReviewGroupDir, FS.DETECTED).open(true);
} catch (IOException e) {
throw new ReviewsFileStorageException(e);
}
return r;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.mylyn.reviews.r4e.core.rrepo.IBlobRegistry#registerReviewBlob(byte[])
*/
public String registerReviewBlob(final byte[] content) throws ReviewsFileStorageException {
String id = null;
ObjectId objid = null;
try {
objid = fInserter.insert(Constants.OBJ_BLOB, content);
fInserter.flush();
} catch (IOException e) {
//Check if the file has been registered in the repository if yes record the id, log the exception and continue
//If the id is not registered throw the exception
id = blobIdFor(content);
InputStream is = getBlobContent(null, id);
if (is == null) {
//The file was not registered in the local repo
throw new ReviewsFileStorageException(e);
} else {
Activator.fTracer
.traceError("IOException while registering content however it's already available in the local repository, "
+ e.getMessage());
try {
is.close();
} catch (IOException ex) {
Activator.fTracer.traceError("IOException while closing probe stream, " + ex.getMessage());
}
}
} finally {
fInserter.release();
}
if (objid != null) {
id = objid.getName();
}
return id;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.mylyn.reviews.r4e.core.rfs.spi.IRFSRegistry#registerReviewBlob(java.io.InputStream)
*/
public String registerReviewBlob(final InputStream content) throws ReviewsFileStorageException {
try {
return registerReviewBlob(IOUtils.readFully(content));
} catch (IOException e) {
throw new ReviewsFileStorageException(e);
}
}
/*
* (non-Javadoc)
*
* @see org.eclipse.mylyn.reviews.r4e.core.rrepo.IBlobRegistry#registerReviewBlob(java.io.File)
*/
public String registerReviewBlob(final File aFromFile) throws ReviewsFileStorageException {
InputStream stream = null;
try {
stream = new FileInputStream(aFromFile);
} catch (FileNotFoundException e) {
throw new ReviewsFileStorageException(e);
}
String id = null;
ObjectId objid = null;
try {
objid = fInserter.insert(Constants.OBJ_BLOB, aFromFile.length(), stream);
fInserter.flush();
FileSupportCommandFactory.getInstance().grantWritePermission(fRepository.getDirectory().getAbsolutePath());
} catch (IOException e) {
throw new ReviewsFileStorageException(e);
} finally {
fInserter.release();
try {
stream.close();
} catch (IOException e) {
StringBuilder sb = new StringBuilder("Exception: " + e.getMessage());
Activator.fTracer.traceDebug(sb.toString());
}
}
if (objid != null) {
id = objid.getName();
}
return id;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.mylyn.reviews.r4e.core.rfs.spi.IRFSRegistry#getBlobContent(org.eclipse.core.runtime.IProgressMonitor,
* java.lang.String)
*/
public InputStream getBlobContent(IProgressMonitor monitor, String id) throws ReviewsFileStorageException {
InputStream resStream = null;
if (id == null) {
return null;
}
try {
ObjectId objId = ObjectId.fromString(id);
resStream = fRepository.open(objId, Constants.OBJ_BLOB).openStream();
} catch (Exception e) {
throw new ReviewsFileStorageException(e);
}
return resStream;
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.mylyn.reviews.r4e.core.rfs.spi.IRFSRegistry#getIFileRevision(org.eclipse.core.runtime.IProgressMonitor
* , org.eclipse.mylyn.reviews.r4e.core.model.R4EFileVersion)
*/
public IFileRevision getIFileRevision(IProgressMonitor monitor, final R4EFileVersion fileVersion)
throws ReviewsFileStorageException {
final String localId = fileVersion.getLocalVersionID();
// Validation
if (localId == null) {
return null;
}
try {
final IPath path = Path.fromPortableString(fileVersion.getRepositoryPath());
return new FileRevision() {
public IFileRevision withAllProperties(IProgressMonitor monitor) throws CoreException {
return this;
}
public boolean isPropertyMissing() {
return false;
}
public IStorage getStorage(IProgressMonitor monitor) throws CoreException {
return getIStorage(null, fileVersion);
}
public String getName() {
return path.lastSegment();
}
};
} catch (Exception e) {
e.printStackTrace();
return null;
}
}
/*
* (non-Javadoc)
*
* @see
* org.eclipse.mylyn.reviews.r4e.core.rfs.spi.IRFSRegistry#getIStorage(org.eclipse.core.runtime.IProgressMonitor,
* org.eclipse.mylyn.reviews.r4e.core.model.R4EFileVersion)
*/
//NOTE: Right now, only the full path prepended with the repo path and appended with the localId is used. If there is a need
//to get the pure repo path, we could modify or add code to do this.
public IStorage getIStorage(IProgressMonitor monitor, R4EFileVersion fileVersion) {
final IPath path = Path.fromPortableString(fileVersion.getRepositoryPath());
final String localId = fileVersion.getLocalVersionID();
// Validation
if (localId == null) {
return null;
}
return new IStorage() {
@SuppressWarnings("rawtypes")
public Object getAdapter(Class adapter) {
return null;
}
public boolean isReadOnly() {
return true;
}
public String getName() {
return path.lastSegment();
}
public IPath getFullPath() {
//bug349739: Here we first need to prepend the repository name to the artifact path to get the full path to the artifact
IPath repoPath = new Path(fRepositoryUtil.getRepositoryName(fRepository));
String pathString = path.toPortableString();
return repoPath.append(Path.fromPortableString(pathString + " " + localId)); // Append localId to
// differentiate
// versions in Repo
}
public InputStream getContents() throws CoreException {
try {
return getBlobContent(null, localId);
} catch (Exception e) {
e.printStackTrace();
throw new CoreException(new Status(IStatus.ERROR, Activator.PLUGIN_ID, e.getMessage()));
}
}
};
}
/**
* @return
*/
public Repository getRepository() {
return fRepository;
}
/**
* Convenience method to close the repository data base
*/
public void close() {
fRepository.close();
}
/*
* (non-Javadoc)
*
* @see org.eclipse.mylyn.reviews.r4e.core.rfs.spi.IRFSRegistry#blobIdFor(java.io.InputStream)
*/
public String blobIdFor(InputStream content) throws ReviewsFileStorageException {
String id = null;
try {
id = blobIdFor(IOUtils.readFully(content));
} catch (IOException e) {
throw new ReviewsFileStorageException(e);
}
return id;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.mylyn.reviews.r4e.core.rfs.spi.IRFSRegistry#blobIdFor(byte[])
*/
public String blobIdFor(byte[] content) {
String id = fInserter.idFor(Constants.OBJ_BLOB, content).getName();
fInserter.release();
return id;
}
/*
* (non-Javadoc)
*
* @see org.eclipse.mylyn.reviews.r4e.core.rfs.spi.IRFSRegistry#blobIdFor(java.io.File)
*/
public String blobIdFor(File aFromFile) throws ReviewsFileStorageException {
InputStream stream = null;
try {
stream = new FileInputStream(aFromFile);
} catch (FileNotFoundException e) {
throw new ReviewsFileStorageException(e);
}
String id = null;
ObjectId objid = null;
try {
objid = fInserter.idFor(Constants.OBJ_BLOB, aFromFile.length(), stream);
FileSupportCommandFactory.getInstance().grantWritePermission(fRepository.getDirectory().getAbsolutePath());
} catch (IOException e) {
throw new ReviewsFileStorageException(e);
} finally {
fInserter.release();
try {
stream.close();
} catch (IOException e) {
StringBuilder sb = new StringBuilder("Exception: " + e.getMessage());
Activator.fTracer.traceDebug(sb.toString());
}
}
if (objid != null) {
id = objid.getName();
}
return id;
}
}