set versions to 1.0-M7

This commit is contained in:
Thorsten Ludewig
2011-01-19 15:49:32 +01:00
56 changed files with 1432 additions and 489 deletions

View File

@@ -6,13 +6,13 @@
<parent>
<groupId>sonia.scm</groupId>
<artifactId>scm</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.maven</groupId>
<artifactId>scm-maven-plugins</artifactId>
<packaging>pom</packaging>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<name>scm-maven-plugins</name>
<modules>
@@ -24,7 +24,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</dependency>
</dependencies>

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm-maven-plugins</artifactId>
<groupId>sonia.scm.maven</groupId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.maven</groupId>
<artifactId>scm-plugin-archetype</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<name>scm-plugin-archetype</name>
</project>

View File

@@ -7,7 +7,7 @@
<parent>
<artifactId>scm-plugins</artifactId>
<groupId>sonia.scm.plugins</groupId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</parent>
<groupId>${groupId}</groupId>
@@ -31,7 +31,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-test</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<scope>test</scope>
</dependency>

View File

@@ -6,13 +6,13 @@
<parent>
<groupId>sonia.scm</groupId>
<artifactId>scm</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-plugins</artifactId>
<packaging>pom</packaging>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<name>scm-plugins</name>
<modules>
@@ -31,7 +31,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</dependency>
</dependencies>
@@ -58,4 +58,33 @@
</resources>
</build>
<profiles>
<profile>
<id>release</id>
<build>
<plugins>
<plugin>
<groupId>sonia.maven</groupId>
<artifactId>web-compressor</artifactId>
<version>1.0-SNAPSHOT</version>
<executions>
<execution>
<phase>compile</phase>
<goals>
<goal>compress-directory</goal>
</goals>
</execution>
</executions>
<configuration>
<replace>true</replace>
<baseDirectory>${project.build.directory}/classes</baseDirectory>
</configuration>
</plugin>
</plugins>
</build>
</profile>
</profiles>
</project>

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm-plugins</artifactId>
<groupId>sonia.scm.plugins</groupId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-activedirectory-auth-plugin</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<name>scm-activedirectory-auth-plugin</name>
<url>https://bitbucket.org/sdorra/scm-manager</url>
<description>
@@ -32,7 +32,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</dependency>
<dependency>

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm-plugins</artifactId>
<groupId>sonia.scm.plugins</groupId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-bzr-plugin</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<name>scm-bzr-plugin</name>
<url>https://bitbucket.org/sdorra/scm-manager</url>
<description>Plugin for the version control system Bazaar</description>

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm-plugins</artifactId>
<groupId>sonia.scm.plugins</groupId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-git-plugin</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<name>scm-git-plugin</name>
<url>https://bitbucket.org/sdorra/scm-manager</url>
<description>Plugin for the version control system Git</description>
@@ -50,7 +50,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-test</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<scope>test</scope>
</dependency>

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm-plugins</artifactId>
<groupId>sonia.scm.plugins</groupId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-graph-plugin</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<name>scm-graph-plugin</name>
<description>Creates an Google Guice injection graph</description>
<url>https://bitbucket.org/sdorra/scm-manager</url>

View File

@@ -7,12 +7,12 @@
<parent>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-plugins</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-hg-plugin</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<name>scm-hg-plugin</name>
<url>https://bitbucket.org/sdorra/scm-manager</url>
<description>Plugin for the version control system Mercurial</description>
@@ -37,7 +37,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-test</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<scope>test</scope>
</dependency>

View File

@@ -29,27 +29,20 @@
*
*/
package sonia.scm.installer;
//~--- non-JDK imports --------------------------------------------------------
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.io.Command;
import sonia.scm.io.CommandResult;
import sonia.scm.io.SimpleCommand;
import sonia.scm.repository.HgConfig;
import sonia.scm.repository.HgRepositoryHandler;
import sonia.scm.util.IOUtil;
import sonia.scm.util.SystemUtil;
//~--- JDK imports ------------------------------------------------------------
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
/**
*
@@ -61,10 +54,6 @@ public abstract class AbstractHgInstaller implements HgInstaller
/** Field description */
public static final String DIRECTORY_REPOSITORY = "repositories";
/** the logger for AbstractHgInstaller */
private static final Logger logger = LoggerFactory
.getLogger(AbstractHgInstaller.class);
//~--- constructors ---------------------------------------------------------
/**
@@ -91,104 +80,15 @@ public abstract class AbstractHgInstaller implements HgInstaller
@Override
public void install(HgConfig config) throws IOException
{
File repoDirectory = new File(baseDirectory, DIRECTORY_REPOSITORY.concat(
File.separator).concat(HgRepositoryHandler.TYPE_NAME));
File repoDirectory = new File(
baseDirectory,
DIRECTORY_REPOSITORY.concat(File.separator).concat(
HgRepositoryHandler.TYPE_NAME));
IOUtil.mkdirs(repoDirectory);
config.setRepositoryDirectory(repoDirectory);
}
/**
* TODO check for windows
*
*
*
* @param path
* @param cmd
*
* @return
*/
protected String search(String[] path, String cmd)
{
String cmdPath = null;
try
{
Command command = new SimpleCommand(cmd, "--version");
CommandResult result = command.execute();
if (result.isSuccessfull())
{
cmdPath = cmd;
}
}
catch (IOException ex)
{}
if (cmdPath == null)
{
for (String pathPart : path)
{
List<String> extensions = getExecutableSearchExtensions();
File file = findFileByExtension(pathPart, cmd, extensions);
if (file != null)
{
cmdPath = file.getAbsolutePath();
break;
}
}
}
if (cmdPath != null)
{
if (logger.isInfoEnabled())
{
logger.info("found {} at {}", cmd, cmdPath);
}
}
else if (logger.isWarnEnabled())
{
logger.warn("could not find {}", cmd);
}
return cmdPath;
}
/**
* Returns a list of file extensions to use when searching for executables.
* The list is in priority order, with the highest priority first.
*/
protected List<String> getExecutableSearchExtensions()
{
List<String> extensions;
if (SystemUtil.isWindows())
{
extensions = Arrays.asList(".exe");
}
else
{
extensions = Arrays.asList("");
}
return extensions;
}
private File findFileByExtension(String parentPath, String cmd,
List<String> potentialExtensions)
{
File file = null;
for (String potentialExtension : potentialExtensions)
{
String fileName = cmd.concat(potentialExtension);
File potentialFile = new File(parentPath, fileName);
if (potentialFile.exists())
{
file = potentialFile;
break;
}
}
return file;
}
//~--- fields ---------------------------------------------------------------
/** Field description */

View File

