From bb96e78efb4131bdb9fc150c17935bd06db9a207 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 28 Oct 2011 12:47:46 +0200 Subject: [PATCH 01/67] fix wrong mercurial hook url with mod_proxy --- .../src/main/java/sonia/scm/repository/HgHookManager.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgHookManager.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgHookManager.java index 698e0f68da..e5b21220b2 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgHookManager.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgHookManager.java @@ -108,7 +108,7 @@ public class HgHookManager { StringBuilder url = new StringBuilder(request.getScheme()); - url.append("://localhost:").append(request.getServerPort()); + url.append("://localhost:").append(request.getLocalPort()); url.append(request.getContextPath()).append("/hook/hg/"); if (hgHookScript == null) @@ -121,7 +121,8 @@ public class HgHookManager if (logger.isDebugEnabled()) { - logger.debug("write hg hook script to '{}'", hgHookScript); + logger.debug("write hg hook script for '{}' to '{}'", url, + hgHookScript); } writeScript(hgHookScript, url.toString()); From e9aa4ea3c36d61cf4d739aca86d26b79293f2847 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 28 Oct 2011 13:29:17 +0200 Subject: [PATCH 02/67] close branch issue-71 From 792954e6c346212f11cb7e82153a8b6257041db0 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Wed, 2 Nov 2011 16:14:55 +0100 Subject: [PATCH 03/67] allow spaces in usernames --- .../main/java/sonia/scm/util/HttpUtil.java | 53 +++++++++++++++++++ .../java/sonia/scm/util/ValidationUtil.java | 2 +- .../sonia/scm/util/ValidationUtilTest.java | 5 +- .../resources/AbstractManagerResource.java | 7 ++- .../resources/js/override/ext.form.vtypes.js | 2 +- 5 files changed, 65 insertions(+), 4 deletions(-) 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 58213e1d4b..819efb509c 100644 --- a/scm-core/src/main/java/sonia/scm/util/HttpUtil.java +++ b/scm-core/src/main/java/sonia/scm/util/HttpUtil.java @@ -43,6 +43,10 @@ import sonia.scm.config.ScmConfiguration; //~--- JDK imports ------------------------------------------------------------ import java.io.IOException; +import java.io.UnsupportedEncodingException; + +import java.net.URLDecoder; +import java.net.URLEncoder; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; @@ -58,6 +62,9 @@ public class HttpUtil /** authentication realm for basic authentication */ public static final String AUTHENTICATION_REALM = "SONIA :: SCM Manager"; + /** Field description */ + public static final String ENCODING = "UTF-8"; + /** authentication header */ public static final String HEADER_WWW_AUTHENTICATE = "WWW-Authenticate"; @@ -112,6 +119,52 @@ public class HttpUtil //~--- methods -------------------------------------------------------------- + /** + * Method description + * + * + * @param value + * + * @return + * @since 1.9 + */ + public static String decode(String value) + { + try + { + value = URLDecoder.decode(value, ENCODING); + } + catch (UnsupportedEncodingException ex) + { + throw new RuntimeException("could not decode", ex); + } + + return value; + } + + /** + * Method description + * + * + * @param value + * + * @return + * @since 1.9 + */ + public static String encode(String value) + { + try + { + value = URLEncoder.encode(value, ENCODING); + } + catch (UnsupportedEncodingException ex) + { + throw new RuntimeException("could not encode", ex); + } + + return value; + } + /** * Send an unauthorized header back to the client * diff --git a/scm-core/src/main/java/sonia/scm/util/ValidationUtil.java b/scm-core/src/main/java/sonia/scm/util/ValidationUtil.java index 7ad5ebfebf..65b079e0af 100644 --- a/scm-core/src/main/java/sonia/scm/util/ValidationUtil.java +++ b/scm-core/src/main/java/sonia/scm/util/ValidationUtil.java @@ -52,7 +52,7 @@ public class ValidationUtil private static final String REGEX_NAME = "^[A-z0-9\\.\\-_]+$"; /** Field description */ - private static final String REGEX_USERNAME = "^[A-z0-9\\.\\-_@]+$"; + private static final String REGEX_USERNAME = "^[^ ][A-z0-9\\.\\-_@ ]+[^ ]$"; //~--- get methods ---------------------------------------------------------- diff --git a/scm-core/src/test/java/sonia/scm/util/ValidationUtilTest.java b/scm-core/src/test/java/sonia/scm/util/ValidationUtilTest.java index e18871af24..6eff3f872f 100644 --- a/scm-core/src/test/java/sonia/scm/util/ValidationUtilTest.java +++ b/scm-core/src/test/java/sonia/scm/util/ValidationUtilTest.java @@ -145,9 +145,12 @@ public class ValidationUtilTest assertTrue(ValidationUtil.isUsernameValid("Test123-git")); assertTrue(ValidationUtil.isUsernameValid("Test_user-123.git")); assertTrue(ValidationUtil.isUsernameValid("test@scm-manager.de")); + assertTrue(ValidationUtil.isUsernameValid("test 123")); // false - assertFalse(ValidationUtil.isUsernameValid("test 123")); + assertFalse(ValidationUtil.isUsernameValid(" test 123")); + assertFalse(ValidationUtil.isUsernameValid(" test 123 ")); + assertFalse(ValidationUtil.isUsernameValid("test 123 ")); assertFalse(ValidationUtil.isUsernameValid("test/123")); assertFalse(ValidationUtil.isUsernameValid("test%123")); assertFalse(ValidationUtil.isUsernameValid("test:123")); diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractManagerResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractManagerResource.java index 7c82bddc87..19854b5192 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractManagerResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractManagerResource.java @@ -45,6 +45,7 @@ import sonia.scm.Manager; import sonia.scm.ModelObject; import sonia.scm.security.ScmSecurityException; import sonia.scm.util.AssertUtil; +import sonia.scm.util.HttpUtil; import sonia.scm.util.Util; //~--- JDK imports ------------------------------------------------------------ @@ -142,9 +143,13 @@ public abstract class AbstractManagerResource Date: Thu, 3 Nov 2011 08:56:51 +0100 Subject: [PATCH 04/67] improve handling of the admin flag --- scm-webapp/pom.xml | 2 +- .../web/security/BasicSecurityContext.java | 89 ++++++++++++++----- .../resources/js/user/sonia.user.formpanel.js | 2 + 3 files changed, 72 insertions(+), 21 deletions(-) diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index 1b053644ab..84427e2955 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -356,7 +356,7 @@ 1.13 1.0 3.0.3 - gfv3ee6 + Tomcat diff --git a/scm-webapp/src/main/java/sonia/scm/web/security/BasicSecurityContext.java b/scm-webapp/src/main/java/sonia/scm/web/security/BasicSecurityContext.java index 58891c3a47..5f9ca864b1 100644 --- a/scm-webapp/src/main/java/sonia/scm/web/security/BasicSecurityContext.java +++ b/scm-webapp/src/main/java/sonia/scm/web/security/BasicSecurityContext.java @@ -123,43 +123,82 @@ public class BasicSecurityContext implements WebSecurityContext AuthenticationResult ar = authenticator.authenticate(request, response, username, password); - if (ar != null) + if ((ar != null) && (ar.getState() == AuthenticationState.SUCCESS)) { user = ar.getUser(); try { + Set groupSet = new HashSet(); + + // load external groups + Collection extGroups = ar.getGroups(); + + if (extGroups != null) + { + groupSet.addAll(extGroups); + } + + // load internal groups + loadGroups(groupSet); + + // check for admin user + if (!user.isAdmin()) + { + user.setAdmin(isAdmin(groupSet)); + + if (logger.isDebugEnabled() && user.isAdmin()) + { + logger.debug("user '{}' is marked as admin by configuration", + user.getType(), user.getName()); + } + } + else if (logger.isDebugEnabled()) + { + logger.debug("authenticator {} marked user '{}' as admin", + user.getType(), user.getName()); + } + + // store user User dbUser = userManager.get(user.getName()); - if ((dbUser != null) && user.copyProperties(dbUser, false)) + if (dbUser != null) { - userManager.modify(dbUser); + + // if database user is an admin, set admin for the current user + if (dbUser.isAdmin()) + { + if (logger.isDebugEnabled()) + { + logger.debug("user '{}' is marked as admin by local database", + user.getType(), user.getName()); + } + + user.setAdmin(true); + } + + // modify existing user, copy properties except password and admin + if (user.copyProperties(dbUser, false)) + { + userManager.modify(dbUser); + } } + + // create new user else if (dbUser == null) { userManager.create(user); } - Collection groupCollection = ar.getGroups(); - - if (groupCollection != null) - { - groups.addAll(groupCollection); - } - - loadGroups(); - - if (!user.isAdmin()) - { - user.setAdmin(isAdmin()); - } + groups = groupSet; if (logger.isDebugEnabled()) { logGroups(); } - String credentials = dbUser.getName(); + // store encrypted credentials in session + String credentials = user.getName(); if (Util.isNotEmpty(password)) { @@ -172,6 +211,12 @@ public class BasicSecurityContext implements WebSecurityContext catch (Exception ex) { user = null; + + if (groups != null) + { + groups.clear(); + } + logger.error("authentication failed", ex); } } @@ -253,8 +298,10 @@ public class BasicSecurityContext implements WebSecurityContext /** * Method description * + * + * @param groupSet */ - private void loadGroups() + private void loadGroups(Set groupSet) { Collection groupCollection = groupManager.getGroupsForMember(user.getName()); @@ -263,7 +310,7 @@ public class BasicSecurityContext implements WebSecurityContext { for (Group group : groupCollection) { - groups.add(group.getName()); + groupSet.add(group.getName()); } } } @@ -308,9 +355,11 @@ public class BasicSecurityContext implements WebSecurityContext * Method description * * + * + * @param groups * @return */ - private boolean isAdmin() + private boolean isAdmin(Collection groups) { boolean result = false; Set adminUsers = configuration.getAdminUsers(); diff --git a/scm-webapp/src/main/webapp/resources/js/user/sonia.user.formpanel.js b/scm-webapp/src/main/webapp/resources/js/user/sonia.user.formpanel.js index 84f6a906e4..a19ce5d471 100644 --- a/scm-webapp/src/main/webapp/resources/js/user/sonia.user.formpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/user/sonia.user.formpanel.js @@ -62,12 +62,14 @@ Sonia.user.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ fieldLabel: this.displayNameText, name: 'displayName', allowBlank: false, + readOnly: this.item != null && this.item != 'xml', helpText: this.displayNameHelpText },{ fieldLabel: this.mailText, name: 'mail', allowBlank: true, vtype: 'email', + readOnly: this.item != null && this.item != 'xml', helpText: this.mailHelpText }]; From 453571f3c4a604a96ec239d33282211da33e68d8 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 3 Nov 2011 14:13:18 +0100 Subject: [PATCH 05/67] fix mercurial hooks with configured force base url --- .../sonia/scm/repository/HgHookManager.java | 66 +++++++++++++++++-- 1 file changed, 59 insertions(+), 7 deletions(-) diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgHookManager.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgHookManager.java index e5b21220b2..00224509e8 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgHookManager.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/repository/HgHookManager.java @@ -41,9 +41,12 @@ import com.google.inject.Singleton; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import sonia.scm.ConfigChangedListener; import sonia.scm.SCMContextProvider; +import sonia.scm.config.ScmConfiguration; import sonia.scm.io.RegexResourceProcessor; import sonia.scm.io.ResourceProcessor; +import sonia.scm.util.HttpUtil; import sonia.scm.util.IOUtil; import sonia.scm.web.HgWebConfigWriter; @@ -64,7 +67,7 @@ import javax.servlet.http.HttpServletRequest; * @author Sebastian Sdorra */ @Singleton -public class HgHookManager +public class HgHookManager implements ConfigChangedListener { /** Field description */ @@ -81,15 +84,31 @@ public class HgHookManager * * * @param context + * @param configuration */ @Inject - public HgHookManager(SCMContextProvider context) + public HgHookManager(SCMContextProvider context, + ScmConfiguration configuration) { this.context = context; + this.configuration = configuration; + this.configuration.addListener(this); } //~--- methods -------------------------------------------------------------- + /** + * Method description + * + * + * @param config + */ + @Override + public void configChanged(ScmConfiguration config) + { + this.changed = true; + } + /** * TODO check if file exists * @@ -106,10 +125,7 @@ public class HgHookManager { if (isScriptWriteAble()) { - StringBuilder url = new StringBuilder(request.getScheme()); - - url.append("://localhost:").append(request.getLocalPort()); - url.append(request.getContextPath()).append("/hook/hg/"); + String url = createUrl(request); if (hgHookScript == null) { @@ -126,6 +142,7 @@ public class HgHookManager } writeScript(hgHookScript, url.toString()); + changed = false; } } } @@ -159,6 +176,35 @@ public class HgHookManager //~--- methods -------------------------------------------------------------- + /** + * Method description + * + * + * @param request + * + * @return + */ + private String createUrl(HttpServletRequest request) + { + String url = null; + + if (configuration.isForceBaseUrl()) + { + url = HttpUtil.getUriWithoutEndSeperator( + configuration.getBaseUrl()).concat("/hook/hg/"); + } + else + { + StringBuilder sb = new StringBuilder(request.getScheme()); + + sb.append("://localhost:").append(request.getLocalPort()); + sb.append(request.getContextPath()).append("/hook/hg/"); + url = sb.toString(); + } + + return url; + } + /** * Method description * @@ -203,14 +249,20 @@ public class HgHookManager */ private boolean isScriptWriteAble() { - return (hgHookScript == null) ||!hgHookScript.exists(); + return (hgHookScript == null) ||!hgHookScript.exists() || changed; } //~--- fields --------------------------------------------------------------- + /** Field description */ + private boolean changed = false; + /** Field description */ private String challenge = UUID.randomUUID().toString(); + /** Field description */ + private ScmConfiguration configuration; + /** Field description */ private SCMContextProvider context; From acedaeff452833ae0c59aac6c4d89fd0cce1e513 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Thu, 3 Nov 2011 14:14:56 +0100 Subject: [PATCH 06/67] fix rolling policy for release logging --- scm-webapp/src/main/resources/logback.release.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scm-webapp/src/main/resources/logback.release.xml b/scm-webapp/src/main/resources/logback.release.xml index 434856cc98..05e383d6f7 100644 --- a/scm-webapp/src/main/resources/logback.release.xml +++ b/scm-webapp/src/main/resources/logback.release.xml @@ -50,7 +50,7 @@ ${LOGDIR}/scm-manager.log - scm-manager-%i.log + ${LOGDIR}/scm-manager-%i.log 1 10 From 0df83ac0aa80a10717922ec790e852a4c62a308e Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sat, 5 Nov 2011 18:16:23 +0100 Subject: [PATCH 07/67] change order of widgets --- .../src/main/webapp/template/footer.html | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/scm-plugin-backend/src/main/webapp/template/footer.html b/scm-plugin-backend/src/main/webapp/template/footer.html index d65c40b3fc..5b590053ec 100644 --- a/scm-plugin-backend/src/main/webapp/template/footer.html +++ b/scm-plugin-backend/src/main/webapp/template/footer.html @@ -43,12 +43,6 @@ var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(po, s); })(); - + + From ebc314a189f0bccc66485c2cce6b7df04a14bcbf Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 6 Nov 2011 14:43:57 +0100 Subject: [PATCH 08/67] added category and screenshots to plugin information --- .../sonia/scm/plugin/PluginInformation.java | 102 +++++++++++++++--- 1 file changed, 89 insertions(+), 13 deletions(-) diff --git a/scm-core/src/main/java/sonia/scm/plugin/PluginInformation.java b/scm-core/src/main/java/sonia/scm/plugin/PluginInformation.java index c5f61b6ada..72ddfb6507 100644 --- a/scm-core/src/main/java/sonia/scm/plugin/PluginInformation.java +++ b/scm-core/src/main/java/sonia/scm/plugin/PluginInformation.java @@ -40,6 +40,10 @@ import sonia.scm.util.Util; //~--- JDK imports ------------------------------------------------------------ +import java.util.List; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; /** @@ -73,8 +77,16 @@ public class PluginInformation implements Validateable final PluginInformation other = (PluginInformation) obj; - if ((this.condition != other.condition) - && ((this.condition == null) ||!this.condition.equals(other.condition))) + if ((this.screenshots != other.screenshots) + && ((this.screenshots == null) + ||!this.screenshots.equals(other.screenshots))) + { + return false; + } + + if ((this.category == null) + ? (other.category != null) + : !this.category.equals(other.category)) { return false; } @@ -93,6 +105,12 @@ public class PluginInformation implements Validateable return false; } + if ((this.condition != other.condition) + && ((this.condition == null) ||!this.condition.equals(other.condition))) + { + return false; + } + if ((this.description == null) ? (other.description != null) : !this.description.equals(other.description)) @@ -145,33 +163,39 @@ public class PluginInformation implements Validateable @Override public int hashCode() { - int hash = 5; + int hash = 7; - hash = 83 * hash + ((this.condition != null) - ? this.condition.hashCode() + hash = 61 * hash + ((this.screenshots != null) + ? this.screenshots.hashCode() : 0); - hash = 83 * hash + ((this.artifactId != null) + hash = 61 * hash + ((this.category != null) + ? this.category.hashCode() + : 0); + hash = 61 * hash + ((this.artifactId != null) ? this.artifactId.hashCode() : 0); - hash = 83 * hash + ((this.author != null) + hash = 61 * hash + ((this.author != null) ? this.author.hashCode() : 0); - hash = 83 * hash + ((this.description != null) + hash = 61 * hash + ((this.condition != null) + ? this.condition.hashCode() + : 0); + hash = 61 * hash + ((this.description != null) ? this.description.hashCode() : 0); - hash = 83 * hash + ((this.groupId != null) + hash = 61 * hash + ((this.groupId != null) ? this.groupId.hashCode() : 0); - hash = 83 * hash + ((this.name != null) + hash = 61 * hash + ((this.name != null) ? this.name.hashCode() : 0); - hash = 83 * hash + ((this.state != null) + hash = 61 * hash + ((this.state != null) ? this.state.hashCode() : 0); - hash = 83 * hash + ((this.url != null) + hash = 61 * hash + ((this.url != null) ? this.url.hashCode() : 0); - hash = 83 * hash + ((this.version != null) + hash = 61 * hash + ((this.version != null) ? this.version.hashCode() : 0); @@ -202,6 +226,17 @@ public class PluginInformation implements Validateable return author; } + /** + * Method description + * + * + * @return + */ + public String getCategory() + { + return category; + } + /** * Method description * @@ -261,6 +296,17 @@ public class PluginInformation implements Validateable return name; } + /** + * Method description + * + * + * @return + */ + public List getScreenshots() + { + return screenshots; + } + /** * Method description * @@ -331,6 +377,17 @@ public class PluginInformation implements Validateable this.author = author; } + /** + * Method description + * + * + * @param category + */ + public void setCategory(String category) + { + this.category = category; + } + /** * Method description * @@ -375,6 +432,17 @@ public class PluginInformation implements Validateable this.name = name; } + /** + * Method description + * + * + * @param screenshots + */ + public void setScreenshots(List screenshots) + { + this.screenshots = screenshots; + } + /** * Method description * @@ -416,6 +484,9 @@ public class PluginInformation implements Validateable /** Field description */ private String author; + /** Field description */ + private String category; + /** Field description */ private PluginCondition condition; @@ -428,6 +499,11 @@ public class PluginInformation implements Validateable /** Field description */ private String name; + /** Field description */ + @XmlElement(name = "screenshot") + @XmlElementWrapper(name = "screenshots") + private List screenshots; + /** Field description */ private PluginState state; From bd244f1be4d1ef49a99c573284fe3f469c830019 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 6 Nov 2011 15:06:58 +0100 Subject: [PATCH 09/67] fix jaxb exception --- scm-core/src/main/java/sonia/scm/plugin/PluginInformation.java | 3 +++ 1 file changed, 3 insertions(+) diff --git a/scm-core/src/main/java/sonia/scm/plugin/PluginInformation.java b/scm-core/src/main/java/sonia/scm/plugin/PluginInformation.java index 72ddfb6507..18fde8a044 100644 --- a/scm-core/src/main/java/sonia/scm/plugin/PluginInformation.java +++ b/scm-core/src/main/java/sonia/scm/plugin/PluginInformation.java @@ -42,6 +42,8 @@ import sonia.scm.util.Util; import java.util.List; +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; @@ -50,6 +52,7 @@ import javax.xml.bind.annotation.XmlRootElement; * * @author Sebastian Sdorra */ +@XmlAccessorType(XmlAccessType.FIELD) @XmlRootElement(name = "plugin-information") public class PluginInformation implements Validateable { From cf8b67bbbc96e287c7fb3327beee9097aba5d961 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 6 Nov 2011 15:13:26 +0100 Subject: [PATCH 10/67] use categories in plugin overview --- .../main/java/sonia/scm/plugin/Category.java | 128 ++++++++++++++++++ .../scm/plugin/CategoryNameComaparator.java | 71 ++++++++++ .../scm/plugin/rest/OverviewResource.java | 54 ++++++-- scm-plugin-backend/src/main/webapp/index.html | 19 ++- 4 files changed, 257 insertions(+), 15 deletions(-) create mode 100644 scm-plugin-backend/src/main/java/sonia/scm/plugin/Category.java create mode 100644 scm-plugin-backend/src/main/java/sonia/scm/plugin/CategoryNameComaparator.java diff --git a/scm-plugin-backend/src/main/java/sonia/scm/plugin/Category.java b/scm-plugin-backend/src/main/java/sonia/scm/plugin/Category.java new file mode 100644 index 0000000000..57dbed6399 --- /dev/null +++ b/scm-plugin-backend/src/main/java/sonia/scm/plugin/Category.java @@ -0,0 +1,128 @@ +/** + * 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.plugin; + +//~--- JDK imports ------------------------------------------------------------ + +import java.util.Arrays; +import java.util.SortedSet; +import java.util.TreeSet; + +/** + * + * @author Sebastian Sdorra + */ +public class Category +{ + + /** + * Constructs ... + * + * + * @param name + * @param plugins + */ + public Category(String name, PluginInformation... plugins) + { + this.name = name; + this.plugins = + new TreeSet(PluginInformationNameComparator.INSTANCE); + + if (plugins != null) + { + this.plugins.addAll(Arrays.asList(plugins)); + } + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + public String getName() + { + return name; + } + + /** + * Method description + * + * + * @return + */ + public SortedSet getPlugins() + { + if (plugins == null) + { + plugins = new TreeSet(); + } + + return plugins; + } + + //~--- set methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param name + */ + public void setName(String name) + { + this.name = name; + } + + /** + * Method description + * + * + * @param plugins + */ + public void setPlugins(SortedSet plugins) + { + this.plugins = plugins; + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private String name; + + /** Field description */ + private SortedSet plugins; +} diff --git a/scm-plugin-backend/src/main/java/sonia/scm/plugin/CategoryNameComaparator.java b/scm-plugin-backend/src/main/java/sonia/scm/plugin/CategoryNameComaparator.java new file mode 100644 index 0000000000..26f560e41a --- /dev/null +++ b/scm-plugin-backend/src/main/java/sonia/scm/plugin/CategoryNameComaparator.java @@ -0,0 +1,71 @@ +/** + * 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.plugin; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.util.Comparator; + +/** + * + * @author Sebastian Sdorra + */ +public class CategoryNameComaparator implements Comparator +{ + + /** Field description */ + public static final CategoryNameComaparator INSTANCE = + new CategoryNameComaparator(); + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param c1 + * @param c2 + * + * @return + */ + @Override + public int compare(Category c1, Category c2) + { + return Util.compare(c1.getName(), c2.getName()); + } +} diff --git a/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/OverviewResource.java b/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/OverviewResource.java index 170d9a6fb9..78e5f07870 100644 --- a/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/OverviewResource.java +++ b/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/OverviewResource.java @@ -37,9 +37,11 @@ package sonia.scm.plugin.rest; import com.google.inject.Inject; +import sonia.scm.plugin.Category; +import sonia.scm.plugin.CategoryNameComaparator; import sonia.scm.plugin.PluginBackend; import sonia.scm.plugin.PluginInformation; -import sonia.scm.plugin.PluginInformationNameComparator; +import sonia.scm.util.Util; //~--- JDK imports ------------------------------------------------------------ @@ -47,6 +49,7 @@ import com.sun.jersey.api.view.Viewable; import java.util.ArrayList; import java.util.Collections; +import java.util.HashMap; import java.util.List; import java.util.Map; @@ -63,6 +66,11 @@ import javax.ws.rs.Path; public class OverviewResource extends ViewableResource { + /** Field description */ + public static final String DEFAULT_CATEGORY = "Miscellaneous"; + + //~--- constructors --------------------------------------------------------- + /** * Constructs ... * @@ -89,14 +97,42 @@ public class OverviewResource extends ViewableResource @GET public Viewable overview() { - List plugins = getPluginOverview(); + List categories = getPluginOverview(); Map vars = createVarMap("Plugin Overview"); - vars.put("plugins", plugins); + vars.put("categories", categories); return new Viewable("/index", vars); } + /** + * Method description + * + * + * @param categories + * @param plugin + */ + private void append(Map categories, + PluginInformation plugin) + { + String name = plugin.getCategory(); + + if (Util.isEmpty(name)) + { + name = DEFAULT_CATEGORY; + } + + Category category = categories.get(name); + + if (category == null) + { + category = new Category(name, plugin); + categories.put(name, category); + } + + category.getPlugins().add(plugin); + } + //~--- get methods ---------------------------------------------------------- /** @@ -105,14 +141,14 @@ public class OverviewResource extends ViewableResource * * @return */ - private List getPluginOverview() + private List getPluginOverview() { List allPlugins = backend.getPlugins(); Collections.sort(allPlugins, PluginInformationComparator.INSTANCE); - List plugins = new ArrayList(); String pid = ""; + Map categoryMap = new HashMap(); for (PluginInformation p : allPlugins) { @@ -121,13 +157,15 @@ public class OverviewResource extends ViewableResource if (!currentPid.equals(pid)) { pid = currentPid; - plugins.add(p); + append(categoryMap, p); } } - Collections.sort(plugins, PluginInformationNameComparator.INSTANCE); + List categories = new ArrayList(categoryMap.values()); - return plugins; + Collections.sort(categories, CategoryNameComaparator.INSTANCE); + + return categories; } //~--- fields --------------------------------------------------------------- diff --git a/scm-plugin-backend/src/main/webapp/index.html b/scm-plugin-backend/src/main/webapp/index.html index b4747f7ab9..1211979cff 100644 --- a/scm-plugin-backend/src/main/webapp/index.html +++ b/scm-plugin-backend/src/main/webapp/index.html @@ -1,18 +1,23 @@ <#include "template/header.html"> -
-<#list plugins as plugin> -

${plugin.name}

-
- ${plugin.description}
- more +
+<#list categories as category> +

${category.name}

+
+ <#list category.plugins as plugin> +

${plugin.name}

+
+ ${plugin.description}
+ more +
+
+ From b2459d1222047dd54bcea1801398a1a78954fbe7 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 6 Nov 2011 18:14:58 +0100 Subject: [PATCH 16/67] fix possible NullPointerException --- .../scm/plugin/PluginInformationComparator.java | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/scm-core/src/main/java/sonia/scm/plugin/PluginInformationComparator.java b/scm-core/src/main/java/sonia/scm/plugin/PluginInformationComparator.java index cdb0777cae..fa9fb606b9 100644 --- a/scm-core/src/main/java/sonia/scm/plugin/PluginInformationComparator.java +++ b/scm-core/src/main/java/sonia/scm/plugin/PluginInformationComparator.java @@ -78,8 +78,21 @@ public class PluginInformationComparator if (result == 0) { - result = plugin.getState().getCompareValue() - - other.getState().getCompareValue(); + PluginState state = plugin.getState(); + PluginState otherState = other.getState(); + + if ((state != null) && (otherState != null)) + { + result = state.getCompareValue() - otherState.getCompareValue(); + } + else if ((state == null) && (otherState != null)) + { + result = 1; + } + else if ((state != null) && (otherState == null)) + { + result = -1; + } } } From fc90b92b97346b024ebbc110e0683ecd4c7775f5 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 6 Nov 2011 18:33:55 +0100 Subject: [PATCH 17/67] create thumbnail's from screenshots --- scm-plugin-backend/pom.xml | 13 ++ .../java/sonia/scm/plugin/PluginUtil.java | 174 ++++++++++++++ .../sonia/scm/plugin/rest/DetailResource.java | 98 +------- .../scm/plugin/rest/ScreenshotResource.java | 215 ++++++++++++++++++ .../src/main/webapp/detail.html | 26 +++ 5 files changed, 434 insertions(+), 92 deletions(-) create mode 100644 scm-plugin-backend/src/main/java/sonia/scm/plugin/PluginUtil.java create mode 100644 scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/ScreenshotResource.java diff --git a/scm-plugin-backend/pom.xml b/scm-plugin-backend/pom.xml index 018feebe88..9da97a4fa8 100644 --- a/scm-plugin-backend/pom.xml +++ b/scm-plugin-backend/pom.xml @@ -68,6 +68,12 @@ ehcache-core ${ehcache.version} + + + com.thebuzzmedia + imgscalr-lib + 3.2 + @@ -115,4 +121,11 @@ + + + The Buzz Media Maven Repository + http://maven.thebuzzmedia.com + + + diff --git a/scm-plugin-backend/src/main/java/sonia/scm/plugin/PluginUtil.java b/scm-plugin-backend/src/main/java/sonia/scm/plugin/PluginUtil.java new file mode 100644 index 0000000000..e4e09c89a3 --- /dev/null +++ b/scm-plugin-backend/src/main/java/sonia/scm/plugin/PluginUtil.java @@ -0,0 +1,174 @@ +/** + * 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.plugin; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +/** + * + * @author Sebastian Sdorra + */ +public class PluginUtil +{ + + /** + * Method description + * + * + * @param plugins + * + * @return + */ + public static List filterSameVersions( + List plugins) + { + List filteredPlugins = + new ArrayList(); + String version = ""; + + for (PluginInformation plugin : plugins) + { + if (!version.equals(plugin.getVersion())) + { + version = plugin.getVersion(); + filteredPlugins.add(plugin); + } + } + + return filteredPlugins; + } + + /** + * Method description + * + * + * @param allVersions + * + * @return + */ + public static List filterSnapshots( + List allVersions) + { + List filtered = new ArrayList(); + + for (PluginInformation plugin : allVersions) + { + if (!plugin.getVersion().contains("SNAPSHOT")) + { + filtered.add(plugin); + } + } + + return filtered; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param backend + * @param groupId + * @param artifactId + * + * @return + */ + public static List getFilteredPluginVersions( + PluginBackend backend, String groupId, String artifactId) + { + List pluginVersions = + PluginUtil.getPluginVersions(backend, groupId, artifactId); + + if (Util.isNotEmpty(pluginVersions)) + { + Collections.sort(pluginVersions, PluginInformationNameComparator.INSTANCE); + pluginVersions = PluginUtil.filterSameVersions(pluginVersions); + } + + return pluginVersions; + } + + /** + * Method description + * + * + * @param backend + * @param groupId + * @param artifactId + * + * @return + */ + public static PluginInformation getLatestPluginVersion(PluginBackend backend, + String groupId, String artifactId) + { + return getFilteredPluginVersions(backend, groupId, artifactId).get(0); + } + + /** + * Method description + * + * + * + * @param backend + * @param groupId + * @param artifactId + * + * @return + */ + public static List getPluginVersions( + PluginBackend backend, final String groupId, final String artifactId) + { + List pluginVersions = + backend.getPlugins(new PluginFilter() + { + @Override + public boolean accept(PluginInformation plugin) + { + return groupId.equals(plugin.getGroupId()) + && artifactId.equals(plugin.getArtifactId()); + } + }); + + return pluginVersions; + } +} diff --git a/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/DetailResource.java b/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/DetailResource.java index 85be9c70e7..575d9d1088 100644 --- a/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/DetailResource.java +++ b/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/DetailResource.java @@ -38,16 +38,14 @@ package sonia.scm.plugin.rest; import com.google.inject.Inject; import sonia.scm.plugin.PluginBackend; -import sonia.scm.plugin.PluginFilter; import sonia.scm.plugin.PluginInformation; +import sonia.scm.plugin.PluginUtil; import sonia.scm.util.Util; //~--- JDK imports ------------------------------------------------------------ import com.sun.jersey.api.view.Viewable; -import java.util.ArrayList; -import java.util.Collections; import java.util.List; import java.util.Map; @@ -102,22 +100,19 @@ public class DetailResource extends ViewableResource @DefaultValue("false") @QueryParam("snapshot") boolean snapshot) { - List pluginVersions = getPluginVersions(groupId, - artifactId); - - if (Util.isEmpty(pluginVersions)) + List pluginVersions = PluginUtil.getFilteredPluginVersions( + backend, groupId, artifactId); + + if (Util.isEmpty(pluginVersions)) { throw new WebApplicationException(Status.NOT_FOUND); } - Collections.sort(pluginVersions, PluginInformationComparator.INSTANCE); - pluginVersions = filterSameVersions(pluginVersions); - PluginInformation latest = pluginVersions.get(0); if (!snapshot) { - pluginVersions = filterSnapshots(pluginVersions); + pluginVersions = PluginUtil.filterSnapshots(pluginVersions); } Map vars = createVarMap(latest.getName()); @@ -128,87 +123,6 @@ public class DetailResource extends ViewableResource return new Viewable("/detail", vars); } - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @param plugins - * - * @return - */ - private List filterSameVersions( - List plugins) - { - List filteredPlugins = - new ArrayList(); - String version = ""; - - for (PluginInformation plugin : plugins) - { - if (!version.equals(plugin.getVersion())) - { - version = plugin.getVersion(); - filteredPlugins.add(plugin); - } - } - - return filteredPlugins; - } - - /** - * Method description - * - * - * @param allVersions - * - * @return - */ - private List filterSnapshots( - List allVersions) - { - List filtered = new ArrayList(); - - for (PluginInformation plugin : allVersions) - { - if (!plugin.getVersion().contains("SNAPSHOT")) - { - filtered.add(plugin); - } - } - - return filtered; - } - - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @param groupId - * @param artifactId - * - * @return - */ - private List getPluginVersions(final String groupId, - final String artifactId) - { - List pluginVersions = - backend.getPlugins(new PluginFilter() - { - @Override - public boolean accept(PluginInformation plugin) - { - return groupId.equals(plugin.getGroupId()) - && artifactId.equals(plugin.getArtifactId()); - } - }); - - return pluginVersions; - } - //~--- fields --------------------------------------------------------------- /** Field description */ diff --git a/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/ScreenshotResource.java b/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/ScreenshotResource.java new file mode 100644 index 0000000000..4b6a02c25d --- /dev/null +++ b/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/ScreenshotResource.java @@ -0,0 +1,215 @@ +/** + * 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.plugin.rest; + +//~--- non-JDK imports -------------------------------------------------------- + +import com.google.inject.Inject; + +import com.thebuzzmedia.imgscalr.Scalr; + +import sonia.scm.plugin.PluginBackend; +import sonia.scm.plugin.PluginInformation; +import sonia.scm.plugin.PluginUtil; +import sonia.scm.util.ChecksumUtil; +import sonia.scm.util.IOUtil; +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.awt.image.BufferedImage; +import java.awt.image.BufferedImageOp; + +import java.io.File; +import java.io.IOException; + +import java.net.URL; + +import java.util.List; + +import javax.imageio.ImageIO; + +import javax.ws.rs.GET; +import javax.ws.rs.Path; +import javax.ws.rs.PathParam; +import javax.ws.rs.Produces; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.Response; +import javax.ws.rs.core.Response.Status; + +/** + * + * @author Sebastian Sdorra + */ +@Path("/screenshot/{groupId}/{artifactId}/{number}/{size}.jpg") +public class ScreenshotResource +{ + + /** Field description */ + public static final String EXTENSION_IMAGE = ".jpg"; + + /** Field description */ + public static final String FORMAT = "jpg"; + + /** Field description */ + public static final String PATH_IMAGE = "images"; + + /** Field description */ + public static final int SIZE_LARGE = 640; + + /** Field description */ + public static final int SIZE_MEDIUM = 320; + + /** Field description */ + public static final int SIZE_SMALL = 200; + + //~--- constructors --------------------------------------------------------- + + /** + * Constructs ... + * + * + * @param backend + */ + @Inject + public ScreenshotResource(PluginBackend backend) + { + this.backend = backend; + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @param groupId + * @param artifactId + * @param number + * @param size + * + * @return + * + * @throws IOException + */ + @GET + @Produces("image/jpeg") + public Response getScreenshot(@PathParam("groupId") String groupId, + @PathParam("artifactId") String artifactId, + @PathParam("number") int number, + @PathParam("size") String size) + throws IOException + { + PluginInformation plugin = PluginUtil.getLatestPluginVersion(backend, + groupId, artifactId); + + if (plugin == null) + { + throw new WebApplicationException(Status.NOT_FOUND); + } + + List screenshots = plugin.getScreenshots(); + + if (Util.isEmpty(screenshots)) + { + throw new WebApplicationException(Status.NOT_FOUND); + } + + String screenshot = screenshots.get(number); + + if (Util.isEmpty(screenshot)) + { + throw new WebApplicationException(Status.NOT_FOUND); + } + + String checksum = ChecksumUtil.createChecksum(screenshot); + StringBuilder path = new StringBuilder(PATH_IMAGE); + + path.append(File.separator).append(groupId); + path.append(File.separator).append(artifactId).append(File.separator); + path.append(String.valueOf(number)).append(File.separator); + path.append(size).append(File.separator).append(checksum); + path.append(EXTENSION_IMAGE); + + File file = new File(backend.getBaseDirectory(), path.toString()); + + if (!file.exists()) + { + createThumbnail(file, screenshot, size.toCharArray()[0]); + } + + return Response.ok(file).build(); + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param file + * @param screenshot + * @param size + * + * @throws IOException + */ + private void createThumbnail(File file, String screenshot, char size) + throws IOException + { + IOUtil.mkdirs(file.getParentFile()); + + int width = SIZE_SMALL; + + switch (size) + { + case 'l' : + width = SIZE_LARGE; + + break; + + case 'm' : + width = SIZE_MEDIUM; + } + + BufferedImage image = ImageIO.read(new URL(screenshot)); + + image = Scalr.resize(image, Scalr.Method.QUALITY, width); + ImageIO.write(image, FORMAT, file); + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private PluginBackend backend; +} diff --git a/scm-plugin-backend/src/main/webapp/detail.html b/scm-plugin-backend/src/main/webapp/detail.html index e8d6a7878f..00ea7db399 100644 --- a/scm-plugin-backend/src/main/webapp/detail.html +++ b/scm-plugin-backend/src/main/webapp/detail.html @@ -45,6 +45,32 @@

 

