From 3637a8de2025be259e696adb780938064bcf7038 Mon Sep 17 00:00:00 2001 From: Sebastian Sdorra Date: Tue, 27 Jun 2017 20:16:05 +0200 Subject: [PATCH] switch from jersey 1.x to resteasy --- pom.xml | 5 +- scm-annotation-processor/pom.xml | 6 +- scm-clients/scm-client-impl/pom.xml | 4 +- scm-core/pom.xml | 6 +- .../scm/security/DefaultCipherHandler.java | 7 +- .../java/sonia/scm/template/Viewable.java | 110 +++---- .../main/java/sonia/scm/web/HgCGIServlet.java | 6 +- scm-webapp/pom.xml | 143 ++++----- .../java/sonia/scm/ScmContextListener.java | 289 +++++++----------- .../main/java/sonia/scm/ScmServletModule.java | 37 +-- .../scm/api/rest/TemplateEngineViewable.java | 64 ++-- .../resources/AbstractPermissionResource.java | 8 +- .../resources/AuthenticationResource.java | 2 +- .../resources/ChangePasswordResource.java | 2 +- .../rest/resources/ConfigurationResource.java | 4 +- .../scm/api/rest/resources/GroupResource.java | 8 +- .../api/rest/resources/PluginResource.java | 16 +- .../resources/RepositoryImportResource.java | 27 +- .../rest/resources/RepositoryResource.java | 22 +- .../resources/RepositoryRootResource.java | 21 +- .../api/rest/resources/SearchResource.java | 4 +- .../api/rest/resources/SupportResource.java | 3 +- .../scm/api/rest/resources/UserResource.java | 8 +- .../java/sonia/scm/debug/DebugResource.java | 4 +- .../scm/net/ahc/JsonContentTransformer.java | 20 +- .../web/security/ApiAuthenticationFilter.java | 2 +- .../src/main/resources/logback.default.xml | 2 + scm-webapp/src/main/webapp/WEB-INF/web.xml | 72 +++-- .../sonia.action.changepasswordwindow.js | 2 +- .../js/config/sonia.config.scmconfigpanel.js | 4 +- .../js/group/sonia.group.formpanel.js | 4 +- .../resources/js/group/sonia.group.panel.js | 2 +- .../resources/js/login/sonia.login.form.js | 2 +- .../js/plugin/sonia.plugin.center.js | 6 +- .../resources/js/plugin/sonia.plugin.grid.js | 2 +- .../sonia.repository.branchcombobox.js | 2 +- .../sonia.repository.changesetviewerpanel.js | 2 +- .../sonia.repository.commitpanel.js | 2 +- .../repository/sonia.repository.formpanel.js | 4 +- .../js/repository/sonia.repository.grid.js | 2 +- .../sonia.repository.healthcheckfailure.js | 2 +- .../sonia.repository.importwindow.js | 4 +- .../js/repository/sonia.repository.js | 2 +- .../js/repository/sonia.repository.panel.js | 4 +- .../sonia.repository.repositorybrowser.js | 2 +- .../sonia.repository.tagcombobox.js | 2 +- .../sonia.security.permissionspanel.js | 8 +- .../main/webapp/resources/js/sonia.global.js | 4 +- .../src/main/webapp/resources/js/sonia.scm.js | 4 +- .../resources/js/user/sonia.user.formpanel.js | 4 +- .../resources/js/user/sonia.user.grid.js | 2 +- .../resources/js/user/sonia.user.panel.js | 2 +- .../test/java/sonia/scm/it/GitLfsITCase.java | 7 +- 53 files changed, 415 insertions(+), 568 deletions(-) rename scm-webapp/src/main/java/sonia/scm/api/rest/UriExtensionsConfig.java => scm-core/src/main/java/sonia/scm/template/Viewable.java (52%) diff --git a/pom.xml b/pom.xml index 7f377a7f18..b0997dcd3d 100644 --- a/pom.xml +++ b/pom.xml @@ -261,7 +261,6 @@ http://download.oracle.com/javase/8/docs/api/ http://download.oracle.com/docs/cd/E17802_01/products/products/servlet/2.5/docs/servlet-2_5-mr2/ - http://jersey.java.net/nonav/apidocs/${jersey.version}/jersey/ https://google.github.io/guice/api-docs/${guice.version}/javadoc http://www.slf4j.org/api/ http://shiro.apache.org/static/current/apidocs/ @@ -482,8 +481,10 @@ 1.7.22 1.1.10 3.0.1 + + 2.0.1 + 1.19.4 4.0 - 1.19.4 1.2.0 diff --git a/scm-annotation-processor/pom.xml b/scm-annotation-processor/pom.xml index 16900521ae..fc4419ba41 100644 --- a/scm-annotation-processor/pom.xml +++ b/scm-annotation-processor/pom.xml @@ -27,9 +27,9 @@ - com.sun.jersey - jersey-core - ${jersey.version} + javax.ws.rs + javax.ws.rs-api + ${jaxrs.version} diff --git a/scm-clients/scm-client-impl/pom.xml b/scm-clients/scm-client-impl/pom.xml index 68ff65317f..ecf2939706 100644 --- a/scm-clients/scm-client-impl/pom.xml +++ b/scm-clients/scm-client-impl/pom.xml @@ -42,13 +42,13 @@ com.sun.jersey jersey-client - ${jersey.version} + ${jersey-client.version} com.sun.jersey.contribs jersey-multipart - ${jersey.version} + ${jersey-client.version} diff --git a/scm-core/pom.xml b/scm-core/pom.xml index f08de28f26..5dfba770e6 100644 --- a/scm-core/pom.xml +++ b/scm-core/pom.xml @@ -78,9 +78,9 @@ - com.sun.jersey - jersey-core - ${jersey.version} + javax.ws.rs + javax.ws.rs-api + ${jaxrs.version} diff --git a/scm-core/src/main/java/sonia/scm/security/DefaultCipherHandler.java b/scm-core/src/main/java/sonia/scm/security/DefaultCipherHandler.java index ddb8a699a7..b4f0d81cd3 100644 --- a/scm-core/src/main/java/sonia/scm/security/DefaultCipherHandler.java +++ b/scm-core/src/main/java/sonia/scm/security/DefaultCipherHandler.java @@ -45,8 +45,6 @@ import sonia.scm.util.IOUtil; //~--- JDK imports ------------------------------------------------------------ -import com.sun.jersey.core.util.Base64; - import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; @@ -60,6 +58,7 @@ import java.security.NoSuchAlgorithmException; import java.security.SecureRandom; import java.util.Arrays; +import java.util.Base64; import javax.crypto.SecretKey; import javax.crypto.spec.IvParameterSpec; @@ -165,7 +164,7 @@ public class DefaultCipherHandler implements CipherHandler { String result = null; try { - byte[] encodedInput = Base64.decode(value); + byte[] encodedInput = Base64.getDecoder().decode(value); byte[] salt = new byte[SALT_LENGTH]; byte[] encoded = new byte[encodedInput.length - SALT_LENGTH]; @@ -222,7 +221,7 @@ public class DefaultCipherHandler implements CipherHandler { System.arraycopy(salt, 0, result, 0, SALT_LENGTH); System.arraycopy(encodedInput, 0, result, SALT_LENGTH, result.length - SALT_LENGTH); - res = new String(Base64.encode(result), ENCODING); + res = new String(Base64.getEncoder().encode(result), ENCODING); } catch (IOException | GeneralSecurityException ex) { throw new CipherException("could not encode string", ex); } diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/UriExtensionsConfig.java b/scm-core/src/main/java/sonia/scm/template/Viewable.java similarity index 52% rename from scm-webapp/src/main/java/sonia/scm/api/rest/UriExtensionsConfig.java rename to scm-core/src/main/java/sonia/scm/template/Viewable.java index 637866ad61..8344d2820e 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/UriExtensionsConfig.java +++ b/scm-core/src/main/java/sonia/scm/template/Viewable.java @@ -28,89 +28,63 @@ * http://bitbucket.org/sdorra/scm-manager * */ +package sonia.scm.template; +import com.google.common.base.Objects; -package sonia.scm.api.rest; - -//~--- JDK imports ------------------------------------------------------------ - -import com.sun.jersey.api.core.PackagesResourceConfig; - -import java.util.HashMap; -import java.util.Map; - -import javax.ws.rs.core.MediaType; - /** - * + * A viewable holds the path to a template and the context object which is used to render the template. Viewables can + * be used as return type of jax-rs resources. + * * @author Sebastian Sdorra + * @since 2.0.0 */ -public class UriExtensionsConfig extends PackagesResourceConfig -{ +public final class Viewable { + + private final String path; + private final Object context; - /** Field description */ - public static final String EXTENSION_JSON = "json"; - - /** Field description */ - public static final String EXTENSION_XML = "xml"; - - //~--- constructors --------------------------------------------------------- - - /** - * Constructs ... - * - */ - public UriExtensionsConfig() - { - super(); + public Viewable(String path, Object context) { + this.path = path; + this.context = context; } - /** - * Constructs ... - * - * - * @param props - */ - public UriExtensionsConfig(Map props) - { - super(props); + public String getPath() { + return path; } - /** - * Constructs ... - * - * - * @param paths - */ - public UriExtensionsConfig(String[] paths) - { - super(paths); + public Object getContext() { + return context; } - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @return - */ @Override - public Map getMediaTypeMappings() - { - if (mediaTypeMap == null) - { - mediaTypeMap = new HashMap(); - mediaTypeMap.put(EXTENSION_JSON, MediaType.APPLICATION_JSON_TYPE); - mediaTypeMap.put(EXTENSION_XML, MediaType.APPLICATION_XML_TYPE); - } - - return mediaTypeMap; + public int hashCode() { + return Objects.hashCode(path, context); } - //~--- fields --------------------------------------------------------------- + @Override + public boolean equals(Object obj) { + if (this == obj) { + return true; + } + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final Viewable other = (Viewable) obj; + return !Objects.equal(this.path, other.path) + && Objects.equal(this.context, other.context); + } - /** Field description */ - private Map mediaTypeMap; + @Override + public String toString() { + return Objects.toStringHelper(this) + .add("path", path) + .add("context", context) + .toString(); + } + } diff --git a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java index be7118323c..e00304c977 100644 --- a/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java +++ b/scm-plugins/scm-hg-plugin/src/main/java/sonia/scm/web/HgCGIServlet.java @@ -62,10 +62,9 @@ import sonia.scm.web.cgi.EnvList; //~--- JDK imports ------------------------------------------------------------ -import com.sun.jersey.core.util.Base64; - import java.io.File; import java.io.IOException; +import java.util.Base64; import java.util.Enumeration; @@ -215,7 +214,8 @@ public class HgCGIServlet extends HttpServlet String encodedUserInfo = authorization.substring( HttpUtil.AUTHORIZATION_SCHEME_BASIC.length()).trim(); - String userInfo = Base64.base64Decode(encodedUserInfo); + // TODO check encoding of user-agent ? + String userInfo = new String(Base64.getDecoder().decode(encodedUserInfo)); env.set(SCM_CREDENTIALS, CipherUtil.getInstance().encode(userInfo)); } diff --git a/scm-webapp/pom.xml b/scm-webapp/pom.xml index c8b6572e92..7d0e0fc8c9 100644 --- a/scm-webapp/pom.xml +++ b/scm-webapp/pom.xml @@ -75,49 +75,75 @@ jjwt 0.4 - - - + + + - com.sun.jersey - jersey-server - ${jersey.version} + com.fasterxml.jackson.core + jackson-core + ${jackson.version} - com.sun.jersey - jersey-json - ${jersey.version} - - - stax-api - stax - - - jaxb-impl - com.sun.xml.bind - - - - - - com.sun.jersey - jersey-bundle - ${jersey.version} - - - - com.sun.jersey.contribs - jersey-guice - ${jersey.version} - - provided + com.fasterxml.jackson.core + jackson-annotations + ${jackson.version} - com.sun.jersey.contribs - jersey-multipart - ${jersey.version} + com.fasterxml.jackson.core + jackson-databind + ${jackson.version} + + + + com.fasterxml.jackson.module + jackson-module-jaxb-annotations + ${jackson.version} + + + + com.fasterxml.jackson.jaxrs + jackson-jaxrs-base + ${jackson.version} + + + + + + org.jboss.resteasy + resteasy-jaxrs + ${resteasy.version} + + + + org.jboss.resteasy + resteasy-jaxb-provider + ${resteasy.version} + + + + org.jboss.resteasy + resteasy-jackson2-provider + ${resteasy.version} + + + + org.jboss.resteasy + resteasy-multipart-provider + ${resteasy.version} + + + + org.jboss.resteasy + resteasy-guice + ${resteasy.version} + + + + org.jboss.resteasy + resteasy-servlet-initializer + ${resteasy.version} @@ -258,18 +284,18 @@ 2.21 test - + com.sun.jersey jersey-client - ${jersey.version} + ${jersey-client.version} test com.sun.jersey.contribs jersey-apache-client - ${jersey.version} + ${jersey-client.version} test @@ -431,49 +457,12 @@ - - org.apache.maven.plugins - maven-antrun-plugin - 1.6 - - - repack - compile - - run - - - - - - - - - - - - - - - - - - - - org.apache.maven.plugins maven-war-plugin 2.2 true - - - ${project.build.directory}/dependency-rewrite - - @@ -537,6 +526,8 @@ 2.9.1 1.0 0.8.17 + 3.1.3.Final + 2.8.6 Tomcat e1 javascript:S3827 diff --git a/scm-webapp/src/main/java/sonia/scm/ScmContextListener.java b/scm-webapp/src/main/java/sonia/scm/ScmContextListener.java index 5824c2f0d6..4b835d9d0b 100644 --- a/scm-webapp/src/main/java/sonia/scm/ScmContextListener.java +++ b/scm-webapp/src/main/java/sonia/scm/ScmContextListener.java @@ -35,13 +35,11 @@ package sonia.scm; //~--- non-JDK imports -------------------------------------------------------- -import com.google.common.base.Stopwatch; import com.google.common.base.Throwables; import com.google.common.collect.Lists; -import com.google.inject.Guice; import com.google.inject.Injector; import com.google.inject.Module; -import com.google.inject.servlet.GuiceServletContextListener; +import java.util.Collections; import org.apache.shiro.guice.web.ShiroWebModule; @@ -65,6 +63,7 @@ import java.util.Set; import javax.servlet.ServletContext; import javax.servlet.ServletContextEvent; +import org.jboss.resteasy.plugins.guice.GuiceResteasyBootstrapServletContextListener; import sonia.scm.debug.DebugModule; import sonia.scm.filter.WebElementModule; import sonia.scm.schedule.Scheduler; @@ -73,183 +72,65 @@ import sonia.scm.schedule.Scheduler; * * @author Sebastian Sdorra */ -public class ScmContextListener extends GuiceServletContextListener +public class ScmContextListener extends GuiceResteasyBootstrapServletContextListener { /** * the logger for ScmContextListener */ - private static final Logger logger = - LoggerFactory.getLogger(ScmContextListener.class); - + private static final Logger LOG = LoggerFactory.getLogger(ScmContextListener.class); + + private final ClassLoader parent; + private final Set plugins; + private Injector injector; + //~--- constructors --------------------------------------------------------- - - /** - * Constructs ... - * - * - * @param parent - * @param plugins - */ + public ScmContextListener(ClassLoader parent, Set plugins) { this.parent = parent; this.plugins = plugins; } - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @param servletContextEvent - */ - @Override - public void contextDestroyed(ServletContextEvent servletContextEvent) - { - if ((globalInjector != null) &&!startupError) - { - // close Scheduler - IOUtil.close(globalInjector.getInstance(Scheduler.class)); - - // close RepositoryManager - IOUtil.close(globalInjector.getInstance(RepositoryManager.class)); - - // close GroupManager - IOUtil.close(globalInjector.getInstance(GroupManager.class)); - - // close UserManager - IOUtil.close(globalInjector.getInstance(UserManager.class)); - - // close CacheManager - IOUtil.close(globalInjector.getInstance(CacheManager.class)); - - //J- - // call destroy of servlet context listeners - globalInjector.getInstance(ServletContextListenerHolder.class) - .contextDestroyed(servletContextEvent); - //J+ - } - - super.contextDestroyed(servletContextEvent); + public Set getPlugins() { + return plugins; } - /** - * Method description - * - * - * @param servletContextEvent - */ @Override - public void contextInitialized(ServletContextEvent servletContextEvent) - { - this.servletContext = servletContextEvent.getServletContext(); - - if (SCMContext.getContext().getStartupError() == null) - { + public void contextInitialized(ServletContextEvent servletContextEvent) { + beforeInjectorCreation(); + super.contextInitialized(servletContextEvent); + afterInjectorCreation(servletContextEvent); + } + + private void beforeInjectorCreation() { + upgradeIfNecessary(); + } + + private void upgradeIfNecessary() { + if (!hasStartupErrors()) { UpgradeManager upgradeHandler = new UpgradeManager(); upgradeHandler.doUpgrade(); } - else - { - startupError = true; - } - - super.contextInitialized(servletContextEvent); - - // call destroy event - if ((globalInjector != null) &&!startupError) - { - //J- - // bind eager singletons - globalInjector.getInstance(EagerSingletonModule.class) - .initialize(globalInjector); - // init servlet context listeners - globalInjector.getInstance(ServletContextListenerHolder.class) - .contextInitialized(servletContextEvent); - //J+ - } } - - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * @return - */ - public Set getPlugins() - { - return plugins; + + private boolean hasStartupErrors() { + return SCMContext.getContext().getStartupError() != null; } - - /** - * Method description - * - * - * @return - */ + @Override - protected Injector getInjector() - { - if (startupError) - { - globalInjector = getErrorInjector(); + protected List getModules(ServletContext context) { + if (hasStartupErrors()) { + return getErrorModules(); } - else - { - globalInjector = getDefaultInjector(servletContext); - } - - return globalInjector; + return getDefaultModules(context); } + + private List getDefaultModules(ServletContext context) { + DefaultPluginLoader pluginLoader = new DefaultPluginLoader(context, parent, plugins); - //~--- methods -------------------------------------------------------------- - - /** - * Method description - * - * - * @param ep - * @param moduleList - */ - private void appendModules(ExtensionProcessor ep, List moduleList) - { - for (Class module : ep.byExtensionPoint(Module.class)) - { - try - { - logger.info("add module {}", module); - moduleList.add(module.newInstance()); - } - catch (IllegalAccessException | InstantiationException ex) - { - throw Throwables.propagate(ex); - } - } - } - - //~--- get methods ---------------------------------------------------------- - - /** - * Method description - * - * - * - * @param servletCtx - * @return - */ - private Injector getDefaultInjector(ServletContext servletCtx) - { - Stopwatch sw = Stopwatch.createStarted(); - DefaultPluginLoader pluginLoader = new DefaultPluginLoader(servletCtx, - parent, plugins); - - ClassOverrides overrides = - ClassOverrides.findOverrides(pluginLoader.getUberClassLoader()); + ClassOverrides overrides = ClassOverrides.findOverrides(pluginLoader.getUberClassLoader()); List moduleList = Lists.newArrayList(); moduleList.add(new ScmInitializerModule()); @@ -257,9 +138,9 @@ public class ScmContextListener extends GuiceServletContextListener moduleList.add(new EagerSingletonModule()); moduleList.add(ShiroWebModule.guiceFilterModule()); moduleList.add(new WebElementModule(pluginLoader)); - moduleList.add(new ScmServletModule(servletCtx, pluginLoader, overrides)); + moduleList.add(new ScmServletModule(context, pluginLoader, overrides)); moduleList.add( - new ScmSecurityModule(servletCtx, pluginLoader.getExtensionProcessor()) + new ScmSecurityModule(context, pluginLoader.getExtensionProcessor()) ); appendModules(pluginLoader.getExtensionProcessor(), moduleList); moduleList.addAll(overrides.getModules()); @@ -268,41 +149,75 @@ public class ScmContextListener extends GuiceServletContextListener moduleList.add(new DebugModule()); } - SCMContextProvider ctx = SCMContext.getContext(); - - Injector injector = - Guice.createInjector(ctx.getStage().getInjectionStage(), moduleList); - - logger.info("created injector in {}", sw.stop()); - - return injector; + return moduleList; + } + + private void appendModules(ExtensionProcessor ep, List moduleList) { + for (Class module : ep.byExtensionPoint(Module.class)) { + try { + LOG.info("add module {}", module); + moduleList.add(module.newInstance()); + } catch (IllegalAccessException | InstantiationException ex) { + throw Throwables.propagate(ex); + } + } + } + + private List getErrorModules() { + return Collections.singletonList(new ScmErrorModule()); } - /** - * Method description - * - * - * @return - */ - private Injector getErrorInjector() + @Override + protected void withInjector(Injector injector) { + this.injector = injector; + } + + private void afterInjectorCreation(ServletContextEvent event) { + if (injector != null && !hasStartupErrors()) { + bindEagerSingletons(); + initializeServletContextListeners(event); + } + } + + private void bindEagerSingletons() { + injector.getInstance(EagerSingletonModule.class).initialize(injector); + } + + private void initializeServletContextListeners(ServletContextEvent event) { + injector.getInstance(ServletContextListenerHolder.class).contextInitialized(event); + } + + @Override + public void contextDestroyed(ServletContextEvent servletContextEvent) { - return Guice.createInjector(new ScmErrorModule()); + if (injector != null &&!hasStartupErrors()) { + closeCloseables(); + destroyServletContextListeners(servletContextEvent); + } + + super.contextDestroyed(servletContextEvent); + } + + private void closeCloseables() { + // close Scheduler + IOUtil.close(injector.getInstance(Scheduler.class)); + + // close RepositoryManager + IOUtil.close(injector.getInstance(RepositoryManager.class)); + + // close GroupManager + IOUtil.close(injector.getInstance(GroupManager.class)); + + // close UserManager + IOUtil.close(injector.getInstance(UserManager.class)); + + // close CacheManager + IOUtil.close(injector.getInstance(CacheManager.class)); } - //~--- fields --------------------------------------------------------------- + private void destroyServletContextListeners(ServletContextEvent event) { + injector.getInstance(ServletContextListenerHolder.class).contextDestroyed(event); + } - /** Field description */ - private final ClassLoader parent; - /** Field description */ - private final Set plugins; - - /** Field description */ - private Injector globalInjector; - - /** Field description */ - private ServletContext servletContext; - - /** Field description */ - private boolean startupError = false; } diff --git a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java index f1bbdf2ce1..8d89f2b2eb 100644 --- a/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java +++ b/scm-webapp/src/main/java/sonia/scm/ScmServletModule.java @@ -35,17 +35,16 @@ package sonia.scm; //~--- non-JDK imports -------------------------------------------------------- -import com.google.common.collect.Maps; import com.google.inject.Provider; import com.google.inject.multibindings.Multibinder; import com.google.inject.name.Names; import com.google.inject.servlet.RequestScoped; +import com.google.inject.servlet.ServletModule; import com.google.inject.throwingproviders.ThrowingProviderBinder; import org.slf4j.Logger; import org.slf4j.LoggerFactory; -import sonia.scm.api.rest.UriExtensionsConfig; import sonia.scm.cache.CacheManager; import sonia.scm.cache.GuavaCacheManager; import sonia.scm.config.ScmConfiguration; @@ -114,14 +113,6 @@ import sonia.scm.web.security.DefaultAdministrationContext; //~--- JDK imports ------------------------------------------------------------ -import com.sun.jersey.api.core.PackagesResourceConfig; -import com.sun.jersey.api.core.ResourceConfig; -import com.sun.jersey.api.json.JSONConfiguration; -import com.sun.jersey.guice.JerseyServletModule; -import com.sun.jersey.guice.spi.container.servlet.GuiceContainer; -import com.sun.jersey.spi.container.servlet.ServletContainer; - -import java.util.Map; import javax.servlet.ServletContext; import sonia.scm.store.ConfigurationStoreFactory; @@ -144,7 +135,7 @@ import sonia.scm.web.UserAgentParser; * * @author Sebastian Sdorra */ -public class ScmServletModule extends JerseyServletModule +public class ScmServletModule extends ServletModule { /** Field description */ @@ -366,30 +357,6 @@ public class ScmServletModule extends JerseyServletModule // bind events // bind(LastModifiedUpdateListener.class); - - // jersey - Map params = Maps.newHashMap(); - - /* - * params.put("com.sun.jersey.spi.container.ContainerRequestFilters", - * "com.sun.jersey.api.container.filter.LoggingFilter"); - * params.put("com.sun.jersey.spi.container.ContainerResponseFilters", - * "com.sun.jersey.api.container.filter.LoggingFilter"); - * params.put("com.sun.jersey.config.feature.Trace", "true"); - * params.put("com.sun.jersey.config.feature.TracePerRequest", "true"); - */ - params.put(JSONConfiguration.FEATURE_POJO_MAPPING, Boolean.TRUE.toString()); - params.put(ResourceConfig.FEATURE_REDIRECT, Boolean.TRUE.toString()); - params.put(ResourceConfig.FEATURE_DISABLE_WADL, Boolean.TRUE.toString()); - - /* - * TODO remove UriExtensionsConfig and PackagesResourceConfig - * to stop jersey classpath scanning - */ - params.put(ServletContainer.RESOURCE_CONFIG_CLASS, - UriExtensionsConfig.class.getName()); - params.put(PackagesResourceConfig.PROPERTY_PACKAGES, "unbound"); - serve(PATTERN_RESTAPI).with(GuiceContainer.class, params); } /** diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/TemplateEngineViewable.java b/scm-webapp/src/main/java/sonia/scm/api/rest/TemplateEngineViewable.java index 4a089ab150..b36cf6c7e7 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/TemplateEngineViewable.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/TemplateEngineViewable.java @@ -42,65 +42,50 @@ import sonia.scm.template.TemplateEngineFactory; //~--- JDK imports ------------------------------------------------------------ -import com.sun.jersey.api.view.Viewable; -import com.sun.jersey.spi.template.ViewProcessor; - import java.io.IOException; import java.io.OutputStream; import java.io.PrintWriter; +import java.lang.annotation.Annotation; +import java.lang.reflect.Type; +import javax.ws.rs.WebApplicationException; +import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.MultivaluedMap; +import javax.ws.rs.ext.MessageBodyWriter; import javax.ws.rs.ext.Provider; +import sonia.scm.template.Viewable; /** * * @author Sebastian Sdorra */ @Provider -public class TemplateEngineViewable implements ViewProcessor +public class TemplateEngineViewable implements MessageBodyWriter { + + private final TemplateEngineFactory templateEngineFactory; - /** - * Constructs ... - * - * - * @param templateEngineFactory - */ @Inject public TemplateEngineViewable(TemplateEngineFactory templateEngineFactory) { this.templateEngineFactory = templateEngineFactory; } - //~--- methods -------------------------------------------------------------- - /** - * Method description - * - * - * @param name - * - * @return - */ @Override - public String resolve(String name) - { - return name; + public boolean isWriteable(Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { + return type.isAssignableFrom(Viewable.class); } - /** - * Method description - * - * - * @param path - * @param viewable - * @param out - * - * @throws IOException - */ @Override - public void writeTo(String path, Viewable viewable, OutputStream out) - throws IOException - { + public long getSize(Viewable viewable, Class type, Type genericType, Annotation[] annotations, MediaType mediaType) { + return -1; + } + + @Override + public void writeTo(Viewable viewable, Class type, Type genericType, Annotation[] annotations, MediaType mediaType, MultivaluedMap httpHeaders, OutputStream entityStream) throws IOException, WebApplicationException { + String path = viewable.getPath(); + TemplateEngine engine = templateEngineFactory.getEngineByExtension(path); if (engine == null) @@ -115,14 +100,9 @@ public class TemplateEngineViewable implements ViewProcessor throw new IOException("could not find template for ".concat(path)); } - PrintWriter writer = new PrintWriter(out); + PrintWriter writer = new PrintWriter(entityStream); - template.execute(writer, viewable.getModel()); + template.execute(writer, viewable.getContext()); writer.flush(); } - - //~--- fields --------------------------------------------------------------- - - /** Field description */ - private TemplateEngineFactory templateEngineFactory; } diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractPermissionResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractPermissionResource.java index e9e63d16d8..040eb6b2dc 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractPermissionResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AbstractPermissionResource.java @@ -133,7 +133,7 @@ public abstract class AbstractPermissionResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response add(@Context UriInfo uriInfo, Permission permission) { AssignedPermission ap = transformPermission(permission); @@ -185,7 +185,7 @@ public abstract class AbstractPermissionResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response update(@PathParam("id") String id, Permission permission) { StoredAssignedPermission sap = getPermission(id); @@ -213,7 +213,7 @@ public abstract class AbstractPermissionResource @ResponseCode(code = 404, condition = "not found, no permission with the specified id available"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Permission get(@PathParam("id") String id) { StoredAssignedPermission sap = getPermission(id); @@ -231,7 +231,7 @@ public abstract class AbstractPermissionResource @ResponseCode(code = 204, condition = "success"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public List getAll() { return getPermissions(getPredicate()); diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AuthenticationResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AuthenticationResource.java index 2c5615c1a0..4291a3f398 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AuthenticationResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/AuthenticationResource.java @@ -93,7 +93,7 @@ import sonia.scm.security.Scope; */ @Singleton @Path("auth") -@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) +@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public class AuthenticationResource { diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ChangePasswordResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ChangePasswordResource.java index a9e904c89f..7aed8dde0b 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ChangePasswordResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ChangePasswordResource.java @@ -117,7 +117,7 @@ public class ChangePasswordResource @ResponseCode(code = 400, condition = "bad request, the old password is not correct"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response changePassword(@FormParam("old-password") String oldPassword, @FormParam("new-password") String newPassword) throws UserException, IOException diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ConfigurationResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ConfigurationResource.java index 2fb6bdda3d..a9beea7679 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ConfigurationResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/ConfigurationResource.java @@ -89,7 +89,7 @@ public class ConfigurationResource * @return */ @GET - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response getConfiguration() { Response response = null; @@ -118,7 +118,7 @@ public class ConfigurationResource * @return */ @POST - @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response setConfig(@Context UriInfo uriInfo, ScmConfiguration newConfig) { diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/GroupResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/GroupResource.java index 808aaa498b..dd61f0aecb 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/GroupResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/GroupResource.java @@ -119,7 +119,7 @@ public class GroupResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @Override public Response create(@Context UriInfo uriInfo, Group group) { @@ -164,7 +164,7 @@ public class GroupResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @Override public Response update(@Context UriInfo uriInfo, @PathParam("id") String name, Group group) @@ -191,7 +191,7 @@ public class GroupResource @ResponseCode(code = 404, condition = "not found, no group with the specified id/name available"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @Override public Response get(@Context Request request, @PathParam("id") String id) { @@ -221,7 +221,7 @@ public class GroupResource * @return */ @GET - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @TypeHint(Group[].class) @StatusCodes({ @ResponseCode(code = 200, condition = "success"), diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/PluginResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/PluginResource.java index c605c7c29a..4a770206eb 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/PluginResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/PluginResource.java @@ -52,7 +52,6 @@ import sonia.scm.plugin.PluginManager; //~--- JDK imports ------------------------------------------------------------ -import com.sun.jersey.multipart.FormDataParam; import com.webcohesion.enunciate.metadata.rs.ResponseCode; import com.webcohesion.enunciate.metadata.rs.StatusCodes; import com.webcohesion.enunciate.metadata.rs.TypeHint; @@ -66,6 +65,7 @@ import java.util.Iterator; import java.util.List; import javax.ws.rs.Consumes; +import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; @@ -124,9 +124,9 @@ public class PluginResource @ResponseCode(code = 500, condition = "internal server error") }) @Consumes(MediaType.MULTIPART_FORM_DATA) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response install( - @FormDataParam("package") InputStream uploadedInputStream) + /*@FormParam("package")*/ InputStream uploadedInputStream) throws IOException { Response response = null; @@ -194,7 +194,7 @@ public class PluginResource @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.TEXT_HTML) public Response installFromUI( - @FormDataParam("package") InputStream uploadedInputStream) + /*@FormParam("package")*/ InputStream uploadedInputStream) throws IOException { return install(uploadedInputStream); @@ -257,7 +257,7 @@ public class PluginResource @ResponseCode(code = 200, condition = "success"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Collection getAll() { return pluginManager.getAll(); @@ -274,7 +274,7 @@ public class PluginResource @ResponseCode(code = 200, condition = "success"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Collection getAvailable() { return pluginManager.getAvailable(); @@ -291,7 +291,7 @@ public class PluginResource @ResponseCode(code = 200, condition = "success"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Collection getAvailableUpdates() { return pluginManager.getAvailableUpdates(); @@ -325,7 +325,7 @@ public class PluginResource @ResponseCode(code = 200, condition = "success"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Collection getOverview() { //J- diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java index 728c935fc1..0fe6f8df1d 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryImportResource.java @@ -69,8 +69,6 @@ import static com.google.common.base.Preconditions.*; //~--- JDK imports ------------------------------------------------------------ -import com.sun.jersey.api.client.ClientResponse.Status; -import com.sun.jersey.multipart.FormDataParam; import com.webcohesion.enunciate.metadata.rs.ResponseCode; import com.webcohesion.enunciate.metadata.rs.ResponseHeader; import com.webcohesion.enunciate.metadata.rs.StatusCodes; @@ -89,6 +87,7 @@ import java.util.Set; import javax.ws.rs.Consumes; import javax.ws.rs.DefaultValue; +import javax.ws.rs.FormParam; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.Path; @@ -111,7 +110,7 @@ import javax.xml.bind.annotation.XmlRootElement; * * @author Sebastian Sdorra */ -@Path("import/repositories") +// @Path("import/repositories") public class RepositoryImportResource { @@ -170,8 +169,8 @@ public class RepositoryImportResource @TypeHint(TypeHint.NO_CONTENT.class) @Consumes(MediaType.MULTIPART_FORM_DATA) public Response importFromBundle(@Context UriInfo uriInfo, - @PathParam("type") String type, @FormDataParam("name") String name, - @FormDataParam("bundle") InputStream inputStream, @QueryParam("compressed") + @PathParam("type") String type, @FormParam("name") String name, + @FormParam("bundle") InputStream inputStream, @QueryParam("compressed") @DefaultValue("false") boolean compressed) { Repository repository = doImportFromBundle(type, name, inputStream, @@ -211,8 +210,8 @@ public class RepositoryImportResource @Consumes(MediaType.MULTIPART_FORM_DATA) @Produces(MediaType.TEXT_HTML) public Response importFromBundleUI(@PathParam("type") String type, - @FormDataParam("name") String name, - @FormDataParam("bundle") InputStream inputStream, @QueryParam("compressed") + @FormParam("name") String name, + @FormParam("bundle") InputStream inputStream, @QueryParam("compressed") @DefaultValue("false") boolean compressed) { Response response; @@ -260,7 +259,7 @@ public class RepositoryImportResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Consumes({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response importFromUrl(@Context UriInfo uriInfo, @PathParam("type") String type, UrlImportRequest request) { @@ -320,7 +319,7 @@ public class RepositoryImportResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(Repository[].class) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response importRepositories(@PathParam("type") String type) { SecurityUtils.getSubject().checkRole(Role.ADMIN); @@ -352,7 +351,7 @@ public class RepositoryImportResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(Repository[].class) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response importRepositories() { SecurityUtils.getSubject().checkRole(Role.ADMIN); @@ -394,7 +393,7 @@ public class RepositoryImportResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(ImportResult.class) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response importRepositoriesFromDirectory( @PathParam("type") String type) { @@ -435,7 +434,7 @@ public class RepositoryImportResource .warn( "import feature is not supported by repository handler for type " .concat(type), ex); - response = Response.status(Status.BAD_REQUEST).build(); + response = Response.status(Response.Status.BAD_REQUEST).build(); } catch (IOException ex) { @@ -451,7 +450,7 @@ public class RepositoryImportResource else { logger.warn("could not find reposiotry handler for type {}", type); - response = Response.status(Status.BAD_REQUEST).build(); + response = Response.status(Response.Status.BAD_REQUEST).build(); } return response; @@ -475,7 +474,7 @@ public class RepositoryImportResource ), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Response getImportableTypes() { SecurityUtils.getSubject().checkRole(Role.ADMIN); diff --git a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java index ad092911ee..ab8210f932 100644 --- a/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java +++ b/scm-webapp/src/main/java/sonia/scm/api/rest/resources/RepositoryResource.java @@ -163,7 +163,7 @@ public class RepositoryResource extends AbstractManagerResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @Override public Response create(@Context UriInfo uriInfo, User user) { @@ -169,7 +169,7 @@ public class UserResource extends AbstractManagerResource @ResponseCode(code = 500, condition = "internal server error") }) @TypeHint(TypeHint.NO_CONTENT.class) - @Consumes({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @Override public Response update(@Context UriInfo uriInfo, @PathParam("id") String name, User user) @@ -196,7 +196,7 @@ public class UserResource extends AbstractManagerResource @ResponseCode(code = 404, condition = "not found, no group with the specified id/name available"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @Override public Response get(@Context Request request, @PathParam("id") String id) { @@ -232,7 +232,7 @@ public class UserResource extends AbstractManagerResource @ResponseCode(code = 403, condition = "forbidden, the current user has no admin privileges"), @ResponseCode(code = 500, condition = "internal server error") }) - @Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON }) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) @Override public Response getAll(@Context Request request, @DefaultValue("0") @QueryParam("start") int start, @DefaultValue("-1") diff --git a/scm-webapp/src/main/java/sonia/scm/debug/DebugResource.java b/scm-webapp/src/main/java/sonia/scm/debug/DebugResource.java index f65e0c7708..0933242b49 100644 --- a/scm-webapp/src/main/java/sonia/scm/debug/DebugResource.java +++ b/scm-webapp/src/main/java/sonia/scm/debug/DebugResource.java @@ -67,7 +67,7 @@ public final class DebugResource * @return all received hook data for the given repository */ @GET - @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public Collection getAll(@PathParam("repository") String repository){ return debugService.getAll(repository); } @@ -81,7 +81,7 @@ public final class DebugResource */ @GET @Path("last") - @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) + @Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML }) public DebugHookData getLast(@PathParam("repository") String repository){ return debugService.getLast(repository); } diff --git a/scm-webapp/src/main/java/sonia/scm/net/ahc/JsonContentTransformer.java b/scm-webapp/src/main/java/sonia/scm/net/ahc/JsonContentTransformer.java index fce81ba386..c22529a8a1 100644 --- a/scm-webapp/src/main/java/sonia/scm/net/ahc/JsonContentTransformer.java +++ b/scm-webapp/src/main/java/sonia/scm/net/ahc/JsonContentTransformer.java @@ -33,13 +33,15 @@ package sonia.scm.net.ahc; //~--- non-JDK imports -------------------------------------------------------- -import com.google.common.io.ByteSource; +import com.fasterxml.jackson.databind.AnnotationIntrospector; +import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.introspect.AnnotationIntrospectorPair; +import com.fasterxml.jackson.databind.introspect.JacksonAnnotationIntrospector; +import com.fasterxml.jackson.databind.type.TypeFactory; +import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector; -import org.codehaus.jackson.map.AnnotationIntrospector; -import org.codehaus.jackson.map.DeserializationConfig; -import org.codehaus.jackson.map.ObjectMapper; -import org.codehaus.jackson.map.introspect.JacksonAnnotationIntrospector; -import org.codehaus.jackson.xc.JaxbAnnotationIntrospector; +import com.google.common.io.ByteSource; import sonia.scm.plugin.Extension; import sonia.scm.util.IOUtil; @@ -73,12 +75,12 @@ public class JsonContentTransformer implements ContentTransformer // allow jackson and jaxb annotations AnnotationIntrospector jackson = new JacksonAnnotationIntrospector(); - AnnotationIntrospector jaxb = new JaxbAnnotationIntrospector(); + AnnotationIntrospector jaxb = new JaxbAnnotationIntrospector(TypeFactory.defaultInstance()); - this.mapper.setAnnotationIntrospector(new AnnotationIntrospector.Pair(jackson, jaxb)); + this.mapper.setAnnotationIntrospector(new AnnotationIntrospectorPair(jackson, jaxb)); // do not fail on unknown json properties - this.mapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false); + this.mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); } //~--- methods -------------------------------------------------------------- diff --git a/scm-webapp/src/main/java/sonia/scm/web/security/ApiAuthenticationFilter.java b/scm-webapp/src/main/java/sonia/scm/web/security/ApiAuthenticationFilter.java index 5c8f57ae80..8340225872 100644 --- a/scm-webapp/src/main/java/sonia/scm/web/security/ApiAuthenticationFilter.java +++ b/scm-webapp/src/main/java/sonia/scm/web/security/ApiAuthenticationFilter.java @@ -67,7 +67,7 @@ public class ApiAuthenticationFilter extends AuthenticationFilter { /** login uri */ - public static final String URI_LOGIN = "/api/rest/authentication/login"; + public static final String URI_LOGIN = "/api/rest/auth/access_token"; //~--- constructors --------------------------------------------------------- diff --git a/scm-webapp/src/main/resources/logback.default.xml b/scm-webapp/src/main/resources/logback.default.xml index 939ff92b37..e2ed890525 100644 --- a/scm-webapp/src/main/resources/logback.default.xml +++ b/scm-webapp/src/main/resources/logback.default.xml @@ -92,6 +92,8 @@ + + diff --git a/scm-webapp/src/main/webapp/WEB-INF/web.xml b/scm-webapp/src/main/webapp/WEB-INF/web.xml index fb906270a4..b65f1f3c6b 100644 --- a/scm-webapp/src/main/webapp/WEB-INF/web.xml +++ b/scm-webapp/src/main/webapp/WEB-INF/web.xml @@ -37,32 +37,60 @@ xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd" metadata-complete="true"> - SCM-Manager ${project.version} + SCM-Manager ${project.version} - - sonia.scm.boot.BootstrapContextListener - - - - sonia.scm.HttpSessionListenerHolder - + - - BootstrapFilter - sonia.scm.boot.BootstrapContextFilter - + + sonia.scm.boot.BootstrapContextListener + - - BootstrapFilter - /* - + + BootstrapFilter + sonia.scm.boot.BootstrapContextFilter + - - index.html - + + BootstrapFilter + /* + + + + + + resteasy.servlet.mapping.prefix + /api/rest + - - 30 - + + Resteasy + + org.jboss.resteasy.plugins.server.servlet.HttpServletDispatcher + + + + + Resteasy + /api/rest/* + + + + + + + sonia.scm.HttpSessionListenerHolder + + + + + + index.html + + + + 30 + diff --git a/scm-webapp/src/main/webapp/resources/js/action/sonia.action.changepasswordwindow.js b/scm-webapp/src/main/webapp/resources/js/action/sonia.action.changepasswordwindow.js index b1c0a5372f..3d044d69c5 100644 --- a/scm-webapp/src/main/webapp/resources/js/action/sonia.action.changepasswordwindow.js +++ b/scm-webapp/src/main/webapp/resources/js/action/sonia.action.changepasswordwindow.js @@ -55,7 +55,7 @@ Sonia.action.ChangePasswordWindow = Ext.extend(Ext.Window,{ title: this.titleText, items: [{ id: 'changePasswordForm', - url: restUrl + 'action/change-password.json', + url: restUrl + 'action/change-password', frame: true, xtype: 'form', monitorValid: true, diff --git a/scm-webapp/src/main/webapp/resources/js/config/sonia.config.scmconfigpanel.js b/scm-webapp/src/main/webapp/resources/js/config/sonia.config.scmconfigpanel.js index a985688a3e..0f9c2fdd57 100644 --- a/scm-webapp/src/main/webapp/resources/js/config/sonia.config.scmconfigpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/config/sonia.config.scmconfigpanel.js @@ -261,7 +261,7 @@ Sonia.config.ScmConfigPanel = Ext.extend(Sonia.config.ConfigPanel,{ onSubmit: function(values){ this.el.mask(this.submitText); Ext.Ajax.request({ - url: restUrl + 'config.json', + url: restUrl + 'config', method: 'POST', jsonData: values, scope: this, @@ -283,7 +283,7 @@ Sonia.config.ScmConfigPanel = Ext.extend(Sonia.config.ConfigPanel,{ onLoad: function(el){ var tid = setTimeout( function(){ el.mask(this.loadingText); }, 100); Ext.Ajax.request({ - url: restUrl + 'config.json', + url: restUrl + 'config', method: 'GET', scope: this, disableCaching: true, diff --git a/scm-webapp/src/main/webapp/resources/js/group/sonia.group.formpanel.js b/scm-webapp/src/main/webapp/resources/js/group/sonia.group.formpanel.js index 5d560d9717..4ec278bf6b 100644 --- a/scm-webapp/src/main/webapp/resources/js/group/sonia.group.formpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/group/sonia.group.formpanel.js @@ -59,7 +59,7 @@ Sonia.group.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ // this.updateMembers(group); this.fireEvent('preUpdate', group); - var url = restUrl + 'groups/' + encodeURIComponent(group.name) + '.json'; + var url = restUrl + 'groups/' + encodeURIComponent(group.name); var el = this.el; var tid = setTimeout( function(){el.mask('Loading ...');}, 100); @@ -96,7 +96,7 @@ Sonia.group.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ } item.type = state.defaultUserType; - var url = restUrl + 'groups.json'; + var url = restUrl + 'groups'; var el = this.el; var tid = setTimeout( function(){el.mask('Loading ...');}, 100); diff --git a/scm-webapp/src/main/webapp/resources/js/group/sonia.group.panel.js b/scm-webapp/src/main/webapp/resources/js/group/sonia.group.panel.js index 18d3841fc2..1bc3fbe819 100644 --- a/scm-webapp/src/main/webapp/resources/js/group/sonia.group.panel.js +++ b/scm-webapp/src/main/webapp/resources/js/group/sonia.group.panel.js @@ -95,7 +95,7 @@ Sonia.group.Panel = Ext.extend(Sonia.rest.Panel, { var selected = grid.getSelectionModel().getSelected(); if ( selected ){ var item = selected.data; - var url = restUrl + 'groups/' + encodeURIComponent(item.name) + '.json'; + var url = restUrl + 'groups/' + encodeURIComponent(item.name); Ext.MessageBox.show({ title: this.removeTitleText, diff --git a/scm-webapp/src/main/webapp/resources/js/login/sonia.login.form.js b/scm-webapp/src/main/webapp/resources/js/login/sonia.login.form.js index 3b14ae2978..ee0d7a689b 100644 --- a/scm-webapp/src/main/webapp/resources/js/login/sonia.login.form.js +++ b/scm-webapp/src/main/webapp/resources/js/login/sonia.login.form.js @@ -61,7 +61,7 @@ Sonia.login.Form = Ext.extend(Ext.FormPanel,{ var config = { labelWidth: 120, - url: restUrl + "auth/access_token.json", + url: restUrl + "auth/access_token", frame: true, title: this.titleText, defaultType: 'textfield', diff --git a/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.center.js b/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.center.js index 11113e2601..ebd2119886 100644 --- a/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.center.js +++ b/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.center.js @@ -81,7 +81,7 @@ Sonia.plugin.Center = Ext.extend(Ext.util.Observable, { var loadingBox = this.createLoadingBox( this.installWaitMsgText ); Ext.Ajax.request({ - url: restUrl + 'plugins/install/' + pluginId + '.json', + url: restUrl + 'plugins/install/' + pluginId, method: 'POST', scope: this, timeout: 300000, // 5min @@ -116,7 +116,7 @@ Sonia.plugin.Center = Ext.extend(Ext.util.Observable, { var loadingBox = this.createLoadingBox( this.uninstallWaitMsgText ); Ext.Ajax.request({ - url: restUrl + 'plugins/uninstall/' + pluginId + '.json', + url: restUrl + 'plugins/uninstall/' + pluginId, method: 'POST', scope: this, success: function(){ @@ -150,7 +150,7 @@ Sonia.plugin.Center = Ext.extend(Ext.util.Observable, { var loadingBox = this.createLoadingBox( this.updateWaitMsgText ); Ext.Ajax.request({ - url: restUrl + 'plugins/update/' + pluginId + '.json', + url: restUrl + 'plugins/update/' + pluginId, method: 'POST', scope: this, timeout: 300000, // 5min diff --git a/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.grid.js b/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.grid.js index cb5ea6bec1..5f44e51ebc 100644 --- a/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.grid.js +++ b/scm-webapp/src/main/webapp/resources/js/plugin/sonia.plugin.grid.js @@ -81,7 +81,7 @@ Sonia.plugin.Grid = Ext.extend(Sonia.rest.Grid, { var pluginStore = new Ext.data.GroupingStore({ proxy: new Ext.data.HttpProxy({ - url: restUrl + 'plugins/overview.json', + url: restUrl + 'plugins/overview', disableCaching: false }), reader: new Ext.data.JsonReader({ diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.branchcombobox.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.branchcombobox.js index cddcad4552..4c3dcbc7c8 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.branchcombobox.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.branchcombobox.js @@ -38,7 +38,7 @@ Sonia.repository.BranchComboBox = Ext.extend(Ext.form.ComboBox, { initComponent: function(){ var branchStore = new Sonia.rest.JsonStore({ proxy: new Ext.data.HttpProxy({ - url: restUrl + 'repositories/' + this.repositoryId + '/branches.json', + url: restUrl + 'repositories/' + this.repositoryId + '/branches', method: 'GET', disableCaching: false }), diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewerpanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewerpanel.js index aa18d29e0d..468b99dbec 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewerpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.changesetviewerpanel.js @@ -46,7 +46,7 @@ Sonia.repository.ChangesetViewerPanel = Ext.extend(Ext.Panel, { initComponent: function(){ if (! this.url){ - this.url = restUrl + 'repositories/' + this.repository.id + '/changesets.json'; + this.url = restUrl + 'repositories/' + this.repository.id + '/changesets'; } if ( ! this.startLimit ){ diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.commitpanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.commitpanel.js index 7b72c4fca3..591d77d43f 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.commitpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.commitpanel.js @@ -131,7 +131,7 @@ Sonia.repository.CommitPanel = Ext.extend(Ext.Panel, { } Ext.Ajax.request({ - url: restUrl + 'repositories/' + this.repository.id + '/changeset/' + this.revision + '.json', + url: restUrl + 'repositories/' + this.repository.id + '/changeset/' + this.revision, method: 'GET', scope: this, success: function(response){ diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.formpanel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.formpanel.js index 66482399ac..422a81ce6b 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.formpanel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.formpanel.js @@ -73,7 +73,7 @@ Sonia.repository.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ if ( debug ){ console.debug( 'update repository: ' + item.name ); } - var url = restUrl + 'repositories/' + item.id + '.json'; + var url = restUrl + 'repositories/' + item.id; var el = this.el; var tid = setTimeout( function(){el.mask('Loading ...');}, 100); @@ -124,7 +124,7 @@ Sonia.repository.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ if ( debug ){ console.debug( 'create repository: ' + item.name ); } - var url = restUrl + 'repositories.json'; + var url = restUrl + 'repositories'; var el = this.el; var tid = setTimeout( function(){el.mask('Loading ...');}, 100); diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.grid.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.grid.js index fb66b91a5a..9e2f76f607 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.grid.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.grid.js @@ -71,7 +71,7 @@ Sonia.repository.Grid = Ext.extend(Sonia.rest.Grid, { var repositoryStore = new Ext.data.GroupingStore({ proxy: new Ext.data.HttpProxy({ - url: restUrl + 'repositories.json', + url: restUrl + 'repositories', disableCaching: false }), idProperty: 'id', diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.healthcheckfailure.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.healthcheckfailure.js index 195d7d7509..076f73e712 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.healthcheckfailure.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.healthcheckfailure.js @@ -75,7 +75,7 @@ Sonia.repository.HealthCheckFailure = Ext.extend(Ext.Panel, { }, rerunHealthChecks: function(){ - var url = restUrl + 'repositories/' + this.repository.id + '/healthcheck.json'; + var url = restUrl + 'repositories/' + this.repository.id + '/healthcheck'; var el = this.el; var tid = setTimeout( function(){el.mask('Loading ...');}, 100); diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.importwindow.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.importwindow.js index 209b554e82..ac6bbc2206 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.importwindow.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.importwindow.js @@ -514,7 +514,7 @@ Sonia.repository.ImportPanel = Ext.extend(Ext.Panel, { importFromUrl: function(layout, repository){ var lbox = this.showLoadingBox(); Ext.Ajax.request({ - url: restUrl + 'import/repositories/' + this.repositoryType + '/url.json', + url: restUrl + 'import/repositories/' + this.repositoryType + '/url', method: 'POST', scope: this, timeout: 300000, // 5min @@ -533,7 +533,7 @@ Sonia.repository.ImportPanel = Ext.extend(Ext.Panel, { importFromDirectory: function(layout){ var lbox = this.showLoadingBox(); Ext.Ajax.request({ - url: restUrl + 'import/repositories/' + this.repositoryType + '/directory.json', + url: restUrl + 'import/repositories/' + this.repositoryType + '/directory', timeout: 300000, // 5min method: 'POST', scope: this, diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js index 7e10a58f4e..e978c0ffe9 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.js @@ -181,7 +181,7 @@ Sonia.repository.get = function(id, callback){ execCallback(repository); } else { Ext.Ajax.request({ - url: restUrl + 'repositories/' + id + '.json', + url: restUrl + 'repositories/' + id, method: 'GET', scope: this, success: function(response){ diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js index 17a301509a..767c294242 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.panel.js @@ -311,7 +311,7 @@ Sonia.repository.Panel = Ext.extend(Sonia.rest.Panel, { console.debug('toggle repository ' + item.name + ' archive to ' + item.archived); } - var url = restUrl + 'repositories/' + item.id + '.json'; + var url = restUrl + 'repositories/' + item.id; this.executeRemoteCall(title, String.format(msg, item.name), 'PUT', url, item, function(result){ main.handleFailure( @@ -331,7 +331,7 @@ Sonia.repository.Panel = Ext.extend(Sonia.rest.Panel, { console.debug( 'remove repository ' + item.name ); } - var url = restUrl + 'repositories/' + item.id + '.json'; + var url = restUrl + 'repositories/' + item.id; this.executeRemoteCall(this.removeTitleText, String.format(this.removeMsgText, item.name), 'DELETE', url, null, function(result){ diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js index 489dd3c06c..59677cab7e 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.repositorybrowser.js @@ -58,7 +58,7 @@ Sonia.repository.RepositoryBrowser = Ext.extend(Ext.grid.GridPanel, { var browserStore = new Sonia.rest.JsonStore({ proxy: new Ext.data.HttpProxy({ - url: restUrl + 'repositories/' + this.repository.id + '/browse.json', + url: restUrl + 'repositories/' + this.repository.id, method: 'GET' }), fields: ['path', 'name', 'length', 'lastModified', 'directory', 'description', 'subrepository'], diff --git a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.tagcombobox.js b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.tagcombobox.js index 3f045a8cf6..5af3cc97f1 100644 --- a/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.tagcombobox.js +++ b/scm-webapp/src/main/webapp/resources/js/repository/sonia.repository.tagcombobox.js @@ -37,7 +37,7 @@ Sonia.repository.TagComboBox = Ext.extend(Ext.form.ComboBox, { initComponent: function(){ var tagStore = new Sonia.rest.JsonStore({ proxy: new Ext.data.HttpProxy({ - url: restUrl + 'repositories/' + this.repositoryId + '/tags.json', + url: restUrl + 'repositories/' + this.repositoryId + '/tags', method: 'GET', disableCaching: false }), diff --git a/scm-webapp/src/main/webapp/resources/js/security/sonia.security.permissionspanel.js b/scm-webapp/src/main/webapp/resources/js/security/sonia.security.permissionspanel.js index 5ea8855251..676114fc78 100644 --- a/scm-webapp/src/main/webapp/resources/js/security/sonia.security.permissionspanel.js +++ b/scm-webapp/src/main/webapp/resources/js/security/sonia.security.permissionspanel.js @@ -53,7 +53,7 @@ Sonia.security.PermissionsPanel = Ext.extend(Ext.Panel, { this.permissionStore = new Sonia.rest.JsonStore({ proxy: new Ext.data.HttpProxy({ api: { - read: restUrl + this.baseUrl + '.json' + read: restUrl + this.baseUrl }, disableCaching: false }), @@ -179,7 +179,7 @@ Sonia.security.PermissionsPanel = Ext.extend(Ext.Panel, { addPermission: function(record){ Ext.Ajax.request({ - url: restUrl + this.baseUrl + '.json', + url: restUrl + this.baseUrl, method: 'POST', jsonData: record.data, scope: this, @@ -194,7 +194,7 @@ Sonia.security.PermissionsPanel = Ext.extend(Ext.Panel, { modifyPermission: function(id, record){ Ext.Ajax.request({ - url: restUrl + this.baseUrl + '/' + encodeURIComponent(id) + '.json', + url: restUrl + this.baseUrl + '/' + encodeURIComponent(id), method: 'PUT', jsonData: record.data, scope: this, @@ -207,7 +207,7 @@ Sonia.security.PermissionsPanel = Ext.extend(Ext.Panel, { removePermission: function(store, record){ Ext.Ajax.request({ - url: restUrl + this.baseUrl + '/' + encodeURIComponent(record.get('id')) + '.json', + url: restUrl + this.baseUrl + '/' + encodeURIComponent(record.get('id')), method: 'DELETE', scope: this, success: function(){ diff --git a/scm-webapp/src/main/webapp/resources/js/sonia.global.js b/scm-webapp/src/main/webapp/resources/js/sonia.global.js index ef7dc72a56..a9b0e9a30e 100644 --- a/scm-webapp/src/main/webapp/resources/js/sonia.global.js +++ b/scm-webapp/src/main/webapp/resources/js/sonia.global.js @@ -83,7 +83,7 @@ var userSearchStore = new Ext.data.JsonStore({ idProperty: 'value', fields: ['value','label'], proxy: new Ext.data.HttpProxy({ - url: restUrl + 'search/users.json', + url: restUrl + 'search/users', method: 'GET' }) }); @@ -93,7 +93,7 @@ var groupSearchStore = new Ext.data.JsonStore({ idProperty: 'value', fields: ['value','label'], proxy: new Ext.data.HttpProxy({ - url: restUrl + 'search/groups.json', + url: restUrl + 'search/groups', method: 'GET' }) }); diff --git a/scm-webapp/src/main/webapp/resources/js/sonia.scm.js b/scm-webapp/src/main/webapp/resources/js/sonia.scm.js index 0efa7b2585..9befb7c676 100644 --- a/scm-webapp/src/main/webapp/resources/js/sonia.scm.js +++ b/scm-webapp/src/main/webapp/resources/js/sonia.scm.js @@ -339,7 +339,7 @@ Sonia.scm.Main = Ext.extend(Ext.util.Observable, { checkLogin: function(){ Ext.Ajax.request({ - url: restUrl + 'auth/state.json', + url: restUrl + 'auth/state', method: 'GET', scope: this, success: function(response){ @@ -367,7 +367,7 @@ Sonia.scm.Main = Ext.extend(Ext.util.Observable, { logout: function(){ Ext.Ajax.request({ - url: restUrl + 'auth/logout.json', + url: restUrl + 'auth/logout', method: 'GET', scope: this, success: function(response){ 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 6ef00e73d7..e8a03e5966 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 @@ -129,7 +129,7 @@ Sonia.user.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ console.debug( 'update user: ' + item.name ); } this.fixRequest(item); - var url = restUrl + 'users/' + encodeURIComponent(item.name) + '.json'; + var url = restUrl + 'users/' + encodeURIComponent(item.name); Ext.Ajax.request({ url: url, jsonData: item, @@ -159,7 +159,7 @@ Sonia.user.FormPanel = Ext.extend(Sonia.rest.FormPanel,{ this.fixRequest(user); // set user type user.type = state.defaultUserType; - var url = restUrl + 'users.json'; + var url = restUrl + 'users'; Ext.Ajax.request({ url: url, jsonData: user, diff --git a/scm-webapp/src/main/webapp/resources/js/user/sonia.user.grid.js b/scm-webapp/src/main/webapp/resources/js/user/sonia.user.grid.js index c44d336ba9..b671e67bdc 100644 --- a/scm-webapp/src/main/webapp/resources/js/user/sonia.user.grid.js +++ b/scm-webapp/src/main/webapp/resources/js/user/sonia.user.grid.js @@ -49,7 +49,7 @@ Sonia.user.Grid = Ext.extend(Sonia.rest.Grid, { var userStore = new Sonia.rest.JsonStore({ proxy: new Ext.data.HttpProxy({ - url: restUrl + 'users.json', + url: restUrl + 'users', disableCaching: false }), idProperty: 'name', diff --git a/scm-webapp/src/main/webapp/resources/js/user/sonia.user.panel.js b/scm-webapp/src/main/webapp/resources/js/user/sonia.user.panel.js index 8e98c645df..0ca0fd78e1 100644 --- a/scm-webapp/src/main/webapp/resources/js/user/sonia.user.panel.js +++ b/scm-webapp/src/main/webapp/resources/js/user/sonia.user.panel.js @@ -126,7 +126,7 @@ Sonia.user.Panel = Ext.extend(Sonia.rest.Panel, { var selected = grid.getSelectionModel().getSelected(); if ( selected ){ var item = selected.data; - var url = restUrl + 'users/' + encodeURIComponent(item.name) + '.json'; + var url = restUrl + 'users/' + encodeURIComponent(item.name); Ext.MessageBox.show({ title: this.removeTitleText, diff --git a/scm-webapp/src/test/java/sonia/scm/it/GitLfsITCase.java b/scm-webapp/src/test/java/sonia/scm/it/GitLfsITCase.java index f8adb90ff1..33e020f85d 100644 --- a/scm-webapp/src/test/java/sonia/scm/it/GitLfsITCase.java +++ b/scm-webapp/src/test/java/sonia/scm/it/GitLfsITCase.java @@ -32,6 +32,9 @@ package sonia.scm.it; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.type.TypeFactory; +import com.fasterxml.jackson.module.jaxb.JaxbAnnotationIntrospector; import com.google.common.base.Charsets; import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.UniformInterfaceException; @@ -41,8 +44,6 @@ import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; import javax.xml.bind.annotation.XmlRootElement; import org.apache.shiro.crypto.hash.Sha256Hash; -import org.codehaus.jackson.map.ObjectMapper; -import org.codehaus.jackson.xc.JaxbAnnotationIntrospector; import org.hamcrest.Matchers; import org.junit.After; import org.junit.Test; @@ -81,7 +82,7 @@ public class GitLfsITCase { private Repository repository; public GitLfsITCase() { - mapper.setAnnotationIntrospector(new JaxbAnnotationIntrospector()); + mapper.setAnnotationIntrospector(new JaxbAnnotationIntrospector(TypeFactory.defaultInstance())); } // lifecycle methods