@@ -35,10 +35,8 @@ package sonia.scm.installer;
//~--- non-JDK imports --------------------------------------------------------
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.repository.HgConfig;
import sonia.scm.util.IOUtil;
//~--- JDK imports ------------------------------------------------------------
@@ -52,29 +50,6 @@ import java.io.IOException;
public class UnixHgInstaller extends AbstractHgInstaller
{
/** Field description */
private static final String[] PATH = new String[]
{
// default path
"/usr/bin",
// manually installed
"/usr/local/bin",
// mac ports
"/opt/local/bin",
// opencsw
"/opt/csw/bin"
};
/** the logger for UnixHgInstaller */
private static final Logger logger =
LoggerFactory.getLogger(UnixHgInstaller.class);
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
@@ -100,8 +75,8 @@ public class UnixHgInstaller extends AbstractHgInstaller
public void install(HgConfig config) throws IOException
{
super.install(config);
config.setHgBinary(search(PATH, "hg"));
config.setPythonBinary(search(PATH, "python"));
config.setHgBinary(IOUtil.search("hg"));
config.setPythonBinary(IOUtil.search("python"));
}
/**

View File

@@ -29,6 +29,8 @@
*
*/
package sonia.scm.installer;
//~--- non-JDK imports --------------------------------------------------------
@@ -36,10 +38,9 @@ package sonia.scm.installer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.io.SimpleCommand;
import sonia.scm.io.SimpleCommandResult;
import sonia.scm.repository.HgConfig;
import sonia.scm.util.IOUtil;
import sonia.scm.util.RegistryUtil;
import sonia.scm.util.Util;
//~--- JDK imports ------------------------------------------------------------
@@ -48,8 +49,6 @@ import java.io.File;
import java.io.FilenameFilter;
import java.io.IOException;
import java.util.Scanner;
/**
*
* @author Sebastian Sdorra
@@ -60,20 +59,21 @@ public class WindowsHgInstaller extends AbstractHgInstaller
/** Field description */
private static final String FILE_LIBRARY_ZIP = "library.zip";
/** Field description */
private static final String FILE_LIB_MERCURIAL =
"Lib\\site-packages\\mercurial";
/** Field description */
private static final String FILE_MERCURIAL_EXE = "hg.exe";
/** Field description */
private static final String FILE_MERCURIAL_SCRIPT = "hg.bat";
/** Field description */
private static final String FILE_TEMPLATES = "templates";
/** Field description */
private static final String FILE_SCRIPTS = "Scripts";
/** Field description */
private static final String FILE_LIB_MERCURIAL = "Lib\\site-packages\\mercurial";
private static final String FILE_TEMPLATES = "templates";
/** Field description */
private static final String[] REGISTRY_HG = new String[]
@@ -87,11 +87,12 @@ public class WindowsHgInstaller extends AbstractHgInstaller
};
/** Field description */
private static final String REGISTRY_PYTHON = "HKEY_CLASSES_ROOT\\Python.File\\shell\\open\\command";
private static final String REGISTRY_PYTHON =
"HKEY_CLASSES_ROOT\\Python.File\\shell\\open\\command";
/** the logger for WindowsHgInstaller */
private static final Logger logger = LoggerFactory
.getLogger(WindowsHgInstaller.class);
private static final Logger logger =
LoggerFactory.getLogger(WindowsHgInstaller.class);
//~--- constructors ---------------------------------------------------------
@@ -122,10 +123,12 @@ public class WindowsHgInstaller extends AbstractHgInstaller
super.install(config);
String pythonBinary = getPythonBinary();
config.setPythonBinary(pythonBinary);
File hgScript = getMercurialScript(pythonBinary);
File hgDirectory = getMercurialDirectory();
if (hgScript != null)
{
config.setHgBinary(hgScript.getAbsolutePath());
@@ -145,8 +148,7 @@ public class WindowsHgInstaller extends AbstractHgInstaller
* @param config
*/
@Override
public void update(HgConfig config)
{}
public void update(HgConfig config) {}
/**
* Method description
@@ -233,8 +235,8 @@ public class WindowsHgInstaller extends AbstractHgInstaller
IOUtil.copy(templateDirectory, new File(libDir, FILE_TEMPLATES));
}
config.setHgBinary(new File(hgDirectory, FILE_MERCURIAL_EXE)
.getAbsolutePath());
config.setHgBinary(new File(hgDirectory,
FILE_MERCURIAL_EXE).getAbsolutePath());
}
//~--- get methods ----------------------------------------------------------
@@ -251,7 +253,7 @@ public class WindowsHgInstaller extends AbstractHgInstaller
for (String registryKey : REGISTRY_HG)
{
String path = getRegistryValue(registryKey, null, null);
String path = RegistryUtil.getRegistryValue(registryKey);
if (path != null)
{
@@ -275,6 +277,10 @@ public class WindowsHgInstaller extends AbstractHgInstaller
* Returns the location of the script to run Mercurial, if Mercurial is
* installed as a Python package from source. Only packages that include a
* templates directory will be recognized.
*
* @param pythonBinary
*
* @return
*/
private File getMercurialScript(String pythonBinary)
{
@@ -283,6 +289,7 @@ public class WindowsHgInstaller extends AbstractHgInstaller
if (pythonBinary != null)
{
File pythonBinaryFile = new File(pythonBinary);
if (pythonBinaryFile.exists())
{
File pythonDir = pythonBinaryFile.getParentFile();
@@ -290,10 +297,14 @@ public class WindowsHgInstaller extends AbstractHgInstaller
File potentialHgScript = new File(scriptsDir, FILE_MERCURIAL_SCRIPT);
File mercurialPackageDir = new File(pythonDir, FILE_LIB_MERCURIAL);
File templatesDir = new File(mercurialPackageDir, FILE_TEMPLATES);
if (potentialHgScript.exists() && templatesDir.exists())
{
hgScript = potentialHgScript;
}
}
}
return hgScript;
}
@@ -305,80 +316,13 @@ public class WindowsHgInstaller extends AbstractHgInstaller
*/
private String getPythonBinary()
{
String python = getRegistryValue(REGISTRY_PYTHON, null, null);
String python = RegistryUtil.getRegistryValue(REGISTRY_PYTHON);
if (python == null)
{
python = search(new String[0], "python");
python = IOUtil.search(new String[0], "python");
}
return python;
}
/**
* Method description
*
*
* @param key
* @param subKey
* @param defaultValue
*
* @return
*/
private String getRegistryValue(String key, String subKey, String defaultValue)
{
String programDirectory = defaultValue;
SimpleCommand command = null;
if (subKey != null)
{
command = new SimpleCommand("reg", "query", key, "/v", subKey);
}
else
{
command = new SimpleCommand("reg", "query", key);
}
try
{
SimpleCommandResult result = command.execute();
if (result.isSuccessfull())
{
String output = result.getOutput();
Scanner scanner = new Scanner(output);
while (scanner.hasNextLine())
{
String line = scanner.nextLine();
int index = line.indexOf("REG_SZ");
if (index > 0)
{
programDirectory = line.substring(index + "REG_SZ".length()).trim();
if (programDirectory.startsWith("\""))
{
programDirectory = programDirectory.substring(1);
programDirectory = programDirectory.substring(0, programDirectory
.indexOf("\""));
}
if (logger.isDebugEnabled())
{
logger.debug("use program directory {}", programDirectory);
}
break;
}
}
}
}
catch (IOException ex)
{
logger.error(ex.getMessage(), ex);
}
return programDirectory;
}
}

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm-plugins</artifactId>
<groupId>sonia.scm.plugins</groupId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-pam-plugin</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<name>scm-pam-plugin</name>
<url>https://bitbucket.org/sdorra/scm-manager</url>
<description>Using pam as an authentication handler.</description>

View File

@@ -7,22 +7,29 @@
<parent>
<artifactId>scm-plugins</artifactId>
<groupId>sonia.scm.plugins</groupId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-svn-plugin</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<name>scm-svn-plugin</name>
<url>https://bitbucket.org/sdorra/scm-manager</url>
<description>Plugin for the version control system Subversion</description>
<dependencies>
<dependency>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.tmatesoft.svnkit</groupId>
<artifactId>svnkit</artifactId>
<version>${svnkit.version}</version>
<artifactId>svnkit-dav</artifactId>
<version>${svnkit-dav.version}</version>
<exclusions>
<exclusion>
<artifactId>trilead-ssh2</artifactId>
@@ -35,25 +42,19 @@
</exclusions>
</dependency>
<dependency>
<groupId>org.tmatesoft.svnkit</groupId>
<artifactId>svnkit-dav</artifactId>
<version>${svnkit.version}</version>
</dependency>
<!-- test scope -->
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-test</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<scope>test</scope>
</dependency>
</dependencies>
<properties>
<svnkit.version>1.3.4</svnkit.version>
<svnkit-dav.version>1.3.5.1</svnkit-dav.version>
</properties>
</project>