+<#if latest.screenshots??> + + + + +

 

+ + +

Plugin Versions

From 8a7091398b02debf5098c4280de5281efac00919 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 7 Nov 2011 12:49:39 +0100 Subject: [PATCH 18/67] added removeAll method to cache --- .../src/main/java/sonia/scm/cache/Cache.java | 20 ++- .../main/java/sonia/scm/cache/EhCache.java | 36 ++++ .../java/sonia/scm/cache/EhCacheTest.java | 159 ++++++++++++++++++ 3 files changed, 213 insertions(+), 2 deletions(-) create mode 100644 scm-webapp/src/test/java/sonia/scm/cache/EhCacheTest.java diff --git a/scm-core/src/main/java/sonia/scm/cache/Cache.java b/scm-core/src/main/java/sonia/scm/cache/Cache.java index 5282d6ede2..319cadcde1 100644 --- a/scm-core/src/main/java/sonia/scm/cache/Cache.java +++ b/scm-core/src/main/java/sonia/scm/cache/Cache.java @@ -33,9 +33,13 @@ package sonia.scm.cache; +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.Filter; + /** - * The main interface for the cache. - * Provides methods to add, access, and remove entries from a cache. + * The main interface for the cache. + * Provides methods to add, access, and remove entries from a cache. * * @author Sebastian Sdorra * @@ -81,6 +85,18 @@ public interface Cache */ public boolean remove(K key); + /** + * Remove all elements with matching {@link Filter} from this cache. + * The method returns true if the operation was successful. + * + * @since 1.9 + * + * @param filter - The filter to match cache keys + * + * @return true if the operation was successful + */ + public boolean removeAll(Filter filter); + //~--- get methods ---------------------------------------------------------- /** diff --git a/scm-webapp/src/main/java/sonia/scm/cache/EhCache.java b/scm-webapp/src/main/java/sonia/scm/cache/EhCache.java index dc2bd185cb..802db9d45c 100644 --- a/scm-webapp/src/main/java/sonia/scm/cache/EhCache.java +++ b/scm-webapp/src/main/java/sonia/scm/cache/EhCache.java @@ -40,6 +40,12 @@ import net.sf.ehcache.Element; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import sonia.scm.Filter; + +//~--- JDK imports ------------------------------------------------------------ + +import java.util.Iterator; + /** * * @author Sebastian Sdorra @@ -126,6 +132,36 @@ public class EhCache implements Cache return cache.remove(key); } + /** + * Method description + * + * + * @param filter + * + * @return + */ + @Override + public boolean removeAll(Filter filter) + { + boolean result = true; + Iterator it = cache.getKeys().iterator(); + + while (it.hasNext()) + { + K key = it.next(); + + if (filter.accept(key)) + { + if (!cache.remove(key)) + { + result = false; + } + } + } + + return result; + } + //~--- get methods ---------------------------------------------------------- /** diff --git a/scm-webapp/src/test/java/sonia/scm/cache/EhCacheTest.java b/scm-webapp/src/test/java/sonia/scm/cache/EhCacheTest.java new file mode 100644 index 0000000000..cfd783d5c8 --- /dev/null +++ b/scm-webapp/src/test/java/sonia/scm/cache/EhCacheTest.java @@ -0,0 +1,159 @@ +/** + * 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.cache; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import sonia.scm.Filter; +import sonia.scm.util.IOUtil; + +import static org.junit.Assert.*; + +/** + * + * @author Sebastian Sdorra + */ +public class EhCacheTest +{ + + /** + * Method description + * + */ + @After + public void after() + { + IOUtil.close(cm); + } + + /** + * Method description + * + */ + @Before + public void before() + { + cm = new EhCacheManager(); + cache = cm.getCache(String.class, String.class, "test"); + } + + /** + * Method description + * + */ + @Test + public void testClear() + { + cache.put("test", "test123"); + cache.put("test-1", "test123"); + cache.clear(); + assertNull(cache.get("test")); + assertNull(cache.get("test-1")); + } + + /** + * Method description + * + */ + @Test + public void testContains() + { + cache.put("test", "test123"); + cache.put("test-1", "test123"); + assertTrue(cache.contains("test")); + assertTrue(cache.contains("test-1")); + assertFalse(cache.contains("test-2")); + } + + /** + * Method description + * + */ + @Test + public void testPutAndGet() + { + cache.put("test", "test123"); + assertEquals("test123", cache.get("test")); + } + + /** + * Method description + * + */ + @Test + public void testRemove() + { + cache.put("test", "test123"); + assertEquals("test123", cache.get("test")); + cache.remove("test"); + assertNull(cache.get("test")); + } + + /** + * Method description + * + */ + @Test + public void testRemoveAll() + { + cache.put("test-1", "test123"); + cache.put("test-2", "test123"); + cache.put("a-1", "test123"); + cache.put("a-2", "test123"); + cache.removeAll(new Filter() + { + @Override + public boolean accept(String item) + { + return item.startsWith("test"); + } + }); + assertNull(cache.get("test-1")); + assertNull(cache.get("test-2")); + assertNotNull(cache.get("a-1")); + assertNotNull(cache.get("a-2")); + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private Cache cache; + + /** Field description */ + private CacheManager cm; +} From a53e2877f21e25aa3b5305938ba78641e989b336 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 7 Nov 2011 13:14:13 +0100 Subject: [PATCH 19/67] added missing blame cache --- scm-webapp/src/main/resources/config/ehcache.xml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/scm-webapp/src/main/resources/config/ehcache.xml b/scm-webapp/src/main/resources/config/ehcache.xml index 6243ed4551..c665c6061a 100644 --- a/scm-webapp/src/main/resources/config/ehcache.xml +++ b/scm-webapp/src/main/resources/config/ehcache.xml @@ -152,4 +152,13 @@ diskPersistent="false" /> + + From 8aa83e56f1e52f2d3a70f764599426c9776ecebb Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 7 Nov 2011 13:17:46 +0100 Subject: [PATCH 20/67] improve repository caching --- .../sonia/scm/repository/BlameViewerUtil.java | 23 +++- .../sonia/scm/repository/CacheClearHook.java | 54 ++++++++-- .../scm/repository/ChangesetViewerUtil.java | 13 ++- .../scm/repository/PartCacheClearHook.java | 61 +++++++++++ .../scm/repository/RepositoryBrowserUtil.java | 18 +++- .../scm/repository/RepositoryCacheKey.java | 51 +++++++++ .../scm/repository/RepositoryFilter.java | 102 ++++++++++++++++++ 7 files changed, 306 insertions(+), 16 deletions(-) create mode 100644 scm-core/src/main/java/sonia/scm/repository/PartCacheClearHook.java create mode 100644 scm-core/src/main/java/sonia/scm/repository/RepositoryCacheKey.java create mode 100644 scm-core/src/main/java/sonia/scm/repository/RepositoryFilter.java diff --git a/scm-core/src/main/java/sonia/scm/repository/BlameViewerUtil.java b/scm-core/src/main/java/sonia/scm/repository/BlameViewerUtil.java index 69a7ded78b..e552a53d1f 100644 --- a/scm-core/src/main/java/sonia/scm/repository/BlameViewerUtil.java +++ b/scm-core/src/main/java/sonia/scm/repository/BlameViewerUtil.java @@ -57,7 +57,7 @@ import java.io.IOException; * @since 1.8 */ @Singleton -public class BlameViewerUtil extends CacheClearHook +public class BlameViewerUtil extends PartCacheClearHook { /** Field description */ @@ -104,8 +104,7 @@ public class BlameViewerUtil extends CacheClearHook * @throws NotSupportedFeatuerException * @throws RepositoryException */ - public BlameResult getBlame(String repositoryId, String revision, - String path) + public BlameResult getBlame(String repositoryId, String revision, String path) throws RepositoryException, NotSupportedFeatuerException, IOException { AssertUtil.assertIsNotEmpty(repositoryId); @@ -137,7 +136,7 @@ public class BlameViewerUtil extends CacheClearHook * @throws RepositoryException */ public BlameResult getBlame(Repository repository, String revision, - String path) + String path) throws RepositoryException, NotSupportedFeatuerException, IOException { AssertUtil.assertIsNotNull(repository); @@ -177,7 +176,7 @@ public class BlameViewerUtil extends CacheClearHook * @version Enter version here... * @author Enter your name here... */ - private static class BlameViewerCacheKey + private static class BlameViewerCacheKey implements RepositoryCacheKey { /** @@ -269,6 +268,20 @@ public class BlameViewerUtil extends CacheClearHook return hash; } + //~--- get methods -------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + public String getRepositoryId() + { + return repositoryId; + } + //~--- fields ------------------------------------------------------------- /** Field description */ diff --git a/scm-core/src/main/java/sonia/scm/repository/CacheClearHook.java b/scm-core/src/main/java/sonia/scm/repository/CacheClearHook.java index 7587502c00..d4dcc8ff55 100644 --- a/scm-core/src/main/java/sonia/scm/repository/CacheClearHook.java +++ b/scm-core/src/main/java/sonia/scm/repository/CacheClearHook.java @@ -38,6 +38,7 @@ package sonia.scm.repository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import sonia.scm.Filter; import sonia.scm.cache.Cache; //~--- JDK imports ------------------------------------------------------------ @@ -63,15 +64,40 @@ public class CacheClearHook implements RepositoryHook * Method description * * @since 1.7 + * */ public void clearCache() { - if (logger.isDebugEnabled()) - { - logger.debug("clear cache"); - } + clearCache(null); + } - cache.clear(); + /** + * Method description + * + * @since 1.9 + * + * @param filter + */ + public void clearCache(Filter filter) + { + if (filter != null) + { + if (logger.isDebugEnabled()) + { + logger.debug("clear cache, with filter"); + } + + cache.removeAll(filter); + } + else + { + if (logger.isDebugEnabled()) + { + logger.debug("clear cache"); + } + + cache.clear(); + } } /** @@ -89,7 +115,9 @@ public class CacheClearHook implements RepositoryHook event.getRepository().getName()); } - cache.clear(); + Filter filter = createFilter(event); + + clearCache(filter); } //~--- get methods ---------------------------------------------------------- @@ -120,6 +148,20 @@ public class CacheClearHook implements RepositoryHook //~--- methods -------------------------------------------------------------- + /** + * Method description + * + * @since 1.9 + * + * + * @param event + * @return + */ + protected Filter createFilter(RepositoryHookEvent event) + { + return null; + } + /** * Method description * diff --git a/scm-core/src/main/java/sonia/scm/repository/ChangesetViewerUtil.java b/scm-core/src/main/java/sonia/scm/repository/ChangesetViewerUtil.java index 8f12bde687..c3e2d7ad47 100644 --- a/scm-core/src/main/java/sonia/scm/repository/ChangesetViewerUtil.java +++ b/scm-core/src/main/java/sonia/scm/repository/ChangesetViewerUtil.java @@ -40,6 +40,7 @@ import com.google.inject.Inject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import sonia.scm.Filter; import sonia.scm.NotSupportedFeatuerException; import sonia.scm.cache.Cache; import sonia.scm.cache.CacheManager; @@ -57,7 +58,7 @@ import java.util.Set; * @author Sebastian Sdorra * @since 1.6 */ -public class ChangesetViewerUtil extends CacheClearHook +public class ChangesetViewerUtil extends PartCacheClearHook { /** Field description */ @@ -91,7 +92,7 @@ public class ChangesetViewerUtil extends CacheClearHook ChangesetPagingResult.class, CACHE_NAME); init(repositoryManager, cache); } - + //~--- get methods ---------------------------------------------------------- /** @@ -247,7 +248,7 @@ public class ChangesetViewerUtil extends CacheClearHook * @version Enter version here..., 11/07/24 * @author Enter your name here... */ - private class ChangesetViewerCacheKey + private class ChangesetViewerCacheKey implements RepositoryCacheKey { /** @@ -340,6 +341,12 @@ public class ChangesetViewerUtil extends CacheClearHook /** Field description */ private int start; + + @Override + public String getRepositoryId() + { + return repository; + } } diff --git a/scm-core/src/main/java/sonia/scm/repository/PartCacheClearHook.java b/scm-core/src/main/java/sonia/scm/repository/PartCacheClearHook.java new file mode 100644 index 0000000000..2a2830501e --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/PartCacheClearHook.java @@ -0,0 +1,61 @@ +/** + * 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.repository; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.Filter; + +/** + * + * @author Sebastian Sdorra + * @since 1.9 + */ +public class PartCacheClearHook extends CacheClearHook +{ + + /** + * Method description + * + * + * @param event + * + * @return + */ + @Override + protected Filter createFilter(RepositoryHookEvent event) + { + return new RepositoryFilter(event); + } +} diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowserUtil.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowserUtil.java index 523a19f041..9291647784 100644 --- a/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowserUtil.java +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryBrowserUtil.java @@ -59,7 +59,7 @@ import java.util.List; * @since 1.6 */ @Singleton -public class RepositoryBrowserUtil extends CacheClearHook +public class RepositoryBrowserUtil extends PartCacheClearHook { /** Field description */ @@ -205,7 +205,7 @@ public class RepositoryBrowserUtil extends CacheClearHook * @version Enter version here..., 11/08/03 * @author Enter your name here... */ - private static class RepositoryBrowserCacheKey + private static class RepositoryBrowserCacheKey implements RepositoryCacheKey { /** @@ -297,6 +297,20 @@ public class RepositoryBrowserUtil extends CacheClearHook return hash; } + //~--- get methods -------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + @Override + public String getRepositoryId() + { + return repositoryId; + } + //~--- fields ------------------------------------------------------------- /** Field description */ diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryCacheKey.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryCacheKey.java new file mode 100644 index 0000000000..115f19c6b6 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryCacheKey.java @@ -0,0 +1,51 @@ +/** + * 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.repository; + +/** + * + * @author Sebastian Sdorra + * @since 1.9 + */ +public interface RepositoryCacheKey +{ + + /** + * Method description + * + * + * @return + */ + public String getRepositoryId(); +} diff --git a/scm-core/src/main/java/sonia/scm/repository/RepositoryFilter.java b/scm-core/src/main/java/sonia/scm/repository/RepositoryFilter.java new file mode 100644 index 0000000000..58be4d3791 --- /dev/null +++ b/scm-core/src/main/java/sonia/scm/repository/RepositoryFilter.java @@ -0,0 +1,102 @@ +/** + * 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.repository; + +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.Filter; + +/** + * + * @author Sebastian Sdorra + * @since 1.9 + * + */ +public class RepositoryFilter implements Filter +{ + + /** + * Constructs ... + * + * + * @param repository + */ + public RepositoryFilter(Repository repository) + { + this(repository.getId()); + } + + /** + * Constructs ... + * + * + * @param event + */ + public RepositoryFilter(RepositoryHookEvent event) + { + this(event.getRepository()); + } + + /** + * Constructs ... + * + * + * @param repositoryId + */ + public RepositoryFilter(String repositoryId) + { + this.repositoryId = repositoryId; + } + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + * + * @param key + * + * @return + */ + @Override + public boolean accept(RepositoryCacheKey key) + { + return repositoryId.equals(key.getRepositoryId()); + } + + //~--- fields --------------------------------------------------------------- + + /** Field description */ + private String repositoryId; +} From 5e40e29e283178287ecaf0b87cccc4b3c36211e8 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 7 Nov 2011 15:26:52 +0100 Subject: [PATCH 21/67] added version subcommand --- .../sonia/scm/cli/cmd/VersionSubCommand.java | 133 ++++++++++++++++++ .../services/sonia.scm.cli.cmd.SubCommand | 3 + .../resources/sonia/resources/i18n.properties | 3 +- 3 files changed, 138 insertions(+), 1 deletion(-) create mode 100644 scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/VersionSubCommand.java diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/VersionSubCommand.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/VersionSubCommand.java new file mode 100644 index 0000000000..285739f2c2 --- /dev/null +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/VersionSubCommand.java @@ -0,0 +1,133 @@ +/** + * 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.cli.cmd; + +//~--- non-JDK imports -------------------------------------------------------- + +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import sonia.scm.util.IOUtil; +import sonia.scm.util.Util; + +//~--- JDK imports ------------------------------------------------------------ + +import java.io.IOException; +import java.io.InputStream; + +import java.util.Properties; + +/** + * + * @author Sebastian Sdorra + * @since 1.9 + */ +@Command( + name = "version", + usage = "usageVersion", + group = "misc" +) +public class VersionSubCommand extends SubCommand +{ + + /** Default version {@link String} */ + public static final String DEFAULT_VERSION = "unknown"; + + /** Path to the maven properties file of the scm-core artifact */ + public static final String MAVEN_PROPERTIES = + "/META-INF/maven/sonia.scm.clients/scm-cli-client/pom.properties"; + + /** Maven property for the version of the artifact */ + public static final String MAVEN_PROPERTY_VERSION = "version"; + + /** the logger for VersionSubCommand */ + private static final Logger logger = + LoggerFactory.getLogger(VersionSubCommand.class); + + //~--- methods -------------------------------------------------------------- + + /** + * Method description + * + */ + @Override + protected void run() + { + String version = getVersion(); + + output.append("scm-cli-client version: ").println(version); + } + + //~--- get methods ---------------------------------------------------------- + + /** + * Method description + * + * + * @return + */ + private String getVersion() + { + String version = null; + InputStream stream = null; + + try + { + stream = VersionSubCommand.class.getResourceAsStream(MAVEN_PROPERTIES); + + if (stream != null) + { + Properties properties = new Properties(); + + properties.load(stream); + version = properties.getProperty(MAVEN_PROPERTY_VERSION); + } + } + catch (IOException ex) + { + logger.warn("could not parse maven.properties", ex); + } + finally + { + IOUtil.close(stream); + } + + if (Util.isEmpty(version)) + { + version = DEFAULT_VERSION; + } + + return version; + } +} diff --git a/scm-clients/scm-cli-client/src/main/resources/META-INF/services/sonia.scm.cli.cmd.SubCommand b/scm-clients/scm-cli-client/src/main/resources/META-INF/services/sonia.scm.cli.cmd.SubCommand index f9bccfe3b0..1f7ba303e2 100644 --- a/scm-clients/scm-cli-client/src/main/resources/META-INF/services/sonia.scm.cli.cmd.SubCommand +++ b/scm-clients/scm-cli-client/src/main/resources/META-INF/services/sonia.scm.cli.cmd.SubCommand @@ -59,3 +59,6 @@ sonia.scm.cli.cmd.ModifyGroupSubCommand # member sonia.scm.cli.cmd.AddMembersSubCommand sonia.scm.cli.cmd.DeleteMembersSubCommand + +# misc +sonia.scm.cli.cmd.VersionSubCommand diff --git a/scm-clients/scm-cli-client/src/main/resources/sonia/resources/i18n.properties b/scm-clients/scm-cli-client/src/main/resources/sonia/resources/i18n.properties index b572a860c9..eab61b1bd7 100644 --- a/scm-clients/scm-cli-client/src/main/resources/sonia/resources/i18n.properties +++ b/scm-clients/scm-cli-client/src/main/resources/sonia/resources/i18n.properties @@ -109,4 +109,5 @@ usageListRepositories= Print a list of all repositories usageModifyGroup = Modify a group usageModifyUser = Modify a user usageModifyRepository = Modify a repository -usageStoreConfig = Stores the current configuration \ No newline at end of file +usageStoreConfig = Stores the current configuration +usageVersion = Show the version of scm-cli-client \ No newline at end of file From 996ad0b04415b2ebc40db14f12403cbcf17b262f Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Mon, 7 Nov 2011 15:31:47 +0100 Subject: [PATCH 22/67] added server-version subcommand --- .../scm/cli/cmd/ServerVersionSubCommand.java | 67 +++++++++++++++++++ .../services/sonia.scm.cli.cmd.SubCommand | 1 + .../resources/sonia/resources/i18n.properties | 3 +- 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/ServerVersionSubCommand.java diff --git a/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/ServerVersionSubCommand.java b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/ServerVersionSubCommand.java new file mode 100644 index 0000000000..e5c60f0779 --- /dev/null +++ b/scm-clients/scm-cli-client/src/main/java/sonia/scm/cli/cmd/ServerVersionSubCommand.java @@ -0,0 +1,67 @@ +/** + * 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.cli.cmd; + +import sonia.scm.ScmState; +import sonia.scm.client.ScmClientSession; +import sonia.scm.util.Util; + +/** + * + * @author Sebastian Sdorra + * @version 1.9 + */ +@Command( + name = "server-version", + usage = "usageServerVersion", + group = "misc" +) +public class ServerVersionSubCommand extends SubCommand +{ + + @Override + protected void run() + { + ScmClientSession session = createSession(); + ScmState state = session.getState(); + String version = null; + if ( state != null ){ + version = state.getVersion(); + + } + if ( Util.isEmpty(version) ){ + version = VersionSubCommand.DEFAULT_VERSION; + } + + output.append("scm-manager version: ").println( version ); + } + +} diff --git a/scm-clients/scm-cli-client/src/main/resources/META-INF/services/sonia.scm.cli.cmd.SubCommand b/scm-clients/scm-cli-client/src/main/resources/META-INF/services/sonia.scm.cli.cmd.SubCommand index 1f7ba303e2..73e50f8940 100644 --- a/scm-clients/scm-cli-client/src/main/resources/META-INF/services/sonia.scm.cli.cmd.SubCommand +++ b/scm-clients/scm-cli-client/src/main/resources/META-INF/services/sonia.scm.cli.cmd.SubCommand @@ -62,3 +62,4 @@ sonia.scm.cli.cmd.DeleteMembersSubCommand # misc sonia.scm.cli.cmd.VersionSubCommand +sonia.scm.cli.cmd.ServerVersionSubCommand diff --git a/scm-clients/scm-cli-client/src/main/resources/sonia/resources/i18n.properties b/scm-clients/scm-cli-client/src/main/resources/sonia/resources/i18n.properties index eab61b1bd7..cebfbeaff6 100644 --- a/scm-clients/scm-cli-client/src/main/resources/sonia/resources/i18n.properties +++ b/scm-clients/scm-cli-client/src/main/resources/sonia/resources/i18n.properties @@ -110,4 +110,5 @@ usageModifyGroup = Modify a group usageModifyUser = Modify a user usageModifyRepository = Modify a repository usageStoreConfig = Stores the current configuration -usageVersion = Show the version of scm-cli-client \ No newline at end of file +usageVersion = Show the version of scm-cli-client +usageServerVersion = Show the version of the scm-manager \ No newline at end of file From 8f35760a333ad650f338c5ef6e6362143dbc0034 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 11 Nov 2011 13:35:10 +0100 Subject: [PATCH 23/67] update jetty to version 7.5.4.v20111024 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index ca7de46e13..d42bbd09d8 100644 --- a/pom.xml +++ b/pom.xml @@ -433,7 +433,7 @@ 1.9.1 2.4.6 2.3.18 - 7.5.1.v20110908 + 7.5.4.v20111024 0.9.30 1.6 UTF-8 From b6f3ca644e69d41316ef5c7907484303c0563256 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 11 Nov 2011 15:13:32 +0100 Subject: [PATCH 24/67] update logback to version 1.0.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index d42bbd09d8..e3b5ee77a5 100644 --- a/pom.xml +++ b/pom.xml @@ -434,7 +434,7 @@ 2.4.6 2.3.18 7.5.4.v20111024 - 0.9.30 + 1.0.0 1.6 UTF-8 SCM-BSD From aefe5ceba67d8f8fed202402c09d6477e6af1d9d Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 11 Nov 2011 15:21:46 +0100 Subject: [PATCH 25/67] update slf4j to verion 1.6.4 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index e3b5ee77a5..39dc5de6be 100644 --- a/pom.xml +++ b/pom.xml @@ -427,7 +427,7 @@ 1.8.5 4.10 - 1.6.3 + 1.6.4 2.5 3.0 1.9.1 From 119674c510e3bbc9eb57307ae08f6cdccd9cd271 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 11 Nov 2011 15:26:37 +0100 Subject: [PATCH 26/67] update jersey to version 1.10 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index 39dc5de6be..c6049b9870 100644 --- a/pom.xml +++ b/pom.xml @@ -430,7 +430,7 @@ 1.6.4 2.5 3.0 - 1.9.1 + 1.10 2.4.6 2.3.18 7.5.4.v20111024 From ac962761a3670a160ab345fb56ac86daafec7eaa Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 11 Nov 2011 15:34:57 +0100 Subject: [PATCH 27/67] update jrebel-maven-plugin to version 1.1.0 --- pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pom.xml b/pom.xml index c6049b9870..e59c48c222 100644 --- a/pom.xml +++ b/pom.xml @@ -389,7 +389,7 @@ org.zeroturnaround jrebel-maven-plugin - 1.0.7 + 1.1.0 generate-rebel-xml From 2d284b4b9c06ae34d2d9ca290be3038017f1900e Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Fri, 11 Nov 2011 15:40:24 +0100 Subject: [PATCH 28/67] update maven-surefire-report-plugin to version 2.10 --- pom.xml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pom.xml b/pom.xml index e59c48c222..5dbe658c38 100644 --- a/pom.xml +++ b/pom.xml @@ -291,7 +291,7 @@ org.apache.maven.plugins maven-surefire-report-plugin - 2.9 + 2.10 @@ -355,7 +355,7 @@ org.apache.maven.plugins maven-surefire-report-plugin - 2.9 + 2.10 From 49d4864e00e2fba5d9e5cd05d84bb3f68c7aa66b Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 13 Nov 2011 16:36:00 +0100 Subject: [PATCH 29/67] added wiki url to plugin information's --- .../sonia/scm/plugin/PluginInformation.java | 95 +++++++++++++------ 1 file changed, 65 insertions(+), 30 deletions(-) diff --git a/scm-core/src/main/java/sonia/scm/plugin/PluginInformation.java b/scm-core/src/main/java/sonia/scm/plugin/PluginInformation.java index 18fde8a044..f8c2ada099 100644 --- a/scm-core/src/main/java/sonia/scm/plugin/PluginInformation.java +++ b/scm-core/src/main/java/sonia/scm/plugin/PluginInformation.java @@ -80,20 +80,6 @@ public class PluginInformation implements Validateable final PluginInformation other = (PluginInformation) obj; - if ((this.screenshots != other.screenshots) - && ((this.screenshots == null) - ||!this.screenshots.equals(other.screenshots))) - { - return false; - } - - if ((this.category == null) - ? (other.category != null) - : !this.category.equals(other.category)) - { - return false; - } - if ((this.artifactId == null) ? (other.artifactId != null) : !this.artifactId.equals(other.artifactId)) @@ -108,6 +94,13 @@ public class PluginInformation implements Validateable return false; } + if ((this.category == null) + ? (other.category != null) + : !this.category.equals(other.category)) + { + return false; + } + if ((this.condition != other.condition) && ((this.condition == null) ||!this.condition.equals(other.condition))) { @@ -135,6 +128,13 @@ public class PluginInformation implements Validateable return false; } + if ((this.screenshots != other.screenshots) + && ((this.screenshots == null) + ||!this.screenshots.equals(other.screenshots))) + { + return false; + } + if (this.state != other.state) { return false; @@ -154,6 +154,13 @@ public class PluginInformation implements Validateable return false; } + if ((this.wiki == null) + ? (other.wiki != null) + : !this.wiki.equals(other.wiki)) + { + return false; + } + return true; } @@ -166,41 +173,44 @@ public class PluginInformation implements Validateable @Override public int hashCode() { - int hash = 7; + int hash = 5; - hash = 61 * hash + ((this.screenshots != null) - ? this.screenshots.hashCode() - : 0); - hash = 61 * hash + ((this.category != null) - ? this.category.hashCode() - : 0); - hash = 61 * hash + ((this.artifactId != null) + hash = 79 * hash + ((this.artifactId != null) ? this.artifactId.hashCode() : 0); - hash = 61 * hash + ((this.author != null) + hash = 79 * hash + ((this.author != null) ? this.author.hashCode() : 0); - hash = 61 * hash + ((this.condition != null) + hash = 79 * hash + ((this.category != null) + ? this.category.hashCode() + : 0); + hash = 79 * hash + ((this.condition != null) ? this.condition.hashCode() : 0); - hash = 61 * hash + ((this.description != null) + hash = 79 * hash + ((this.description != null) ? this.description.hashCode() : 0); - hash = 61 * hash + ((this.groupId != null) + hash = 79 * hash + ((this.groupId != null) ? this.groupId.hashCode() : 0); - hash = 61 * hash + ((this.name != null) + hash = 79 * hash + ((this.name != null) ? this.name.hashCode() : 0); - hash = 61 * hash + ((this.state != null) + hash = 79 * hash + ((this.screenshots != null) + ? this.screenshots.hashCode() + : 0); + hash = 79 * hash + ((this.state != null) ? this.state.hashCode() : 0); - hash = 61 * hash + ((this.url != null) + hash = 79 * hash + ((this.url != null) ? this.url.hashCode() : 0); - hash = 61 * hash + ((this.version != null) + hash = 79 * hash + ((this.version != null) ? this.version.hashCode() : 0); + hash = 79 * hash + ((this.wiki != null) + ? this.wiki.hashCode() + : 0); return hash; } @@ -343,6 +353,17 @@ public class PluginInformation implements Validateable return version; } + /** + * Method description + * + * + * @return + */ + public String getWiki() + { + return wiki; + } + /** * Method description * @@ -479,6 +500,17 @@ public class PluginInformation implements Validateable this.version = version; } + /** + * Method description + * + * + * @param wiki + */ + public void setWiki(String wiki) + { + this.wiki = wiki; + } + //~--- fields --------------------------------------------------------------- /** Field description */ @@ -515,4 +547,7 @@ public class PluginInformation implements Validateable /** Field description */ private String version; + + /** Field description */ + private String wiki; } From 539784e2d5942e8f7ad7b8e8d4656e659fe2e14a Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 13 Nov 2011 17:19:20 +0100 Subject: [PATCH 30/67] resolve maven conflict --- scm-webapp/pom.xml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index 1b053644ab..b4375a626c 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -57,6 +57,12 @@ 1.9-SNAPSHOT + + com.sun.jersey + jersey-server + ${jersey.version} + + com.sun.jersey jersey-json From f51f0d5609e25c873ae1c58168b665d53b8ec5ac Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 13 Nov 2011 17:23:51 +0100 Subject: [PATCH 31/67] show wiki url in plugin detail page --- scm-plugin-backend/src/main/webapp/detail.html | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/scm-plugin-backend/src/main/webapp/detail.html b/scm-plugin-backend/src/main/webapp/detail.html index 00ea7db399..fd70b80219 100644 --- a/scm-plugin-backend/src/main/webapp/detail.html +++ b/scm-plugin-backend/src/main/webapp/detail.html @@ -41,6 +41,16 @@ + <#if latest.wiki??> + + Wiki + + + ${latest.wiki} + + + +

 

