move core plugins back to main repository, because of a broken release management

This commit is contained in:
Sebastian Sdorra
2011-07-01 18:43:26 +02:00
parent 9aaf71f5ca
commit fa1d433a36
58 changed files with 9240 additions and 0 deletions

View File

@@ -0,0 +1,124 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.api.rest.resources;
//~--- non-JDK imports --------------------------------------------------------
import com.google.inject.Inject;
import com.google.inject.Singleton;
import sonia.scm.repository.GitConfig;
import sonia.scm.repository.GitRepositoryHandler;
//~--- JDK imports ------------------------------------------------------------
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.UriInfo;
/**
*
* @author Sebastian Sdorra
*/
@Singleton
@Path("config/repositories/git")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public class GitConfigResource
{
/**
* Constructs ...
*
*
*
* @param repositoryHandler
*/
@Inject
public GitConfigResource(GitRepositoryHandler repositoryHandler)
{
this.repositoryHandler = repositoryHandler;
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
@GET
public GitConfig getConfig()
{
GitConfig config = repositoryHandler.getConfig();
if (config == null)
{
config = new GitConfig();
repositoryHandler.setConfig(config);
}
return config;
}
//~--- set methods ----------------------------------------------------------
/**
* Method description
*
*
* @param uriInfo
* @param config
*
* @return
*/
@POST
@Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response setConfig(@Context UriInfo uriInfo, GitConfig config)
{
repositoryHandler.setConfig(config);
repositoryHandler.storeConfig();
return Response.created(uriInfo.getRequestUri()).build();
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private GitRepositoryHandler repositoryHandler;
}

View File

@@ -0,0 +1,305 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.repository;
//~--- non-JDK imports --------------------------------------------------------
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.NoHeadException;
import org.eclipse.jgit.diff.DiffEntry;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Ref;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.treewalk.EmptyTreeIterator;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
//~--- JDK imports ------------------------------------------------------------
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
*
* @author Sebastian Sdorra
*/
public class GitChangesetViewer implements ChangesetViewer
{
/** Field description */
public static final int ID_LENGTH = 20;
/** the logger for GitChangesetViewer */
private static final Logger logger =
LoggerFactory.getLogger(GitChangesetViewer.class);
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
*
* @param handler
* @param repository
*/
public GitChangesetViewer(GitRepositoryHandler handler, Repository repository)
{
this.handler = handler;
this.repository = repository;
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @param start
* @param max
*
* @return
*/
@Override
public ChangesetPagingResult getChangesets(int start, int max)
{
ChangesetPagingResult changesets = null;
File directory = handler.getDirectory(repository);
org.eclipse.jgit.lib.Repository gr = null;
TreeWalk treeWalk = null;
try
{
gr = GitUtil.open(directory);
if (!gr.getAllRefs().isEmpty())
{
Git git = new Git(gr);
List<Changeset> changesetList = new ArrayList<Changeset>();
int counter = 0;
treeWalk = new TreeWalk(gr);
Map<ObjectId, String> tags = createTagMap(gr);
for (RevCommit commit : git.log().call())
{
if ((counter >= start) && (counter < start + max))
{
changesetList.add(createChangeset(treeWalk, tags, commit));
}
counter++;
}
changesets = new ChangesetPagingResult(counter, changesetList);
}
}
catch (NoHeadException ex)
{
logger.error("could not read changesets", ex);
}
catch (IOException ex)
{
logger.error("could not open repository", ex);
}
finally
{
GitUtil.release(treeWalk);
GitUtil.close(gr);
}
return changesets;
}
//~--- methods --------------------------------------------------------------
/**
* TODO: copy and rename
*
*
* @param modifications
* @param entry
*/
private void appendModification(Modifications modifications, DiffEntry entry)
{
switch (entry.getChangeType())
{
case ADD :
modifications.getAdded().add(entry.getNewPath());
break;
case MODIFY :
modifications.getModified().add(entry.getNewPath());
break;
case DELETE :
modifications.getRemoved().add(entry.getOldPath());
break;
}
}
/**
* Method description
*
*
*
* @param treeWalk
* @param tags
* @param commit
*
* @return
*
* @throws IOException
*/
private Changeset createChangeset(TreeWalk treeWalk,
Map<ObjectId, String> tags,
RevCommit commit)
throws IOException
{
String id = commit.getId().abbreviate(ID_LENGTH).name();
long date = GitUtil.getCommitTime(commit);
PersonIdent authorIndent = commit.getCommitterIdent();
Person author = new Person(authorIndent.getName(),
authorIndent.getEmailAddress());
String message = commit.getShortMessage();
Changeset changeset = new Changeset(id, date, author, message);
Modifications modifications = createModifications(treeWalk, commit);
if (modifications != null)
{
changeset.setModifications(modifications);
}
String tag = tags.get(commit.getId());
if (tag != null)
{
changeset.getTags().add(tag);
}
return changeset;
}
/**
* Method description
*
*
* @param treeWalk
* @param commit
*
* @return
*
* @throws IOException
*/
private Modifications createModifications(TreeWalk treeWalk, RevCommit commit)
throws IOException
{
Modifications modifications = null;
treeWalk.reset();
treeWalk.setRecursive(true);
if (commit.getParentCount() > 0)
{
treeWalk.addTree(commit.getParent(0).getTree());
}
else
{
treeWalk.addTree(new EmptyTreeIterator());
}
treeWalk.addTree(commit.getTree());
List<DiffEntry> entries = DiffEntry.scan(treeWalk);
for (DiffEntry e : entries)
{
if (!e.getOldId().equals(e.getNewId()))
{
if (modifications == null)
{
modifications = new Modifications();
}
appendModification(modifications, e);
}
}
return modifications;
}
/**
* Method description
*
*
* @param repository
*
* @return
*/
private Map<ObjectId,
String> createTagMap(org.eclipse.jgit.lib.Repository repository)
{
Map<ObjectId, String> tagMap = new HashMap<ObjectId, String>();
Map<String, Ref> tags = repository.getTags();
if (tags != null)
{
for (Map.Entry<String, Ref> e : tags.entrySet())
{
tagMap.put(e.getValue().getObjectId(), e.getKey());
}
}
return tagMap;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private GitRepositoryHandler handler;
/** Field description */
private Repository repository;
}

View File

@@ -0,0 +1,45 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.repository;
//~--- JDK imports ------------------------------------------------------------
import javax.xml.bind.annotation.XmlRootElement;
/**
*
* @author Sebastian Sdorra
*/
@XmlRootElement(name = "config")
public class GitConfig extends SimpleRepositoryConfig {}

View File

@@ -0,0 +1,338 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.repository;
//~--- non-JDK imports --------------------------------------------------------
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.lib.ObjectLoader;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevTree;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
import org.eclipse.jgit.treewalk.filter.AndTreeFilter;
import org.eclipse.jgit.treewalk.filter.PathFilter;
import org.eclipse.jgit.treewalk.filter.TreeFilter;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.util.Util;
//~--- JDK imports ------------------------------------------------------------
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author Sebastian Sdorra
*/
public class GitRepositoryBrowser implements RepositoryBrowser
{
/** the logger for GitRepositoryBrowser */
private static final Logger logger =
LoggerFactory.getLogger(GitRepositoryBrowser.class);
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
*
* @param handler
* @param repository
*/
public GitRepositoryBrowser(GitRepositoryHandler handler,
Repository repository)
{
this.handler = handler;
this.repository = repository;
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @param revision
* @param path
* @param output
*
*
* @throws IOException
* @throws RepositoryException
*/
@Override
public void getContent(String revision, String path, OutputStream output)
throws IOException, RepositoryException
{
File directory = handler.getDirectory(repository);
org.eclipse.jgit.lib.Repository repo = GitUtil.open(directory);
TreeWalk treeWalk = null;
RevWalk revWalk = null;
try
{
treeWalk = new TreeWalk(repo);
treeWalk.setRecursive(Util.nonNull(path).contains("/"));
ObjectId revId = GitUtil.getRevisionId(repo, revision);
revWalk = new RevWalk(repo);
RevCommit entry = revWalk.parseCommit(revId);
RevTree revTree = entry.getTree();
treeWalk.addTree(revTree);
treeWalk.setFilter(PathFilter.create(path));
if (treeWalk.next())
{
// Path exists
if (treeWalk.getFileMode(0).getObjectType() == Constants.OBJ_BLOB)
{
ObjectId blobId = treeWalk.getObjectId(0);
ObjectLoader loader = repo.open(blobId);
loader.copyTo(output);
}
else
{
// Not a blob, its something else (tree, gitlink)
throw new PathNotFoundException(path);
}
}
else
{
throw new PathNotFoundException(path);
}
}
finally
{
GitUtil.release(revWalk);
GitUtil.release(treeWalk);
GitUtil.close(repo);
}
}
/**
* Method description
*
*
* @param revision
* @param path
*
* @return
*
* @throws IOException
* @throws RepositoryException
*/
@Override
public BrowserResult getResult(String revision, String path)
throws IOException, RepositoryException
{
BrowserResult result = null;
File directory = handler.getDirectory(repository);
org.eclipse.jgit.lib.Repository repo = GitUtil.open(directory);
RevWalk revWalk = null;
TreeWalk treeWalk = null;
try
{
ObjectId revId = GitUtil.getRevisionId(repo, revision);
treeWalk = new TreeWalk(repo);
revWalk = new RevWalk(repo);
treeWalk.addTree(revWalk.parseTree(revId));
result = new BrowserResult();
List<FileObject> files = new ArrayList<FileObject>();
if (Util.isEmpty(path))
{
while (treeWalk.next())
{
files.add(createFileObject(repo, revId, treeWalk));
}
}
else
{
String[] parts = path.split("/");
int current = 0;
int limit = parts.length;
while (treeWalk.next())
{
String name = treeWalk.getNameString();
if (current >= limit)
{
String p = treeWalk.getPathString();
if (p.split("/").length > limit)
{
files.add(createFileObject(repo, revId, treeWalk));
}
}
else if (name.equalsIgnoreCase(parts[current]))
{
current++;
treeWalk.enterSubtree();
}
}
}
result.setFiles(files);
result.setRevision(revId.getName());
}
finally
{
GitUtil.close(repo);
GitUtil.release(revWalk);
GitUtil.release(treeWalk);
}
return result;
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
*
*
* @param repo
* @param revId
* @param treeWalk
*
* @return
*
* @throws IOException
*/
private FileObject createFileObject(org.eclipse.jgit.lib.Repository repo,
ObjectId revId, TreeWalk treeWalk)
throws IOException
{
FileObject file = new FileObject();
String path = treeWalk.getPathString();
file.setName(treeWalk.getNameString());
file.setPath(path);
ObjectLoader loader = repo.open(treeWalk.getObjectId(0));
file.setDirectory(loader.getType() == Constants.OBJ_TREE);
file.setLength(loader.getSize());
// don't show message and date for directories to improve performance
if (!file.isDirectory())
{
RevCommit commit = getLatestCommit(repo, revId, path);
if (commit != null)
{
file.setLastModified(GitUtil.getCommitTime(commit));
file.setDescription(commit.getShortMessage());
}
else if (logger.isWarnEnabled())
{
logger.warn("could not find latest commit for {} on {}", path, revId);
}
}
return file;
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
*
* @param repo
* @param revId
* @param path
*
* @return
*/
private RevCommit getLatestCommit(org.eclipse.jgit.lib.Repository repo,
ObjectId revId, String path)
{
RevCommit result = null;
RevWalk walk = null;
try
{
walk = new RevWalk(repo);
walk.setTreeFilter(AndTreeFilter.create(PathFilter.create(path),
TreeFilter.ANY_DIFF));
RevCommit commit = walk.parseCommit(revId);
walk.markStart(commit);
result = Util.getFirst(walk);
}
catch (Exception ex)
{
logger.error("could not parse commit for file", ex);
}
finally
{
GitUtil.release(walk);
}
return result;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private GitRepositoryHandler handler;
/** Field description */
private Repository repository;
}

View File

@@ -0,0 +1,208 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.repository;
//~--- non-JDK imports --------------------------------------------------------
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.eclipse.jgit.storage.file.FileRepository;
import org.eclipse.jgit.storage.file.FileRepositoryBuilder;
import sonia.scm.Type;
import sonia.scm.io.FileSystem;
import sonia.scm.plugin.ext.Extension;
import sonia.scm.store.StoreFactory;
import sonia.scm.util.AssertUtil;
//~--- JDK imports ------------------------------------------------------------
import java.io.File;
import java.io.IOException;
/**
*
* @author Sebastian Sdorra
*/
@Singleton
@Extension
public class GitRepositoryHandler
extends AbstractSimpleRepositoryHandler<GitConfig>
{
/** Field description */
public static final String TYPE_DISPLAYNAME = "Git";
/** Field description */
public static final String TYPE_NAME = "git";
/** Field description */
public static final Type TYPE = new Type(TYPE_NAME, TYPE_DISPLAYNAME);
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
*
* @param storeFactory
* @param fileSystem
*/
@Inject
public GitRepositoryHandler(StoreFactory storeFactory, FileSystem fileSystem)
{
super(storeFactory, fileSystem);
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @param repository
*
* @return
*/
@Override
public ChangesetViewer getChangesetViewer(Repository repository)
{
GitChangesetViewer changesetViewer = null;
AssertUtil.assertIsNotNull(repository);
String type = repository.getType();
AssertUtil.assertIsNotEmpty(type);
if (TYPE_NAME.equals(type))
{
changesetViewer = new GitChangesetViewer(this, repository);
}
else
{
throw new IllegalArgumentException("mercurial repository is required");
}
return changesetViewer;
}
/**
* Method description
*
*
* @param repository
*
* @return
*/
@Override
public RepositoryBrowser getRepositoryBrowser(Repository repository)
{
AssertUtil.assertIsNotNull(repository);
return new GitRepositoryBrowser(this, repository);
}
/**
* Method description
*
*
* @return
*/
@Override
public Type getType()
{
return TYPE;
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param repository
* @param directory
*
* @throws IOException
* @throws RepositoryException
*/
@Override
protected void create(Repository repository, File directory)
throws RepositoryException, IOException
{
FileRepository fr = null;
try
{
fr = new FileRepositoryBuilder().setGitDir(
directory).readEnvironment().findGitDir().build();
fr.create(true);
}
finally
{
if (fr != null)
{
fr.close();
}
}
}
/**
* Method description
*
*
* @return
*/
@Override
protected GitConfig createInitialConfig()
{
return new GitConfig();
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
@Override
protected Class<GitConfig> getConfigClass()
{
return GitConfig.class;
}
}

View File

@@ -0,0 +1,167 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.repository;
//~--- non-JDK imports --------------------------------------------------------
import java.io.File;
import org.eclipse.jgit.lib.Constants;
import org.eclipse.jgit.lib.ObjectId;
import org.eclipse.jgit.revwalk.RevCommit;
import org.eclipse.jgit.revwalk.RevWalk;
import org.eclipse.jgit.treewalk.TreeWalk;
import sonia.scm.util.Util;
//~--- JDK imports ------------------------------------------------------------
import java.io.IOException;
import org.eclipse.jgit.lib.RepositoryCache;
import org.eclipse.jgit.util.FS;
/**
*
* @author Sebastian Sdorra
*/
public class GitUtil
{
/**
* Method description
*
*
* @param repo
*/
public static void close(org.eclipse.jgit.lib.Repository repo)
{
if (repo != null)
{
repo.close();
}
}
/**
* Method description
*
*
* @param walk
*/
public static void release(TreeWalk walk)
{
if (walk != null)
{
walk.release();
}
}
/**
* Method description
*
*
* @param walk
*/
public static void release(RevWalk walk)
{
if (walk != null)
{
walk.release();
}
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @param commit
*
* @return
*/
public static long getCommitTime(RevCommit commit)
{
long date = commit.getCommitTime();
date = date * 1000;
return date;
}
/**
* Method description
*
*
* @param directory
*
* @return
*
* @throws IOException
*/
public static org.eclipse.jgit.lib.Repository open(File directory)
throws IOException
{
return RepositoryCache.open(RepositoryCache.FileKey.lenient(directory,
FS.DETECTED), true);
}
/**
* Method description
*
*
* @param repo
* @param revision
*
* @return
*
* @throws IOException
*/
public static ObjectId getRevisionId(org.eclipse.jgit.lib.Repository repo,
String revision)
throws IOException
{
ObjectId revId = null;
if (Util.isNotEmpty(revision))
{
revId = repo.resolve(revision);
}
else
{
revId = repo.resolve(Constants.HEAD);
}
return revId;
}
}

View File

@@ -0,0 +1,121 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.web;
//~--- non-JDK imports --------------------------------------------------------
import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.Singleton;
import sonia.scm.repository.GitRepositoryHandler;
import sonia.scm.repository.RepositoryManager;
import sonia.scm.web.filter.RegexPermissionFilter;
import sonia.scm.web.security.WebSecurityContext;
//~--- JDK imports ------------------------------------------------------------
import javax.servlet.http.HttpServletRequest;
/**
*
* @author Sebastian Sdorra
*/
@Singleton
public class GitPermissionFilter extends RegexPermissionFilter
{
/** Field description */
public static final String PARAMETER_SERVICE = "service";
/** Field description */
public static final String PARAMETER_VALUE_RECEIVE = "git-receive-pack";
/** Field description */
public static final String URI_RECEIVE_PACK = "git-receive-pack";
/** Field description */
public static final String URI_REF_INFO = "/info/refs";
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
*
*
* @param securityContextProvider
* @param repositoryManager
*/
@Inject
public GitPermissionFilter(
Provider<WebSecurityContext> securityContextProvider,
RepositoryManager repositoryManager)
{
super(securityContextProvider, repositoryManager);
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
@Override
protected String getType()
{
return GitRepositoryHandler.TYPE_NAME;
}
/**
* Method description
*
*
* @param request
*
* @return
*/
@Override
protected boolean isWriteRequest(HttpServletRequest request)
{
String uri = request.getRequestURI();
return uri.endsWith(URI_RECEIVE_PACK)
|| (uri.endsWith(URI_REF_INFO)
&& PARAMETER_VALUE_RECEIVE.equals(
request.getParameter(PARAMETER_SERVICE)));
}
}

View File

@@ -0,0 +1,210 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.web;
//~--- non-JDK imports --------------------------------------------------------
import org.eclipse.jgit.errors.RepositoryNotFoundException;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.lib.RepositoryCache;
import org.eclipse.jgit.lib.RepositoryCache.FileKey;
import org.eclipse.jgit.transport.resolver.RepositoryResolver;
import org.eclipse.jgit.transport.resolver.ServiceNotAuthorizedException;
import org.eclipse.jgit.transport.resolver.ServiceNotEnabledException;
import org.eclipse.jgit.util.FS;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.repository.GitConfig;
import sonia.scm.repository.GitRepositoryHandler;
//~--- JDK imports ------------------------------------------------------------
import java.io.File;
import java.io.IOException;
import javax.servlet.http.HttpServletRequest;
/**
*
* @author Sebastian Sdorra
*/
public class GitRepositoryResolver
implements RepositoryResolver<HttpServletRequest>
{
/** the logger for GitRepositoryResolver */
private static final Logger logger =
LoggerFactory.getLogger(GitRepositoryResolver.class);
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
*
*
* @param handler
*/
public GitRepositoryResolver(GitRepositoryHandler handler)
{
this.handler = handler;
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @param name
*
* @return
*/
private static boolean isUnreasonableName(final String name)
{
if (name.length() == 0)
{
return true; // no empty paths
}
if (name.indexOf('\\') >= 0)
{
return true; // no windows/dos style paths
}
if (new File(name).isAbsolute())
{
return true; // no absolute paths
}
if (name.startsWith("../"))
{
return true; // no "l../etc/passwd"
}
if (name.contains("/../"))
{
return true; // no "foo/../etc/passwd"
}
if (name.contains("/./"))
{
return true; // "foo/./foo" is insane to ask
}
if (name.contains("//"))
{
return true; // double slashes is sloppy, don't use it
}
return false; // is a reasonable name
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param request
* @param repositoryName
*
* @return
*
* @throws RepositoryNotFoundException
* @throws ServiceNotAuthorizedException
* @throws ServiceNotEnabledException
*/
@Override
public Repository open(HttpServletRequest request, String repositoryName)
throws RepositoryNotFoundException, ServiceNotAuthorizedException,
ServiceNotEnabledException
{
Repository repository = null;
if (isUnreasonableName(repositoryName))
{
throw new RepositoryNotFoundException(repositoryName);
}
try
{
GitConfig config = handler.getConfig();
if (config.isValid())
{
File gitdir = new File(config.getRepositoryDirectory(), repositoryName);
if (logger.isDebugEnabled())
{
logger.debug("try to open git repository at {}", gitdir);
}
if (!gitdir.exists())
{
throw new RepositoryNotFoundException(repositoryName);
}
repository = RepositoryCache.open(FileKey.lenient(gitdir, FS.DETECTED),
true);
}
else
{
if (logger.isWarnEnabled())
{
logger.warn("gitconfig is not valid, the service is not available");
}
throw new ServiceNotEnabledException();
}
}
catch (RuntimeException e)
{
throw new RepositoryNotFoundException(repositoryName, e);
}
catch (IOException e)
{
throw new RepositoryNotFoundException(repositoryName, e);
}
return repository;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private GitRepositoryHandler handler;
}

View File

@@ -0,0 +1,205 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.web;
//~--- non-JDK imports --------------------------------------------------------
import org.apache.commons.lang.StringEscapeUtils;
import org.eclipse.jgit.api.Git;
import org.eclipse.jgit.api.errors.NoHeadException;
import org.eclipse.jgit.lib.PersonIdent;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.revwalk.RevCommit;
import sonia.scm.io.RegexResourceProcessor;
import sonia.scm.io.ResourceProcessor;
import sonia.scm.util.IOUtil;
import sonia.scm.util.Util;
//~--- JDK imports ------------------------------------------------------------
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.Date;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author Sebastian Sdorra
*/
public class GitRepositoryViewer
{
/** Field description */
public static final String MIMETYPE_HTML = "text/html";
/** Field description */
public static final String RESOURCE_GITINDEX = "/sonia/scm/git.index.html";
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param response
* @param repository
* @param repositoryName
*
* @throws IOException
* @throws NoHeadException
* @throws ServletException
*/
public void handleRequest(HttpServletResponse response,
Repository repository, String repositoryName)
throws IOException, ServletException, NoHeadException
{
response.setContentType(MIMETYPE_HTML);
ResourceProcessor processor = new RegexResourceProcessor();
processor.addVariable("name", repositoryName);
StringBuilder sb = new StringBuilder();
if (!repository.getAllRefs().isEmpty())
{
Git git = new Git(repository);
int c = 0;
for (RevCommit commit : git.log().call())
{
appendCommit(sb, commit);
c++;
if (c > logSize)
{
break;
}
}
}
processor.addVariable("commits", sb.toString());
BufferedReader reader = null;
PrintWriter writer = null;
try
{
reader = new BufferedReader(
new InputStreamReader(
GitRepositoryViewer.class.getResourceAsStream(
RESOURCE_GITINDEX)));
writer = response.getWriter();
processor.process(reader, writer);
}
finally
{
IOUtil.close(reader);
IOUtil.close(writer);
}
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
public int getLogSize()
{
return logSize;
}
//~--- set methods ----------------------------------------------------------
/**
* Method description
*
*
* @param logSize
*/
public void setLogSize(int logSize)
{
this.logSize = logSize;
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param sb
* @param commit
*/
private void appendCommit(StringBuilder sb, RevCommit commit)
{
sb.append("<tr><td class=\"small\">");
long time = commit.getCommitTime();
sb.append(Util.formatDate(new Date(time * 1000)));
sb.append("</td><td class=\"small\">");
PersonIdent person = commit.getCommitterIdent();
if (person != null)
{
String name = person.getName();
if (Util.isNotEmpty(name))
{
sb.append(StringEscapeUtils.escapeHtml(name));
}
}
sb.append("</td><td>");
sb.append(StringEscapeUtils.escapeHtml(commit.getFullMessage()));
sb.append("</td></tr>");
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private int logSize = 25;
}

View File

@@ -0,0 +1,67 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.web;
//~--- non-JDK imports --------------------------------------------------------
import com.google.inject.servlet.ServletModule;
import sonia.scm.plugin.ext.Extension;
import sonia.scm.web.filter.BasicAuthenticationFilter;
/**
*
* @author Sebastian Sdorra
*/
@Extension
public class GitServletModule extends ServletModule
{
/** Field description */
public static final String PATTERN_GIT = "/git/*";
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*/
@Override
protected void configureServlets()
{
filter(PATTERN_GIT).through(BasicAuthenticationFilter.class);
filter(PATTERN_GIT).through(GitPermissionFilter.class);
serve(PATTERN_GIT).with(ScmGitServlet.class);
}
}

View File

@@ -0,0 +1,176 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.web;
//~--- non-JDK imports --------------------------------------------------------
import com.google.inject.Inject;
import com.google.inject.Singleton;
import org.eclipse.jgit.http.server.GitServlet;
import org.eclipse.jgit.lib.Repository;
import org.eclipse.jgit.transport.resolver.RepositoryResolver;
import sonia.scm.repository.GitRepositoryHandler;
import sonia.scm.util.HttpUtil;
//~--- JDK imports ------------------------------------------------------------
import java.io.IOException;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
/**
*
* @author Sebastian Sdorra
*/
@Singleton
public class ScmGitServlet extends GitServlet
{
/** Field description */
public static final String REGEX_GITHTTPBACKEND =
"(?x)^/git/(.*/(HEAD|info/refs|objects/(info/[^/]+|[0-9a-f]{2}/[0-9a-f]{38}|pack/pack-[0-9a-f]{40}\\.(pack|idx))|git-(upload|receive)-pack))$";
/** Field description */
private static final long serialVersionUID = -7712897339207470674L;
/** Field description */
private static final Pattern REGEX_REPOSITORYNAME =
Pattern.compile("/git/([^/]+)/?.*");
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
*
* @param handler
*/
@Inject
public ScmGitServlet(GitRepositoryHandler handler)
{
resolver = new GitRepositoryResolver(handler);
setRepositoryResolver(resolver);
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param request
* @param response
*
* @throws IOException
* @throws ServletException
*/
@Override
protected void service(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
String uri = HttpUtil.getStrippedURI(request);
if (uri.matches(REGEX_GITHTTPBACKEND))
{
super.service(request, response);
}
else
{
printGitInformation(request, response);
}
}
/**
* Method description
*
*
*
* @param request
* @param response
*
* @throws IOException
* @throws ServletException
*/
private void printGitInformation(HttpServletRequest request,
HttpServletResponse response)
throws ServletException, IOException
{
String uri = HttpUtil.getStrippedURI(request);
Matcher m = REGEX_REPOSITORYNAME.matcher(uri);
String name = null;
Repository repository = null;
try
{
if (m.matches())
{
name = m.group(1);
repository = resolver.open(request, name);
}
if (repository != null)
{
new GitRepositoryViewer().handleRequest(response, repository, name);
}
else
{
response.sendError(HttpServletResponse.SC_NOT_FOUND);
}
}
catch (Exception ex)
{
throw new ServletException(ex);
}
finally
{
if (repository != null)
{
repository.close();
}
}
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private RepositoryResolver<HttpServletRequest> resolver;
}

View File

@@ -0,0 +1,63 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!--
Copyright (c) 2010, Sebastian Sdorra
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of SCM-Manager; nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
http://bitbucket.org/sdorra/scm-manager
-->
<!--
Document : plugin.xml
Created on : October 12, 2010, 8:29 AM
Author : sdorra
Description:
Purpose of the document follows.
-->
<plugin>
<information>
<groupId>${project.groupId}</groupId>
<artifactId>${project.artifactId}</artifactId>
<version>${project.version}</version>
<name>${project.name}</name>
<description>${project.description}</description>
<author>Sebastian Sdorra</author>
<url>${project.url}</url>
</information>
<conditions>
<min-version>1.1</min-version>
</conditions>
<resources>
<script>/sonia/scm/git.config.js</script>
</resources>
</plugin>

View File

@@ -0,0 +1,97 @@
/*
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
Ext.ns("Sonia.git");
Sonia.git.ConfigPanel = Ext.extend(Sonia.config.SimpleConfigForm, {
// labels
titleText: 'Git Settings',
repositoryDirectoryText: 'Repository directory',
// helpTexts
repositoryDirectoryHelpText: 'Location of the Git repositories.',
initComponent: function(){
var config = {
title : this.titleText,
configUrl: restUrl + 'config/repositories/git.json',
items : [{
xtype: 'textfield',
name: 'repositoryDirectory',
fieldLabel: this.repositoryDirectoryText,
helpText: this.repositoryDirectoryHelpText,
allowBlank : false
}]
}
Ext.apply(this, Ext.apply(this.initialConfig, config));
Sonia.git.ConfigPanel.superclass.initComponent.apply(this, arguments);
}
});
Ext.reg("gitConfigPanel", Sonia.git.ConfigPanel);
// i18n
if ( i18n != null && i18n.country == 'de' ){
Ext.override(Sonia.git.ConfigPanel, {
// labels
titleText: 'Git Einstellungen',
repositoryDirectoryText: 'Repository-Verzeichnis',
// helpTexts
repositoryDirectoryHelpText: 'Verzeichnis der Git-Repositories.'
});
}
// register information panel
initCallbacks.push(function(main){
main.registerInfoPanel('git', {
checkoutTemplate: 'git clone <a href="{0}" target="_blank">{0}</a>',
xtype: 'repositoryExtendedInfoPanel'
});
});
// register panel
registerConfigPanel({
xtype : 'gitConfigPanel'
});

View File

@@ -0,0 +1,114 @@
<!--
Copyright (c) 2010, Sebastian Sdorra
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice,
this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of SCM-Manager; nor the names of its
contributors may be used to endorse or promote products derived from this
software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
http://bitbucket.org/sdorra/scm-manager
-->
<html>
<head>
<title>SCM :: Manager - Git Repository - ${name}</title>
<style type="text/css">
body {
background-color: #ffffff;
margin: 10px;
color: #202020;
font-family: Verdana,Helvetica,Arial,sans-serif;
font-size: 75%;
}
h1, h2, h3, h4, h5 {
font-family: Arial, "Arial CE", "Lucida Grande CE", lucida, "Helvetica CE", sans-serif;
font-weight: bold;
margin: 0px;
padding: 0px;
color: #D20005;
}
h1 {
font-size: 18px;
border-bottom: 1px solid #AFAFAF;
}
h2 {
font-size: 14px;
border-bottom: 1px solid #AFAFAF;
}
a:link, a:visited {
color: #045491;
font-weight: bold;
text-decoration: none;
}
a:link:hover, a:visited:hover {
color: #045491;
font-weight: bold;
text-decoration: underline;
}
table {
border: 0 none;
border-collapse: collapse;
font-size: 100%;
margin: 20px 0;
padding: 20px;
width: 100%;
}
td, th {
padding: 3px;
vertical-align: top;
border: 1px solid #CCCCCC;
text-align: left;
}
.small {
width: 20%;
}
</style>
</head>
<body>
<h1>SCM :: Manager - Git Repository - ${name}</h1>
<table>
<thead>
<tr>
<th class="small">Time</th>
<th class="small">Author</th>
<th>Message</th>
</tr>
</thead>
<tbody>
${commits}
</tbody>
</table>
<h2>Git Informations</h2>
<ul>
<li><a href="http://git-scm.com/" target="_blank">Git Homepage</a></li>
<li><a href="http://www.kernel.org/pub/software/scm/git/docs/gittutorial.html" target="_blank">Git Tutorial</a></li>
<li><a href="http://www.kernel.org/pub/software/scm/git/docs/user-manual.html" target="_blank">Git User's Manual</a></li>
</ul>
</body>
</html>

View File

@@ -0,0 +1,104 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
package sonia.scm.repository;
//~--- non-JDK imports --------------------------------------------------------
import sonia.scm.io.DefaultFileSystem;
import sonia.scm.store.StoreFactory;
import static org.junit.Assert.*;
//~--- JDK imports ------------------------------------------------------------
import java.io.File;
/**
*
* @author Sebastian Sdorra
*/
public class GitRepositoryHandlerTest extends SimpleRepositoryHandlerTestBase
{
/**
* Method description
*
*
* @param directory
*/
@Override
protected void checkDirectory(File directory)
{
File head = new File(directory, "HEAD");
assertTrue(head.exists());
assertTrue(head.isFile());
File config = new File(directory, "config");
assertTrue(config.exists());
assertTrue(config.isFile());
File refs = new File(directory, "refs");
assertTrue(refs.exists());
assertTrue(refs.isDirectory());
}
/**
* Method description
*
*
* @param factory
* @param directory
*
* @return
*/
@Override
protected RepositoryHandler createRepositoryHandler(StoreFactory factory,
File directory)
{
GitRepositoryHandler repositoryHandler = new GitRepositoryHandler(factory,
new DefaultFileSystem());
repositoryHandler.init(contextProvider);
GitConfig config = new GitConfig();
config.setRepositoryDirectory(directory);
repositoryHandler.setConfig(config);
return repositoryHandler;
}
}