001: /*
002: * Licensed to the Apache Software Foundation (ASF) under one
003: * or more contributor license agreements. See the NOTICE file
004: * distributed with this work for additional information
005: * regarding copyright ownership. The ASF licenses this file
006: * to you under the Apache License, Version 2.0 (the
007: * "License"); you may not use this file except in compliance
008: * with the License. You may obtain a copy of the License at
009: *
010: * http://www.apache.org/licenses/LICENSE-2.0
011: *
012: * Unless required by applicable law or agreed to in writing,
013: * software distributed under the License is distributed on an
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015: * KIND, either express or implied. See the License for the
016: * specific language governing permissions and limitations
017: * under the License.
018: */
019:
020: package org.apache.axis2.transport.http.server;
021:
022: import edu.emory.mathcs.backport.java.util.concurrent.Executor;
023: import org.apache.axis2.context.ConfigurationContext;
024: import org.apache.commons.logging.Log;
025: import org.apache.commons.logging.LogFactory;
026: import org.apache.http.ConnectionReuseStrategy;
027: import org.apache.http.HttpResponseFactory;
028: import org.apache.http.impl.DefaultConnectionReuseStrategy;
029: import org.apache.http.impl.DefaultHttpResponseFactory;
030: import org.apache.http.params.HttpParams;
031: import org.apache.http.protocol.BasicHttpProcessor;
032: import org.apache.http.protocol.HttpProcessor;
033: import org.apache.http.protocol.ResponseConnControl;
034: import org.apache.http.protocol.ResponseContent;
035: import org.apache.http.protocol.ResponseDate;
036: import org.apache.http.protocol.ResponseServer;
037:
038: import java.util.Iterator;
039: import java.util.LinkedList;
040: import java.util.List;
041:
042: public class DefaultHttpConnectionManager implements
043: HttpConnectionManager {
044:
045: private static Log LOG = LogFactory
046: .getLog(DefaultHttpConnectionManager.class);
047:
048: private final ConfigurationContext configurationContext;
049:
050: /** The thread pool used to execute processors. */
051: private final Executor executor;
052:
053: private final WorkerFactory workerfactory;
054:
055: private final HttpParams params;
056:
057: /** The list of processors. */
058: // XXX: is this list really needed?
059: private final List processors;
060:
061: private HttpFactory httpFactory = null;
062:
063: public DefaultHttpConnectionManager(
064: final ConfigurationContext configurationContext,
065: final Executor executor, final WorkerFactory workerfactory,
066: final HttpParams params) {
067: super ();
068: if (configurationContext == null) {
069: throw new IllegalArgumentException(
070: "Configuration context may not be null");
071: }
072: if (executor == null) {
073: throw new IllegalArgumentException(
074: "Executor may not be null");
075: }
076: if (workerfactory == null) {
077: throw new IllegalArgumentException(
078: "Worker factory may not be null");
079: }
080: if (params == null) {
081: throw new IllegalArgumentException(
082: "HTTP parameters may not be null");
083: }
084: this .configurationContext = configurationContext;
085: this .executor = executor;
086: this .workerfactory = workerfactory;
087: this .params = params;
088: this .processors = new LinkedList();
089: }
090:
091: public DefaultHttpConnectionManager(
092: final ConfigurationContext configurationContext,
093: final Executor executor, final WorkerFactory workerfactory,
094: final HttpParams params, final HttpFactory httpFactory) {
095: this (configurationContext, executor, workerfactory, params);
096: this .httpFactory = httpFactory;
097: }
098:
099: /**
100: * Removes the destroyed processors.
101: *
102: * @see IOProcessor#destroy()
103: */
104: //XXX: is this method really needed? Processors are removed as soon as they complete
105: private synchronized void cleanup() {
106: for (Iterator i = this .processors.iterator(); i.hasNext();) {
107: IOProcessor processor = (IOProcessor) i.next();
108: if (processor.isDestroyed()) {
109: i.remove();
110: }
111: }
112: }
113:
114: /**
115: * Adds the specified {@linkplain IOProcessor} to the list of processors in
116: * progress.
117: *
118: * @param processor The processor to add.
119: * @throws NullPointerException If processor is <code>null</code>.
120: */
121: private synchronized void addProcessor(final IOProcessor processor) {
122: if (processor == null) {
123: throw new NullPointerException(
124: "The processor can't be null");
125: }
126: this .processors.add(processor);
127: }
128:
129: /**
130: * Removes the specified {@linkplain IOProcessor} from the list of
131: * processors.
132: *
133: * @param processor The processor to remove.
134: * @throws NullPointerException If processor is <code>null</code>.
135: */
136: synchronized void removeProcessor(final IOProcessor processor)
137: throws NullPointerException {
138: if (processor == null) {
139: throw new NullPointerException(
140: "The processor can't be null");
141: }
142: this .processors.remove(processor);
143: }
144:
145: public void process(final AxisHttpConnection conn) {
146: if (conn == null) {
147: throw new IllegalArgumentException(
148: "HTTP connection may not be null");
149: }
150: // Evict destroyed processors
151: cleanup();
152:
153: // Assemble new Axis HTTP service
154: HttpProcessor httpProcessor;
155: ConnectionReuseStrategy connStrategy;
156: HttpResponseFactory responseFactory;
157:
158: if (httpFactory != null) {
159: httpProcessor = httpFactory.newHttpProcessor();
160: connStrategy = httpFactory.newConnStrategy();
161: responseFactory = httpFactory.newResponseFactory();
162: } else {
163: BasicHttpProcessor p = new BasicHttpProcessor();
164: p.addInterceptor(new RequestSessionCookie());
165: p.addInterceptor(new ResponseDate());
166: p.addInterceptor(new ResponseServer());
167: p.addInterceptor(new ResponseContent());
168: p.addInterceptor(new ResponseConnControl());
169: p.addInterceptor(new ResponseSessionCookie());
170: httpProcessor = p;
171: connStrategy = new DefaultConnectionReuseStrategy();
172: responseFactory = new DefaultHttpResponseFactory();
173: }
174:
175: AxisHttpService httpService = new AxisHttpService(
176: httpProcessor, connStrategy, responseFactory,
177: this .configurationContext, this .workerfactory
178: .newWorker());
179: httpService.setParams(this .params);
180:
181: // Create I/O processor to execute HTTP service
182: IOProcessorCallback callback = new IOProcessorCallback() {
183:
184: public void completed(final IOProcessor processor) {
185: removeProcessor(processor);
186: if (LOG.isDebugEnabled()) {
187: LOG.debug(processor + " terminated");
188: }
189: }
190:
191: };
192: IOProcessor processor = new HttpServiceProcessor(httpService,
193: conn, callback);
194:
195: addProcessor(processor);
196: this .executor.execute(processor);
197: }
198:
199: public synchronized void shutdown() {
200: for (int i = 0; i < this .processors.size(); i++) {
201: IOProcessor processor = (IOProcessor) this.processors
202: .get(i);
203: processor.destroy();
204: }
205: this.processors.clear();
206: }
207:
208: }
|