From 3e5fb381202e42094ec48b4ca44d0a9520f9139e Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 13 Nov 2011 17:54:53 +0100 Subject: [PATCH 32/67] display message if the plugin is not released --- .../src/main/webapp/detail.html | 54 ++++++++++--------- 1 file changed, 29 insertions(+), 25 deletions(-) diff --git a/scm-plugin-backend/src/main/webapp/detail.html b/scm-plugin-backend/src/main/webapp/detail.html index fd70b80219..ed6602aae0 100644 --- a/scm-plugin-backend/src/main/webapp/detail.html +++ b/scm-plugin-backend/src/main/webapp/detail.html @@ -84,31 +84,35 @@

Plugin Versions

-<#list versions as version> -

${version.version}

-
-

${version.description}

- <#if version.condition??> -

Conditions

-
    - <#if version.condition.minVersion??> -
  • Minimum Version: ${version.condition.minVersion}
  • - - <#if version.condition.os??> -
  • - Operatingsystems: - <#list version.condition.os as os> - ${os}<#if os_has_next>, - -
  • - - <#if version.condition.arch??> -
  • Architecture: ${version.condition.arch}
  • - -
- -
- +<#if versions?has_content> + <#list versions as version> +

${version.version}

+
+

${version.description}

+ <#if version.condition??> +

