001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.openejb.server;
017:
018: import java.util.concurrent.Executor;
019: import java.util.concurrent.LinkedBlockingQueue;
020: import java.util.concurrent.ThreadPoolExecutor;
021: import java.util.concurrent.ThreadFactory;
022: import java.util.concurrent.TimeUnit;
023:
024: import org.apache.openejb.util.LogCategory;
025: import org.apache.openejb.util.Logger;
026:
027: import java.io.IOException;
028: import java.io.InputStream;
029: import java.io.OutputStream;
030: import java.net.Socket;
031: import java.util.Properties;
032:
033: public class ServicePool implements ServerService {
034: private static final Logger log = Logger.getInstance(
035: LogCategory.SERVICEPOOL,
036: "org.apache.openejb.util.resources");
037:
038: private final ServerService next;
039: private final Executor executor;
040:
041: public ServicePool(ServerService next, final String name,
042: final int threads, final long keepAliveTime) {
043: this .next = next;
044:
045: ThreadPoolExecutor p = new ThreadPoolExecutor(threads, threads,
046: keepAliveTime, TimeUnit.MILLISECONDS,
047: new LinkedBlockingQueue());
048: p.setThreadFactory(new ThreadFactory() {
049: private volatile int id = 0;
050:
051: public Thread newThread(Runnable arg0) {
052: Thread thread = new Thread(arg0, name + " "
053: + getNextID());
054: return thread;
055: }
056:
057: private int getNextID() {
058: return id++;
059: }
060:
061: });
062: executor = p;
063: }
064:
065: public ServicePool(ServerService next, Executor executor) {
066: this .next = next;
067: this .executor = executor;
068: }
069:
070: public void service(InputStream in, OutputStream out)
071: throws ServiceException, IOException {
072: }
073:
074: public void service(final Socket socket) throws ServiceException,
075: IOException {
076: final Runnable service = new Runnable() {
077: public void run() {
078: try {
079: next.service(socket);
080: } catch (SecurityException e) {
081: log.error("Security error: " + e.getMessage(), e);
082: } catch (Throwable e) {
083: log.error("Unexpected error", e);
084: } finally {
085: try {
086: if (socket != null) {
087: socket.close();
088: }
089: } catch (Throwable t) {
090: log
091: .warning(
092: "Error while closing connection with client",
093: t);
094: }
095: }
096: }
097: };
098:
099: final ClassLoader tccl = Thread.currentThread()
100: .getContextClassLoader();
101: Runnable ctxCL = new Runnable() {
102: public void run() {
103: ClassLoader cl = Thread.currentThread()
104: .getContextClassLoader();
105: Thread.currentThread().setContextClassLoader(tccl);
106: try {
107: service.run();
108: } finally {
109: Thread.currentThread().setContextClassLoader(cl);
110: }
111: }
112: };
113:
114: executor.execute(ctxCL);
115: }
116:
117: /**
118: * Pulls out the access log information
119: *
120: * @param props
121: * @throws ServiceException
122: */
123: public void init(Properties props) throws Exception {
124: // Do our stuff
125:
126: // Then call the next guy
127: next.init(props);
128: }
129:
130: public void start() throws ServiceException {
131: // Do our stuff
132:
133: // Then call the next guy
134: next.start();
135: }
136:
137: public void stop() throws ServiceException {
138: // Do our stuff
139:
140: // Then call the next guy
141: next.stop();
142: }
143:
144: /**
145: * Gets the name of the service.
146: * Used for display purposes only
147: */
148: public String getName() {
149: return next.getName();
150: }
151:
152: /**
153: * Gets the ip number that the
154: * daemon is listening on.
155: */
156: public String getIP() {
157: return next.getIP();
158: }
159:
160: /**
161: * Gets the port number that the
162: * daemon is listening on.
163: */
164: public int getPort() {
165: return next.getPort();
166: }
167:
168: }
|