From 5368c4b41046c2f0adabdeb6261ee216b5e696f1 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 9 Sep 2010 10:22:57 +0200 Subject: [PATCH] implementing HgRepositoryManager --- .../scm/repository/HgPermissionBuilder.java | 146 ++++++++++ .../scm/repository/HgPermissionReader.java | 156 +++++++++++ .../scm/repository/HgRepositoryManager.java | 251 +++++++++++++++++- .../src/main/java/sonia/scm/util/Util.java | 30 +++ 4 files changed, 577 insertions(+), 6 deletions(-) create mode 100644 plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgPermissionBuilder.java create mode 100644 plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgPermissionReader.java diff --git a/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgPermissionBuilder.java b/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgPermissionBuilder.java new file mode 100644 index 0000000000..e37035bbd8 --- /dev/null +++ b/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgPermissionBuilder.java @@ -0,0 +1,146 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package sonia.scm.repository; + +import java.util.Collection; +import sonia.scm.group.Group; + +/** + * + * @author Sebastian Sdorra + */ +public class HgPermissionBuilder +{ + + /** + * Constructs ... + * + * + * @param permissions + */ + public HgPermissionBuilder(Collection permissions) + { + buildPermissions(permissions); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + public String getReadPermission() + { + return read.toString(); + } + + /** + * Method description + * + * + * @return + */ + public String getWritePermission() + { + return write.toString(); + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param permissions + */ + private void buildPermissions(Collection permissions) + { + boolean firstRead = true; + boolean firstWrite = true; + + for (Permission permission : permissions) + { + String name = permission.getName(); + + if (permission.isGroupPermission()) + { + name = createGroupString(name); + } + + if (permission.isReadable()) + { + if (!firstRead) + { + read.append(", "); + } + else + { + firstRead = false; + } + + read.append(name); + } + + if (permission.isWriteable()) + { + if (!firstWrite) + { + write.append(", "); + } + else + { + firstWrite = false; + } + + write.append(name); + } + } + } + + /** + * Method description + * + * + * @param name + * + * @return + */ + private String createGroupString(String name) + { + StringBuilder result = new StringBuilder(); + + result.append("__").append(name).append(", "); + + Group group = /*SCMContext.getContext().getGroupManager().get(name);*/ null; + + if (group != null) + { + Collection memerbers = group.getMembers(); + + if (memerbers != null) + { + for (String member : memerbers) + { + result.append(member).append(", "); + } + } + } + + result.append("__").append(name); + + return result.toString(); + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private StringBuilder read = new StringBuilder(); + + /** Field description */ + private StringBuilder write = new StringBuilder(); +} diff --git a/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgPermissionReader.java b/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgPermissionReader.java new file mode 100644 index 0000000000..6136f12324 --- /dev/null +++ b/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgPermissionReader.java @@ -0,0 +1,156 @@ +/* + * To change this template, choose Tools | Templates + * and open the template in the editor. + */ + +package sonia.scm.repository; + +import java.util.ArrayList; +import java.util.Iterator; +import java.util.List; +import sonia.scm.util.Util; + +/** + * + * @author Sebastian Sdorra + */ +public class HgPermissionReader +{ + + /** + * Method description + * + * + * @param read + * @param write + * + * @return + */ + public List readPermissions(String read, String write) + { + List readPerms = createPermList(read); + List writePerms = createPermList(write); + + return createPermissionList(readPerms, writePerms); + } + + /** + * Method description + * + * + * @param perms + * + * @return + */ + private List createGroups(List perms) + { + List groups = new ArrayList(); + boolean start = false; + Iterator permIt = perms.iterator(); + + while (permIt.hasNext()) + { + String perm = permIt.next(); + + if (perm.startsWith("__")) + { + if (start) + { + start = false; + } + else + { + start = true; + groups.add(perm.substring(2)); + } + + permIt.remove(); + } + else if (start) + { + permIt.remove(); + } + } + + return groups; + } + + /** + * Method description + * + * + * @param value + * + * @return + */ + private List createPermList(String value) + { + List perms = new ArrayList(); + + if (Util.isNotEmpty(value)) + { + String[] values = value.split(","); + + for (String name : values) + { + perms.add(name.trim()); + } + } + + return perms; + } + + /** + * Method description + * + * + * @param readPerms + * @param writePerms + * + * @return + */ + private List createPermissionList(List readPerms, + List writePerms) + { + List permissions = new ArrayList(); + List readGroups = createGroups(readPerms); + List writeGroups = createGroups(writePerms); + + createPermissions(permissions, readPerms, writePerms, false); + createPermissions(permissions, readGroups, writeGroups, true); + + return permissions; + } + + /** + * Method description + * + * + * @param permissions + * @param readPermissions + * @param writePermissions + * @param group + */ + private void createPermissions(List permissions, + List readPermissions, + List writePermissions, boolean group) + { + for (String readPerm : readPermissions) + { + boolean write = false; + + if (writePermissions.contains(readPerm)) + { + write = true; + writePermissions.remove(readPerm); + } + + permissions.add(new Permission(readPerm, true, write, group)); + } + + for (String writePerm : writePermissions) + { + permissions.add(new Permission(writePerm, false, true, group)); + } + } +} diff --git a/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryManager.java b/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryManager.java index 59a7c6257b..2d3644e400 100644 --- a/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryManager.java +++ b/plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgRepositoryManager.java @@ -10,14 +10,25 @@ package sonia.scm.repository; //~--- non-JDK imports -------------------------------------------------------- import sonia.scm.SCMContextProvider; +import sonia.scm.io.CommandResult; +import sonia.scm.io.ExtendedCommand; +import sonia.scm.io.INIConfiguration; +import sonia.scm.io.INIConfigurationReader; +import sonia.scm.io.INIConfigurationWriter; +import sonia.scm.io.INISection; import sonia.scm.util.AssertUtil; +import sonia.scm.util.Util; //~--- JDK imports ------------------------------------------------------------ import java.io.File; 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; @@ -46,6 +57,10 @@ public class HgRepositoryManager extends AbstractRepositoryManager public static final String CONFIG_FILE = "config".concat(File.separator).concat("hg.xml"); + /** Field description */ + private static final Logger logger = + Logger.getLogger(HgRepositoryManager.class.getName()); + //~--- methods -------------------------------------------------------------- /** @@ -70,7 +85,33 @@ public class HgRepositoryManager extends AbstractRepositoryManager public void create(Repository repository) throws RepositoryException, IOException { - throw new UnsupportedOperationException("Not supported yet."); + File directory = getDirectory(repository); + + if (directory.exists()) + { + throw new RepositoryAllreadyExistExeption(); + } + + ExtendedCommand command = new ExtendedCommand(config.getHgBinary(), "init", + directory.getPath()); + CommandResult result = command.execute(); + + if (!result.isSuccessfull()) + { + StringBuilder msg = new StringBuilder("hg exit with error "); + + msg.append(result.getReturnCode()).append(" and message: '"); + msg.append(result.getOutput()).append("'"); + + throw new RepositoryException(msg.toString()); + } + + repository.setType(TYPE_NAME); + + File hgDirectory = new File(directory, ".hg"); + + writeHgrc(repository, hgDirectory); + fireEvent(repository, RepositoryEvent.CREATE); } /** @@ -86,7 +127,17 @@ public class HgRepositoryManager extends AbstractRepositoryManager public void delete(Repository repository) throws RepositoryException, IOException { - throw new UnsupportedOperationException("Not supported yet."); + File directory = getDirectory(repository); + + if (new File(directory, ".hg").exists()) + { + Util.delete(directory); + fireEvent(repository, RepositoryEvent.DELETE); + } + else + { + throw new RepositoryException("repository does not exists"); + } } /** @@ -130,7 +181,14 @@ public class HgRepositoryManager extends AbstractRepositoryManager public void modify(Repository repository) throws RepositoryException, IOException { - throw new UnsupportedOperationException("Not supported yet."); + File directory = getDirectory(repository); + File hgDirectory = new File(directory, ".hg"); + + if (hgDirectory.exists()) + { + writeHgrc(repository, hgDirectory); + fireEvent(repository, RepositoryEvent.MODIFY); + } } /** @@ -146,7 +204,13 @@ public class HgRepositoryManager extends AbstractRepositoryManager public void refresh(Repository repository) throws RepositoryException, IOException { - throw new UnsupportedOperationException("Not supported yet."); + File directory = getDirectory(repository); + File hgDirectory = new File(directory, ".hg"); + + if (hgDirectory.exists()) + { + readHgrc(repository, hgDirectory); + } } //~--- get methods ---------------------------------------------------------- @@ -162,7 +226,21 @@ public class HgRepositoryManager extends AbstractRepositoryManager @Override public Repository get(String name) { - throw new UnsupportedOperationException("Not supported yet."); + Repository repository = null; + File directory = getDirectory(name); + + if (directory.exists() && directory.isDirectory()) + { + File hgDirectory = new File(directory, ".hg"); + + if (hgDirectory.exists() && hgDirectory.isDirectory()) + { + repository = new Repository(TYPE_NAME, name); + readHgrc(repository, hgDirectory); + } + } + + return repository; } /** @@ -174,7 +252,23 @@ public class HgRepositoryManager extends AbstractRepositoryManager @Override public Collection getAll() { - throw new UnsupportedOperationException("Not supported yet."); + List repositories = new ArrayList(); + String[] repositoryNames = config.getRepositoryDirectory().list(); + + if ((repositoryNames != null) && (repositoryNames.length > 0)) + { + for (String repositoryName : repositoryNames) + { + Repository repository = get(repositoryName); + + if (repository != null) + { + repositories.add(repository); + } + } + } + + return repositories; } /** @@ -201,6 +295,151 @@ public class HgRepositoryManager extends AbstractRepositoryManager return config != null; } + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param section + * @param permissions + */ + private void appendPermission(INISection section, + Collection permissions) + { + HgPermissionBuilder builder = new HgPermissionBuilder(permissions); + + section.setParameter("allow_read", builder.getReadPermission()); + section.setParameter("allow_push", builder.getWritePermission()); + } + + /** + * Method description + * + * + * @param repository + * @param hgDirectory + */ + private void readHgrc(Repository repository, File hgDirectory) + { + File hgrc = new File(hgDirectory, "hgrc"); + + if (hgrc.exists() && hgrc.isFile()) + { + try + { + INIConfiguration iniConfig = new INIConfigurationReader().read(hgrc); + INISection section = iniConfig.getSection("web"); + + if (section != null) + { + repository.setDescription(section.getParameter("description")); + repository.setContact(section.getParameter("contact")); + + String read = section.getParameter("allow_read"); + String write = section.getParameter("allow_push"); + + if ((read != null) || (write != null)) + { + if (read == null) + { + read = ""; + } + + if (write == null) + { + write = ""; + } + + List permissions = + new HgPermissionReader().readPermissions(read, write); + + repository.setPermissions(permissions); + } + } + } + catch (IOException ex) + { + logger.log(Level.SEVERE, null, ex); + } + } + } + + /** + * Method description + * + * + * @param repository + * @param hgDirectory + * + * @throws IOException + */ + private void writeHgrc(Repository repository, File hgDirectory) + throws IOException + { + INISection section = new INISection("web"); + + section.setParameter("name", repository.getName()); + + String description = repository.getDescription(); + + if (Util.isNotEmpty(description)) + { + section.setParameter("description", description); + } + + String contact = repository.getContact(); + + if (Util.isNotEmpty(contact)) + { + section.setParameter("contact", contact); + } + + Collection permissions = repository.getPermissions(); + + if (permissions != null) + { + appendPermission(section, permissions); + } + + INIConfiguration iniConfig = new INIConfiguration(); + + iniConfig.addSection(section); + + File hgrc = new File(hgDirectory, "hgrc"); + INIConfigurationWriter writer = new INIConfigurationWriter(); + + writer.write(iniConfig, hgrc); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param name + * + * @return + */ + private File getDirectory(String name) + { + return new File(config.getRepositoryDirectory(), name); + } + + /** + * Method description + * + * + * @param repository + * + * @return + */ + private File getDirectory(Repository repository) + { + return getDirectory(repository.getName()); + } + //~--- fields --------------------------------------------------------------- /** Field description */ diff --git a/scm-core/src/main/java/sonia/scm/util/Util.java b/scm-core/src/main/java/sonia/scm/util/Util.java index 41251577c4..b8f7344285 100644 --- a/scm-core/src/main/java/sonia/scm/util/Util.java +++ b/scm-core/src/main/java/sonia/scm/util/Util.java @@ -10,6 +10,7 @@ package sonia.scm.util; //~--- JDK imports ------------------------------------------------------------ import java.io.Closeable; +import java.io.File; import java.io.IOException; import java.util.Collection; @@ -49,6 +50,35 @@ public class Util } } + /** + * Method description + * + * + * @param file + * + * @throws IOException + */ + public static void delete(File file) throws IOException + { + if (file.isDirectory()) + { + File[] children = file.listFiles(); + + if (children != null) + { + for (File child : children) + { + delete(child); + } + } + } + + if (!file.delete()) + { + throw new IOException("could not delete file ".concat(file.getPath())); + } + } + //~--- get methods ---------------------------------------------------------- /**