/* * Copyright (c) 2008, Rickard Öberg. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * */ package org.qi4j.library.http; import java.io.File; import java.net.InetAddress; import java.net.URL; import java.net.UnknownHostException; import java.security.CodeSource; import java.security.ProtectionDomain; import javax.servlet.Filter; import javax.servlet.Servlet; import org.mortbay.jetty.Connector; import org.mortbay.jetty.Server; import org.mortbay.jetty.servlet.Context; import org.mortbay.jetty.servlet.DefaultServlet; import org.mortbay.jetty.servlet.FilterHolder; import org.mortbay.jetty.servlet.ServletHolder; import org.qi4j.api.configuration.Configuration; import org.qi4j.api.injection.scope.Service; import org.qi4j.api.injection.scope.This; import org.qi4j.api.injection.scope.Uses; import org.qi4j.api.service.Activatable; import org.qi4j.api.service.ServiceReference; import org.qi4j.library.http.Dispatchers.Dispatcher; import org.qi4j.spi.service.ServiceDescriptor; import static org.mortbay.jetty.servlet.Context.SESSIONS; /** * JAVADOC */ public class JettyMixin implements Activatable, HttpService { private static final Integer DEFAULT_PORT = 8080; private Configuration<JettyConfiguration> configuration; @Service private Iterable<ServiceReference<Servlet>> servlets; @Service private Iterable<ServiceReference<Filter>> filters; private Server server; private Context root; public JettyMixin( @Uses ServiceDescriptor descriptor, @This Configuration<JettyConfiguration> configuration ) { this.configuration = configuration; // Create a server given the host port Integer port = configuration.configuration().port().get(); if( port == null ) { port = DEFAULT_PORT; } server = new Server( port ); // Sets the context root root = new Context( server, "/", SESSIONS ); // Sets the default servlet for default context root.addServlet( DefaultServlet.class, "/" ); } private void addServlets( Context root, Iterable<ServiceReference<Servlet>> servlets ) { // Iterate the available servlets and add it to the server for( ServiceReference<Servlet> servlet : servlets ) { ServletInfo servletInfo = servlet.metaInfo( ServletInfo.class ); String servletPath = servletInfo.getPath(); Servlet servletInstance = servlet.get(); ServletHolder holder = new ServletHolder( servletInstance ); holder.setInitParameters( servletInfo.initParams() ); root.addServlet( holder, servletPath ); } } private void addFilters( Context root, Iterable<ServiceReference<Filter>> filters ) { // Iterate the available filters and add it to the server for( ServiceReference<Filter> filter : filters ) { FilterInfo filterInfo = filter.metaInfo( FilterInfo.class ); String filterPath = filterInfo.getPath(); Filter filterInstance = filter.get(); FilterHolder holder = new FilterHolder( filterInstance ); holder.setInitParameters( filterInfo.initParameters() ); root.addFilter( holder, filterPath, toInt( filterInfo.dispatchers() ) ); } } private int toInt( Dispatchers dispatches ) { int value = 0; for( Dispatcher dispatcher : dispatches ) { value |= FilterHolder.dispatch( dispatcher.name().toLowerCase() ); } return value; } private String rootResourceBase( String resourcePath ) { if( resourcePath.length() == 0 ) { ProtectionDomain domain = getClass().getProtectionDomain(); CodeSource source = domain.getCodeSource(); URL location = source.getLocation(); String basePath = location.getPath(); File base = new File( basePath ); return base.getAbsolutePath(); } else { return resourcePath; } } public final void activate() throws Exception { // Sets the resource root.setResourceBase( rootResourceBase( configuration.configuration().resourcePath().get() ) ); addServlets( root, servlets ); addFilters( root, filters ); Connector[] connectors = server.getConnectors(); Connector connector = connectors[ 0 ]; int hostPort = configuration.configuration().port().get(); connector.setPort( hostPort ); server.start(); } public final void passivate() throws Exception { server.stop(); for( Connector connector : server.getConnectors() ) { connector.close(); } } public Interface[] interfacesServed() { Connector[] connectors = server.getConnectors(); Interface[] result = new Interface[connectors.length]; int index = 0; for( Connector connector : connectors ) { String host = this.configuration.configuration().hostName().get(); if( host == null ) { host = connector.getHost(); if( host == null ) // If serving all interfaces. { try { host = InetAddress.getLocalHost().getHostAddress(); } catch( UnknownHostException e ) { InternalError error = new InternalError( "UnknownHost for local interface." ); error.initCause( e ); throw error; } } } result[ index++ ] = new InterfaceImpl( host, connector.getPort(), Interface.Protocol.http ); } return result; } private static class InterfaceImpl implements Interface { private String host; private int port; private Protocol protocol; public InterfaceImpl( String host, int port, Protocol protocol ) { this.host = host; this.port = port; //To change body of created methods use File | Settings | File Templates. this.protocol = protocol; } public String hostName() { return host; } public int port() { return port; } public Protocol protocol() { return protocol; } } }