switch from jersey 1.x to resteasy

This commit is contained in:
Sebastian Sdorra
2017-06-27 20:16:05 +02:00
parent aec3d5d65d
commit 3637a8de20
53 changed files with 415 additions and 568 deletions

View File

@@ -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<PluginWrapper> plugins;
private Injector injector;
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
*
* @param parent
* @param plugins
*/
public ScmContextListener(ClassLoader parent, Set<PluginWrapper> 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<PluginWrapper> 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<PluginWrapper> getPlugins()
{
return plugins;
private boolean hasStartupErrors() {
return SCMContext.getContext().getStartupError() != null;
}
/**
* Method description
*
*
* @return
*/
@Override
protected Injector getInjector()
{
if (startupError)
{
globalInjector = getErrorInjector();
protected List<? extends Module> getModules(ServletContext context) {
if (hasStartupErrors()) {
return getErrorModules();
}
else
{
globalInjector = getDefaultInjector(servletContext);
}
return globalInjector;
return getDefaultModules(context);
}
private List<? extends Module> getDefaultModules(ServletContext context) {
DefaultPluginLoader pluginLoader = new DefaultPluginLoader(context, parent, plugins);
//~--- methods --------------------------------------------------------------
/**
* Method description
*
*
* @param ep
* @param moduleList
*/
private void appendModules(ExtensionProcessor ep, List<Module> moduleList)
{
for (Class<? extends Module> 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<Module> 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<Module> moduleList) {
for (Class<? extends Module> 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<? extends Module> 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<PluginWrapper> plugins;
/** Field description */
private Injector globalInjector;
/** Field description */
private ServletContext servletContext;
/** Field description */
private boolean startupError = false;
}

View File

@@ -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<String, String> 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);
}
/**

View File

@@ -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<String>
public class TemplateEngineViewable implements MessageBodyWriter<Viewable>
{
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<String, Object> 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<String>
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;
}

View File

@@ -1,116 +0,0 @@
/**
* Copyright (c) 2010, Sebastian Sdorra
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
* 3. Neither the name of SCM-Manager; nor the names of its
* contributors may be used to endorse or promote products derived from this
* software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* http://bitbucket.org/sdorra/scm-manager
*
*/
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;
/**
*
* @author Sebastian Sdorra
*/
public class UriExtensionsConfig extends PackagesResourceConfig
{
/** Field description */
public static final String EXTENSION_JSON = "json";
/** Field description */
public static final String EXTENSION_XML = "xml";
//~--- constructors ---------------------------------------------------------
/**
* Constructs ...
*
*/
public UriExtensionsConfig()
{
super();
}
/**
* Constructs ...
*
*
* @param props
*/
public UriExtensionsConfig(Map<String, Object> props)
{
super(props);
}
/**
* Constructs ...
*
*
* @param paths
*/
public UriExtensionsConfig(String[] paths)
{
super(paths);
}
//~--- get methods ----------------------------------------------------------
/**
* Method description
*
*
* @return
*/
@Override
public Map<String, MediaType> getMediaTypeMappings()
{
if (mediaTypeMap == null)
{
mediaTypeMap = new HashMap<String, MediaType>();
mediaTypeMap.put(EXTENSION_JSON, MediaType.APPLICATION_JSON_TYPE);
mediaTypeMap.put(EXTENSION_XML, MediaType.APPLICATION_XML_TYPE);
}
return mediaTypeMap;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private Map<String, MediaType> mediaTypeMap;
}

View File

@@ -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<Permission> getAll()
{
return getPermissions(getPredicate());

View File

@@ -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
{

View File

@@ -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

View File

@@ -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)
{

View File

@@ -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"),

View File

@@ -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<PluginInformation> 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<PluginInformation> 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<PluginInformation> 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<PluginInformation> getOverview()
{
//J-

View File

@@ -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);

View File

@@ -163,7 +163,7 @@ public class RepositoryResource extends AbstractManagerResource<Repository, Repo
@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, Repository repository)
{
@@ -288,7 +288,7 @@ public class RepositoryResource extends AbstractManagerResource<Repository, Repo
@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 id, Repository repository)
{
@@ -307,7 +307,7 @@ public class RepositoryResource extends AbstractManagerResource<Repository, Repo
*/
@GET
@Path("{id}")
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@StatusCodes({
@ResponseCode(code = 200, condition = "success"),
@ResponseCode(code = 404, condition = "not found, no repository with the specified id available"),
@@ -332,7 +332,7 @@ public class RepositoryResource extends AbstractManagerResource<Repository, Repo
* @return all repositories
*/
@GET
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
@StatusCodes({
@ResponseCode(code = 200, condition = "success"),
@ResponseCode(code = 500, condition = "internal server error")
@@ -369,7 +369,7 @@ public class RepositoryResource extends AbstractManagerResource<Repository, Repo
@ResponseCode(code = 500, condition = "internal server error")
})
@TypeHint(BlameResult.class)
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response getBlame(@PathParam("id") String id,
@QueryParam("revision") String revision, @QueryParam("path") String path)
throws RepositoryException, IOException
@@ -441,7 +441,7 @@ public class RepositoryResource extends AbstractManagerResource<Repository, Repo
@ResponseCode(code = 500, condition = "internal server error")
})
@TypeHint(Branches.class)
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response getBranches(@PathParam("id") String id)
throws RepositoryException, IOException
{
@@ -503,7 +503,7 @@ public class RepositoryResource extends AbstractManagerResource<Repository, Repo
@ResponseCode(code = 500, condition = "internal server error")
})
@TypeHint(BrowserResult.class)
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
//J-
public Response getBrowserResult(
@PathParam("id") String id,
@@ -583,7 +583,7 @@ public class RepositoryResource extends AbstractManagerResource<Repository, Repo
@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 getByTypeAndName(@PathParam("type") String type,
@PathParam("name") String name)
{
@@ -624,7 +624,7 @@ public class RepositoryResource extends AbstractManagerResource<Repository, Repo
@ResponseCode(code = 500, condition = "internal server error")
})
@TypeHint(Changeset.class)
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response getChangeset(@PathParam("id") String id,
@PathParam("revision") String revision)
throws IOException, RepositoryException
@@ -696,7 +696,7 @@ public class RepositoryResource extends AbstractManagerResource<Repository, Repo
@ResponseCode(code = 500, condition = "internal server error")
})
@TypeHint(ChangesetPagingResult.class)
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
//J-
public Response getChangesets(
@PathParam("id") String id,
@@ -936,7 +936,7 @@ public class RepositoryResource extends AbstractManagerResource<Repository, Repo
@ResponseCode(code = 500, condition = "internal server error")
})
@TypeHint(Tags.class)
@Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
@Produces({ MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML })
public Response getTags(@PathParam("id") String id)
throws RepositoryException, IOException
{

View File

@@ -50,8 +50,6 @@ import sonia.scm.util.HttpUtil;
//~--- JDK imports ------------------------------------------------------------
import com.sun.jersey.api.view.Viewable;
import java.io.IOException;
import java.util.Collection;
@@ -67,6 +65,7 @@ import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import sonia.scm.template.Viewable;
/**
*
@@ -76,17 +75,13 @@ import javax.ws.rs.core.MediaType;
public class RepositoryRootResource
{
/** Field description */
public static final String TEMPLATE = "/templates/repository-root.mustache";
//~--- constructors ---------------------------------------------------------
private static final String TEMPLATE = "/templates/repository-root.mustache";
private final RepositoryManager repositoryManager;
/**
* Constructs ...
*
*
*
* @param templateHandler
*
* @param repositoryManager
*/
@Inject
@@ -330,10 +325,4 @@ public class RepositoryRootResource
/** Field description */
private UrlProvider urlProvider;
}
//~--- fields ---------------------------------------------------------------
/** Field description */
private RepositoryManager repositoryManager;
}

View File

@@ -153,7 +153,7 @@ public class SearchResource
@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 SearchResults searchGroups(@QueryParam("query") String queryString)
{
return groupSearchHandler.search(queryString,
@@ -188,7 +188,7 @@ public class SearchResource
@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 SearchResults searchUsers(@QueryParam("query") String queryString)
{
return userSearchHandler.search(queryString,

View File

@@ -55,8 +55,6 @@ import sonia.scm.util.SystemUtil;
//~--- JDK imports ------------------------------------------------------------
import com.sun.jersey.api.view.Viewable;
import java.io.IOException;
import java.util.List;
@@ -71,6 +69,7 @@ import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import sonia.scm.store.ConfigurationStoreFactory;
import sonia.scm.template.Viewable;
/**
*

View File

@@ -124,7 +124,7 @@ public class UserResource extends AbstractManagerResource<User, UserException>
@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<User, UserException>
@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<User, UserException>
@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<User, UserException>
@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")

View File

@@ -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<DebugHookData> 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);
}

View File

@@ -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 --------------------------------------------------------------

View File

@@ -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 ---------------------------------------------------------