diff --git a/scm-clients/scm-client-api/src/main/java/sonia/scm/client/ScmClientSession.java b/scm-clients/scm-client-api/src/main/java/sonia/scm/client/ScmClientSession.java
index 7523460478..7e39258390 100644
--- a/scm-clients/scm-client-api/src/main/java/sonia/scm/client/ScmClientSession.java
+++ b/scm-clients/scm-client-api/src/main/java/sonia/scm/client/ScmClientSession.java
@@ -36,7 +36,6 @@ package sonia.scm.client;
//~--- non-JDK imports --------------------------------------------------------
import sonia.scm.ScmState;
-import sonia.scm.user.User;
//~--- JDK imports ------------------------------------------------------------
diff --git a/scm-clients/scm-client-api/src/main/java/sonia/scm/client/ScmUrlProvider.java b/scm-clients/scm-client-api/src/main/java/sonia/scm/client/ScmUrlProvider.java
index 11b226f11e..a7033913db 100644
--- a/scm-clients/scm-client-api/src/main/java/sonia/scm/client/ScmUrlProvider.java
+++ b/scm-clients/scm-client-api/src/main/java/sonia/scm/client/ScmUrlProvider.java
@@ -38,6 +38,7 @@ package sonia.scm.client;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import sonia.scm.url.UrlProvider;
import sonia.scm.util.Util;
//~--- JDK imports ------------------------------------------------------------
@@ -47,6 +48,16 @@ import java.text.MessageFormat;
/**
*
* @author Sebastian Sdorra
+ * @deprecated use {@link UrlProvider} instead. For example:
+ *
+ * {@code
+ * URLProvider provider = URLProviderFactory.createUrlProvider(
+ * baseUrl,
+ * UrlProviderFactory.TYPE_RESTAPI_XML
+ * );
+ * String authUrl = provider.getAuthenticationUrl();
+ * }
+ *
*/
public class ScmUrlProvider
{
diff --git a/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/AbstractClientHandler.java b/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/AbstractClientHandler.java
index eb4d8a9f15..0e29456adc 100644
--- a/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/AbstractClientHandler.java
+++ b/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/AbstractClientHandler.java
@@ -35,7 +35,11 @@ package sonia.scm.client;
//~--- non-JDK imports --------------------------------------------------------
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
import sonia.scm.ModelObject;
+import sonia.scm.url.UrlProvider;
import sonia.scm.util.AssertUtil;
//~--- JDK imports ------------------------------------------------------------
@@ -57,6 +61,12 @@ public abstract class AbstractClientHandler
implements ClientHandler
{
+ /** the logger for AbstractClientHandler */
+ private static final Logger logger =
+ LoggerFactory.getLogger(AbstractClientHandler.class);
+
+ //~--- constructors ---------------------------------------------------------
+
/**
* Constructs ...
*
@@ -233,7 +243,15 @@ public abstract class AbstractClientHandler
public List getAll()
{
List items = null;
- WebResource resource = client.resource(getItemsUrl());
+ String url = getItemsUrl();
+
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("fetch all items of {} from url", itemClass.getSimpleName(),
+ url);
+ }
+
+ WebResource resource = client.resource(url);
ClientResponse response = null;
try
@@ -283,6 +301,11 @@ public abstract class AbstractClientHandler
*/
protected T getItemByUrl(String url)
{
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("fetch item {} from url {}", itemClass.getSimpleName(), url);
+ }
+
T item = null;
WebResource resource = client.resource(url);
ClientResponse response = null;
@@ -316,10 +339,8 @@ public abstract class AbstractClientHandler
protected JerseyClientSession session;
/** Field description */
- protected ScmUrlProvider urlProvider;
+ protected UrlProvider urlProvider;
/** Field description */
private Class itemClass;
-
- ;
}
diff --git a/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyClientChangesetHandler.java b/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyClientChangesetHandler.java
index f9f7e8beaa..2fffb5afe3 100644
--- a/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyClientChangesetHandler.java
+++ b/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyClientChangesetHandler.java
@@ -80,8 +80,8 @@ public class JerseyClientChangesetHandler implements ClientChangesetHandler
{
ChangesetPagingResult result = null;
String url =
- session.getUrlProvider().getRepositoryChangesetUrl(repository.getId(),
- start, limit);
+ session.getUrlProvider().getRepositoryUrlProvider().getChangesetUrl(
+ repository.getId(), start, limit);
WebResource resource = session.getClient().resource(url);
ClientResponse response = null;
@@ -121,8 +121,8 @@ public class JerseyClientChangesetHandler implements ClientChangesetHandler
{
ChangesetPagingResult result = null;
String url =
- session.getUrlProvider().getRepositoryChangesetUrl(repository.getId(),
- path, revision, start, limit);
+ session.getUrlProvider().getRepositoryUrlProvider().getChangesetUrl(
+ repository.getId(), path, revision, start, limit);
WebResource resource = session.getClient().resource(url);
ClientResponse response = null;
diff --git a/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyClientProvider.java b/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyClientProvider.java
index 0b99b03edf..8c38f83eb1 100644
--- a/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyClientProvider.java
+++ b/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyClientProvider.java
@@ -42,6 +42,8 @@ import org.sonatype.spice.jersey.client.ahc.AhcHttpClient;
import org.sonatype.spice.jersey.client.ahc.config.DefaultAhcConfig;
import sonia.scm.ScmState;
+import sonia.scm.url.UrlProvider;
+import sonia.scm.url.UrlProviderFactory;
import sonia.scm.util.AssertUtil;
import sonia.scm.util.Util;
@@ -114,15 +116,22 @@ public class JerseyClientProvider implements ScmClientProvider
logger.info("create new session for {} with username {}", url, user);
}
- ScmUrlProvider urlProvider = new ScmUrlProvider(url);
+ UrlProvider urlProvider = UrlProviderFactory.createUrlProvider(url,
+ UrlProviderFactory.TYPE_RESTAPI_XML);
DefaultAhcConfig config = new DefaultAhcConfig();
AhcHttpClient client = AhcHttpClient.create(config);
ClientResponse response = null;
if (Util.isNotEmpty(username) && Util.isNotEmpty(password))
{
- WebResource resource = ClientUtil.createResource(client,
- urlProvider.getAuthenticationLoginUrl(),
+ String authUrl = urlProvider.getAuthenticationUrl();
+
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("try login at {}", authUrl);
+ }
+
+ WebResource resource = ClientUtil.createResource(client, authUrl,
enableLogging);
if (logger.isDebugEnabled())
@@ -139,8 +148,14 @@ public class JerseyClientProvider implements ScmClientProvider
}
else
{
- WebResource resource = ClientUtil.createResource(client,
- urlProvider.getAuthenticationUrl(),
+ String stateUrl = urlProvider.getStateUrl();
+
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("retrive state from {}", stateUrl);
+ }
+
+ WebResource resource = ClientUtil.createResource(client, stateUrl,
enableLogging);
if (logger.isDebugEnabled())
diff --git a/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyClientRepositoryBrowser.java b/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyClientRepositoryBrowser.java
index 985748f0ab..571c30f7db 100644
--- a/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyClientRepositoryBrowser.java
+++ b/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyClientRepositoryBrowser.java
@@ -91,8 +91,8 @@ public class JerseyClientRepositoryBrowser implements ClientRepositoryBrowser
{
List blameLines = null;
String url =
- session.getUrlProvider().getBlameUrl(repository.getId(), path,
- revision);
+ session.getUrlProvider().getRepositoryUrlProvider().getBlameUrl(
+ repository.getId(), path, revision);
WebResource resource = session.getClient().resource(url);
ClientResponse response = null;
@@ -134,8 +134,8 @@ public class JerseyClientRepositoryBrowser implements ClientRepositoryBrowser
{
InputStream input = null;
String url =
- session.getUrlProvider().getRepositoryContentUrl(repository.getId(),
- path, revision);
+ session.getUrlProvider().getRepositoryUrlProvider().getContentUrl(
+ repository.getId(), path, revision);
WebResource resource = session.getClient().resource(url);
ClientResponse response = null;
@@ -171,8 +171,8 @@ public class JerseyClientRepositoryBrowser implements ClientRepositoryBrowser
{
List files = null;
String url =
- session.getUrlProvider().getRepositoryBrowseUrl(repository.getId(), path,
- revision);
+ session.getUrlProvider().getRepositoryUrlProvider().getBrowseUrl(
+ repository.getId(), path, revision);
WebResource resource = session.getClient().resource(url);
ClientResponse response = null;
@@ -219,7 +219,7 @@ public class JerseyClientRepositoryBrowser implements ClientRepositoryBrowser
@Override
public List getFiles(String revision)
{
- return getFiles(revision, "");
+ return getFiles(revision, Util.EMPTY_STRING);
}
//~--- fields ---------------------------------------------------------------
diff --git a/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyClientSession.java b/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyClientSession.java
index c9ea432b31..7e662bc938 100644
--- a/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyClientSession.java
+++ b/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyClientSession.java
@@ -39,6 +39,7 @@ import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import sonia.scm.ScmState;
+import sonia.scm.url.UrlProvider;
//~--- JDK imports ------------------------------------------------------------
@@ -65,7 +66,7 @@ public class JerseyClientSession implements ScmClientSession
* @param urlProvider
* @param state
*/
- public JerseyClientSession(Client client, ScmUrlProvider urlProvider,
+ public JerseyClientSession(Client client, UrlProvider urlProvider,
ScmState state)
{
this.client = client;
@@ -146,7 +147,7 @@ public class JerseyClientSession implements ScmClientSession
*
* @return
*/
- public ScmUrlProvider getUrlProvider()
+ public UrlProvider getUrlProvider()
{
return urlProvider;
}
@@ -172,5 +173,5 @@ public class JerseyClientSession implements ScmClientSession
private ScmState state;
/** Field description */
- private ScmUrlProvider urlProvider;
+ private UrlProvider urlProvider;
}
diff --git a/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyGroupClientHandler.java b/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyGroupClientHandler.java
index 5f3969ffc7..0c22798279 100644
--- a/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyGroupClientHandler.java
+++ b/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyGroupClientHandler.java
@@ -105,7 +105,7 @@ public class JerseyGroupClientHandler extends AbstractClientHandler
@Override
protected String getItemUrl(String itemId)
{
- return urlProvider.getGroupUrl(itemId);
+ return urlProvider.getGroupUrlProvider().getDetailUrl(itemId);
}
/**
@@ -117,6 +117,6 @@ public class JerseyGroupClientHandler extends AbstractClientHandler
@Override
protected String getItemsUrl()
{
- return urlProvider.getGroupsUrl();
+ return urlProvider.getGroupUrlProvider().getAllUrl();
}
}
diff --git a/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyRepositoryClientHandler.java b/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyRepositoryClientHandler.java
index 6309a5b245..4d0efd2869 100644
--- a/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyRepositoryClientHandler.java
+++ b/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyRepositoryClientHandler.java
@@ -160,7 +160,7 @@ public class JerseyRepositoryClientHandler
@Override
protected String getItemUrl(String itemId)
{
- return urlProvider.getRepositoryUrl(itemId);
+ return urlProvider.getRepositoryUrlProvider().getDetailUrl(itemId);
}
/**
@@ -172,6 +172,6 @@ public class JerseyRepositoryClientHandler
@Override
protected String getItemsUrl()
{
- return urlProvider.getRepositoriesUrl();
+ return urlProvider.getRepositoryUrlProvider().getAllUrl();
}
}
diff --git a/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyUserClientHandler.java b/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyUserClientHandler.java
index c28d3eda70..a353434379 100644
--- a/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyUserClientHandler.java
+++ b/scm-clients/scm-client-impl/src/main/java/sonia/scm/client/JerseyUserClientHandler.java
@@ -105,7 +105,7 @@ public class JerseyUserClientHandler extends AbstractClientHandler
@Override
protected String getItemUrl(String itemId)
{
- return urlProvider.getUserUrl(itemId);
+ return urlProvider.getUserUrlProvider().getDetailUrl(itemId);
}
/**
@@ -117,6 +117,6 @@ public class JerseyUserClientHandler extends AbstractClientHandler
@Override
protected String getItemsUrl()
{
- return urlProvider.getUsersUrl();
+ return urlProvider.getUserUrlProvider().getAllUrl();
}
}
diff --git a/scm-clients/scm-client-impl/src/test/java/sonia/scm/client/it/ClientTestUtil.java b/scm-clients/scm-client-impl/src/test/java/sonia/scm/client/it/ClientTestUtil.java
index fc0e47805e..b2efca3439 100644
--- a/scm-clients/scm-client-impl/src/test/java/sonia/scm/client/it/ClientTestUtil.java
+++ b/scm-clients/scm-client-impl/src/test/java/sonia/scm/client/it/ClientTestUtil.java
@@ -40,6 +40,7 @@ import sonia.scm.client.JerseyClientProvider;
import sonia.scm.client.JerseyClientSession;
import sonia.scm.client.ScmUrlProvider;
import sonia.scm.config.ScmConfiguration;
+import sonia.scm.url.UrlProvider;
//~--- JDK imports ------------------------------------------------------------
@@ -124,10 +125,10 @@ public class ClientTestUtil
public static void setAnonymousAccess(boolean access)
{
JerseyClientSession adminSession = createAdminSession();
- ScmUrlProvider up = adminSession.getUrlProvider();
+ UrlProvider up = adminSession.getUrlProvider();
Client client = adminSession.getClient();
- WebResource resource = ClientUtil.createResource(client,
- up.getResourceUrl("config"), REQUEST_LOGGING);
+ WebResource resource = ClientUtil.createResource(client, up.getConfigUrl(),
+ REQUEST_LOGGING);
ScmConfiguration config = resource.get(ScmConfiguration.class);
config.setAnonymousAccessEnabled(access);
diff --git a/scm-core/src/main/java/sonia/scm/net/HttpClient.java b/scm-core/src/main/java/sonia/scm/net/HttpClient.java
index 5878df1e1c..590f682e14 100644
--- a/scm-core/src/main/java/sonia/scm/net/HttpClient.java
+++ b/scm-core/src/main/java/sonia/scm/net/HttpClient.java
@@ -59,6 +59,19 @@ public interface HttpClient
*/
public HttpResponse post(String url) throws IOException;
+ /**
+ * Method description
+ *
+ *
+ * @param request
+ *
+ * @return
+ * @since 1.9
+ *
+ * @throws IOException
+ */
+ public HttpResponse post(HttpRequest request) throws IOException;
+
/**
* Method description
*
@@ -87,6 +100,19 @@ public interface HttpClient
*/
public HttpResponse get(String url) throws IOException;
+ /**
+ * Method description
+ *
+ *
+ * @param request
+ *
+ * @return
+ * @since 1.9
+ *
+ * @throws IOException
+ */
+ public HttpResponse get(HttpRequest request) throws IOException;
+
/**
* Method description
*
diff --git a/scm-core/src/main/java/sonia/scm/net/HttpRequest.java b/scm-core/src/main/java/sonia/scm/net/HttpRequest.java
new file mode 100644
index 0000000000..7bd99abc9c
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/net/HttpRequest.java
@@ -0,0 +1,264 @@
+/**
+ * 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.net;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import sonia.scm.util.AssertUtil;
+
+//~--- JDK imports ------------------------------------------------------------
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ *
+ * @author Sebastian Sdorra
+ * @since 1.9
+ */
+public class HttpRequest
+{
+
+ /**
+ * Constructs ...
+ *
+ *
+ * @param url
+ */
+ public HttpRequest(String url)
+ {
+ this.url = url;
+ }
+
+ //~--- methods --------------------------------------------------------------
+
+ /**
+ * Method description
+ *
+ *
+ * @param name
+ * @param values
+ *
+ * @return
+ */
+ public HttpRequest addHeader(String name, String... values)
+ {
+ AssertUtil.assertIsNotNull(name);
+
+ if (headers == null)
+ {
+ headers = new HashMap>();
+ }
+
+ appendValues(headers, name, values);
+
+ return this;
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param name
+ * @param values
+ *
+ * @return
+ */
+ public HttpRequest addParameters(String name, String... values)
+ {
+ AssertUtil.assertIsNotNull(name);
+
+ if (parameters == null)
+ {
+ parameters = new HashMap>();
+ }
+
+ appendValues(parameters, name, values);
+
+ return this;
+ }
+
+ //~--- get methods ----------------------------------------------------------
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ public Map> getHeaders()
+ {
+ return headers;
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ public Map> getParameters()
+ {
+ return parameters;
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ public String getPassword()
+ {
+ return password;
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ public String getUrl()
+ {
+ return url;
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ public String getUsername()
+ {
+ return username;
+ }
+
+ //~--- set methods ----------------------------------------------------------
+
+ /**
+ * Method description
+ *
+ *
+ * @param username
+ * @param password
+ *
+ * @return
+ */
+ public HttpRequest setBasicAuthentication(String username, String password)
+ {
+ this.username = username;
+ this.password = password;
+
+ return this;
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param headers
+ *
+ * @return
+ */
+ public HttpRequest setHeaders(Map> headers)
+ {
+ this.headers = headers;
+
+ return this;
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param parameters
+ *
+ * @return
+ */
+ public HttpRequest setParameters(Map> parameters)
+ {
+ this.parameters = parameters;
+
+ return this;
+ }
+
+ //~--- methods --------------------------------------------------------------
+
+ /**
+ * Method description
+ *
+ *
+ * @param map
+ * @param name
+ * @param values
+ */
+ private void appendValues(Map> map, String name,
+ String[] values)
+ {
+ List valueList = map.get(name);
+
+ if (valueList == null)
+ {
+ valueList = new ArrayList();
+ map.put(name, valueList);
+ }
+
+ if (values != null)
+ {
+ valueList.addAll(Arrays.asList(values));
+ }
+ }
+
+ //~--- fields ---------------------------------------------------------------
+
+ /** Field description */
+ private Map> headers;
+
+ /** Field description */
+ private Map> parameters;
+
+ /** Field description */
+ private String password;
+
+ /** Field description */
+ private String url;
+
+ /** Field description */
+ private String username;
+}
diff --git a/scm-core/src/main/java/sonia/scm/url/ModelUrlProvider.java b/scm-core/src/main/java/sonia/scm/url/ModelUrlProvider.java
new file mode 100644
index 0000000000..ea60645d00
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/url/ModelUrlProvider.java
@@ -0,0 +1,58 @@
+/**
+ * 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.url;
+
+/**
+ * @since 1.9
+ * @author Sebastian Sdorra
+ */
+public interface ModelUrlProvider
+{
+
+ /**
+ * Method description
+ *
+ *
+ * @param name
+ *
+ * @return
+ */
+ public String getDetailUrl(String name);
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ public String getAllUrl();
+
+}
diff --git a/scm-core/src/main/java/sonia/scm/url/RepositoryUrlProvider.java b/scm-core/src/main/java/sonia/scm/url/RepositoryUrlProvider.java
new file mode 100644
index 0000000000..cb34869b96
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/url/RepositoryUrlProvider.java
@@ -0,0 +1,117 @@
+/**
+ * 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.url;
+
+/**
+ * @since 1.9
+ * @author Sebastian Sdorra
+ */
+public interface RepositoryUrlProvider extends ModelUrlProvider
+{
+
+ /**
+ * Method description
+ *
+ *
+ * @param repositoryId
+ * @param path
+ * @param revision
+ *
+ * @return
+ */
+ public String getBlameUrl(String repositoryId, String path, String revision);
+
+ /**
+ * Method description
+ *
+ *
+ * @param repositoryId
+ * @param path
+ * @param revision
+ *
+ * @return
+ */
+ public String getBrowseUrl(String repositoryId, String path, String revision);
+
+ /**
+ * Method description
+ *
+ *
+ * @param repositoryId
+ * @param path
+ * @param revision
+ * @param start
+ * @param limit
+ *
+ * @return
+ */
+ public String getChangesetUrl(String repositoryId, String path,
+ String revision, int start, int limit);
+
+ /**
+ * Method description
+ *
+ *
+ * @param repositoryId
+ * @param start
+ * @param limit
+ *
+ * @return
+ */
+ public String getChangesetUrl(String repositoryId, int start, int limit);
+
+ /**
+ * Method description
+ *
+ *
+ * @param repositoryId
+ * @param path
+ * @param revision
+ *
+ * @return
+ */
+ public String getContentUrl(String repositoryId, String path,
+ String revision);
+
+ /**
+ * Method description
+ *
+ *
+ * @param repositoryId
+ * @param revision
+ *
+ * @return
+ */
+ public String getDiffUrl(String repositoryId, String revision);
+}
diff --git a/scm-core/src/main/java/sonia/scm/url/RestModelUrlProvider.java b/scm-core/src/main/java/sonia/scm/url/RestModelUrlProvider.java
new file mode 100644
index 0000000000..3974135a53
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/url/RestModelUrlProvider.java
@@ -0,0 +1,97 @@
+/**
+ * Copyright (c) 2010, Sebastian Sdorra
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of SCM-Manager; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://bitbucket.org/sdorra/scm-manager
+ *
+ */
+
+
+
+package sonia.scm.url;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import sonia.scm.util.HttpUtil;
+
+/**
+ * @since 1.9
+ * @author Sebastian Sdorra
+ */
+public class RestModelUrlProvider implements ModelUrlProvider
+{
+
+ /**
+ * Constructs ...
+ *
+ *
+ * @param baseUrl
+ * @param modelSuffix
+ * @param extension
+ */
+ public RestModelUrlProvider(String baseUrl, String modelSuffix,
+ String extension)
+ {
+ this.base = HttpUtil.append(baseUrl, modelSuffix);
+ this.extension = extension;
+ }
+
+ //~--- get methods ----------------------------------------------------------
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ @Override
+ public String getAllUrl()
+ {
+ return base.concat(extension);
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param name
+ *
+ * @return
+ */
+ @Override
+ public String getDetailUrl(String name)
+ {
+ return HttpUtil.append(base, name).concat(extension);
+ }
+
+ //~--- fields ---------------------------------------------------------------
+
+ /** Field description */
+ protected String base;
+
+ /** Field description */
+ protected String extension;
+}
diff --git a/scm-core/src/main/java/sonia/scm/url/RestRepositoryUrlProvider.java b/scm-core/src/main/java/sonia/scm/url/RestRepositoryUrlProvider.java
new file mode 100644
index 0000000000..e75dd5fd14
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/url/RestRepositoryUrlProvider.java
@@ -0,0 +1,207 @@
+/**
+ * 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.url;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import sonia.scm.util.UrlBuilder;
+
+/**
+ * @since 1.9
+ * @author Sebastian Sdorra
+ */
+public class RestRepositoryUrlProvider extends RestModelUrlProvider
+ implements RepositoryUrlProvider
+{
+
+ /** Field description */
+ public static final String PARAMETER_LIMIT = "limit";
+
+ /** Field description */
+ public static final String PARAMETER_PATH = "path";
+
+ /** Field description */
+ public static final String PARAMETER_REVISION = "revision";
+
+ /** Field description */
+ public static final String PARAMETER_START = "start";
+
+ /** Field description */
+ public static final String PART_BLAME = "blame";
+
+ /** Field description */
+ public static final String PART_BROWSE = "browse";
+
+ /** Field description */
+ public static final String PART_CHANGESETS = "changesets";
+
+ /** Field description */
+ public static final String PART_CONTENT = "content";
+
+ /** Field description */
+ public static final String PART_DIFF = "diff";
+
+ //~--- constructors ---------------------------------------------------------
+
+ /**
+ * Constructs ...
+ *
+ *
+ * @param baseUrl
+ * @param modelSuffix
+ * @param extension
+ */
+ public RestRepositoryUrlProvider(String baseUrl, String modelSuffix,
+ String extension)
+ {
+ super(baseUrl, modelSuffix, extension);
+ }
+
+ //~--- get methods ----------------------------------------------------------
+
+ /**
+ * Method description
+ *
+ *
+ * @param repositoryId
+ * @param path
+ * @param revision
+ *
+ * @return
+ */
+ @Override
+ public String getBlameUrl(String repositoryId, String path, String revision)
+ {
+ return new UrlBuilder(base).appendUrlPart(repositoryId).appendUrlPart(
+ PART_BLAME).append(extension).appendParameter(
+ PARAMETER_PATH, path).appendParameter(
+ PARAMETER_REVISION, revision).toString();
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param repositoryId
+ * @param path
+ * @param revision
+ *
+ * @return
+ */
+ @Override
+ public String getBrowseUrl(String repositoryId, String path, String revision)
+ {
+ return new UrlBuilder(base).appendUrlPart(repositoryId).appendUrlPart(
+ PART_BROWSE).append(extension).appendParameter(
+ PARAMETER_PATH, path).appendParameter(
+ PARAMETER_REVISION, revision).toString();
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param repositoryId
+ * @param path
+ * @param revision
+ * @param start
+ * @param limit
+ *
+ * @return
+ */
+ @Override
+ public String getChangesetUrl(String repositoryId, String path,
+ String revision, int start, int limit)
+ {
+ return new UrlBuilder(base).appendUrlPart(repositoryId).appendUrlPart(
+ PART_CHANGESETS).append(extension).appendParameter(
+ PARAMETER_PATH, path).appendParameter(
+ PARAMETER_REVISION, revision).appendParameter(
+ PARAMETER_START, start).appendParameter(
+ PARAMETER_LIMIT, limit).toString();
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param repositoryId
+ * @param start
+ * @param limit
+ *
+ * @return
+ */
+ @Override
+ public String getChangesetUrl(String repositoryId, int start, int limit)
+ {
+ return new UrlBuilder(base).appendUrlPart(repositoryId).appendUrlPart(
+ PART_CHANGESETS).append(extension).appendParameter(
+ PARAMETER_START, start).appendParameter(
+ PARAMETER_LIMIT, limit).toString();
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param repositoryId
+ * @param path
+ * @param revision
+ *
+ * @return
+ */
+ @Override
+ public String getContentUrl(String repositoryId, String path, String revision)
+ {
+ return new UrlBuilder(base).appendUrlPart(repositoryId).appendUrlPart(
+ PART_CONTENT).appendParameter(PARAMETER_PATH, path).appendParameter(
+ PARAMETER_REVISION, revision).toString();
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param repositoryId
+ * @param revision
+ *
+ * @return
+ */
+ @Override
+ public String getDiffUrl(String repositoryId, String revision)
+ {
+ return new UrlBuilder(base).appendUrlPart(repositoryId).appendUrlPart(
+ PART_DIFF).appendParameter(PARAMETER_REVISION, revision).toString();
+ }
+}
diff --git a/scm-core/src/main/java/sonia/scm/url/RestUrlProvider.java b/scm-core/src/main/java/sonia/scm/url/RestUrlProvider.java
new file mode 100644
index 0000000000..1d60f2a91b
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/url/RestUrlProvider.java
@@ -0,0 +1,164 @@
+/**
+ * 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.url;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import sonia.scm.util.HttpUtil;
+
+/**
+ * @since 1.9
+ * @author Sebastian Sdorra
+ */
+public class RestUrlProvider implements UrlProvider
+{
+
+ /** Field description */
+ public static final String PART_API = "api/rest/";
+
+ /** Field description */
+ public static final String PART_AUTHENTICATION = "authentication/login";
+
+ /** Field description */
+ public static final String PART_CONFIG = "config";
+
+ /** Field description */
+ public static final String PART_GROUP = "groups";
+
+ /** Field description */
+ public static final String PART_REPOSITORIES = "repositories";
+
+ /** Field description */
+ public static final String PART_STATE = "authentication";
+
+ /** Field description */
+ public static final String PART_USER = "users";
+
+ //~--- constructors ---------------------------------------------------------
+
+ /**
+ * Constructs ...
+ *
+ *
+ * @param baseUrl
+ * @param extension
+ */
+ public RestUrlProvider(String baseUrl, String extension)
+ {
+ this.baseUrl = HttpUtil.append(baseUrl, PART_API);
+ this.extension = extension;
+ }
+
+ //~--- get methods ----------------------------------------------------------
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ @Override
+ public String getAuthenticationUrl()
+ {
+ return HttpUtil.append(baseUrl, PART_AUTHENTICATION).concat(extension);
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ @Override
+ public String getConfigUrl()
+ {
+ return HttpUtil.append(baseUrl, PART_CONFIG).concat(extension);
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ @Override
+ public ModelUrlProvider getGroupUrlProvider()
+ {
+ return new RestModelUrlProvider(baseUrl, PART_GROUP, extension);
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ @Override
+ public RepositoryUrlProvider getRepositoryUrlProvider()
+ {
+ return new RestRepositoryUrlProvider(baseUrl, PART_REPOSITORIES, extension);
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ @Override
+ public String getStateUrl()
+ {
+ return HttpUtil.append(baseUrl, PART_STATE).concat(extension);
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ @Override
+ public ModelUrlProvider getUserUrlProvider()
+ {
+ return new RestModelUrlProvider(baseUrl, PART_USER, extension);
+ }
+
+ //~--- fields ---------------------------------------------------------------
+
+ /** Field description */
+ protected String baseUrl;
+
+ /** Field description */
+ protected String extension;
+}
diff --git a/scm-core/src/main/java/sonia/scm/url/UrlProvider.java b/scm-core/src/main/java/sonia/scm/url/UrlProvider.java
new file mode 100644
index 0000000000..694ea1b698
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/url/UrlProvider.java
@@ -0,0 +1,90 @@
+/**
+ * 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.url;
+
+/**
+ * @since 1.9
+ * @author Sebastian Sdorra
+ */
+public interface UrlProvider
+{
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ public String getAuthenticationUrl();
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ public String getConfigUrl();
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ public ModelUrlProvider getGroupUrlProvider();
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ public RepositoryUrlProvider getRepositoryUrlProvider();
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ public String getStateUrl();
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ public ModelUrlProvider getUserUrlProvider();
+}
diff --git a/scm-core/src/main/java/sonia/scm/url/UrlProviderFactory.java b/scm-core/src/main/java/sonia/scm/url/UrlProviderFactory.java
new file mode 100644
index 0000000000..71de584c06
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/url/UrlProviderFactory.java
@@ -0,0 +1,89 @@
+/**
+ * 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.url;
+
+/**
+ * @since 1.9
+ * @author Sebastian Sdorra
+ */
+public class UrlProviderFactory
+{
+
+ /** Field description */
+ public static final String TYPE_RESTAPI_JSON = "json-rest-api";
+
+ /** Field description */
+ public static final String TYPE_RESTAPI_XML = "xml-rest-api";
+
+ /** Field description */
+ public static final String TYPE_WUI = "wui";
+
+ /** Field description */
+ private static final String EXTENSION_JSON = ".json";
+
+ /** Field description */
+ private static final String EXTENSION_XML = ".xml";
+
+ //~--- methods --------------------------------------------------------------
+
+ /**
+ * Method description
+ *
+ *
+ *
+ * @param baseUrl
+ * @param type
+ *
+ * @return
+ */
+ public static UrlProvider createUrlProvider(String baseUrl, String type)
+ {
+ UrlProvider provider = null;
+
+ if (TYPE_RESTAPI_JSON.equals(type))
+ {
+ provider = new RestUrlProvider(baseUrl, EXTENSION_JSON);
+ }
+ else if (TYPE_RESTAPI_XML.equals(type))
+ {
+ provider = new RestUrlProvider(baseUrl, EXTENSION_XML);
+ }
+ else if (TYPE_WUI.equals(type))
+ {
+ provider = new WUIUrlProvider(baseUrl);
+ }
+
+ return provider;
+ }
+}
diff --git a/scm-core/src/main/java/sonia/scm/url/WUIModelUrlProvider.java b/scm-core/src/main/java/sonia/scm/url/WUIModelUrlProvider.java
new file mode 100644
index 0000000000..bef0ef3b68
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/url/WUIModelUrlProvider.java
@@ -0,0 +1,91 @@
+/**
+ * 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.url;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import sonia.scm.util.HttpUtil;
+
+/**
+ * @since 1.9
+ * @author Sebastian Sdorra
+ */
+public class WUIModelUrlProvider implements ModelUrlProvider
+{
+
+ /**
+ * Constructs ...
+ *
+ *
+ * @param baseUrl
+ * @param component
+ */
+ public WUIModelUrlProvider(String baseUrl, String component)
+ {
+ this.url = HttpUtil.appendHash(baseUrl, component);
+ }
+
+ //~--- get methods ----------------------------------------------------------
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ @Override
+ public String getAllUrl()
+ {
+ return url;
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param name
+ *
+ * @return
+ */
+ @Override
+ public String getDetailUrl(String name)
+ {
+ return url.concat(WUIUrlBuilder.SEPARATOR).concat(name);
+ }
+
+ //~--- fields ---------------------------------------------------------------
+
+ /** Field description */
+ private String url;
+}
diff --git a/scm-core/src/main/java/sonia/scm/url/WUIRepositoryUrlProvider.java b/scm-core/src/main/java/sonia/scm/url/WUIRepositoryUrlProvider.java
new file mode 100644
index 0000000000..136d160186
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/url/WUIRepositoryUrlProvider.java
@@ -0,0 +1,196 @@
+/**
+ * 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.url;
+
+/**
+ *
+ * @author Sebastian Sdorra
+ */
+public class WUIRepositoryUrlProvider extends WUIModelUrlProvider
+ implements RepositoryUrlProvider
+{
+
+ /** Field description */
+ public static final String COMPONENT_BROWSER = "repositoryBrowser";
+
+ /** Field description */
+ public static final String COMPONENT_CHANGESETS =
+ "repositoryChangesetViewerPanel";
+
+ /** Field description */
+ public static final String COMPONENT_CONTENT = "contentPanel";
+
+ /** Field description */
+ public static final String COMPONENT_DIFF = "diffPanel";
+
+ /** Field description */
+ public static final String VIEW_BLAME = "blame";
+
+ /** Field description */
+ public static final String VIEW_CONTENT = "content";
+
+ /** Field description */
+ public static final String VIEW_HISTORY = "history";
+
+ //~--- constructors ---------------------------------------------------------
+
+ /**
+ * Constructs ...
+ *
+ *
+ * @param baseUrl
+ * @param component
+ */
+ public WUIRepositoryUrlProvider(String baseUrl, String component)
+ {
+ super(baseUrl, component);
+ this.baseUrl = baseUrl;
+ }
+
+ //~--- get methods ----------------------------------------------------------
+
+ /**
+ * Method description
+ *
+ *
+ * @param repositoryId
+ * @param path
+ * @param revision
+ *
+ * @return
+ */
+ @Override
+ public String getBlameUrl(String repositoryId, String path, String revision)
+ {
+ return new WUIUrlBuilder(baseUrl, COMPONENT_CONTENT).append(
+ repositoryId).append(revision).append(path).append(
+ VIEW_BLAME).toString();
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param repositoryId
+ * @param path
+ * @param revision
+ *
+ * @return
+ */
+ @Override
+ public String getBrowseUrl(String repositoryId, String path, String revision)
+ {
+ return new WUIUrlBuilder(baseUrl, COMPONENT_BROWSER).append(
+ repositoryId).append(revision).append(path).toString();
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param repositoryId
+ * @param path
+ * @param revision
+ * @param start
+ * @param limit
+ *
+ * @return
+ */
+ @Override
+ public String getChangesetUrl(String repositoryId, String path,
+ String revision, int start, int limit)
+ {
+
+ // TODO handle start and limit
+ return new WUIUrlBuilder(baseUrl, COMPONENT_CONTENT).append(
+ repositoryId).append(revision).append(path).append(
+ VIEW_HISTORY).toString();
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param repositoryId
+ * @param start
+ * @param limit
+ *
+ * @return
+ */
+ @Override
+ public String getChangesetUrl(String repositoryId, int start, int limit)
+ {
+ return new WUIUrlBuilder(baseUrl, COMPONENT_CHANGESETS).append(
+ repositoryId).append(start).append(limit).toString();
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param repositoryId
+ * @param path
+ * @param revision
+ *
+ * @return
+ */
+ @Override
+ public String getContentUrl(String repositoryId, String path, String revision)
+ {
+ return new WUIUrlBuilder(baseUrl, COMPONENT_CONTENT).append(
+ repositoryId).append(revision).append(path).append(
+ VIEW_HISTORY).toString();
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param repositoryId
+ * @param revision
+ *
+ * @return
+ */
+ @Override
+ public String getDiffUrl(String repositoryId, String revision)
+ {
+ return new WUIUrlBuilder(baseUrl, COMPONENT_DIFF).append(
+ repositoryId).append(revision).toString();
+ }
+
+ //~--- fields ---------------------------------------------------------------
+
+ /** Field description */
+ private String baseUrl;
+}
diff --git a/scm-core/src/main/java/sonia/scm/url/WUIUrlBuilder.java b/scm-core/src/main/java/sonia/scm/url/WUIUrlBuilder.java
new file mode 100644
index 0000000000..c9744effe3
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/url/WUIUrlBuilder.java
@@ -0,0 +1,123 @@
+/**
+ * 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.url;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import sonia.scm.util.HttpUtil;
+
+/**
+ * @since 1.9
+ * @author Sebastian Sdorra
+ */
+public class WUIUrlBuilder
+{
+
+ /** Field description */
+ public static final String NULL = "null";
+
+ /** Field description */
+ public static final String SEPARATOR = ";";
+
+ //~--- constructors ---------------------------------------------------------
+
+ /**
+ * Constructs ...
+ *
+ *
+ * @param baseUrl
+ * @param component
+ */
+ public WUIUrlBuilder(String baseUrl, String component)
+ {
+ this.url = HttpUtil.appendHash(baseUrl, component);
+ }
+
+ //~--- methods --------------------------------------------------------------
+
+ /**
+ * Method description
+ *
+ *
+ * @param value
+ *
+ * @return
+ */
+ public WUIUrlBuilder append(String value)
+ {
+ if (value == null)
+ {
+ value = NULL;
+ }
+
+ if (!this.url.endsWith(SEPARATOR))
+ {
+ this.url = this.url.concat(SEPARATOR);
+ }
+
+ this.url = this.url.concat(value);
+
+ return this;
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param value
+ *
+ * @return
+ */
+ public WUIUrlBuilder append(int value)
+ {
+ return append(String.valueOf(value));
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ @Override
+ public String toString()
+ {
+ return url;
+ }
+
+ //~--- fields ---------------------------------------------------------------
+
+ /** Field description */
+ private String url;
+}
diff --git a/scm-core/src/main/java/sonia/scm/url/WUIUrlProvider.java b/scm-core/src/main/java/sonia/scm/url/WUIUrlProvider.java
new file mode 100644
index 0000000000..f022e3ca0d
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/url/WUIUrlProvider.java
@@ -0,0 +1,157 @@
+/**
+ * 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.url;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import sonia.scm.util.HttpUtil;
+
+/**
+ * @since 1.9
+ * @author Sebastian Sdorra
+ */
+public class WUIUrlProvider implements UrlProvider
+{
+
+ /** Field description */
+ public static final String COMPONENT_CONFIG = "scmConfig";
+
+ /** Field description */
+ public static final String COMPONENT_GROUP = "groupPanel";
+
+ /** Field description */
+ public static final String COMPONENT_REPOSITORY = "repositoryPanel";
+
+ /** Field description */
+ public static final String COMPONENT_USER = "userPanel";
+
+ /** Field description */
+ public static final String PART_INDEX = "index.html";
+
+ //~--- constructors ---------------------------------------------------------
+
+ /**
+ * Constructs ...
+ *
+ *
+ * @param baseUrl
+ */
+ public WUIUrlProvider(String baseUrl)
+ {
+ this.baseUrl = HttpUtil.append(baseUrl, PART_INDEX);
+ }
+
+ //~--- get methods ----------------------------------------------------------
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ @Override
+ public String getAuthenticationUrl()
+ {
+
+ // ???
+ return null;
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ @Override
+ public String getConfigUrl()
+ {
+ return HttpUtil.appendHash(baseUrl, COMPONENT_CONFIG);
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ @Override
+ public ModelUrlProvider getGroupUrlProvider()
+ {
+ return new WUIModelUrlProvider(baseUrl, COMPONENT_GROUP);
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ @Override
+ public RepositoryUrlProvider getRepositoryUrlProvider()
+ {
+ return new WUIRepositoryUrlProvider(baseUrl, COMPONENT_REPOSITORY);
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ @Override
+ public String getStateUrl()
+ {
+
+ // ???
+ return null;
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ @Override
+ public ModelUrlProvider getUserUrlProvider()
+ {
+ return new WUIModelUrlProvider(baseUrl, COMPONENT_USER);
+ }
+
+ //~--- fields ---------------------------------------------------------------
+
+ /** Field description */
+ private String baseUrl;
+}
diff --git a/scm-core/src/main/java/sonia/scm/util/HttpUtil.java b/scm-core/src/main/java/sonia/scm/util/HttpUtil.java
index 819efb509c..c5ab47b8e2 100644
--- a/scm-core/src/main/java/sonia/scm/util/HttpUtil.java
+++ b/scm-core/src/main/java/sonia/scm/util/HttpUtil.java
@@ -92,6 +92,30 @@ public class HttpUtil
*/
public static final String SCHEME_HTTPS = "https";
+ /**
+ * Url hash separator
+ * @since 1.9
+ */
+ public static final String SEPARATOR_HASH = "#";
+
+ /**
+ * Url parameter separator
+ * @since 1.9
+ */
+ public static final String SEPARATOR_PARAMETER = "&";
+
+ /**
+ * Url parameters separator
+ * @since 1.9
+ */
+ public static final String SEPARATOR_PARAMETERS = "?";
+
+ /**
+ * Url parameter value separator
+ * @since 1.9
+ */
+ public static final String SEPARATOR_PARAMETER_VALUE = "=";
+
/**
* Url folder separator
* @since 1.5
@@ -119,6 +143,69 @@ public class HttpUtil
//~--- methods --------------------------------------------------------------
+ /**
+ * Method description
+ *
+ *
+ * @param uri
+ * @param suffix
+ *
+ * @return
+ * @since 1.9
+ */
+ public static String append(String uri, String suffix)
+ {
+ if (!uri.endsWith(SEPARATOR_PATH))
+ {
+ uri = uri.concat(SEPARATOR_PATH);
+ }
+
+ return uri.concat(suffix);
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param uri
+ * @param hash
+ *
+ * @return
+ * @since 1.9
+ */
+ public static String appendHash(String uri, String hash)
+ {
+ return uri.concat(SEPARATOR_HASH).concat(hash);
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param uri
+ * @param name
+ * @param value
+ *
+ * @return
+ * @since 1.9
+ */
+ public static String appendParameter(String uri, String name, String value)
+ {
+ String s = null;
+
+ if (uri.contains(SEPARATOR_PARAMETERS))
+ {
+ s = SEPARATOR_PARAMETERS;
+ }
+ else
+ {
+ s = SEPARATOR_PARAMETER;
+ }
+
+ return new StringBuilder(uri).append(s).append(name).append(
+ SEPARATOR_PARAMETER_VALUE).append(value).toString();
+ }
+
/**
* Method description
*
diff --git a/scm-core/src/main/java/sonia/scm/util/UrlBuilder.java b/scm-core/src/main/java/sonia/scm/util/UrlBuilder.java
new file mode 100644
index 0000000000..e8ba4dfcf3
--- /dev/null
+++ b/scm-core/src/main/java/sonia/scm/util/UrlBuilder.java
@@ -0,0 +1,208 @@
+/**
+ * Copyright (c) 2010, Sebastian Sdorra
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ * this list of conditions and the following disclaimer in the documentation
+ * and/or other materials provided with the distribution.
+ * 3. Neither the name of SCM-Manager; nor the names of its
+ * contributors may be used to endorse or promote products derived from this
+ * software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://bitbucket.org/sdorra/scm-manager
+ *
+ */
+
+
+
+package sonia.scm.util;
+
+//~--- JDK imports ------------------------------------------------------------
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+/**
+ * @since 1.9
+ * @author Sebastian Sdorra
+ */
+public class UrlBuilder
+{
+
+ /**
+ * Constructs ...
+ *
+ *
+ * @param baseUrl
+ */
+ public UrlBuilder(String baseUrl)
+ {
+ this.url = baseUrl;
+
+ if (baseUrl.contains(HttpUtil.SEPARATOR_PARAMETERS))
+ {
+ separator = HttpUtil.SEPARATOR_PARAMETER;
+ }
+ else
+ {
+ separator = HttpUtil.SEPARATOR_PARAMETERS;
+ }
+ }
+
+ //~--- methods --------------------------------------------------------------
+
+ /**
+ * Method description
+ *
+ *
+ * @param part
+ *
+ * @return
+ */
+ public UrlBuilder append(String part)
+ {
+ url = url.concat(part);
+
+ return this;
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param name
+ * @param value
+ *
+ * @return
+ */
+ public UrlBuilder appendParameter(String name, boolean value)
+ {
+ return appendParameter(name, String.valueOf(value));
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param name
+ * @param value
+ *
+ * @return
+ */
+ public UrlBuilder appendParameter(String name, int value)
+ {
+ return appendParameter(name, String.valueOf(value));
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param name
+ * @param value
+ *
+ * @return
+ */
+ public UrlBuilder appendParameter(String name, long value)
+ {
+ return appendParameter(name, String.valueOf(value));
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param name
+ * @param value
+ *
+ * @return
+ */
+ public UrlBuilder appendParameter(String name, String value)
+ {
+ if (Util.isNotEmpty(name) && Util.isNotEmpty(value))
+ {
+ url = new StringBuilder(url).append(separator).append(name).append(
+ HttpUtil.SEPARATOR_PARAMETER_VALUE).append(value).toString();
+ parameterAdded = true;
+ }
+
+ return this;
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param part
+ *
+ * @return
+ */
+ public UrlBuilder appendUrlPart(String part)
+ {
+ if (parameterAdded)
+ {
+ throw new IllegalStateException("parameter added");
+ }
+
+ url = HttpUtil.append(url, part);
+
+ return this;
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ @Override
+ public String toString()
+ {
+ return url;
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ public URL toURL()
+ {
+ try
+ {
+ return new URL(url);
+ }
+ catch (MalformedURLException ex)
+ {
+ throw new RuntimeException(ex);
+ }
+ }
+
+ //~--- fields ---------------------------------------------------------------
+
+ /** Field description */
+ private boolean parameterAdded = false;
+
+ /** Field description */
+ private String separator;
+
+ /** Field description */
+ private String url;
+}
diff --git a/scm-plugin-backend/pom.xml b/scm-plugin-backend/pom.xml
index 9da97a4fa8..4e0686e1c7 100644
--- a/scm-plugin-backend/pom.xml
+++ b/scm-plugin-backend/pom.xml
@@ -96,6 +96,7 @@
.hg/**
**/html5.js
**/*.html
+ **/fancybox/**
true
diff --git a/scm-server/pom.xml b/scm-server/pom.xml
index 3fad0c31dc..5d8010314a 100644
--- a/scm-server/pom.xml
+++ b/scm-server/pom.xml
@@ -20,7 +20,7 @@
commons-daemon
commons-daemon
- 1.0.5
+ 1.0.8
@@ -75,6 +75,7 @@
scm-server
+ 1.0.8
sonia.scm.server.ScmServerDaemon
commons-daemon
diff --git a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java
index 03e097e1e2..324d0c6306 100644
--- a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java
+++ b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java
@@ -77,6 +77,11 @@ import sonia.scm.store.StoreFactory;
import sonia.scm.template.FreemarkerTemplateHandler;
import sonia.scm.template.TemplateHandler;
import sonia.scm.template.TemplateServlet;
+import sonia.scm.url.RestJsonUrlProvider;
+import sonia.scm.url.RestXmlUrlProvider;
+import sonia.scm.url.UrlProvider;
+import sonia.scm.url.UrlProviderFactory;
+import sonia.scm.url.WebUIUrlProvider;
import sonia.scm.user.UserManager;
import sonia.scm.user.xml.XmlUserManager;
import sonia.scm.util.DebugServlet;
@@ -244,6 +249,17 @@ public class ScmServletModule extends ServletModule
// bind httpclient
bind(HttpClient.class).to(URLHttpClient.class);
+ // bind url provider staff
+ bind(UrlProvider.class).annotatedWith(
+ Names.named(UrlProviderFactory.TYPE_RESTAPI_JSON)).toProvider(
+ RestJsonUrlProvider.class);
+ bind(UrlProvider.class).annotatedWith(
+ Names.named(UrlProviderFactory.TYPE_RESTAPI_XML)).toProvider(
+ RestXmlUrlProvider.class);
+ bind(UrlProvider.class).annotatedWith(
+ Names.named(UrlProviderFactory.TYPE_WUI)).toProvider(
+ WebUIUrlProvider.class);
+
/*
* filter(PATTERN_PAGE,
* PATTERN_STATIC_RESOURCES).through(StaticResourceFilter.class);
diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java
index 15ea897589..72a9746e77 100644
--- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java
+++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java
@@ -66,7 +66,6 @@ import sonia.scm.repository.RepositoryManager;
import sonia.scm.repository.RepositoryNotFoundException;
import sonia.scm.util.AssertUtil;
import sonia.scm.util.HttpUtil;
-import sonia.scm.util.SecurityUtil;
import sonia.scm.util.Util;
import sonia.scm.web.security.WebSecurityContext;
@@ -244,18 +243,7 @@ public class RepositoryResource
@Override
public Response get(@Context Request request, @PathParam("id") String id)
{
- Response response = null;
-
- if (SecurityUtil.isAdmin(securityContextProvider))
- {
- response = super.get(request, id);
- }
- else
- {
- response = Response.status(Response.Status.FORBIDDEN).build();
- }
-
- return response;
+ return super.get(request, id);
}
/**
@@ -410,6 +398,47 @@ public class RepositoryResource
return response;
}
+ /**
+ * Returns a repository.
+ *
+ * Status codes:
+ *
+ * - 200 get successful
+ * - 404 not found,
+ * no repository with the specified type and name available
+ * - 500 internal server error
+ *
+ *
+ * @param request the current request
+ * @param type the type of the repository
+ * @param name the name of the repository
+ *
+ * @return the {@link Repository} with the specified type and name
+ */
+ @GET
+ @Path("{type}/{name}")
+ @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ @TypeHint(Repository.class)
+ public Response getByTypeAndName(@Context Request request,
+ @PathParam("type") String type,
+ @PathParam("name") String name)
+ {
+ Response response = null;
+ Repository repository = repositoryManager.get(type, name);
+
+ if (repository != null)
+ {
+ prepareForReturn(repository);
+ response = Response.ok(repository).build();
+ }
+ else
+ {
+ response = Response.status(Response.Status.NOT_FOUND).build();
+ }
+
+ return response;
+ }
+
/**
* Returns a list of {@link Changeset} for the given repository.
*
@@ -570,7 +599,7 @@ public class RepositoryResource
@GET
@Path("{id}/diff")
@TypeHint(DiffStreamingOutput.class)
- @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
+ @Produces(MediaType.APPLICATION_OCTET_STREAM)
public Response getDiff(@PathParam("id") String id,
@QueryParam("revision") String revision,
@QueryParam("path") String path)
diff --git a/scm-webapp/src/main/java/sonia/scm/net/URLHttpClient.java b/scm-webapp/src/main/java/sonia/scm/net/URLHttpClient.java
index 3f298fe6cc..0c91afac1f 100644
--- a/scm-webapp/src/main/java/sonia/scm/net/URLHttpClient.java
+++ b/scm-webapp/src/main/java/sonia/scm/net/URLHttpClient.java
@@ -83,6 +83,9 @@ public class URLHttpClient implements HttpClient
/** Field description */
public static final String HEADER_ACCEPT_ENCODING_VALUE = "gzip";
+ /** Field description */
+ public static final String HEADER_AUTHORIZATION = "Authorization";
+
/** Field description */
public static final String HEADER_PROXY_AUTHORIZATION = "Proxy-Authorization";
@@ -141,7 +144,8 @@ public class URLHttpClient implements HttpClient
@Override
public HttpResponse post(String url) throws IOException
{
- HttpURLConnection connection = (HttpURLConnection) openConnection(url);
+ HttpURLConnection connection = (HttpURLConnection) openConnection(null,
+ url);
connection.setRequestMethod(METHOD_POST);
@@ -163,10 +167,180 @@ public class URLHttpClient implements HttpClient
public HttpResponse post(String url, Map> parameters)
throws IOException
{
- HttpURLConnection connection = (HttpURLConnection) openConnection(url);
+ HttpURLConnection connection = (HttpURLConnection) openConnection(null,
+ url);
connection.setRequestMethod(METHOD_POST);
+ appendPostParameter(connection, parameters);
+ return new URLHttpResponse(connection);
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param request
+ *
+ * @return
+ *
+ * @throws IOException
+ */
+ @Override
+ public HttpResponse post(HttpRequest request) throws IOException
+ {
+ HttpURLConnection connection = (HttpURLConnection) openConnection(request,
+ request.getUrl());
+
+ connection.setRequestMethod(METHOD_POST);
+ appendPostParameter(connection, request.getParameters());
+
+ return new URLHttpResponse(connection);
+ }
+
+ //~--- get methods ----------------------------------------------------------
+
+ /**
+ * Method description
+ *
+ *
+ * @param spec
+ *
+ * @return
+ *
+ * @throws IOException
+ */
+ @Override
+ public HttpResponse get(String spec) throws IOException
+ {
+ return new URLHttpResponse(openConnection(null, spec));
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param url
+ * @param parameters
+ *
+ * @return
+ *
+ * @throws IOException
+ */
+ @Override
+ public HttpResponse get(String url, Map> parameters)
+ throws IOException
+ {
+ url = createGetUrl(url, parameters);
+
+ return new URLHttpResponse(openConnection(null, url));
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param request
+ *
+ * @return
+ *
+ * @throws IOException
+ */
+ @Override
+ public HttpResponse get(HttpRequest request) throws IOException
+ {
+ String url = createGetUrl(request.getUrl(), request.getParameters());
+
+ return new URLHttpResponse(openConnection(request, url));
+ }
+
+ //~--- methods --------------------------------------------------------------
+
+ /**
+ * Method description
+ *
+ *
+ * @param connection
+ * @param header
+ * @param username
+ * @param password
+ */
+ private void appendBasicAuthHeader(HttpURLConnection connection,
+ String header, String username,
+ String password)
+ {
+ if (Util.isNotEmpty(username) || Util.isNotEmpty(password))
+ {
+ username = Util.nonNull(username);
+ password = Util.nonNull(password);
+
+ if (logger.isDebugEnabled())
+ {
+ logger.debug("append {} header for user {}", header, username);
+ }
+
+ String auth = username.concat(CREDENTIAL_SEPARATOR).concat(password);
+
+ auth = new String(Base64.encode(auth.getBytes()));
+ connection.addRequestProperty(header,
+ PREFIX_BASIC_AUTHENTICATION.concat(auth));
+ }
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param headers
+ * @param connection
+ */
+ private void appendHeaders(Map> headers,
+ URLConnection connection)
+ {
+ if (Util.isNotEmpty(headers))
+ {
+ for (Map.Entry> e : headers.entrySet())
+ {
+ String name = e.getKey();
+ List values = e.getValue();
+
+ if (Util.isNotEmpty(name) && Util.isNotEmpty(values))
+ {
+ for (String value : values)
+ {
+ if (logger.isTraceEnabled())
+ {
+ logger.trace("append header {}:{}", name, value);
+ }
+
+ connection.setRequestProperty(name, value);
+ }
+ }
+ else if (logger.isWarnEnabled())
+ {
+ logger.warn("value of {} header is empty", name);
+ }
+ }
+ }
+ else if (logger.isTraceEnabled())
+ {
+ logger.trace("header map is emtpy");
+ }
+ }
+
+ /**
+ * Method description
+ *
+ *
+ * @param connection
+ * @param parameters
+ *
+ * @throws IOException
+ */
+ private void appendPostParameter(HttpURLConnection connection,
+ Map> parameters)
+ throws IOException
+ {
if (Util.isNotEmpty(parameters))
{
connection.setDoOutput(true);
@@ -206,26 +380,6 @@ public class URLHttpClient implements HttpClient
IOUtil.close(writer);
}
}
-
- return new URLHttpResponse(connection);
- }
-
- //~--- get methods ----------------------------------------------------------
-
- /**
- * Method description
- *
- *
- * @param spec
- *
- * @return
- *
- * @throws IOException
- */
- @Override
- public HttpResponse get(String spec) throws IOException
- {
- return new URLHttpResponse(openConnection(spec));
}
/**
@@ -236,12 +390,8 @@ public class URLHttpClient implements HttpClient
* @param parameters
*
* @return
- *
- * @throws IOException
*/
- @Override
- public HttpResponse get(String url, Map> parameters)
- throws IOException
+ private String createGetUrl(String url, Map> parameters)
{
if (Util.isNotEmpty(parameters))
{
@@ -275,11 +425,9 @@ public class URLHttpClient implements HttpClient
url = ub.toString();
}
- return new URLHttpResponse(openConnection(url));
+ return url;
}
- //~--- methods --------------------------------------------------------------
-
/**
* Method description
*
@@ -306,30 +454,36 @@ public class URLHttpClient implements HttpClient
* Method description
*
*
+ *
+ * @param request
* @param spec
*
* @return
*
* @throws IOException
*/
- private URLConnection openConnection(String spec) throws IOException
+ private HttpURLConnection openConnection(HttpRequest request, String spec)
+ throws IOException
{
- return openConnection(new URL(spec));
+ return openConnection(request, new URL(spec));
}
/**
* Method description
*
*
+ *
+ * @param request
* @param url
*
* @return
*
* @throws IOException
*/
- private URLConnection openConnection(URL url) throws IOException
+ private HttpURLConnection openConnection(HttpRequest request, URL url)
+ throws IOException
{
- URLConnection connection = null;
+ HttpURLConnection connection = null;
if (configuration.isEnableProxy())
{
@@ -345,7 +499,9 @@ public class URLHttpClient implements HttpClient
new InetSocketAddress(configuration.getProxyServer(),
configuration.getProxyPort());
- connection = url.openConnection(new Proxy(Proxy.Type.HTTP, address));
+ connection =
+ (HttpURLConnection) url.openConnection(new Proxy(Proxy.Type.HTTP,
+ address));
}
else
{
@@ -354,11 +510,25 @@ public class URLHttpClient implements HttpClient
logger.debug("fetch '{}'", url.toExternalForm());
}
- connection = url.openConnection();
+ connection = (HttpURLConnection) url.openConnection();
}
connection.setReadTimeout(TIMEOUT_RAED);
connection.setConnectTimeout(TIMEOUT_CONNECTION);
+
+ if (request != null)
+ {
+ Map> headers = request.getHeaders();
+
+ appendHeaders(headers, connection);
+
+ String username = request.getUsername();
+ String password = request.getPassword();
+
+ appendBasicAuthHeader(connection, HEADER_AUTHORIZATION, username,
+ password);
+ }
+
connection.setRequestProperty(HEADER_ACCEPT_ENCODING,
HEADER_ACCEPT_ENCODING_VALUE);
connection.setRequestProperty(
@@ -367,21 +537,8 @@ public class URLHttpClient implements HttpClient
String username = configuration.getProxyUser();
String password = configuration.getProxyPassword();
- if (Util.isNotEmpty(username) || Util.isNotEmpty(password))
- {
- if (logger.isDebugEnabled())
- {
- logger.debug("enable proxy authentication for user '{}'",
- Util.nonNull(username));
- }
-
- String auth = Util.nonNull(username).concat(CREDENTIAL_SEPARATOR).concat(
- Util.nonNull(password));
-
- auth = PREFIX_BASIC_AUTHENTICATION.concat(
- new String(Base64.encode(auth.getBytes())));
- connection.setRequestProperty(HEADER_PROXY_AUTHORIZATION, auth);
- }
+ appendBasicAuthHeader(connection, HEADER_PROXY_AUTHORIZATION, username,
+ password);
return connection;
}
diff --git a/scm-webapp/src/main/java/sonia/scm/url/RestJsonUrlProvider.java b/scm-webapp/src/main/java/sonia/scm/url/RestJsonUrlProvider.java
new file mode 100644
index 0000000000..7be05d9f39
--- /dev/null
+++ b/scm-webapp/src/main/java/sonia/scm/url/RestJsonUrlProvider.java
@@ -0,0 +1,81 @@
+/**
+ * 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.url;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+import sonia.scm.config.ScmConfiguration;
+
+/**
+ *
+ * @author Sebastian Sdorra
+ */
+public class RestJsonUrlProvider implements Provider
+{
+
+ /**
+ * Constructs ...
+ *
+ *
+ * @param configuration
+ */
+ @Inject
+ public RestJsonUrlProvider(ScmConfiguration configuration)
+ {
+ this.configuration = configuration;
+ }
+
+ //~--- get methods ----------------------------------------------------------
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ @Override
+ public UrlProvider get()
+ {
+ return UrlProviderFactory.createUrlProvider(configuration.getBaseUrl(),
+ UrlProviderFactory.TYPE_RESTAPI_JSON);
+ }
+
+ //~--- fields ---------------------------------------------------------------
+
+ /** Field description */
+ private ScmConfiguration configuration;
+}
diff --git a/scm-webapp/src/main/java/sonia/scm/url/RestXmlUrlProvider.java b/scm-webapp/src/main/java/sonia/scm/url/RestXmlUrlProvider.java
new file mode 100644
index 0000000000..a4e8d8f1f2
--- /dev/null
+++ b/scm-webapp/src/main/java/sonia/scm/url/RestXmlUrlProvider.java
@@ -0,0 +1,81 @@
+/**
+ * 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.url;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+import sonia.scm.config.ScmConfiguration;
+
+/**
+ *
+ * @author Sebastian Sdorra
+ */
+public class RestXmlUrlProvider implements Provider
+{
+
+ /**
+ * Constructs ...
+ *
+ *
+ * @param configuration
+ */
+ @Inject
+ public RestXmlUrlProvider(ScmConfiguration configuration)
+ {
+ this.configuration = configuration;
+ }
+
+ //~--- get methods ----------------------------------------------------------
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ @Override
+ public UrlProvider get()
+ {
+ return UrlProviderFactory.createUrlProvider(configuration.getBaseUrl(),
+ UrlProviderFactory.TYPE_RESTAPI_XML);
+ }
+
+ //~--- fields ---------------------------------------------------------------
+
+ /** Field description */
+ private ScmConfiguration configuration;
+}
diff --git a/scm-webapp/src/main/java/sonia/scm/url/WebUIUrlProvider.java b/scm-webapp/src/main/java/sonia/scm/url/WebUIUrlProvider.java
new file mode 100644
index 0000000000..a71b3cd6d7
--- /dev/null
+++ b/scm-webapp/src/main/java/sonia/scm/url/WebUIUrlProvider.java
@@ -0,0 +1,81 @@
+/**
+ * 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.url;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import com.google.inject.Inject;
+import com.google.inject.Provider;
+
+import sonia.scm.config.ScmConfiguration;
+
+/**
+ *
+ * @author Sebastian Sdorra
+ */
+public class WebUIUrlProvider implements Provider
+{
+
+ /**
+ * Constructs ...
+ *
+ *
+ * @param configuration
+ */
+ @Inject
+ public WebUIUrlProvider(ScmConfiguration configuration)
+ {
+ this.configuration = configuration;
+ }
+
+ //~--- get methods ----------------------------------------------------------
+
+ /**
+ * Method description
+ *
+ *
+ * @return
+ */
+ @Override
+ public UrlProvider get()
+ {
+ return UrlProviderFactory.createUrlProvider(configuration.getBaseUrl(),
+ UrlProviderFactory.TYPE_WUI);
+ }
+
+ //~--- fields ---------------------------------------------------------------
+
+ /** Field description */
+ private ScmConfiguration configuration;
+}
diff --git a/scm-webapp/src/main/webapp/resources/js/config/sonia.config.repositoryconfig.js b/scm-webapp/src/main/webapp/resources/js/config/sonia.config.repositoryconfig.js
index 6ca37afda3..68f5a1dda7 100644
--- a/scm-webapp/src/main/webapp/resources/js/config/sonia.config.repositoryconfig.js
+++ b/scm-webapp/src/main/webapp/resources/js/config/sonia.config.repositoryconfig.js
@@ -34,6 +34,7 @@ Sonia.config.RepositoryConfig = Ext.extend(Sonia.config.ConfigPanel,{
initComponent: function(){
var config = {
+ title: main.tabRepositoryTypesText,
panels: repositoryConfigPanels
}
diff --git a/scm-webapp/src/main/webapp/resources/js/config/sonia.config.scmconfigpanel.js b/scm-webapp/src/main/webapp/resources/js/config/sonia.config.scmconfigpanel.js
index 0ca5e4772d..aa49d48aac 100644
--- a/scm-webapp/src/main/webapp/resources/js/config/sonia.config.scmconfigpanel.js
+++ b/scm-webapp/src/main/webapp/resources/js/config/sonia.config.scmconfigpanel.js
@@ -90,6 +90,7 @@ Sonia.config.ScmConfigPanel = Ext.extend(Sonia.config.ConfigPanel,{
initComponent: function(){
var config = {
+ title: main.navGeneralConfigText,
panels: [{
xtype: 'configForm',
title: this.titleText,
diff --git a/scm-webapp/src/main/webapp/resources/js/group/sonia.group.grid.js b/scm-webapp/src/main/webapp/resources/js/group/sonia.group.grid.js
index 7ed4599e6b..17e2f90d9a 100644
--- a/scm-webapp/src/main/webapp/resources/js/group/sonia.group.grid.js
+++ b/scm-webapp/src/main/webapp/resources/js/group/sonia.group.grid.js
@@ -48,7 +48,7 @@ Sonia.group.Grid = Ext.extend(Sonia.rest.Grid, {
url: restUrl + 'groups.json',
disableCaching: false
}),
- id: 'name',
+ idProperty: 'name',
fields: [ 'name', 'members', 'description', 'creationDate', 'type', 'properties'],
sortInfo: {
field: 'name'
diff --git a/scm-webapp/src/main/webapp/resources/js/group/sonia.group.panel.js b/scm-webapp/src/main/webapp/resources/js/group/sonia.group.panel.js
index a3e840db3c..f2971d16a8 100644
--- a/scm-webapp/src/main/webapp/resources/js/group/sonia.group.panel.js
+++ b/scm-webapp/src/main/webapp/resources/js/group/sonia.group.panel.js
@@ -181,14 +181,25 @@ Sonia.History.register('groupPanel', {
return token;
},
- onChange: function(repoId){
+ onChange: function(groupId){
var panel = Ext.getCmp('groups');
if ( ! panel ){
main.addGroupsTabPanel();
panel = Ext.getCmp('groups');
- }
- if (repoId){
- panel.getGrid().selectById(repoId);
+ if (groupId){
+ var selected = false;
+ panel.getGrid().getStore().addListener('load', function(){
+ if (!selected){
+ panel.getGrid().selectById(groupId);
+ selected = true;
+ }
+ });
+ }
+ } else {
+ main.addTab(panel);
+ if (groupId){
+ panel.getGrid().selectById(groupId);
+ }
}
}
});
\ No newline at end of file
diff --git a/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.grid.js b/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.grid.js
index a73dde78c4..62f47ec849 100644
--- a/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.grid.js
+++ b/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.grid.js
@@ -65,6 +65,7 @@ Sonia.plugin.Grid = Ext.extend(Sonia.rest.Grid, {
});
var config = {
+ title: main.tabPluginsText,
autoExpandColumn: 'description',
store: new Sonia.plugin.Store({
url: restUrl + 'plugins/overview.json'
diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewergrid.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewergrid.js
index 75604d0f93..a1ee25e495 100644
--- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewergrid.js
+++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewergrid.js
@@ -140,7 +140,7 @@ Sonia.repository.ChangesetViewerGrid = Ext.extend(Ext.grid.GridPanel, {
openDiffViewer: function(revision){
main.addTab({
- id: 'diffPanel|' + this.repository.id + '|' + revision,
+ id: 'diffPanel;' + this.repository.id + ';' + revision,
xtype: 'diffPanel',
repository: this.repository,
revision: revision,
@@ -150,7 +150,7 @@ Sonia.repository.ChangesetViewerGrid = Ext.extend(Ext.grid.GridPanel, {
openRepositoryBrowser: function(revision){
main.addTab({
- id: 'repositoryBrowser|' + this.repository.id + '|' + revision,
+ id: 'repositoryBrowser;' + this.repository.id + ';' + revision,
xtype: 'repositoryBrowser',
repository: this.repository,
revision: revision,
diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewerpanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewerpanel.js
index 8469c89451..4a1995809b 100644
--- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewerpanel.js
+++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewerpanel.js
@@ -154,7 +154,7 @@ Sonia.History.register('repositoryChangesetViewerPanel', {
if (limit){
limit = parseInt(limit);
}
- var id = 'repositoryChangesetViewerPanel|' + repoId;
+ var id = 'repositoryChangesetViewerPanel;' + repoId;
Sonia.repository.get(repoId, function(repository){
var panel = Ext.getCmp(id);
if (! panel){
diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.contentpanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.contentpanel.js
index 50bbcd8473..de8706da37 100644
--- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.contentpanel.js
+++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.contentpanel.js
@@ -210,7 +210,7 @@ Sonia.History.register('contentPanel', {
if (!view || view == 'null'){
view = 'content';
}
- var id = 'contentPanel|' + repoId + '|' + revision + '|' + path;
+ var id = 'contentPanel;' + repoId + ';' + revision + ';' + path;
Sonia.repository.get(repoId, function(repository){
var panel = Ext.getCmp(id);
if (! panel){
diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.diffpanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.diffpanel.js
index 3393e43fa3..c5abf52472 100644
--- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.diffpanel.js
+++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.diffpanel.js
@@ -81,7 +81,7 @@ Sonia.History.register('diffPanel', {
},
onChange: function(repoId, revision){
- var id = 'diffPanel|' + repoId + '|' + revision;
+ var id = 'diffPanel;' + repoId + ';' + revision;
Sonia.repository.get(repoId, function(repository){
var panel = Ext.getCmp(id);
if (! panel){
diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js
index 0edbd171e2..c27034865b 100644
--- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js
+++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.extendedinfopanel.js
@@ -95,7 +95,7 @@ Sonia.repository.ExtendedInfoPanel = Ext.extend(Sonia.repository.InfoPanel,{
createRepositoryBrowser: function(){
return {
- id: 'repositoryBrowser|' + this.item.id + '|null',
+ id: 'repositoryBrowser;' + this.item.id + ';null',
xtype: 'repositoryBrowser',
repository: this.item,
closable: true
diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.grid.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.grid.js
index a3ca4a2883..114f72b1ad 100644
--- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.grid.js
+++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.grid.js
@@ -55,6 +55,7 @@ Sonia.repository.Grid = Ext.extend(Sonia.rest.Grid, {
url: restUrl + 'repositories.json',
disableCaching: false
}),
+ idProperty: 'id',
reader: new Ext.data.JsonReader({
fields: [{
name: 'id'
@@ -81,7 +82,6 @@ Sonia.repository.Grid = Ext.extend(Sonia.rest.Grid, {
name: 'properties'
}]
}),
- id: 'id',
sortInfo: {
field: 'name'
},
diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js
index f0d0024da8..20c40c62a7 100644
--- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js
+++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.infopanel.js
@@ -148,7 +148,7 @@ Sonia.repository.InfoPanel = Ext.extend(Ext.Panel, {
createChangesetViewer: function(){
return {
- id: 'repositoryChangesetViewerPanel|' + this.item.id,
+ id: 'repositoryChangesetViewerPanel;' + this.item.id,
repository: this.item,
xtype: 'repositoryChangesetViewerPanel',
closable: true,
diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js
index f29668c29b..227bc0df1d 100644
--- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js
+++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js
@@ -107,7 +107,20 @@ Sonia.repository.get = function(id, callback){
if ( grid ){
var store = grid.getStore();
if (store){
- var rec = store.getById(id);
+ var rec = null;
+ var index = id.indexOf('/');
+ if ( index > 0 ){
+ var type = id.substring(0, index);
+ var name = id.substring(index);
+ index = store.findBy(function(rec){
+ return rec.get('name') == name && rec.get('type') == type;
+ });
+ if ( index >= 0 ){
+ rec = store.getAt(index);
+ }
+ } else {
+ rec = store.getById(id);
+ }
if (rec){
repository = rec.data;
}
diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js
index 28be95d035..6a76207fea 100644
--- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js
+++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js
@@ -295,9 +295,20 @@ Sonia.History.register('repositoryPanel', {
if ( ! panel ){
main.addRepositoriesTabPanel();
panel = Ext.getCmp('repositories');
- }
- if (repoId){
- panel.getGrid().selectById(repoId);
+ if ( repoId ){
+ var selected = false;
+ panel.getGrid().getStore().addListener('load', function(){
+ if (!selected){
+ panel.getGrid().selectedById(repoId);
+ selected = true;
+ }
+ });
+ }
+ } else {
+ main.addTab(panel);
+ if (repoId){
+ panel.getGrid().selectById(repoId);
+ }
}
}
});
\ No newline at end of file
diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js
index 91a099d1b4..4b181c8d9c 100644
--- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js
+++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js
@@ -329,7 +329,7 @@ Sonia.History.register('repositoryBrowser', {
if (path == 'null'){
path = '';
}
- var id = 'repositoryBrowser|' + repoId + "|" + revision;
+ var id = 'repositoryBrowser;' + repoId + ';' + revision;
Sonia.repository.get(repoId, function(repository){
var panel = Ext.getCmp(id);
if (! panel){
diff --git a/scm-webapp/src/main/webapp/resources/js/rest/sonia.rest.grid.js b/scm-webapp/src/main/webapp/resources/js/rest/sonia.rest.grid.js
index 08f06bc7e0..2c4e1a684a 100644
--- a/scm-webapp/src/main/webapp/resources/js/rest/sonia.rest.grid.js
+++ b/scm-webapp/src/main/webapp/resources/js/rest/sonia.rest.grid.js
@@ -134,6 +134,9 @@ Sonia.rest.Grid = Ext.extend(Ext.grid.GridPanel, {
},
selectById: function(id){
+ if (debug){
+ console.debug( 'select by id ' + id );
+ }
var index = this.getStore().indexOfId(id);
if ( index >= 0 ){
this.getSelectionModel().selectRow(index);
diff --git a/scm-webapp/src/main/webapp/resources/js/sonia.global.js b/scm-webapp/src/main/webapp/resources/js/sonia.global.js
index 5fa51f6b48..6d23c35b92 100644
--- a/scm-webapp/src/main/webapp/resources/js/sonia.global.js
+++ b/scm-webapp/src/main/webapp/resources/js/sonia.global.js
@@ -85,7 +85,7 @@ var groupSearchStore = new Ext.data.JsonStore({
Sonia = {
- idSeparator: '|',
+ idSeparator: ';',
idNoneObject: '-',
id: function(){
@@ -93,7 +93,7 @@ Sonia = {
for ( var i=0; i