View File

@@ -6,7 +6,7 @@
<groupId>sonia.scm</groupId>
<artifactId>scm</artifactId>
<packaging>pom</packaging>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<name>scm</name>
<url>http://bitbucket.org/sdorra/scm-manager</url>
@@ -277,7 +277,7 @@
<slf4j.version>1.6.1</slf4j.version>
<servlet.version>2.5</servlet.version>
<guice.version>2.0</guice.version>
<jersey.version>1.5-ea08</jersey.version>
<jersey.version>1.5</jersey.version>
<ehcache.version>2.3.1</ehcache.version>
<project.build.javaLevel>1.6</project.build.javaLevel>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

View File

@@ -6,13 +6,13 @@
<parent>
<groupId>sonia.scm</groupId>
<artifactId>scm</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.samples</groupId>
<artifactId>scm-samples</artifactId>
<packaging>pom</packaging>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<name>scm-samples</name>
<modules>

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm-samples</artifactId>
<groupId>sonia.scm.samples</groupId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.sample</groupId>
<artifactId>scm-sample-auth</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<name>scm-sample-auth</name>
<description>Sample Authentication Plugin</description>
<url>https://bitbucket.org/sdorra/scm-manager</url>
@@ -29,7 +29,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</dependency>
</dependencies>

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm-samples</artifactId>
<groupId>sonia.scm.samples</groupId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.sample</groupId>
<artifactId>scm-sample-hello</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<name>scm-sample-hello</name>
<description>A simple hello world plugin</description>
<url>https://bitbucket.org/sdorra/scm-manager</url>
@@ -29,7 +29,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</dependency>
</dependencies>

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm</artifactId>
<groupId>sonia.scm</groupId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</parent>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<name>scm-core</name>
<dependencies>

View File

@@ -0,0 +1,75 @@
/**
* 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.resources;
//~--- non-JDK imports --------------------------------------------------------
import sonia.scm.plugin.ExtensionPoint;
//~--- JDK imports ------------------------------------------------------------
import java.io.InputStream;
/**
*
* @author Sebastian Sdorra
*/
@ExtensionPoint
public interface ResourceHandler
{
/**
* Method description
*
*
* @return
*/
public String getName();
/**
* Method description
*
*
* @return
*/
public InputStream getResource();
/**
* Method description
*
*
* @return
*/
public ResourceType getType();
}

View File

@@ -0,0 +1,65 @@
/**
* 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.resources;
//~--- non-JDK imports --------------------------------------------------------
import sonia.scm.util.Util;
//~--- JDK imports ------------------------------------------------------------
import java.util.Comparator;
/**
*
* @author Sebastian Sdorra
*/
public class ResourceHandlerComparator implements Comparator<ResourceHandler>
{
/**
* Method description
*
*
* @param handler
* @param otherHandler
*
* @return
*/
@Override
public int compare(ResourceHandler handler, ResourceHandler otherHandler)
{
return Util.compare(handler.getName(), otherHandler.getName());
}
}

View File

@@ -0,0 +1,40 @@
/**
* 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.resources;
/**
*
* @author Sebastian Sdorra
*/
public enum ResourceType { SCRIPT, STYLESHEET }

View File

@@ -131,15 +131,64 @@ public class User
*
*
* @param user
*
* @return
*/
public void copyProperties(User user)
public boolean copyProperties(User user)
{
user.setAdmin(admin);
user.setDisplayName(displayName);
user.setMail(mail);
user.setName(name);
user.setPassword(password);
user.setType(type);
return copyProperties(user, true);
}
/**
* Method description
*
*
* @param user
* @param copyPassword
*
* @return
*/
public boolean copyProperties(User user, boolean copyPassword)
{
boolean result = false;
if (user.isAdmin() != admin)
{
result = true;
user.setAdmin(admin);
}
if (Util.isNotEquals(user.getDisplayName(), displayName))
{
result = true;
user.setDisplayName(displayName);
}
if (Util.isNotEquals(user.getMail(), mail))
{
result = true;
user.setMail(mail);
}
if (Util.isNotEquals(user.getName(), name))
{
result = true;
user.setName(name);
}
if (copyPassword && Util.isNotEquals(user.getPassword(), password))
{
result = true;
user.setPassword(password);
}
if (Util.isNotEquals(user.getType(), type))
{
result = true;
user.setType(type);
}
return result;
}
/**
@@ -263,9 +312,9 @@ public class User
*
* @return
*/
public long getLastLogin()
public Long getLastModified()
{
return lastLogin;
return lastModified;
}
/**
@@ -378,11 +427,11 @@ public class User
* Method description
*
*
* @param lastLogin
* @param lastModified
*/
public void setLastLogin(long lastLogin)
public void setLastModified(long lastModified)
{
this.lastLogin = lastLogin;
this.lastModified = lastModified;
}
/**
@@ -444,7 +493,7 @@ public class User
/** Field description */
@XmlJavaTypeAdapter(XmlTimestampDateAdapter.class)
private Long lastLogin;
private Long lastModified;
/** Field description */
private String mail;

View File

