GitServlet implementation.

This commit is contained in:
robin shine 2013-09-25 18:09:28 +08:00
parent a34f8ca977
commit b9fecdfb87
45 changed files with 575 additions and 123 deletions

View File

@ -37,7 +37,7 @@
<dependency>
<groupId>org.hibernate</groupId>
<artifactId>hibernate-validator</artifactId>
<version>5.0.0.Final</version>
<version>5.0.1.Final</version>
</dependency>
</dependencies>

View File

@ -19,6 +19,7 @@ public abstract class AbstractEditContext implements EditContext {
this.bean = bean;
}
@Override
public Serializable getBean() {
return bean;
}

View File

@ -6,6 +6,8 @@ import java.util.Map;
public interface EditContext extends Serializable {
Serializable getBean();
void validate();
List<ValidationError> getValidationErrors(boolean recursive);

View File

@ -33,16 +33,21 @@
<artifactId>commons.loader</artifactId>
<version>1.0.29</version>
</dependency>
<!-- dependency>
<dependency>
<groupId>org.eclipse.jgit</groupId>
<artifactId>org.eclipse.jgit</artifactId>
<artifactId>org.eclipse.jgit.http.server</artifactId>
<version>3.0.0.201306101825-r</version>
</dependency-->
</dependency>
<dependency>
<groupId>com.pmease</groupId>
<artifactId>commons.util</artifactId>
<version>1.0.29</version>
</dependency>
<dependency>
<groupId>com.pmease</groupId>
<artifactId>commons.jetty</artifactId>
<version>1.0.29</version>
</dependency>
</dependencies>
<repositories>

View File

@ -0,0 +1,32 @@
package com.pmease.commons.git;
import java.io.OutputStream;
import com.google.common.base.Preconditions;
import com.pmease.commons.util.execution.Commandline;
import com.pmease.commons.util.execution.LineConsumer;
public class AdvertiseReceiveRefsCommand extends GitCommand<Git> {
private OutputStream output;
public AdvertiseReceiveRefsCommand(Git git) {
super(git);
}
public AdvertiseReceiveRefsCommand output(OutputStream output) {
this.output = output;
return this;
}
@Override
public Git call() {
Preconditions.checkNotNull(output);
Commandline cmd = git().cmd();
cmd.addArgs("receive-pack", "--stateless-rpc", "--advertise-refs", ".");
cmd.execute(output, new LineConsumer.ErrorLogger(), null).checkReturnCode();
return git();
}
}

View File

@ -0,0 +1,32 @@
package com.pmease.commons.git;
import java.io.OutputStream;
import com.google.common.base.Preconditions;
import com.pmease.commons.util.execution.Commandline;
import com.pmease.commons.util.execution.LineConsumer;
public class AdvertiseUploadRefsCommand extends GitCommand<Git> {
private OutputStream output;
public AdvertiseUploadRefsCommand(Git git) {
super(git);
}
public AdvertiseUploadRefsCommand output(OutputStream output) {
this.output = output;
return this;
}
@Override
public Git call() {
Preconditions.checkNotNull(output);
Commandline cmd = git().cmd();
cmd.addArgs("upload-pack", "--stateless-rpc", "--advertise-refs", ".");
cmd.execute(output, new LineConsumer.ErrorLogger(), null).checkReturnCode();
return git();
}
}

View File

@ -19,6 +19,22 @@ public class Git {
this.repoDir = repoDir;
}
public UploadCommand upload() {
return new UploadCommand(this);
}
public ReceiveCommand receive() {
return new ReceiveCommand(this);
}
public AdvertiseUploadRefsCommand advertiseUploadRefs() {
return new AdvertiseUploadRefsCommand(this);
}
public AdvertiseReceiveRefsCommand advertiseReceiveRefs() {
return new AdvertiseReceiveRefsCommand(this);
}
public InitCommand init() {
return new InitCommand(this);
}

View File

@ -0,0 +1,42 @@
package com.pmease.commons.git;
import java.io.InputStream;
import java.io.OutputStream;
import com.google.common.base.Preconditions;
import com.pmease.commons.util.execution.Commandline;
import com.pmease.commons.util.execution.LineConsumer;
public class ReceiveCommand extends GitCommand<Git> {
private InputStream input;
private OutputStream output;
public ReceiveCommand(Git git) {
super(git);
}
public ReceiveCommand input(InputStream input) {
this.input = input;
return this;
}
public ReceiveCommand output(OutputStream output) {
this.output = output;
return this;
}
@Override
public Git call() {
Preconditions.checkNotNull(input);
Preconditions.checkNotNull(output);
Commandline cmd = git().cmd();
cmd.addArgs("receive-pack", "--stateless-rpc", ".");
cmd.execute(output, new LineConsumer.ErrorLogger(), input).checkReturnCode();
return git();
}
}

View File

@ -0,0 +1,42 @@
package com.pmease.commons.git;
import java.io.InputStream;
import java.io.OutputStream;
import com.google.common.base.Preconditions;
import com.pmease.commons.util.execution.Commandline;
import com.pmease.commons.util.execution.LineConsumer;
public class UploadCommand extends GitCommand<Git> {
private InputStream input;
private OutputStream output;
public UploadCommand(Git git) {
super(git);
}
public UploadCommand input(InputStream input) {
this.input = input;
return this;
}
public UploadCommand output(OutputStream output) {
this.output = output;
return this;
}
@Override
public Git call() {
Preconditions.checkNotNull(input);
Preconditions.checkNotNull(output);
Commandline cmd = git().cmd();
cmd.addArgs("upload-pack", "--stateless-rpc", ".");
cmd.execute(output, new LineConsumer.ErrorLogger(), input).checkReturnCode();
return git();
}
}

View File

@ -101,7 +101,7 @@
</repositories>
<properties>
<moduleClass>com.pmease.commons.hibernate.HibernateModule</moduleClass>
<hibernateVersion>4.2.0.Final</hibernateVersion>
<hibernateVersion>4.2.5.Final</hibernateVersion>
<bonecpVersion>0.8.0-rc1</bonecpVersion>
</properties>
<version>1.0.30</version>

View File

@ -16,5 +16,4 @@ import java.lang.annotation.RetentionPolicy;
@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
public @interface Sessional {
boolean transactional() default false;
}

View File

@ -2,6 +2,8 @@ package com.pmease.commons.hibernate.dao;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.DetachedCriteria;
import org.hibernate.criterion.Order;
@ -10,7 +12,7 @@ import com.google.inject.Inject;
import com.pmease.commons.hibernate.AbstractEntity;
import com.pmease.commons.util.ReflectionUtils;
public class DefaultGenericDao<T extends AbstractEntity> implements GenericDao<T> {
public abstract class AbstractGenericDao<T extends AbstractEntity> implements GenericDao<T> {
private GeneralDao generalDao;
@ -18,9 +20,9 @@ public class DefaultGenericDao<T extends AbstractEntity> implements GenericDao<T
@SuppressWarnings("unchecked")
@Inject
public DefaultGenericDao(GeneralDao generalDao) {
public AbstractGenericDao(GeneralDao generalDao) {
this.generalDao = generalDao;
List<Class<?>> typeArguments = ReflectionUtils.getTypeArguments(DefaultGenericDao.class, getClass());
List<Class<?>> typeArguments = ReflectionUtils.getTypeArguments(AbstractGenericDao.class, getClass());
entityClass = ((Class<T>) typeArguments.get(0));
}
@ -44,11 +46,6 @@ public class DefaultGenericDao<T extends AbstractEntity> implements GenericDao<T
generalDao.delete(entity);
}
@Override
public void deleteById(Long entityId) {
generalDao.deleteById(entityClass, entityId);
}
@Override
public int count(Criterion[] criterions) {
DetachedCriteria detachedCriteria = DetachedCriteria.forClass(entityClass);
@ -105,4 +102,14 @@ public class DefaultGenericDao<T extends AbstractEntity> implements GenericDao<T
return (T) generalDao.find(detachedCriteria);
}
@Override
public Session getSession() {
return generalDao.getSession();
}
@Override
public Criteria createCriteria() {
return getSession().createCriteria(entityClass);
}
}

View File

@ -56,19 +56,13 @@ public class DefaultGeneralDao implements GeneralDao, Serializable {
getSession().delete(entity);
}
private Session getSession() {
@Override
public Session getSession() {
return sessionProvider.get();
}
@Transactional
@Override
public <T extends AbstractEntity> void deleteById(Class<T> entityClass, Long entityId) {
T entity = load(unproxy(entityClass), entityId);
delete(entity);
}
protected <T extends AbstractEntity> Class<T> unproxy(Class<T> entityClass) {
//cm will be null if entityClass is not registered with Hibernate or when
//class meta data will be null if entityClass is not registered with Hibernate or when
//it is a Hibernate proxy class (e.x. test.googlecode.genericdao.model.Person_$$_javassist_5).
//So if a class is not recognized, we will look at superclasses to see if
//it is a proxy.

View File

@ -3,6 +3,7 @@ package com.pmease.commons.hibernate.dao;
import java.util.List;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.criterion.DetachedCriteria;
import com.pmease.commons.hibernate.AbstractEntity;
@ -56,16 +57,6 @@ public interface GeneralDao {
* the entity to be deleted
*/
void delete(AbstractEntity entity);
/**
* Delete entity of specified class and identifier without actually loading the entity.
*
* @param entityClass
* class of the entity
* @param entityId
* identifier of the entity
*/
<T extends AbstractEntity> void deleteById(Class<T> entityClass, Long entityId);
/**
* Query with specified criteria.
@ -98,5 +89,6 @@ public interface GeneralDao {
* number of entities matching specified {@link DetachedCriteria}
*/
<T extends AbstractEntity> int count(DetachedCriteria detachedCriteria);
Session getSession();
}

View File

@ -4,6 +4,8 @@ import java.util.List;
import javax.annotation.Nullable;
import org.hibernate.Criteria;
import org.hibernate.Session;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Order;
@ -50,16 +52,6 @@ public interface GenericDao<T extends AbstractEntity> {
*/
public void delete(T entity);
/**
* Delete entity of specified identifier without actually loading the entity.
*
* @param entityClass
* class of the entity
* @param entityId
* identifier of the entity
*/
void deleteById(Long entityId);
/**
* Search entity with specified criterions and orders.
*
@ -122,5 +114,9 @@ public interface GenericDao<T extends AbstractEntity> {
* number of entities matching specified criterions
*/
int count(@Nullable Criterion[] criterions);
Session getSession();
Criteria createCriteria();
}

View File

@ -12,7 +12,6 @@ import org.apache.shiro.subject.Subject;
import com.google.common.base.Preconditions;
import com.pmease.commons.hibernate.AbstractEntity;
import com.pmease.commons.loader.AppLoader;
@SuppressWarnings("serial")
@MappedSuperclass
@ -55,14 +54,10 @@ public abstract class AbstractUser extends AbstractEntity implements Authenticat
return new Subject.Builder().principals(principals).buildSubject();
}
public static AbstractUser getCurrent() {
public static Long getCurrentId() {
Object principal = SecurityUtils.getSubject().getPrincipal();
Preconditions.checkNotNull(principal);
Long userId = (Long) principal;
if (userId != 0L)
return AppLoader.getInstance(AbstractRealm.class).getUserById(userId);
else
return null;
return (Long) principal;
}
}

View File

@ -202,4 +202,23 @@ public class FileUtils extends org.apache.commons.io.FileUtils {
throw new RuntimeException(e);
}
}
public static void createDir(File dir) {
if (!dir.exists()) {
if (!dir.mkdirs())
throw new GeneralException("Unable to create directory: " + dir.getAbsolutePath());
}
}
public static void cleanDir(File dir) {
if (dir.exists()) {
try {
org.apache.commons.io.FileUtils.cleanDirectory(dir);
} catch (IOException e) {
throw new RuntimeException(e);
}
} else {
createDir(dir);
}
}
}

View File

@ -3,6 +3,7 @@ package com.pmease.commons.util.execution;
import java.io.ByteArrayInputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
@ -32,7 +33,7 @@ public class Commandline {
private File workingDir;
private Map<String, String> environment = new HashMap<String, String>();
public Commandline(String command) {
String[] parts = StringUtils.parseQuoteTokens(command);
Preconditions.checkArgument(parts.length != 0, "Argument 'command' is invalid.");
@ -105,8 +106,8 @@ public class Commandline {
return this;
}
public ExecuteResult execute(OutputStream stdoutConsumer, LineConsumer stderrConsumer) {
return execute(stdoutConsumer, stderrConsumer, null);
public ExecuteResult execute(OutputStream stdout, LineConsumer stderr) {
return execute(stdout, stderr, null);
}
private ProcessBuilder createProcessBuilder() {
@ -148,39 +149,34 @@ public class Commandline {
return processBuilder;
}
public ExecuteResult execute(OutputStream stdoutConsumer, final LineConsumer stderrConsumer,
@Nullable byte[] stdinBytes) {
public ExecuteResult execute(OutputStream stdout, final LineConsumer stderr, @Nullable InputStream stdin) {
Process process;
try {
ProcessBuilder processBuilder = createProcessBuilder();
process = processBuilder.redirectErrorStream(stderrConsumer == null).start();
process = processBuilder.redirectErrorStream(stderr == null).start();
} catch (IOException e) {
throw new RuntimeException(e);
}
ByteArrayInputStream inputStream = null;
if (stdinBytes != null && stdinBytes.length != 0)
inputStream = new ByteArrayInputStream(stdinBytes);
final StringBuffer errorMessage = new StringBuffer();
OutputStream errorMessageCollector = null;
if (stderrConsumer != null) {
errorMessageCollector = new LineConsumer(stderrConsumer.getEncoding()) {
if (stderr != null) {
errorMessageCollector = new LineConsumer(stderr.getEncoding()) {
@Override
public void consume(String line) {
if (errorMessage.length() != 0)
errorMessage.append("\n");
errorMessage.append(line);
stderrConsumer.consume(line);
stderr.consume(line);
}
};
}
ProcessStreamPumper streamPumper = ProcessStreamPumper.pump(process, stdoutConsumer,
errorMessageCollector, inputStream);
ProcessStreamPumper streamPumper = ProcessStreamPumper.pump(process, stdout,
errorMessageCollector, stdin);
ExecuteResult result = new ExecuteResult(this);

View File

@ -1,5 +1,7 @@
package com.pmease.commons.util.execution;
import com.pmease.commons.util.GeneralException;
public class ExecuteResult {
private int returnCode;
@ -34,11 +36,11 @@ public class ExecuteResult {
*/
public RuntimeException buildException() {
if (errorMessage != null) {
throw new RuntimeException("Failed to run command: " + commandDescription +
throw new GeneralException("Failed to run command: " + commandDescription +
"\nCommand return code: " + getReturnCode() +
"\nCommand error output: " + errorMessage);
} else {
throw new RuntimeException("Failed to run command: " + commandDescription +
throw new GeneralException("Failed to run command: " + commandDescription +
"\nCommand return code: " + getReturnCode());
}

View File

@ -12,7 +12,7 @@ import org.slf4j.LoggerFactory;
public class ProcessStreamPumper {
private static final int BUFFER_SIZE = 64000;
private static final int BUFFER_SIZE = 64*1024;
private static final Logger logger = LoggerFactory.getLogger(ProcessStreamPumper.class);
@ -22,20 +22,20 @@ public class ProcessStreamPumper {
private final Future<?> stdinPumper;
private final OutputStream stdoutStream;
private final OutputStream stdout;
private final OutputStream stderrStream;
private final OutputStream stderr;
private ProcessStreamPumper(Process process, @Nullable OutputStream stdoutStream,
@Nullable OutputStream stderrStream, @Nullable InputStream stdinStream) {
this.stdoutStream = stdoutStream;
this.stderrStream = stderrStream;
private ProcessStreamPumper(Process process, @Nullable OutputStream stdout,
@Nullable OutputStream stderr, @Nullable InputStream stdin) {
this.stdout = stdout;
this.stderr = stderr;
stdoutPumper = createPump(process.getInputStream(), stdoutStream, false);
stderrPumper = createPump(process.getErrorStream(), stderrStream, false);
stdoutPumper = createPump(process.getInputStream(), stdout, false);
stderrPumper = createPump(process.getErrorStream(), stderr, false);
if (stdinStream != null)
stdinPumper = createPump(stdinStream, process.getOutputStream(), true);
if (stdin != null)
stdinPumper = createPump(stdin, process.getOutputStream(), true);
else
stdinPumper = null;
}
@ -45,7 +45,7 @@ public class ProcessStreamPumper {
return new ProcessStreamPumper(process, stdoutStream, stderrStream, stdinStream);
}
public void waitFor() {
public void waitFor() {
while (!stdoutPumper.isDone() || !stderrPumper.isDone() ||
(stdinPumper != null && !stdinPumper.isDone())) {
try {
@ -53,16 +53,16 @@ public class ProcessStreamPumper {
} catch (InterruptedException e) {
}
}
if (stdoutStream != null) {
if (stdout != null) {
try {
stdoutStream.flush();
stdout.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
}
if (stderrStream != null) {
if (stderr != null) {
try {
stderrStream.flush();
stderr.flush();
} catch (IOException e) {
throw new RuntimeException(e);
}
@ -76,12 +76,14 @@ public class ProcessStreamPumper {
public void run() {
byte[] buf = new byte[BUFFER_SIZE];
try {
int length;
while ((length = input.read(buf)) > 0) {
if (output != null)
if (output != null) {
output.write(buf, 0, length);
//output.flush();
}
}
if (closeWhenExhausted && output!=null) {

View File

@ -0,0 +1,139 @@
package com.pmease.gitop.core;
import java.io.IOException;
import javax.inject.Inject;
import javax.inject.Singleton;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.lang3.StringUtils;
import org.eclipse.jgit.http.server.ServletUtils;
import org.eclipse.jgit.transport.PacketLineOut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.pmease.commons.git.Git;
import com.pmease.gitop.core.manager.RepositoryManager;
import com.pmease.gitop.core.manager.UserManager;
import com.pmease.gitop.core.model.Repository;
@Singleton
@SuppressWarnings("serial")
public class GitServlet extends HttpServlet {
private static final Logger logger = LoggerFactory.getLogger(GitServlet.class);
private static final String INFO_REFS = "/info/refs";
private final RepositoryManager repositoryManager;
@Inject
public GitServlet(UserManager userManager, RepositoryManager repositoryManager) {
this.repositoryManager = repositoryManager;
}
private Repository getRepository(HttpServletResponse response, String repoInfo) throws IOException {
String ownerName = StringUtils.substringBefore(repoInfo, "/");
String repositoryName = StringUtils.substringAfter(repoInfo, "/");
if (StringUtils.isBlank(ownerName) || StringUtils.isBlank(repositoryName)) {
String message = "Expecting url of format http(s)://<server>:<port>/<owner name>/<repository name>";
logger.error("Error serving git request: " + message);
response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
return null;
}
Repository repository = repositoryManager.find(ownerName, repositoryName);
if (repository == null) {
String message = "Unable to find repository '" + repositoryName + "' owned by '" + ownerName + "'.";
logger.error("Error serving git request: " + message);
response.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
return null;
}
return repository;
}
private void doNotCache(HttpServletResponse response) {
response.setHeader("Expires", "Fri, 01 Jan 1980 00:00:00 GMT");
response.setHeader("Pragma", "no-cache");
response.setHeader("Cache-Control", "no-cache, max-age=0, must-revalidate");
}
@Override
protected void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String pathInfo = StringUtils.stripStart(req.getPathInfo(), "/");
String service = StringUtils.substringAfterLast(pathInfo, "/");
String repoInfo = StringUtils.substringBeforeLast(pathInfo, "/");
Repository repository = getRepository(resp, repoInfo);
if (repository != null) {
doNotCache(resp);
resp.setHeader("Content-Type", "application/x-" + service + "-result");
Git git = new Git(repositoryManager.locateStorage(repository));
try {
if (service.contains("upload")) {
git.upload().input(ServletUtils.getInputStream(req)).output(resp.getOutputStream()).call();
} else if (service.contains("receive")) {
git.receive().input(ServletUtils.getInputStream(req)).output(resp.getOutputStream()).call();
} else {
String message = "Invalid service name '" + service + "'.";
logger.error("Error serving git request: " + message);
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
}
} catch (Exception e) {
logger.error("Error serving git request.", e);
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
}
}
}
@Override
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
String pathInfo = StringUtils.stripStart(req.getPathInfo(), "/");
if (!pathInfo.endsWith(INFO_REFS)) {
String message = "Invalid refs request url: " + req.getRequestURL();
logger.error("Error serving git request: " + message);
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
return;
}
String repoInfo = pathInfo.substring(0, pathInfo.length() - INFO_REFS.length());
Repository repository = getRepository(resp, repoInfo);
if (repository != null) {
doNotCache(resp);
String service = req.getParameter("service");
resp.setHeader("Content-Type", "application/x-" + service + "-advertisement");
PacketLineOut pack = new PacketLineOut(resp.getOutputStream());
pack.setFlushOnEnd(false);
pack.writeString("# service=" + service + "\n");
pack.end();
Git git = new Git(repositoryManager.locateStorage(repository));
try {
if (service.contains("upload")) {
git.advertiseUploadRefs().output(resp.getOutputStream()).call();
} else if (service.contains("receive")) {
git.advertiseReceiveRefs().output(resp.getOutputStream()).call();
} else {
String message = "Invalid service name '" + service + "'.";
logger.error("Error serving git request: " + message);
resp.sendError(HttpServletResponse.SC_BAD_REQUEST, message);
}
} catch (Exception e) {
logger.error("Error serving git request.", e);
resp.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
}
}
}
}

View File

@ -0,0 +1,30 @@
package com.pmease.gitop.core;
import javax.inject.Inject;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import com.pmease.commons.jetty.ServletContextConfigurator;
public class GitServletContextConfigurator implements ServletContextConfigurator {
private final GitServlet gitServlet;
@Inject
public GitServletContextConfigurator(GitServlet gitServlet) {
this.gitServlet = gitServlet;
}
@Override
public void configure(ServletContextHandler context) {
ServletHolder servletHolder = new ServletHolder(gitServlet);
context.addServlet(servletHolder, "/git/*");
servletHolder = new ServletHolder(new org.eclipse.jgit.http.server.GitServlet());
servletHolder.setInitParameter("base-path", "w:/temp/git");
servletHolder.setInitParameter("export-all", "1");
context.addServlet(servletHolder, "/jgit/*");
}
}

View File

@ -8,6 +8,7 @@ import org.hibernate.cfg.NamingStrategy;
import com.pmease.commons.hibernate.AbstractEntity;
import com.pmease.commons.hibernate.ModelProvider;
import com.pmease.commons.hibernate.PrefixedNamingStrategy;
import com.pmease.commons.jetty.ServletContextConfigurator;
import com.pmease.commons.loader.AbstractPlugin;
import com.pmease.commons.loader.AbstractPluginModule;
import com.pmease.commons.shiro.AbstractRealm;
@ -41,6 +42,7 @@ public class GitopModule extends AbstractPluginModule {
});
contribute(ServletContextConfigurator.class, GitServletContextConfigurator.class);
}
@Override

View File

@ -13,5 +13,7 @@ public interface RepositoryManager extends GenericDao<Repository> {
File locateStorage(Repository repository);
Repository find(String ownerName, String repositoryName);
Collection<Repository> findPublic();
}

View File

@ -7,7 +7,7 @@ import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import com.pmease.commons.hibernate.Sessional;
import com.pmease.commons.hibernate.dao.DefaultGenericDao;
import com.pmease.commons.hibernate.dao.AbstractGenericDao;
import com.pmease.commons.hibernate.dao.GeneralDao;
import com.pmease.commons.util.namedentity.EntityLoader;
import com.pmease.commons.util.namedentity.NamedEntity;
@ -16,7 +16,7 @@ import com.pmease.gitop.core.model.Branch;
import com.pmease.gitop.core.model.Repository;
@Singleton
public class DefaultBranchManager extends DefaultGenericDao<Branch> implements BranchManager {
public class DefaultBranchManager extends AbstractGenericDao<Branch> implements BranchManager {
@Inject
public DefaultBranchManager(GeneralDao generalDao) {

View File

@ -9,7 +9,7 @@ import org.hibernate.criterion.Restrictions;
import com.google.common.base.Preconditions;
import com.pmease.commons.hibernate.Sessional;
import com.pmease.commons.hibernate.Transactional;
import com.pmease.commons.hibernate.dao.DefaultGenericDao;
import com.pmease.commons.hibernate.dao.AbstractGenericDao;
import com.pmease.commons.hibernate.dao.GeneralDao;
import com.pmease.gitop.core.manager.ConfigManager;
import com.pmease.gitop.core.model.Config;
@ -18,7 +18,7 @@ import com.pmease.gitop.core.setting.MailSetting;
import com.pmease.gitop.core.setting.StorageSetting;
@Singleton
public class DefaultConfigManager extends DefaultGenericDao<Config> implements ConfigManager {
public class DefaultConfigManager extends AbstractGenericDao<Config> implements ConfigManager {
@Inject
public DefaultConfigManager(GeneralDao generalDao) {

View File

@ -3,13 +3,13 @@ package com.pmease.gitop.core.manager.impl;
import javax.inject.Inject;
import javax.inject.Singleton;
import com.pmease.commons.hibernate.dao.DefaultGenericDao;
import com.pmease.commons.hibernate.dao.AbstractGenericDao;
import com.pmease.commons.hibernate.dao.GeneralDao;
import com.pmease.gitop.core.manager.MergeRequestManager;
import com.pmease.gitop.core.model.MergeRequest;
@Singleton
public class DefaultMergeRequestManager extends DefaultGenericDao<MergeRequest> implements MergeRequestManager {
public class DefaultMergeRequestManager extends AbstractGenericDao<MergeRequest> implements MergeRequestManager {
@Inject
public DefaultMergeRequestManager(GeneralDao generalDao) {

View File

@ -3,13 +3,13 @@ package com.pmease.gitop.core.manager.impl;
import javax.inject.Inject;
import javax.inject.Singleton;
import com.pmease.commons.hibernate.dao.DefaultGenericDao;
import com.pmease.commons.hibernate.dao.AbstractGenericDao;
import com.pmease.commons.hibernate.dao.GeneralDao;
import com.pmease.gitop.core.manager.MergeRequestUpdateManager;
import com.pmease.gitop.core.model.MergeRequestUpdate;
@Singleton
public class DefaultMergeRequestUpdateManager extends DefaultGenericDao<MergeRequestUpdate>
public class DefaultMergeRequestUpdateManager extends AbstractGenericDao<MergeRequestUpdate>
implements MergeRequestUpdateManager {
@Inject

View File

@ -3,14 +3,14 @@ package com.pmease.gitop.core.manager.impl;
import javax.inject.Inject;
import javax.inject.Singleton;
import com.pmease.commons.hibernate.dao.DefaultGenericDao;
import com.pmease.commons.hibernate.dao.AbstractGenericDao;
import com.pmease.commons.hibernate.dao.GeneralDao;
import com.pmease.gitop.core.manager.RepositoryAuthorizationByIndividualManager;
import com.pmease.gitop.core.model.RepositoryAuthorizationByIndividual;
@Singleton
public class DefaultRepositoryAuthorizationByIndividualManager
extends DefaultGenericDao<RepositoryAuthorizationByIndividual>
extends AbstractGenericDao<RepositoryAuthorizationByIndividual>
implements RepositoryAuthorizationByIndividualManager {
@Inject

View File

@ -3,13 +3,13 @@ package com.pmease.gitop.core.manager.impl;
import javax.inject.Inject;
import javax.inject.Singleton;
import com.pmease.commons.hibernate.dao.DefaultGenericDao;
import com.pmease.commons.hibernate.dao.AbstractGenericDao;
import com.pmease.commons.hibernate.dao.GeneralDao;
import com.pmease.gitop.core.manager.RepositoryAuthorizationByTeamManager;
import com.pmease.gitop.core.model.RepositoryAuthorizationByTeam;
@Singleton
public class DefaultRepositoryAuthorizationByTeamManager extends DefaultGenericDao<RepositoryAuthorizationByTeam>
public class DefaultRepositoryAuthorizationByTeamManager extends AbstractGenericDao<RepositoryAuthorizationByTeam>
implements RepositoryAuthorizationByTeamManager {
@Inject

View File

@ -6,26 +6,57 @@ import java.util.Collection;
import javax.inject.Inject;
import javax.inject.Singleton;
import org.hibernate.Criteria;
import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import com.pmease.commons.hibernate.dao.DefaultGenericDao;
import com.pmease.commons.git.Git;
import com.pmease.commons.hibernate.Transactional;
import com.pmease.commons.hibernate.dao.AbstractGenericDao;
import com.pmease.commons.hibernate.dao.GeneralDao;
import com.pmease.commons.util.FileUtils;
import com.pmease.gitop.core.manager.ConfigManager;
import com.pmease.gitop.core.manager.RepositoryManager;
import com.pmease.gitop.core.model.Repository;
@Singleton
public class DefaultRepositoryManager extends DefaultGenericDao<Repository> implements RepositoryManager {
public class DefaultRepositoryManager extends AbstractGenericDao<Repository> implements RepositoryManager {
private ConfigManager configManager;
@Inject
public DefaultRepositoryManager(GeneralDao generalDao) {
public DefaultRepositoryManager(GeneralDao generalDao, ConfigManager configManager) {
super(generalDao);
this.configManager = configManager;
}
@Transactional
@Override
public void save(Repository entity) {
if (entity.isNew()) {
super.save(entity);
File gitDir = locateStorage(entity);
FileUtils.cleanDir(gitDir);
new Git(gitDir).init().bare(true).call();
} else {
super.save(entity);
}
}
@Transactional
@Override
public void delete(Repository entity) {
super.delete(entity);
FileUtils.deleteDir(locateStorage(entity));
}
@Override
public File locateStorage(Repository repository) {
//TODO: repository storage
return null;
return new File(configManager.getStorageSetting().getRepoStorageDir(), repository.getId().toString());
}
@Override
@ -33,4 +64,15 @@ public class DefaultRepositoryManager extends DefaultGenericDao<Repository> impl
return query(new Criterion[]{Restrictions.eq("publiclyAccessible", true)});
}
@Override
public Repository find(String ownerName, String repositoryName) {
Criteria criteria = createCriteria();
criteria.add(Restrictions.eq("name", repositoryName));
criteria.createAlias("owner", "owner");
criteria.add(Restrictions.eq("owner.name", ownerName));
criteria.setMaxResults(1);
return (Repository) criteria.uniqueResult();
}
}

View File

@ -6,13 +6,13 @@ import javax.inject.Singleton;
import org.hibernate.Session;
import com.pmease.commons.hibernate.dao.DefaultGenericDao;
import com.pmease.commons.hibernate.dao.AbstractGenericDao;
import com.pmease.commons.hibernate.dao.GeneralDao;
import com.pmease.gitop.core.manager.RoleManager;
import com.pmease.gitop.core.model.Role;
@Singleton
public class DefaultRoleManager extends DefaultGenericDao<Role> implements RoleManager {
public class DefaultRoleManager extends AbstractGenericDao<Role> implements RoleManager {
@Inject
public DefaultRoleManager(GeneralDao generalDao, Provider<Session> sessionProvider) {

View File

@ -7,7 +7,7 @@ import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import com.pmease.commons.hibernate.Sessional;
import com.pmease.commons.hibernate.dao.DefaultGenericDao;
import com.pmease.commons.hibernate.dao.AbstractGenericDao;
import com.pmease.commons.hibernate.dao.GeneralDao;
import com.pmease.commons.util.namedentity.EntityLoader;
import com.pmease.commons.util.namedentity.NamedEntity;
@ -16,7 +16,7 @@ import com.pmease.gitop.core.model.Team;
import com.pmease.gitop.core.model.User;
@Singleton
public class DefaultTeamManager extends DefaultGenericDao<Team> implements TeamManager {
public class DefaultTeamManager extends AbstractGenericDao<Team> implements TeamManager {
@Inject
public DefaultTeamManager(GeneralDao generalDao) {

View File

@ -3,14 +3,14 @@ package com.pmease.gitop.core.manager.impl;
import javax.inject.Inject;
import javax.inject.Singleton;
import com.pmease.commons.hibernate.dao.DefaultGenericDao;
import com.pmease.commons.hibernate.dao.AbstractGenericDao;
import com.pmease.commons.hibernate.dao.GeneralDao;
import com.pmease.gitop.core.manager.UserAuthorizationByIndividualManager;
import com.pmease.gitop.core.model.UserAuthorizationByIndividual;
@Singleton
public class DefaultUserAuthorizationByIndividualManager
extends DefaultGenericDao<UserAuthorizationByIndividual>
extends AbstractGenericDao<UserAuthorizationByIndividual>
implements UserAuthorizationByIndividualManager {
@Inject

View File

@ -9,7 +9,7 @@ import org.hibernate.criterion.Restrictions;
import com.google.common.base.Preconditions;
import com.pmease.commons.hibernate.Sessional;
import com.pmease.commons.hibernate.dao.DefaultGenericDao;
import com.pmease.commons.hibernate.dao.AbstractGenericDao;
import com.pmease.commons.hibernate.dao.GeneralDao;
import com.pmease.commons.util.namedentity.EntityLoader;
import com.pmease.commons.util.namedentity.NamedEntity;
@ -17,7 +17,7 @@ import com.pmease.gitop.core.manager.UserManager;
import com.pmease.gitop.core.model.User;
@Singleton
public class DefaultUserManager extends DefaultGenericDao<User> implements UserManager {
public class DefaultUserManager extends AbstractGenericDao<User> implements UserManager {
private volatile Long rootUserId;

View File

@ -7,7 +7,7 @@ import org.hibernate.criterion.Restrictions;
import com.pmease.commons.hibernate.Sessional;
import com.pmease.commons.hibernate.Transactional;
import com.pmease.commons.hibernate.dao.DefaultGenericDao;
import com.pmease.commons.hibernate.dao.AbstractGenericDao;
import com.pmease.commons.hibernate.dao.GeneralDao;
import com.pmease.gitop.core.manager.VoteInvitationManager;
import com.pmease.gitop.core.model.MergeRequest;
@ -15,7 +15,7 @@ import com.pmease.gitop.core.model.User;
import com.pmease.gitop.core.model.VoteInvitation;
@Singleton
public class DefaultVoteInvitationManager extends DefaultGenericDao<VoteInvitation> implements VoteInvitationManager {
public class DefaultVoteInvitationManager extends AbstractGenericDao<VoteInvitation> implements VoteInvitationManager {
public DefaultVoteInvitationManager(GeneralDao generalDao) {
super(generalDao);

View File

@ -6,7 +6,7 @@ import org.hibernate.criterion.Criterion;
import org.hibernate.criterion.Restrictions;
import com.pmease.commons.hibernate.Sessional;
import com.pmease.commons.hibernate.dao.DefaultGenericDao;
import com.pmease.commons.hibernate.dao.AbstractGenericDao;
import com.pmease.commons.hibernate.dao.GeneralDao;
import com.pmease.gitop.core.manager.VoteManager;
import com.pmease.gitop.core.model.MergeRequestUpdate;
@ -14,7 +14,7 @@ import com.pmease.gitop.core.model.User;
import com.pmease.gitop.core.model.Vote;
@Singleton
public class DefaultVoteManager extends DefaultGenericDao<Vote> implements VoteManager {
public class DefaultVoteManager extends AbstractGenericDao<Vote> implements VoteManager {
public DefaultVoteManager(GeneralDao generalDao) {
super(generalDao);

View File

@ -44,7 +44,6 @@ public class Repository extends AbstractEntity implements UserBelonging {
private boolean publiclyAccessible;
@Column(nullable=false)
private RepositoryOperation defaultAuthorizedOperation;
private GateKeeper gateKeeper;

View File

@ -13,6 +13,7 @@ import org.hibernate.validator.constraints.NotEmpty;
import com.pmease.commons.editable.annotation.Editable;
import com.pmease.commons.editable.annotation.Password;
import com.pmease.commons.loader.AppLoader;
import com.pmease.commons.shiro.AbstractUser;
import com.pmease.gitop.core.Gitop;
import com.pmease.gitop.core.manager.RepositoryManager;
@ -40,7 +41,7 @@ public class User extends AbstractUser implements ProtectedObject {
@Column(nullable=false)
private String email;
private String description;
private String fullName;
@OneToMany(mappedBy="user")
private Collection<TeamMembership> teamMemberships = new ArrayList<TeamMembership>();
@ -102,12 +103,12 @@ public class User extends AbstractUser implements ProtectedObject {
}
@Editable
public String getDescription() {
return description;
public String getFullName() {
return fullName;
}
public void setDescription(String description) {
this.description = description;
public void setFullName(String fullName) {
this.fullName = fullName;
}
public Collection<TeamMembership> getTeamMemberships() {
@ -228,7 +229,15 @@ public class User extends AbstractUser implements ProtectedObject {
}
public static User getCurrent() {
return (User) AbstractUser.getCurrent();
Long userId = getCurrentId();
if (userId != 0L) {
return AppLoader.getInstance(UserManager.class).load(userId);
} else {
User user = new User();
user.setId(userId);
user.setName("Anonymous");
return user;
}
}
@Override

View File

@ -1,3 +1,2 @@
<wicket:extend>
<div wicket:id="test"></div>
</wicket:extend>

View File

@ -0,0 +1,8 @@
<wicket:extend>
<div style="margin: 100px 200px;">
<form wicket:id="form">
<div wicket:id="editor"></div>
<input type="submit" value="Save" class="btn btn-primary"></input>
</form>
</div>
</wicket:extend>

View File

@ -0,0 +1,46 @@
package com.pmease.gitop.web;
import org.apache.wicket.markup.html.form.Form;
import com.pmease.commons.editable.EditContext;
import com.pmease.commons.wicket.editable.EditHelper;
import com.pmease.gitop.core.Gitop;
import com.pmease.gitop.core.manager.RepositoryManager;
import com.pmease.gitop.core.manager.UserManager;
import com.pmease.gitop.core.model.Repository;
@SuppressWarnings("serial")
public class TestPage extends BasePage {
@Override
protected void onInitialize() {
super.onInitialize();
final EditContext editContext = EditHelper.getContext(new Repository());
Form<?> form = new Form<Void>("form") {
@Override
protected void onSubmit() {
super.onSubmit();
editContext.validate();
if (!editContext.hasValidationError(true)) {
Repository repository = (Repository) editContext.getBean();
repository.setOwner(Gitop.getInstance(UserManager.class).getRootUser());
Gitop.getInstance(RepositoryManager.class).save(repository);
}
}
};
form.add(EditHelper.renderForEdit(editContext, "editor"));
add(form);
}
@Override
protected String getTitle() {
return "Test page used by Robin";
}
}

View File

@ -15,6 +15,8 @@ public class WicketConfig extends AbstractWicketConfig {
mountPage("/", HomePage.class);
mountPage("/init", ServerInitPage.class);
mountPage("/test", TestPage.class);
}
@Override

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 KiB