package org.odata4j.examples.cxf.producer.server;
import java.net.MalformedURLException;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import javax.ws.rs.core.Application;
import javax.ws.rs.ext.RuntimeDelegate;
import org.apache.cxf.jaxrs.servlet.CXFNonSpringJaxrsServlet;
import org.core4j.Enumerable;
import org.eclipse.jetty.security.SecurityHandler;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.HandlerCollection;
import org.eclipse.jetty.servlet.ServletContextHandler;
import org.eclipse.jetty.servlet.ServletHolder;
import org.odata4j.core.Throwables;
import org.odata4j.producer.server.ODataServer;
/**
* OData server using the CXF JAX-RS implementation and Jetty as HTTP server.
*/
public class ODataCxfServer implements ODataServer {
private String appBaseUri;
private Class<? extends Application> odataApp;
private Class<? extends Application> rootApp;
private final List<Handler> jettyRequestHandlers = new ArrayList<Handler>();
private SecurityHandler jettySecurityHandler;
private Server server;
public ODataCxfServer(String appBaseUri) {
this.appBaseUri = appBaseUri;
// ensure that the correct JAX-RS implementation (CXF) is loaded
if (!(RuntimeDelegate.getInstance() instanceof org.apache.cxf.jaxrs.impl.RuntimeDelegateImpl))
RuntimeDelegate.setInstance(new org.apache.cxf.jaxrs.impl.RuntimeDelegateImpl());
}
public ODataCxfServer(String appBaseUri, Class<? extends Application> odataApp, Class<? extends Application> rootApp) {
this(appBaseUri);
this.odataApp = odataApp;
this.rootApp = rootApp;
}
@Override
public ODataServer setODataApplication(Class<? extends Application> odataApp) {
this.odataApp = odataApp;
return this;
}
@Override
public ODataServer setRootApplication(Class<? extends Application> rootApp) {
this.rootApp = rootApp;
return this;
}
public ODataCxfServer addJettyRequestHandler(Handler handler) {
jettyRequestHandlers.add(handler);
return this;
}
public ODataCxfServer setJettySecurityHandler(SecurityHandler securityHandler) {
jettySecurityHandler = securityHandler;
return this;
}
@Override
public ODataServer start() {
if (odataApp == null)
throw new RuntimeException("ODataApplication not set");
URL url;
try {
url = new URL(appBaseUri);
} catch (MalformedURLException e) {
throw Throwables.propagate(e);
}
CXFNonSpringJaxrsServlet odataServlet = new CXFNonSpringJaxrsServlet();
ServletHolder odataServletHolder = new ServletHolder(odataServlet);
odataServletHolder.setInitParameter("javax.ws.rs.Application", odataApp.getCanonicalName());
ServletContextHandler contextHandler = new ServletContextHandler(ServletContextHandler.SESSIONS);
contextHandler.addServlet(odataServletHolder, normalizePath(url.getPath()) + "/*");
if (rootApp != null) {
CXFNonSpringJaxrsServlet rootServlet = new CXFNonSpringJaxrsServlet();
ServletHolder rootServletHolder = new ServletHolder(rootServlet);
rootServletHolder.setInitParameter("javax.ws.rs.Application", rootApp.getCanonicalName());
contextHandler.addServlet(rootServletHolder, "/*");
}
if (jettySecurityHandler != null)
contextHandler.setSecurityHandler(jettySecurityHandler);
server = new Server(url.getPort());
server.setHandler(getHandlerCollection(contextHandler));
try {
server.start();
return this;
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
@Override
public ODataServer stop() {
try {
server.stop();
return this;
} catch (Exception e) {
throw Throwables.propagate(e);
}
}
private static String normalizePath(String path) {
if (path.endsWith("/"))
return path.substring(0, path.length() - 1);
return path;
}
private HandlerCollection getHandlerCollection(ServletContextHandler contextHandler) {
List<Handler> handlers = jettyRequestHandlers;
handlers.add(contextHandler);
HandlerCollection handlerCollection = new HandlerCollection();
handlerCollection.setHandlers(Enumerable.create(handlers).toArray(Handler.class));
return handlerCollection;
}
}