@@ -38,6 +38,9 @@ package sonia.scm.util;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.io.Command;
import sonia.scm.io.CommandResult;
import sonia.scm.io.SimpleCommand;
import sonia.scm.io.ZipUnArchiver;
//~--- JDK imports ------------------------------------------------------------
@@ -52,6 +55,9 @@ import java.io.OutputStream;
import java.io.Reader;
import java.io.Writer;
import java.util.Arrays;
import java.util.List;
/**
*
* @author Sebastian Sdorra
@@ -59,6 +65,26 @@ import java.io.Writer;
public class IOUtil
{
/** Field description */
public static final String DEFAULT_CHECKPARAMETER = "--version";
/** Field description */
public static final String[] DEFAULT_PATH = new String[]
{
// default path
"/usr/bin",
// manually installed
"/usr/local/bin",
// mac ports
"/opt/local/bin",
// opencsw
"/opt/csw/bin"
};
/** Field description */
private static final Logger logger =
LoggerFactory.getLogger(IOUtil.class.getName());
@@ -260,6 +286,144 @@ public class IOUtil
}
}
/**
*
*
* @param cmd
*
* @return
*/
public static String search(String cmd)
{
return search(DEFAULT_PATH, cmd, DEFAULT_CHECKPARAMETER);
}
/**
*
*
* @param path
* @param cmd
*
* @return
*/
public static String search(String[] path, String cmd)
{
return search(path, cmd, DEFAULT_CHECKPARAMETER);
}
/**
* TODO check for windows
*
*
*
* @param path
* @param cmd
* @param checkParameter
*
* @return
*/
public static String search(String[] path, String cmd, String checkParameter)
{
String cmdPath = null;
try
{
Command command = new SimpleCommand(cmd, checkParameter);
CommandResult result = command.execute();
if (result.isSuccessfull())
{
cmdPath = cmd;
}
}
catch (IOException ex) {}
if (cmdPath == null)
{
for (String pathPart : path)
{
List<String> extensions = getExecutableSearchExtensions();
File file = findFileByExtension(pathPart, cmd, extensions);
if (file != null)
{
cmdPath = file.getAbsolutePath();
break;
}
}
}
if (cmdPath != null)
{
if (logger.isInfoEnabled())
{
logger.info("found {} at {}", cmd, cmdPath);
}
}
else if (logger.isWarnEnabled())
{
logger.warn("could not find {}", cmd);
}
return cmdPath;
}
/**
* Method description
*
*
* @param parentPath
* @param cmd
* @param potentialExtensions
*
* @return
*/
private static File findFileByExtension(String parentPath, String cmd,
List<String> potentialExtensions)
{
File file = null;
for (String potentialExtension : potentialExtensions)
{
String fileName = cmd.concat(potentialExtension);
File potentialFile = new File(parentPath, fileName);
if (potentialFile.exists())
{
file = potentialFile;
break;
}
}
return file;
}
//~--- get methods ----------------------------------------------------------
/**
* Returns a list of file extensions to use when searching for executables.
* The list is in priority order, with the highest priority first.
*
* @return
*/
private static List<String> getExecutableSearchExtensions()
{
List<String> extensions;
if (SystemUtil.isWindows())
{
extensions = Arrays.asList(".exe");
}
else
{
extensions = Arrays.asList("");
}
return extensions;
}
//~--- inner classes --------------------------------------------------------
/**

View File

@@ -0,0 +1,156 @@
/**
* 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.util;
//~--- non-JDK imports --------------------------------------------------------
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.io.SimpleCommand;
import sonia.scm.io.SimpleCommandResult;
//~--- JDK imports ------------------------------------------------------------
import java.io.IOException;
import java.util.Scanner;
/**
*
* @author Sebastian Sdorra
*/
public class RegistryUtil
{
/** the logger for RegistryUtil */
private static final Logger logger =
LoggerFactory.getLogger(RegistryUtil.class);
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @param key
*
* @return
*/
public static String getRegistryValue(String key)
{
return getRegistryValue(key, null, null);
}
/**
* Method description
*
*
* @param key
* @param defaultValue
*
* @return
*/
public static String getRegistryValue(String key, String defaultValue)
{
return getRegistryValue(key, null, defaultValue);
}
/**
* Method description
*
*
* @param key
* @param subKey
* @param defaultValue
*
* @return
*/
public static String getRegistryValue(String key, String subKey,
String defaultValue)
{
String value = defaultValue;
SimpleCommand command = null;
if (subKey != null)
{
command = new SimpleCommand("reg", "query", key, "/v", subKey);
}
else
{
command = new SimpleCommand("reg", "query", key);
}
try
{
SimpleCommandResult result = command.execute();
if (result.isSuccessfull())
{
String output = result.getOutput();
Scanner scanner = new Scanner(output);
while (scanner.hasNextLine())
{
String line = scanner.nextLine();
int index = line.indexOf("REG_SZ");
if (index > 0)
{
value = line.substring(index + "REG_SZ".length()).trim();
if (value.startsWith("\""))
{
value = value.substring(1);
value = value.substring(0, value.indexOf("\""));
}
if (logger.isDebugEnabled())
{
logger.debug("registry value {} at {}", value, key);
}
break;
}
}
}
}
catch (IOException ex)
{
logger.error(ex.getMessage(), ex);
}
return value;
}
}

View File

@@ -54,6 +54,36 @@ public class Util
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param object
* @param otherObject
* @param <T>
*
* @return
*/
public static <T extends Comparable> int compare(T object, T otherObject)
{
int result = 0;
if ((object != null) && (otherObject != null))
{
result = object.compareTo(otherObject);
}
else if ((object == null) && (otherObject != null))
{
result = 1;
}
else if ((object != null) && (otherObject == null))
{
result = -1;
}
return result;
}
/**
* Method description
*
@@ -142,6 +172,33 @@ public class Util
return parseDate(dateString, null);
}
/**
* Method description
*
*
* @param byteValue
*
* @return
*/
public static String toString(byte[] byteValue)
{
StringBuilder buffer = new StringBuilder();
for (int i = 0; i < byteValue.length; i++)
{
int x = byteValue[i] & 0xff;
if (x < 16)
{
buffer.append('0');
}
buffer.append(Integer.toString(x, 16));
}
return buffer.toString();
}
//~--- get methods ----------------------------------------------------------
/**
@@ -183,6 +240,22 @@ public class Util
return (array == null) || (array.length == 0);
}
/**
* Method description
*
*
* @param object
* @param other
*
* @return
*/
public static boolean isEquals(Object object, Object other)
{
return (object == null)
? other == null
: object.equals(other);
}
/**
* Method description
*
@@ -222,32 +295,17 @@ public class Util
return (array != null) && (array.length > 0);
}
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param byteValue
* @param object
* @param other
*
* @return
*/
public static String toString(byte[] byteValue)
public static boolean isNotEquals(Object object, Object other)
{
StringBuilder buffer = new StringBuilder();
for (int i = 0; i < byteValue.length; i++)
{
int x = byteValue[i] & 0xff;
if (x < 16)
{
buffer.append('0');
}
buffer.append(Integer.toString(x, 16));
}
return buffer.toString();
return !isEquals(object, other);
}
}

View File

