/*
* Copyright (C) 2013 Intel Corporation
* All rights reserved.
*/
package com.intel.mtwilson.jersey2;
import com.intel.mtwilson.jaxrs2.feature.JacksonFeature;
import com.intel.dcsg.cpg.extensions.Registrar;
import com.intel.mtwilson.launcher.ExtensionCacheLauncher;
import org.glassfish.jersey.server.ResourceConfig;
import java.util.Set;
/**
* See also:
* https://jersey.java.net/apidocs/2.5/jersey/org/glassfish/jersey/server/ResourceConfig.html (especially about what can be configured from our constructor here like providers and setting the class loader)
*
* https://jersey.java.net/apidocs/latest/jersey/
*
* https://jersey.java.net/documentation/latest/index.html
* https://jersey.java.net/documentation/latest/modules-and-dependencies.html
* https://jersey.java.net/documentation/latest/deployment.html
* https://jersey.java.net/documentation/latest/message-body-workers.html
* https://jersey.java.net/documentation/latest/resource-builder.html
* https://jersey.java.net/documentation/latest/uris-and-links.html
* https://jersey.java.net/documentation/latest/ioc.html
* https://jersey.java.net/documentation/latest/appendix-properties.html#appendix-properties-common
* https://jersey.java.net/documentation/latest/appendix-properties.html#appendix-properties-server
*
*
* https://jersey.java.net/apidocs/1.8/jersey/com/sun/jersey/spi/service/ServiceFinder.html (similar to Java's SPI and our Extensions... cpg-extensions separates classpath scanning from the class registry itself which is nice )
* https://jersey.java.net/apidocs/1.11/jersey/com/sun/jersey/core/spi/scanning/PackageNamesScanner.html
*
* http://grepcode.com/file/repo1.maven.org/maven2/org.glassfish.jersey.containers/jersey-container-servlet-core/2.1/org/glassfish/jersey/servlet/WebAppResourcesScanner.java?av=f
*
* http://grepcode.com/file/repo1.maven.org/maven2/org.glassfish.jersey.core/jersey-server/2.1/org/glassfish/jersey/server/internal/scanning/JarFileScanner.java#JarFileScanner
*
*
* @author jbuhacoff
*/
//@ApplicationPath("/v2")
public abstract class AbstractJerseyPluginApplication extends ResourceConfig {
private static final org.slf4j.Logger log = org.slf4j.LoggerFactory.getLogger(AbstractJerseyPluginApplication.class);
// protected abstract File[] getJars();
protected abstract Registrar[] getRegistrars();
public AbstractJerseyPluginApplication() {
// ExtensionDirectoryLauncher launcher = new ExtensionDirectoryLauncher();
ExtensionCacheLauncher launcher = new ExtensionCacheLauncher();
launcher.setRegistrars(getRegistrars());
launcher.run(); // loads application jars, scans extension jars for the plugins as specified by getRegistrars()
// Util.scanJars(Util.findAllJars(),getRegistrars());
register(JacksonFeature.class);
log.debug("Registering YAML, XML, JSON providers");
// THESE WERE ENABLED:
//register(com.fasterxml.jackson.jaxrs.base.JsonMappingExceptionMapper.class);
//register(com.fasterxml.jackson.jaxrs.base.JsonParseExceptionMapper.class);
//register(com.fasterxml.jackson.jaxrs.json.JacksonJsonProvider.class);
//register(com.fasterxml.jackson.jaxrs.json.JsonParseExceptionMapper.class);
/* // THESE WERE ENABLED:
register(com.fasterxml.jackson.jaxrs.json.JacksonJaxbJsonProvider.class);
register(com.fasterxml.jackson.jaxrs.xml.JacksonJaxbXMLProvider.class);
register(com.fasterxml.jackson.jaxrs.xml.JacksonXMLProvider.class);
*/
//register(com.fasterxml.jackson.jaxrs.json.JsonMappingExceptionMapper.class);
//register(com.fasterxml.jackson.jaxrs.xml.JsonParseExceptionMapper.class);
//register(com.fasterxml.jackson.jaxrs.xml.JsonMappingExceptionMapper.class);
// we can register javax.ws.rs filters here that implement
// javax.ws.rs.container.ContainerRequestFilter or
// javax.ws.rs.container.ContainerResponseFilter,
// but registering servlet filters will not work;
// that is why the LocalizableResponseFilter (implements
// ContainerResponseFilter) can be registered here but
// the ShiroFilter must be declared in web.xml instead.
log.debug("Registering exception mappers and filters");
//register(com.intel.mtwilson.util.LocalizedExceptionMapper.class);
register(org.glassfish.jersey.server.filter.HttpMethodOverrideFilter.class); // jersey2 equivalent of com.sun.jersey.api.container.filter.PostReplaceFilter
//register(org.glassfish.jersey.client.filter.HttpDigestAuthFilter.class);
//register(com.intel.mtwilson.as.helper.ASAuthenticationFilter.class);
//register(org.apache.shiro.web.servlet.ShiroFilter.class); // must be in web.xml because it's a servlet filter, not a javax.ws.rs filter
//register(com.intel.mtwilson.audit.helper.AuditJerseyRequestFilter.class);
//register(com.intel.mtwilson.audit.helper.AuditJerseyResponseFilter.class);
register(com.intel.mtwilson.shiro.AuthorizationExceptionMapper.class);
//register(com.intel.mtwilson.util.ASLocalizationFilter.class);
register(com.intel.mtwilson.jaxrs2.server.filter.ErrorLogFilter.class);
log.debug("Registering other resources");
register(org.glassfish.jersey.server.wadl.internal.WadlResource.class);
// packages("com.intel.mtwilson.as.rest.v2.resource");
// packages("com.intel.mtwilson.authz.shiro");
// log.debug("listing all jersey provider classes");
// List<Object> providers = Extensions.findAll(Provider.class.getName()); // this is the @Provider annotation so something must scan the classpath for these
// for(Object provider : providers) {
// register(provider); // or register(provider.getClass());
// }
log.debug("resourceconfig classloader is: {}", getClassLoader().getClass().getName()); // sun.misc.Launcher$AppClassLoader explains why the extensions can't be cast... this is the system classloader and the extensions are loaded by one of the strategies in cpg-classpath. or you might see org.eclipse.jetty.webapp.WebAppClassLoader when using the WebAppContext handler
if( getClassLoader().getParent() != null ) {
log.debug("and the parent classloader is: {}", getClassLoader().getParent().getClass().getName()); // sun.misc.Launcher$ExtClassLoader // or you would see sun.misc.Launcher$AppClassLoader if the current classloader is the WebAppClassLoader
}
/*
List<HttpResource> rs = Extensions.findAll(HttpResource.class);
log.debug("Found {} HttpResource implmentations", rs.size());
for(HttpResource r : rs) {
log.debug("Adding resource: {}", r.getClass().getName());
registerClasses(r.getClass());
// registerResources(r);
}
*/
}
// workaround for netbeans 7.3.1 bug (fixed in netbeans 7.4) https://netbeans.org/bugzilla/show_bug.cgi?id=234581
// with this workaround netbeans will continue to auto-generate addRestResourceClasses but it's harmless
// because it will never be called
public void getClasses(int unused) {}
/**
* Do not modify addRestResourceClasses() method.
* It is automatically re-generated by NetBeans REST support to populate
* given list with all resources defined in the project.
*/
/***** UNUSED
private void addRestResourceClasses(Set<Class<?>> resources) {
// resources.add(com.intel.mtwilson.as.rest.v2.resource.Files.class);
// resources.add(com.intel.mtwilson.as.rest.v2.resource.Hosts.class);
// resources.add(com.intel.mtwilson.as.rest.v2.resource.Users.class);
// resources.add(com.intel.mtwilson.jersey.provider.ApplicationYamlProvider.class);
// resources.add(com.intel.mtwilson.jersey.provider.JacksonObjectMapperProvider.class);
// resources.add(com.intel.mtwilson.jersey.provider.JacksonXmlMapperProvider.class);
// resources.add(com.intel.mtwilson.jersey.provider.JacksonYamlObjectMapperProvider.class);
// resources.add(com.intel.mtwilson.jersey.resource.AbstractResource.class);
// resources.add(com.intel.mtwilson.util.LocalizedExceptionMapper.class);
}*/
}