diff --git a/plugins/pom.xml b/plugins/pom.xml index ba78057d2d..fb4f93a261 100644 --- a/plugins/pom.xml +++ b/plugins/pom.xml @@ -17,6 +17,7 @@ scm-hg-plugin + scm-svn-plugin diff --git a/plugins/scm-svn-plugin/pom.xml b/plugins/scm-svn-plugin/pom.xml new file mode 100644 index 0000000000..650325decd --- /dev/null +++ b/plugins/scm-svn-plugin/pom.xml @@ -0,0 +1,18 @@ + + + + 4.0.0 + + + scm-plugins + sonia.scm.plugins + 1.0-SNAPSHOT + + + sonia.scm.plugins + scm-svn-plugin + 1.0-SNAPSHOT + scm-svn-plugin + + diff --git a/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnConfig.java b/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnConfig.java new file mode 100644 index 0000000000..577b5d1c86 --- /dev/null +++ b/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnConfig.java @@ -0,0 +1,100 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + + + +package sonia.scm.repository; + +//~--- JDK imports ------------------------------------------------------------ + +import javax.xml.bind.annotation.XmlRootElement; + +/** + * + * @author Sebastian Sdorra + */ +@XmlRootElement(name = "config") +public class SvnConfig extends BasicRepositoryConfig +{ + + /** + * Method description + * + * + * @return + */ + public String getRepositoryDirectory() + { + return repositoryDirectory; + } + + /** + * Method description + * + * + * @return + */ + public String getSvnAccessFile() + { + return svnAccessFile; + } + + /** + * Method description + * + * + * @return + */ + public String getSvnAdminBinary() + { + return svnAdminBinary; + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param repositoryDirectory + */ + public void setRepositoryDirectory(String repositoryDirectory) + { + this.repositoryDirectory = repositoryDirectory; + } + + /** + * Method description + * + * + * @param svnAccessFile + */ + public void setSvnAccessFile(String svnAccessFile) + { + this.svnAccessFile = svnAccessFile; + } + + /** + * Method description + * + * + * @param svnAdminBinary + */ + public void setSvnAdminBinary(String svnAdminBinary) + { + this.svnAdminBinary = svnAdminBinary; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private String repositoryDirectory; + + /** Field description */ + private String svnAccessFile; + + /** Field description */ + private String svnAdminBinary; +} diff --git a/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryHandler.java b/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryHandler.java new file mode 100644 index 0000000000..4a3a9a2c30 --- /dev/null +++ b/plugins/scm-svn-plugin/src/main/java/sonia/scm/repository/SvnRepositoryHandler.java @@ -0,0 +1,332 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + + + +package sonia.scm.repository; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.ConfigurationException; +import sonia.scm.SCMContextProvider; +import sonia.scm.io.CommandResult; +import sonia.scm.io.ExtendedCommand; +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.File; +import java.io.FilenameFilter; +import java.io.IOException; + +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.logging.Level; +import java.util.logging.Logger; + +import javax.xml.bind.JAXB; + +/** + * + * @author Sebastian Sdorra + */ +public class SvnRepositoryHandler extends AbstractRepositoryHandler +{ + + /** Field description */ + public static final String TYPE_DISPLAYNAME = "Subversion"; + + /** Field description */ + public static final String TYPE_NAME = "svn"; + + /** Field description */ + public static final RepositoryType TYPE = new RepositoryType(TYPE_NAME, + TYPE_DISPLAYNAME); + + /** Field description */ + private static final Logger logger = + Logger.getLogger(SvnRepositoryHandler.class.getName()); + + /** Field description */ + public static final String CONFIG_DIRECTORY = + "config".concat(File.separator).concat("svn"); + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param repository + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public void create(Repository repository) + throws RepositoryException, IOException + { + initNewRepository(repository); + + File directory = getDirectory(repository); + + if (directory.exists()) + { + throw new RepositoryAllreadyExistExeption(); + } + + ExtendedCommand cmd = new ExtendedCommand(config.getSvnAdminBinary(), + "create", directory.getPath()); + CommandResult result = cmd.execute(); + + if (!result.isSuccessfull()) + { + StringBuilder msg = new StringBuilder("svnadmin exit with error "); + + msg.append(result.getReturnCode()).append(" and message: '"); + msg.append(result.getOutput()).append("'"); + + throw new RepositoryException(msg.toString()); + } + + repository.setType(TYPE_NAME); + JAXB.marshal(repository, getRepositoryFile(repository)); + } + + /** + * Method description + * + * + * @param repository + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public void delete(Repository repository) + throws RepositoryException, IOException + { + File directory = getDirectory(repository); + File repositoryFile = getRepositoryFile(repository); + + if (directory.exists() && repositoryFile.exists()) + { + Util.delete(directory); + Util.delete(repositoryFile); + } + else + { + throw new RepositoryException("repository does not exists"); + } + } + + /** + * Method description + * + * + * @param context + */ + @Override + public void init(SCMContextProvider context) + { + super.init(context); + + File baseDirectory = context.getBaseDirectory(); + + configDirectory = new File(baseDirectory, CONFIG_DIRECTORY); + + if (!configDirectory.exists() &&!configDirectory.mkdirs()) + { + throw new ConfigurationException("could not create config directory"); + } + } + + /** + * Method description + * + * + * @param repository + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public void modify(Repository repository) + throws RepositoryException, IOException + { + Repository old = get(repository.getId()); + + if (old.getName().equals(repository.getName())) + { + JAXB.marshal(repository, getRepositoryFile(repository)); + } + else + { + throw new RepositoryException( + "the name of a repository could not changed"); + } + } + + /** + * Method description + * + * + * @param repository + * + * @throws IOException + * @throws RepositoryException + */ + @Override + public void refresh(Repository repository) + throws RepositoryException, IOException + { + Repository fresh = get(repository.getId()); + + fresh.copyProperties(repository); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param id + * + * @return + */ + @Override + public Repository get(String id) + { + Repository repository = null; + File repositoryFile = getRepositoryFile(id); + + if (repositoryFile.exists()) + { + repository = JAXB.unmarshal(repositoryFile, Repository.class); + } + + return repository; + } + + /** + * Method description + * + * + * @return + */ + @Override + public Collection getAll() + { + List repositories = new ArrayList(); + File[] repositoryFiles = configDirectory.listFiles(new FilenameFilter() + { + @Override + public boolean accept(File dir, String name) + { + return name.endsWith(".xml"); + } + }); + + for (File repositoryFile : repositoryFiles) + { + try + { + Repository repository = JAXB.unmarshal(repositoryFile, + Repository.class); + + repositories.add(repository); + } + catch (Exception ex) + { + logger.log(Level.SEVERE, null, ex); + } + } + + return repositories; + } + + /** + * Method description + * + * + * @return + */ + @Override + public RepositoryType getType() + { + return TYPE; + } + + /** + * Method description + * + * + * @return + */ + @Override + protected Class getConfigClass() + { + return SvnConfig.class; + } + + /** + * Method description + * + * + * @param repository + * + * @return + */ + protected File getDirectory(Repository repository) + { + File directory = null; + + if (isConfigured()) + { + directory = new File(config.getRepositoryDirectory(), + repository.getName()); + } + else + { + throw new ConfigurationException("RepositoryHandler is not configured"); + } + + return directory; + } + + /** + * Method description + * + * + * + * @param id + * + * @return + */ + private File getRepositoryFile(String id) + { + return new File(configDirectory, id.concat(".xml")); + } + + /** + * Method description + * + * + * @param repository + * + * @return + */ + private File getRepositoryFile(Repository repository) + { + return getRepositoryFile(repository.getId()); + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private File configDirectory; +} diff --git a/plugins/scm-svn-plugin/src/main/resources/META-INF/services/sonia.scm.repository.RepositoryHandler b/plugins/scm-svn-plugin/src/main/resources/META-INF/services/sonia.scm.repository.RepositoryHandler new file mode 100644 index 0000000000..ab9c76f40a --- /dev/null +++ b/plugins/scm-svn-plugin/src/main/resources/META-INF/services/sonia.scm.repository.RepositoryHandler @@ -0,0 +1 @@ +sonia.scm.repository.SvnRepositoryHandler \ No newline at end of file diff --git a/scm-core/src/main/java/sonia/scm/repository/Repository.java b/scm-core/src/main/java/sonia/scm/repository/Repository.java index 636910b92e..f50c697a78 100644 --- a/scm-core/src/main/java/sonia/scm/repository/Repository.java +++ b/scm-core/src/main/java/sonia/scm/repository/Repository.java @@ -96,6 +96,24 @@ public class Repository implements Serializable } } + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param repository + */ + public void copyProperties(Repository repository) + { + repository.setName(name); + repository.setContact(contact); + repository.setCreationDate(creationDate); + repository.setDescription(description); + repository.setPermissions(permissions); + repository.setUrl(url); + } + //~--- get methods ---------------------------------------------------------- /** diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index a8e5c37171..49181b7e0f 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -43,6 +43,12 @@ 1.0-SNAPSHOT + + sonia.scm.plugins + scm-svn-plugin + 1.0-SNAPSHOT + + com.sun.jersey jersey-json