@@ -186,8 +186,35 @@ public class AuthenticationResult
return user;
}
/**
* Method description
*
*
* @return
*/
public boolean isCacheable()
{
return cacheable;
}
//~--- set methods ----------------------------------------------------------
/**
* Method description
*
*
* @param cacheable
*/
public void setCacheable(boolean cacheable)
{
this.cacheable = cacheable;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private boolean cacheable = true;
/** Field description */
private Collection<String> groups;

View File

@@ -0,0 +1,141 @@
/**
* 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.resources;
//~--- non-JDK imports --------------------------------------------------------
import org.junit.Test;
import static org.junit.Assert.*;
//~--- JDK imports ------------------------------------------------------------
import java.io.InputStream;
import java.util.Arrays;
/**
*
* @author Sebastian Sdorra
*/
public class ResourceHandlerComparatorTest
{
/**
* Method description
*
*/
@Test
public void testCompare()
{
ResourceHandler[] handlers = new ResourceHandler[4];
handlers[0] = new DummyResourceHandler("xyz");
handlers[1] = new DummyResourceHandler("abc");
handlers[2] = new DummyResourceHandler(null);
handlers[3] = new DummyResourceHandler("mno");
Arrays.sort(handlers, new ResourceHandlerComparator());
assertEquals("abc", handlers[0].getName());
assertEquals("mno", handlers[1].getName());
assertEquals("xyz", handlers[2].getName());
assertEquals(null, handlers[3].getName());
}
//~--- inner classes --------------------------------------------------------
/**
* Class description
*
*
* @version Enter version here..., 2011-01-18
* @author Sebastian Sdorra
*/
private static class DummyResourceHandler implements ResourceHandler
{
/**
* Constructs ...
*
*
* @param name
*/
public DummyResourceHandler(String name)
{
this.name = name;
}
//~--- get methods --------------------------------------------------------
/**
* Method description
*
*
* @return
*/
@Override
public String getName()
{
return name;
}
/**
* Method description
*
*
* @return
*/
@Override
public InputStream getResource()
{
throw new UnsupportedOperationException("Not supported yet.");
}
/**
* Method description
*
*
* @return
*/
@Override
public ResourceType getType()
{
throw new UnsupportedOperationException("Not supported yet.");
}
//~--- fields -------------------------------------------------------------
/** Field description */
private String name;
}
}

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm</artifactId>
<groupId>sonia.scm</groupId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</parent>
<groupId>sonia.scm</groupId>
<artifactId>scm-server-api</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<name>scm-server-api</name>
<dependencies>
@@ -20,7 +20,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</dependency>
</dependencies>

View File

@@ -29,6 +29,8 @@
*
*/
package sonia.scm.server;
//~--- non-JDK imports --------------------------------------------------------
@@ -39,6 +41,7 @@ import org.slf4j.LoggerFactory;
import sonia.scm.cli.CliException;
import sonia.scm.cli.CliParser;
import sonia.scm.cli.DefaultCliHelpBuilder;
import sonia.scm.util.IOUtil;
import sonia.scm.util.ServiceUtil;
//~--- JDK imports ------------------------------------------------------------
@@ -68,10 +71,51 @@ public class ServerApplication
/** Field description */
public static final int RETURNCODE_MISSING_SERVER_IMPLEMENTATION = 3;
/** Field description */
public static final String SERVERCONFIG = "/config.xml";
/** Field description */
private static final Logger logger =
LoggerFactory.getLogger(ServerApplication.class.getName());
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
private static ServerConfig getServerConfig()
{
ServerConfig config = null;
InputStream input =
ServerApplication.class.getResourceAsStream(SERVERCONFIG);
if (input != null)
{
try
{
config = JAXB.unmarshal(input, ServerConfig.class);
}
catch (Exception ex)
{
logger.error(ex.getMessage(), ex);
}
finally
{
IOUtil.close(input);
}
}
if (config == null)
{
config = new ServerConfig();
}
return config;
}
//~--- methods --------------------------------------------------------------
/**
@@ -97,10 +141,10 @@ public class ServerApplication
ApplicationInformation appInfo = JAXB.unmarshal(input,
ApplicationInformation.class);
ServerConfig config = new ServerConfig();
ServerConfig config = getServerConfig();
CliParser parser = new CliParser();
parser.parse(parser, args);
parser.parse(config, args);
if (config.getShowHelp())
{

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm</artifactId>
<groupId>sonia.scm</groupId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</parent>
<groupId>sonia.scm</groupId>
<artifactId>scm-server-jetty</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<name>scm-server-jetty</name>
<dependencies>
@@ -20,7 +20,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-server-api</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</dependency>
<dependency>

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm</artifactId>
<groupId>sonia.scm</groupId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</parent>
<groupId>sonia.scm</groupId>
<artifactId>scm-server</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<name>scm-server</name>
<packaging>pom</packaging>
@@ -21,19 +21,19 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-server-api</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-server-jetty</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</dependency>
</dependencies>

View File

@@ -7,12 +7,12 @@
<parent>
<artifactId>scm</artifactId>
<groupId>sonia.scm</groupId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</parent>
<groupId>sonia.scm</groupId>
<artifactId>scm-test</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<name>scm-test</name>
<dependencies>
@@ -26,7 +26,7 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</dependency>
<dependency>

View File

@@ -7,13 +7,13 @@
<parent>
<groupId>sonia.scm</groupId>
<artifactId>scm</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</parent>
<groupId>sonia.scm</groupId>
<artifactId>scm-webapp</artifactId>
<packaging>war</packaging>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<name>scm-webapp</name>
<dependencies>
@@ -28,25 +28,25 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-core</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-hg-plugin</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-svn-plugin</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-git-plugin</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</dependency>
<dependency>
@@ -84,15 +84,9 @@
</dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
<version>${slf4j.version}</version>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
<version>1.2.16</version>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>0.9.27</version>
</dependency>
<dependency>
@@ -131,6 +125,12 @@
<groupId>org.sonatype.aether</groupId>
<artifactId>aether-connector-wagon</artifactId>
<version>${aether.version}</version>
<exclusions>
<exclusion>
<artifactId>xbean-reflect</artifactId>
<groupId>org.apache.xbean</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
@@ -164,8 +164,14 @@
<dependency>
<groupId>sonia.scm</groupId>
<artifactId>scm-test</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-simple</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
@@ -226,7 +232,7 @@
<properties>
<aether.version>1.9</aether.version>
<wagon.version>1.0-beta-7</wagon.version>
<maven.version>3.0.1</maven.version>
<maven.version>3.0.2</maven.version>
</properties>
<profiles>
@@ -266,7 +272,6 @@
<configuration>
<source>src/main/webapp/index.html</source>
<target>${project.build.directory}/web-compressor/index.html</target>
<compressCSS>false</compressCSS>
</configuration>
</plugin>
@@ -282,37 +287,37 @@
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-graph-plugin</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm.sample</groupId>
<artifactId>scm-sample-auth</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm.sample</groupId>
<artifactId>scm-sample-hello</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-activedirectory-auth-plugin</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-pam-plugin</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</dependency>
<dependency>
<groupId>sonia.scm.plugins</groupId>
<artifactId>scm-bzr-plugin</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</dependency>
<dependency>

View File

@@ -47,6 +47,7 @@ import sonia.scm.plugin.ext.Extension;
import sonia.scm.plugin.ext.ExtensionProcessor;
import sonia.scm.repository.RepositoryHandler;
import sonia.scm.repository.RepositoryListener;
import sonia.scm.resources.ResourceHandler;
import sonia.scm.security.EncryptionHandler;
import sonia.scm.user.UserListener;
import sonia.scm.web.security.AuthenticationHandler;
@@ -97,6 +98,8 @@ public class BindingExtensionProcessor implements ExtensionProcessor
Multibinder.newSetBinder(binder, RepositoryHandler.class);
Multibinder<AuthenticationHandler> authenticators =
Multibinder.newSetBinder(binder, AuthenticationHandler.class);
Multibinder<ResourceHandler> resourceHandler =
Multibinder.newSetBinder(binder, ResourceHandler.class);
authenticators.addBinding().to(XmlAuthenticationHandler.class);
@@ -176,6 +179,15 @@ public class BindingExtensionProcessor implements ExtensionProcessor
authenticationListeners.add(listener);
}
else if (ResourceHandler.class.isAssignableFrom(extensionClass))
{
if (logger.isInfoEnabled())
{
logger.info("bind ResourceHandler {}", extensionClass.getName());
}
resourceHandler.addBinding().to(extensionClass);
}
else
{
if (logger.isInfoEnabled())

View File

@@ -116,6 +116,10 @@ public class ScmServletModule extends ServletModule
/** Field description */
public static final String PATTERN_STYLESHEET = "*.css";
/** Field description */
public static final String RESOURCE_REGEX =
"^/(?:resources|api|plugins|index)[\\./].*(?:html|\\.css|\\.js|\\.xml|\\.json|\\.txt)";
/** Field description */
public static final String REST_PACKAGE = "sonia.scm.api.rest";
@@ -192,7 +196,7 @@ public class ScmServletModule extends ServletModule
* PATTERN_STATIC_RESOURCES).through(StaticResourceFilter.class);
*/
filter(PATTERN_ALL).through(SSLFilter.class);
filter(PATTERN_PAGE, PATTERN_COMPRESSABLE).through(GZipFilter.class);
filterRegex(RESOURCE_REGEX).through(GZipFilter.class);
filter(PATTERN_RESTAPI, PATTERN_DEBUG).through(SecurityFilter.class);
// debug servlet

View File