Conditions

+
    + <#if version.condition.minVersion??> +
  • Minimum Version: ${version.condition.minVersion}
  • + + <#if version.condition.os??> +
  • + Operatingsystems: + <#list version.condition.os as os> + ${os}<#if os_has_next>, + +
  • + + <#if version.condition.arch??> +
  • Architecture: ${version.condition.arch}
  • + +
+ +
+ +<#else> + Plugin not yet released +

 

From 124cae18d78bd6bacb0ed8b4c0dc9fd4a577c043 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 13 Nov 2011 18:05:33 +0100 Subject: [PATCH 33/67] added google analytics support to plugin backend --- .../scm/plugin/BackendConfiguration.java | 28 ++++++++++++++++++- .../sonia/scm/plugin/rest/DetailResource.java | 15 ++++++---- .../scm/plugin/rest/OverviewResource.java | 7 +++-- .../scm/plugin/rest/ViewableResource.java | 7 ++++- .../src/main/webapp/template/header.html | 15 ++++++++++ 5 files changed, 62 insertions(+), 10 deletions(-) diff --git a/scm-plugin-backend/src/main/java/sonia/scm/plugin/BackendConfiguration.java b/scm-plugin-backend/src/main/java/sonia/scm/plugin/BackendConfiguration.java index 75b04c60d8..2546eea937 100644 --- a/scm-plugin-backend/src/main/java/sonia/scm/plugin/BackendConfiguration.java +++ b/scm-plugin-backend/src/main/java/sonia/scm/plugin/BackendConfiguration.java @@ -116,6 +116,17 @@ public class BackendConfiguration return scannInterval; } + /** + * Method description + * + * + * @return + */ + public String getTrackingCode() + { + return trackingCode; + } + /** * Method description * @@ -195,6 +206,17 @@ public class BackendConfiguration this.scannInterval = scannInterval; } + /** + * Method description + * + * + * @param trackingCode + */ + public void setTrackingCode(String trackingCode) + { + this.trackingCode = trackingCode; + } + //~--- fields --------------------------------------------------------------- /** Field description */ @@ -211,7 +233,7 @@ public class BackendConfiguration private boolean multithreaded = true; /** Field description */ - @XmlElement(name= "news-url") + @XmlElement(name = "news-url") private URL newsUrl; /** Field description */ @@ -223,4 +245,8 @@ public class BackendConfiguration @XmlElement(name = "scann-interval") @XmlJavaTypeAdapter(XmlIntervalAdapter.class) private Long scannInterval; + + /** Field description */ + @XmlElement(name = "tracking-code") + private String trackingCode; } diff --git a/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/DetailResource.java b/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/DetailResource.java index 575d9d1088..3541d66813 100644 --- a/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/DetailResource.java +++ b/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/DetailResource.java @@ -37,6 +37,7 @@ package sonia.scm.plugin.rest; import com.google.inject.Inject; +import sonia.scm.plugin.BackendConfiguration; import sonia.scm.plugin.PluginBackend; import sonia.scm.plugin.PluginInformation; import sonia.scm.plugin.PluginUtil; @@ -74,11 +75,13 @@ public class DetailResource extends ViewableResource * * @param context * @param backend + * @param configuration */ @Inject - public DetailResource(ServletContext context, PluginBackend backend) + public DetailResource(ServletContext context, PluginBackend backend, + BackendConfiguration configuration) { - super(context); + super(context, configuration); this.backend = backend; } @@ -100,10 +103,10 @@ public class DetailResource extends ViewableResource @DefaultValue("false") @QueryParam("snapshot") boolean snapshot) { - List pluginVersions = PluginUtil.getFilteredPluginVersions( - backend, groupId, artifactId); - - if (Util.isEmpty(pluginVersions)) + List pluginVersions = + PluginUtil.getFilteredPluginVersions(backend, groupId, artifactId); + + if (Util.isEmpty(pluginVersions)) { throw new WebApplicationException(Status.NOT_FOUND); } diff --git a/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/OverviewResource.java b/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/OverviewResource.java index 78e5f07870..22bac4a7c0 100644 --- a/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/OverviewResource.java +++ b/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/OverviewResource.java @@ -37,6 +37,7 @@ package sonia.scm.plugin.rest; import com.google.inject.Inject; +import sonia.scm.plugin.BackendConfiguration; import sonia.scm.plugin.Category; import sonia.scm.plugin.CategoryNameComaparator; import sonia.scm.plugin.PluginBackend; @@ -78,11 +79,13 @@ public class OverviewResource extends ViewableResource * * @param context * @param backend + * @param configuration */ @Inject - public OverviewResource(ServletContext context, PluginBackend backend) + public OverviewResource(ServletContext context, PluginBackend backend, + BackendConfiguration configuration) { - super(context); + super(context, configuration); this.backend = backend; } diff --git a/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/ViewableResource.java b/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/ViewableResource.java index c9cb327c0f..9d278c389a 100644 --- a/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/ViewableResource.java +++ b/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/ViewableResource.java @@ -39,6 +39,7 @@ import java.util.HashMap; import java.util.Map; import javax.servlet.ServletContext; +import sonia.scm.plugin.BackendConfiguration; /** * @@ -53,10 +54,13 @@ public class ViewableResource * * @param context */ - public ViewableResource(ServletContext context) + public ViewableResource(ServletContext context, BackendConfiguration configuration) { this.contextPath = context.getContextPath(); + this.configuration = configuration; } + + private BackendConfiguration configuration; //~--- methods -------------------------------------------------------------- @@ -73,6 +77,7 @@ public class ViewableResource Map vars = new HashMap(); vars.put("contextPath", contextPath); + vars.put("configuration", configuration); vars.put("title", title); return vars; diff --git a/scm-plugin-backend/src/main/webapp/template/header.html b/scm-plugin-backend/src/main/webapp/template/header.html index bc3d5b83ea..b675a200d9 100644 --- a/scm-plugin-backend/src/main/webapp/template/header.html +++ b/scm-plugin-backend/src/main/webapp/template/header.html @@ -48,6 +48,21 @@ + <#if configuration.trackingConde??> + +
From bd0b46f9e2823d9e04a28fa886abca9307a536b0 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Sun, 13 Nov 2011 18:10:20 +0100 Subject: [PATCH 34/67] fix bugs with empty tracking code --- .../sonia/scm/plugin/rest/ViewableResource.java | 14 ++++++++++---- .../src/main/webapp/template/header.html | 2 +- 2 files changed, 11 insertions(+), 5 deletions(-) diff --git a/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/ViewableResource.java b/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/ViewableResource.java index 9d278c389a..d4b3373646 100644 --- a/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/ViewableResource.java +++ b/scm-plugin-backend/src/main/java/sonia/scm/plugin/rest/ViewableResource.java @@ -33,13 +33,16 @@ package sonia.scm.plugin.rest; +//~--- non-JDK imports -------------------------------------------------------- + +import sonia.scm.plugin.BackendConfiguration; + //~--- JDK imports ------------------------------------------------------------ import java.util.HashMap; import java.util.Map; import javax.servlet.ServletContext; -import sonia.scm.plugin.BackendConfiguration; /** * @@ -53,14 +56,14 @@ public class ViewableResource * * * @param context + * @param configuration */ - public ViewableResource(ServletContext context, BackendConfiguration configuration) + public ViewableResource(ServletContext context, + BackendConfiguration configuration) { this.contextPath = context.getContextPath(); this.configuration = configuration; } - - private BackendConfiguration configuration; //~--- methods -------------------------------------------------------------- @@ -85,6 +88,9 @@ public class ViewableResource //~--- fields --------------------------------------------------------------- + /** Field description */ + private BackendConfiguration configuration; + /** Field description */ private String contextPath; } diff --git a/scm-plugin-backend/src/main/webapp/template/header.html b/scm-plugin-backend/src/main/webapp/template/header.html index b675a200d9..a9eb351a48 100644 --- a/scm-plugin-backend/src/main/webapp/template/header.html +++ b/scm-plugin-backend/src/main/webapp/template/header.html @@ -48,7 +48,7 @@ - <#if configuration.trackingConde??> + <#if configuration.trackingCode??>