@@ -41,6 +41,7 @@ import com.google.inject.Singleton;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.SCMContext;
import sonia.scm.ScmState;
import sonia.scm.Type;
import sonia.scm.repository.RepositoryManager;
@@ -78,6 +79,40 @@ public class AuthenticationResource
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param request
* @param response
* @param username
* @param password
*
* @return
*/
@POST
@Path("login")
public ScmState authenticate(@Context HttpServletRequest request,
@Context HttpServletResponse response,
@FormParam("username") String username,
@FormParam("password") String password)
{
ScmState state = null;
User user = securityContext.authenticate(request, response, username,
password);
if ((user != null) &&!SCMContext.USER_ANONYMOUS.equals(user.getName()))
{
state = new ScmState(securityContext, repositoryManger.getTypes());
}
else
{
throw new WebApplicationException(Response.Status.UNAUTHORIZED);
}
return state;
}
/**
* Method description
*
@@ -112,40 +147,6 @@ public class AuthenticationResource
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @param request
* @param response
* @param username
* @param password
*
* @return
*/
@POST
@Path("login")
public ScmState getState(@Context HttpServletRequest request,
@Context HttpServletResponse response,
@FormParam("username") String username,
@FormParam("password") String password)
{
ScmState state = null;
User user = securityContext.authenticate(request, response, username,
password);
if (user != null)
{
state = new ScmState(securityContext, repositoryManger.getTypes());
}
else
{
throw new WebApplicationException(Response.Status.UNAUTHORIZED);
}
return state;
}
/**
* Method description
*

View File

@@ -39,6 +39,9 @@ import com.google.inject.Inject;
import com.google.inject.Singleton;
import sonia.scm.boot.BootstrapUtil;
import sonia.scm.resources.ResourceHandler;
import sonia.scm.resources.ResourceHandlerComparator;
import sonia.scm.resources.ResourceType;
import sonia.scm.util.IOUtil;
import sonia.scm.util.Util;
@@ -48,7 +51,10 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import java.util.TreeSet;
@@ -75,11 +81,14 @@ public class ScriptResourceServlet extends AbstractResourceServlet
*
*
* @param pluginLoader
* @param resourceHandlers
*/
@Inject
public ScriptResourceServlet(PluginLoader pluginLoader)
public ScriptResourceServlet(PluginLoader pluginLoader,
Set<ResourceHandler> resourceHandlers)
{
this.pluginLoader = pluginLoader;
this.resourceHandlers = resourceHandlers;
}
//~--- methods --------------------------------------------------------------
@@ -110,6 +119,22 @@ public class ScriptResourceServlet extends AbstractResourceServlet
appendResource(stream, resource);
}
}
if (Util.isNotEmpty(resourceHandlers))
{
List<ResourceHandler> handlerList =
new ArrayList<ResourceHandler>(resourceHandlers);
Collections.sort(handlerList, new ResourceHandlerComparator());
for (ResourceHandler resourceHandler : resourceHandlers)
{
if (resourceHandler.getType() == ResourceType.SCRIPT)
{
appendResource(resourceHandler.getResource(), stream);
}
}
}
}
//~--- get methods ----------------------------------------------------------
@@ -143,6 +168,21 @@ public class ScriptResourceServlet extends AbstractResourceServlet
{
InputStream input = getResourceAsStream(script);
appendResource(input, stream);
}
/**
* Method description
*
*
* @param input
* @param stream
*
* @throws IOException
*/
private void appendResource(InputStream input, OutputStream stream)
throws IOException
{
if (input != null)
{
try
@@ -239,4 +279,7 @@ public class ScriptResourceServlet extends AbstractResourceServlet
/** Field description */
private PluginLoader pluginLoader;
/** Field description */
private Set<ResourceHandler> resourceHandlers;
}

View File

@@ -380,7 +380,7 @@ public class XmlRepositoryManager extends AbstractRepositoryManager
for (Repository repository : repositoryDB.values())
{
if (isReader(repository))
if (handlerMap.containsKey(repository.getType()) && isReader(repository))
{
repositories.add(repository.clone());
}

View File

@@ -273,6 +273,7 @@ public class XmlUserManager extends AbstractUserManager
if (userDB.contains(name))
{
AssertUtil.assertIsValid(user);
user.setLastModified(System.currentTimeMillis());
synchronized (XmlUserManager.class)
{

View File

@@ -124,21 +124,13 @@ public class BasicSecurityContext implements WebSecurityContext
try
{
user.setLastLogin(System.currentTimeMillis());
User dbUser = userManager.get(username);
if (dbUser != null)
if ((dbUser != null) && dbUser.copyProperties(user, false))
{
// update properties
dbUser.setDisplayName(user.getDisplayName());
dbUser.setLastLogin(user.getLastLogin());
dbUser.setMail(user.getMail());
dbUser.setType(user.getType());
userManager.modify(dbUser);
}
else
else if (dbUser == null)
{
userManager.create(user);
}

View File

@@ -42,6 +42,9 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.SCMContextProvider;
import sonia.scm.cache.CacheManager;
import sonia.scm.cache.SimpleCache;
import sonia.scm.security.EncryptionHandler;
import sonia.scm.user.User;
import sonia.scm.util.AssertUtil;
import sonia.scm.util.IOUtil;
@@ -63,6 +66,9 @@ import javax.servlet.http.HttpServletResponse;
public class ChainAuthenticatonManager extends AbstractAuthenticationManager
{
/** Field description */
public static final String CACHE_NAME = "sonia.cache.auth";
/** the logger for ChainAuthenticatonManager */
private static final Logger logger =
LoggerFactory.getLogger(ChainAuthenticatonManager.class);
@@ -74,13 +80,20 @@ public class ChainAuthenticatonManager extends AbstractAuthenticationManager
*
*
* @param authenticationHandlerSet
* @param encryptionHandler
* @param cacheManager
*/
@Inject
public ChainAuthenticatonManager(
Set<AuthenticationHandler> authenticationHandlerSet)
Set<AuthenticationHandler> authenticationHandlerSet,
EncryptionHandler encryptionHandler, CacheManager cacheManager)
{
AssertUtil.assertIsNotEmpty(authenticationHandlerSet);
AssertUtil.assertIsNotNull(cacheManager);
this.authenticationHandlerSet = authenticationHandlerSet;
this.encryptionHandler = encryptionHandler;
this.cache = cacheManager.getSimpleCache(String.class,
AuthenticationCacheValue.class, CACHE_NAME);
}
//~--- methods --------------------------------------------------------------
@@ -99,6 +112,74 @@ public class ChainAuthenticatonManager extends AbstractAuthenticationManager
@Override
public AuthenticationResult authenticate(HttpServletRequest request,
HttpServletResponse response, String username, String password)
{
AssertUtil.assertIsNotEmpty(username);
AssertUtil.assertIsNotEmpty(password);
String encryptedPassword = encryptionHandler.encrypt(password);
AuthenticationResult ar = getCached(username, encryptedPassword);
if (ar == null)
{
ar = doAuthentication(request, response, username, password);
if ((ar != null) && ar.isCacheable())
{
cache.put(username,
new AuthenticationCacheValue(ar, encryptedPassword));
}
}
else if (logger.isDebugEnabled())
{
logger.debug("authenticate {} via cache", username);
}
return ar;
}
/**
* Method description
*
*
* @throws IOException
*/
@Override
public void close() throws IOException
{
for (AuthenticationHandler authenticator : authenticationHandlerSet)
{
IOUtil.close(authenticator);
}
}
/**
* Method description
*
*
* @param context
*/
@Override
public void init(SCMContextProvider context)
{
for (AuthenticationHandler authenticator : authenticationHandlerSet)
{
authenticator.init(context);
}
}
/**
* Method description
*
*
* @param request
* @param response
* @param username
* @param password
*
* @return
*/
private AuthenticationResult doAuthentication(HttpServletRequest request,
HttpServletResponse response, String username, String password)
{
AuthenticationResult ar = null;
@@ -142,38 +223,80 @@ public class ChainAuthenticatonManager extends AbstractAuthenticationManager
return ar;
}
/**
* Method description
*
*
* @throws IOException
*/
@Override
public void close() throws IOException
{
for (AuthenticationHandler authenticator : authenticationHandlerSet)
{
IOUtil.close(authenticator);
}
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @param context
* @param username
* @param encryptedPassword
*
* @return
*/
@Override
public void init(SCMContextProvider context)
private AuthenticationResult getCached(String username,
String encryptedPassword)
{
for (AuthenticationHandler authenticator : authenticationHandlerSet)
AuthenticationResult result = null;
AuthenticationCacheValue value = cache.get(username);
if (value != null)
{
authenticator.init(context);
String cachedPassword = value.password;
if (cachedPassword.equals(encryptedPassword))
{
result = value.authenticationResult;
}
}
return result;
}
//~--- inner classes --------------------------------------------------------
/**
* Class description
*
*
* @version Enter version here..., 2011-01-15
* @author Sebastian Sdorra
*/
private static class AuthenticationCacheValue
{
/**
* Constructs ...
*
*
* @param authenticationResult
* @param password
*/
public AuthenticationCacheValue(AuthenticationResult authenticationResult,
String password)
{
this.authenticationResult = authenticationResult;
this.password = password;
}
//~--- fields -------------------------------------------------------------
/** Field description */
private AuthenticationResult authenticationResult;
/** Field description */
private String password;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private Set<AuthenticationHandler> authenticationHandlerSet;
/** Field description */
private SimpleCache<String, AuthenticationCacheValue> cache;
/** Field description */
private EncryptionHandler encryptionHandler;
}

View File

@@ -97,6 +97,16 @@
diskExpiryThreadIntervalSeconds="2400"
/>
<cache
name="sonia.cache.auth"
maxElementsInMemory="200000"
eternal="false"
overflowToDisk="false"
timeToIdleSeconds="30"
timeToLiveSeconds="60"
diskPersistent="false"
/>
<cache
name="sonia.cache.repository"
maxElementsInMemory="20000"

View File

@@ -1,46 +0,0 @@
#
# 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
#
#
log4j.rootLogger=WARN, SoniaConsole
log4j.category.sonia.scm = DEBUG
log4j.category.sonia.scm.util.ServiceUtil = WARN
log4j.appender.SoniaConsole=org.apache.log4j.ConsoleAppender
log4j.appender.SoniaConsole.layout=org.apache.log4j.PatternLayout
log4j.appender.SoniaConsole.layout.ConversionPattern=%d %-5p [%c] - %m%n
log4j.appender.SoniaFile=org.apache.log4j.RollingFileAppender
log4j.appender.SoniaFile.layout=org.apache.log4j.PatternLayout
log4j.appender.SoniaFile.layout.ConversionPattern=%d %-5p [%c] - %m%n
log4j.appender.SoniaFile.maxFileSize=10MB
log4j.appender.SoniaFile.MaxBackupIndex=20
log4j.appender.SoniaFile.File=/sonia/scm/logs/scm.log

View File

@@ -0,0 +1,28 @@
<?xml version="1.0" encoding="UTF-8"?>
<!--
Document : logback.xml
Created on : January 18, 2011, 5:46 PM
Author : sdorra
Description:
Purpose of the document follows.
-->
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are by default assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger - %msg%n</pattern>
</encoder>
</appender>
<logger name="sonia.scm" level="DEBUG" />
<logger name="sonia.scm.util.ServiceUtil" level="WARN" />
<root level="WARN">
<appender-ref ref="STDOUT" />
</root>
</configuration>

View File

@@ -49,6 +49,7 @@
<script type="text/javascript" src="resources/extjs/adapter/ext/ext-base.js"></script>
<script type="text/javascript" src="resources/extjs/ext-all-debug.js"></script>
<script type="text/javascript" src="resources/extjs/util/CheckColumn.js"></script>
<script type="text/javascript" src="resources/js/sonia.global.js"></script>
<script type="text/javascript" src="resources/js/sonia.navigation.js"></script>

View File

@@ -0,0 +1,71 @@
/*!
* Ext JS Library 3.3.1
* Copyright(c) 2006-2010 Sencha Inc.
* licensing@sencha.com
* http://www.sencha.com/license
*/
Ext.ns('Ext.ux.grid');
/**
* @class Ext.ux.grid.CheckColumn
* @extends Ext.grid.Column
* <p>A Column subclass which renders a checkbox in each column cell which toggles the truthiness of the associated data field on click.</p>
* <p><b>Note. As of ExtJS 3.3 this no longer has to be configured as a plugin of the GridPanel.</b></p>
* <p>Example usage:</p>
* <pre><code>
var cm = new Ext.grid.ColumnModel([{
header: 'Foo',
...
},{
xtype: 'checkcolumn',
header: 'Indoor?',
dataIndex: 'indoor',
width: 55
}
]);
// create the grid
var grid = new Ext.grid.EditorGridPanel({
...
colModel: cm,
...
});
* </code></pre>
* In addition to toggling a Boolean value within the record data, this
* class toggles a css class between <tt>'x-grid3-check-col'</tt> and
* <tt>'x-grid3-check-col-on'</tt> to alter the background image used for
* a column.
*/
Ext.ux.grid.CheckColumn = Ext.extend(Ext.grid.Column, {
/**
* @private
* Process and refire events routed from the GridView's processEvent method.
*/
processEvent : function(name, e, grid, rowIndex, colIndex){
if (name == 'mousedown') {
var record = grid.store.getAt(rowIndex);
record.set(this.dataIndex, !record.data[this.dataIndex]);
return false; // Cancel row selection.
} else {
return Ext.grid.ActionColumn.superclass.processEvent.apply(this, arguments);
}
},
renderer : function(v, p, record){
p.css += ' x-grid3-check-col-td';
return String.format('<div class="x-grid3-check-col{0}">&#160;</div>', v ? '-on' : '');
},
// Deprecate use as a plugin. Remove in 4.0
init: Ext.emptyFn
});
// register ptype. Deprecate. Remove in 4.0
Ext.preg('checkcolumn', Ext.ux.grid.CheckColumn);
// backwards compat. Remove in 4.0
Ext.grid.CheckColumn = Ext.ux.grid.CheckColumn;
// register Column xtype
Ext.grid.Column.types.checkcolumn = Ext.ux.grid.CheckColumn;

View File

@@ -237,6 +237,10 @@ Sonia.group.FormPanel = Ext.extend(Sonia.rest.FormPanel,{
item.members = members;
},
clearModifications: function(){
Ext.getCmp('memberGrid').getStore().commitChanges();
},
update: function(group){
if ( debug ){
console.debug( 'update group ' + group.name );
@@ -258,7 +262,7 @@ Sonia.group.FormPanel = Ext.extend(Sonia.rest.FormPanel,{
if ( debug ){
console.debug('update success');
}
// this.clearModifications();
this.clearModifications();
clearTimeout(tid);
el.unmask();
this.execCallback(this.onUpdate, group);

View File

@@ -226,7 +226,11 @@ Sonia.repository.FormPanel = Ext.extend(Sonia.rest.FormPanel,{
this.permissionStore = new Ext.data.JsonStore({
root: 'permissions',
fields: [ 'name', 'type', 'groupPermission' ],
fields: [
{name: 'name'},
{name: 'type'},
{name: 'groupPermission', type: 'boolean'}
],
sortInfo: {
field: 'name'
}
@@ -237,6 +241,12 @@ Sonia.repository.FormPanel = Ext.extend(Sonia.rest.FormPanel,{
sortable: true
},
columns: [{
id: 'groupPermission',
xtype: 'checkcolumn',
header: 'Group Permission',
dataIndex: 'groupPermission',
width: 40
},{
id: 'name',
header: 'Name',
dataIndex: 'name',
@@ -264,12 +274,6 @@ Sonia.repository.FormPanel = Ext.extend(Sonia.rest.FormPanel,{
]
})
})
},{
id: 'groupPermission',
header: 'Group',
dataIndex: 'groupPermission',
width: 60,
editor: new Ext.form.Checkbox()
}]
});
@@ -323,6 +327,7 @@ Sonia.repository.FormPanel = Ext.extend(Sonia.rest.FormPanel,{
xtype: 'editorgrid',
title: 'Permissions',
clicksToEdit: 1,
autoExpandColumn: 'name',
frame: true,
width: '100%',
autoHeight: true,
@@ -374,7 +379,7 @@ Sonia.repository.FormPanel = Ext.extend(Sonia.rest.FormPanel,{
},
clearModifications: function(){
// todo
Ext.getCmp('permissionGrid').getStore().commitChanges();
},
update: function(item){

View File

@@ -92,13 +92,16 @@ Ext.onReady(function(){
// adds a tab to main TabPanel
function addTabPanel(id, xtype, title){
mainTabPanel.add({
id: id,
xtype: xtype,
title: title,
closable: true,
autoScroll: true
});
var tab = mainTabPanel.findById( id );
if ( tab == null ){
mainTabPanel.add({
id: id,
xtype: xtype,
title: title,
closable: true,
autoScroll: true
});
}
mainTabPanel.setActiveTab(id);
}

View File

@@ -59,7 +59,7 @@ Sonia.user.Grid = Ext.extend(Sonia.rest.Grid, {
var userStore = new Sonia.rest.JsonStore({
url: restUrl + 'users.json',
fields: [ 'name', 'displayName', 'mail', 'admin', 'creationDate', 'lastLogin', 'type'],
fields: [ 'name', 'displayName', 'mail', 'admin', 'creationDate', 'lastModified', 'type'],
sortInfo: {
field: 'name'
}
@@ -77,7 +77,7 @@ Sonia.user.Grid = Ext.extend(Sonia.rest.Grid, {
{id: 'mail', header: 'Mail', dataIndex: 'mail', renderer: this.renderMailto, width: 200},
{id: 'admin', header: 'Admin', dataIndex: 'admin', renderer: this.renderCheckbox, width: 50},
{id: 'creationDate', header: 'Creation date', dataIndex: 'creationDate'},
{id: 'lastLogin', header: 'Last login', dataIndex: 'lastLogin'},
{id: 'lastLogin', header: 'Last modified', dataIndex: 'lastModified'},
{id: 'type', header: 'Type', dataIndex: 'type', width: 80}
]
});

View File

@@ -39,6 +39,9 @@ import org.junit.Test;
import sonia.scm.AbstractTestBase;
import sonia.scm.SCMContextProvider;
import sonia.scm.cache.CacheManager;
import sonia.scm.cache.EhCacheManager;
import sonia.scm.security.MessageDigestEncryptionHandler;
import sonia.scm.user.User;
import sonia.scm.user.UserTestData;
import sonia.scm.util.MockUtil;
@@ -69,8 +72,8 @@ public class ChainAuthenticationManagerTest extends AbstractTestBase
@Test
public void testAuthenticateFailed()
{
AuthenticationResult result = manager.authenticate(request, response, trillian.getName(),
"trillian");
AuthenticationResult result = manager.authenticate(request, response,
trillian.getName(), "trillian");
assertNull(result);
}
@@ -82,7 +85,8 @@ public class ChainAuthenticationManagerTest extends AbstractTestBase
@Test
public void testAuthenticateNotFound()
{
AuthenticationResult result = manager.authenticate(request, response, "dent", "trillian");
AuthenticationResult result = manager.authenticate(request, response,
"dent", "trillian");
assertNull(result);
}
@@ -94,14 +98,14 @@ public class ChainAuthenticationManagerTest extends AbstractTestBase
@Test
public void testAuthenticateSuccess()
{
AuthenticationResult result = manager.authenticate(request, response, trillian.getName(),
"trillian123");
AuthenticationResult result = manager.authenticate(request, response,
trillian.getName(), "trillian123");
assertNotNull(result);
assertUserEquals(trillian, result.getUser());
assertEquals("trilliansType", result.getUser().getType());
result = manager.authenticate(request, response, perfect.getName(),
"perfect123");
"perfect123");
assertNotNull(perfect);
assertUserEquals(perfect, result.getUser());
assertEquals("perfectsType", result.getUser().getType());
@@ -126,7 +130,8 @@ public class ChainAuthenticationManagerTest extends AbstractTestBase
trillian.setPassword("trillian123");
handlerSet.add(new SingleUserAuthenticaionHandler("trilliansType",
trillian));
manager = new ChainAuthenticatonManager(handlerSet);
manager = new ChainAuthenticatonManager(handlerSet,
new MessageDigestEncryptionHandler(), cacheManager);
manager.init(contextProvider);
request = MockUtil.getHttpServletRequest();
response = MockUtil.getHttpServletResponse();
@@ -266,6 +271,9 @@ public class ChainAuthenticationManagerTest extends AbstractTestBase
//~--- fields ---------------------------------------------------------------
/** Field description */
private CacheManager cacheManager = new EhCacheManager();
/** Field description */
private ChainAuthenticatonManager manager;

4
third-party/pom.xml vendored
View File

@@ -6,13 +6,13 @@
<parent>
<groupId>sonia.scm</groupId>
<artifactId>scm</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.third-party</groupId>
<artifactId>sonia.scm.third-party</artifactId>
<packaging>pom</packaging>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<name>third-party</name>
<modules>

View File

@@ -6,13 +6,13 @@
<parent>
<groupId>sonia.scm.third-party</groupId>
<artifactId>sonia.scm.third-party</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</parent>
<groupId>sonia.scm.third-party</groupId>
<artifactId>shared-libs</artifactId>
<packaging>pom</packaging>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
<name>shared-libs</name>
<build>

View File

@@ -6,13 +6,13 @@
<parent>
<groupId>sonia.scm.third-party</groupId>
<artifactId>sonia.scm.third-party</artifactId>
<version>1.0-M6-SNAPSHOT</version>
<version>1.0-M7-SNAPSHOT</version>
</parent>
<groupId>org.tmatesoft.svnkit</groupId>
<artifactId>svnkit-dav</artifactId>
<packaging>jar</packaging>
<version>1.3.4</version>
<version>1.3.5.1</version>
<name>svnkit-dav</name>
<dependencies>
@@ -21,14 +21,19 @@
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
<version>${servlet.version}</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>org.tmatesoft.svnkit</groupId>
<artifactId>svnkit</artifactId>
<version>1.3.4</version>
<version>${svnkit.version}</version>
</dependency>
</dependencies>
</project>
<properties>
<svnkit.version>1.3.5</svnkit.version>
</properties>
</project>

View File

@@ -182,6 +182,7 @@ public class DAVRepositoryManager {
String uri = DAVPathUtil.addLeadingSlash(url.getURIEncodedPath());
if (uri.startsWith(getResourceContext())) {
uri = uri.substring(getResourceContext().length());
uri = DAVPathUtil.addLeadingSlash(uri);
} else {
SVNErrorManager.error(SVNErrorMessage.create(SVNErrorCode.RA_DAV_REQUEST_FAILED, "Invalid URL ''{0}'' requested", url.toString()),
SVNLogType.NETWORK);
@@ -291,7 +292,7 @@ public class DAVRepositoryManager {
}
requestContext = SVNPathUtil.append(requestContext, servletPath);
}
return SVNEncodingUtil.uriEncode(requestContext);
return encodeRequestContext(requestContext);
}
String reposName = DAVPathUtil.head(pathInfo);
@@ -301,9 +302,13 @@ public class DAVRepositoryManager {
}
String pathToRepos = SVNPathUtil.append(requestContext, servletPath);
requestContext = SVNPathUtil.append(pathToRepos, reposName);
return SVNEncodingUtil.uriEncode(requestContext);
return encodeRequestContext(requestContext);
}
requestContext = DAVPathUtil.append(requestContext, reposName);
return SVNEncodingUtil.uriEncode(requestContext);
return encodeRequestContext(requestContext);
}
private String encodeRequestContext(String requestContext){
return SVNEncodingUtil.uriEncode( DAVPathUtil.addLeadingSlash(requestContext) );
}
}