001: /*
002: * Copyright (c) 1998-2008 Caucho Technology -- all rights reserved
003: *
004: * This file is part of Resin(R) Open Source
005: *
006: * Each copy or derived work must preserve the copyright notice and this
007: * notice unmodified.
008: *
009: * Resin Open Source is free software; you can redistribute it and/or modify
010: * it under the terms of the GNU General Public License as published by
011: * the Free Software Foundation; either version 2 of the License, or
012: * (at your option) any later version.
013: *
014: * Resin Open Source is distributed in the hope that it will be useful,
015: * but WITHOUT ANY WARRANTY; without even the implied warranty of
016: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE, or any warranty
017: * of NON-INFRINGEMENT. See the GNU General Public License for more
018: * details.
019: *
020: * You should have received a copy of the GNU General Public License
021: * along with Resin Open Source; if not, write to the
022: *
023: * Free Software Foundation, Inc.
024: * 59 Temple Place, Suite 330
025: * Boston, MA 02111-1307 USA
026: *
027: * @author Scott Ferguson
028: */
029:
030: package com.caucho.iiop;
031:
032: import com.caucho.server.connection.Connection;
033: import com.caucho.server.port.ServerRequest;
034: import com.caucho.transaction.*;
035: import com.caucho.vfs.ReadStream;
036: import com.caucho.vfs.WriteStream;
037: import com.caucho.jca.*;
038: import com.caucho.iiop.orb.*;
039:
040: import java.io.IOException;
041: import java.net.InetAddress;
042: import java.lang.reflect.Method;
043: import java.util.ArrayList;
044: import java.util.logging.Level;
045: import java.util.logging.Logger;
046: import javax.naming.*;
047: import javax.transaction.*;
048: import javax.rmi.CORBA.ValueHandler;
049:
050: /**
051: * Protocol specific information for each request. ServerRequest
052: * is reused to reduce memory allocations.
053: *
054: * <p>ServerRequests are created by Server.createRequest()
055: */
056: public class IiopRequest implements ServerRequest {
057: private static final Logger log = Logger
058: .getLogger(IiopRequest.class.getName());
059:
060: Connection _conn;
061: IiopProtocol _server;
062: ORBImpl _orb;
063: IiopReader _reader;
064:
065: ClassLoader _loader;
066:
067: StreamMessageWriter _messageWriter;
068: IiopWriter _writer10;
069: IiopWriter _writer11;
070: IiopWriter _writer12;
071:
072: ReadStream _readStream;
073: WriteStream _writeStream;
074:
075: CosServer _cos;
076: IiopSkeleton _cosSkel;
077:
078: String _hostName;
079: int _port;
080:
081: private UserTransactionProxy _utm;
082:
083: TransactionManagerImpl _tm;
084: UserTransaction _ut;
085:
086: IiopRequest(IiopProtocol server, Connection conn) {
087: _server = server;
088: _conn = conn;
089:
090: InetAddress local = _conn.getLocalAddress();
091:
092: _reader = new IiopReader();
093:
094: _messageWriter = new StreamMessageWriter();
095:
096: _writer10 = new Iiop10Writer();
097: _writer10.init(_messageWriter);
098: _writer11 = new Iiop11Writer();
099: _writer11.init(_messageWriter);
100: _writer12 = new Iiop12Writer();
101: _writer12.init(_messageWriter);
102:
103: _cos = _server.getCos();
104: _utm = UserTransactionProxy.getInstance();
105:
106: _loader = Thread.currentThread().getContextClassLoader();
107: }
108:
109: /**
110: * Initialize the connection. At this point, the current thread is the
111: * connection thread.
112: */
113: public void init() {
114: }
115:
116: public boolean isWaitForRead() {
117: return true;
118: }
119:
120: /**
121: * Handles a new connection. The controlling TcpServer may call
122: * handleConnection again after the connection completes, so
123: * the implementation must initialize any variables for each connection.
124: *
125: * @param conn Information about the connection, including buffered
126: * read and write streams.
127: */
128: public boolean handleRequest() throws IOException {
129: Thread thread = Thread.currentThread();
130: ClassLoader oldLoader = thread.getContextClassLoader();
131:
132: try {
133: thread.setContextClassLoader(_loader);
134:
135: log.finer("IIOP[" + _conn.getId() + "]: handle request");
136:
137: _readStream = _conn.getReadStream();
138: _writeStream = _conn.getWriteStream();
139:
140: if (_orb == null) {
141: InetAddress local = _conn.getLocalAddress();
142: _orb = _server.getOrb(local.getHostName(), _conn
143: .getLocalPort());
144:
145: _reader.setOrb(_orb);
146: _writer10.setOrb(_orb);
147: _writer11.setOrb(_orb);
148: _writer12.setOrb(_orb);
149: }
150:
151: if (_cosSkel != null) {
152: } else {
153: InetAddress local = _conn.getLocalAddress();
154: _hostName = local.getHostName();
155: _port = _conn.getLocalPort();
156:
157: _cos.setHost(_hostName);
158: _cos.setPort(_port);
159:
160: ArrayList<Class> apiList = new ArrayList<Class>();
161: apiList.add(_cos.getClass());
162:
163: _cosSkel = new IiopSkeleton(_cos, apiList, _loader,
164: _hostName, _port, "/NameService");
165: }
166:
167: _reader.init(_readStream);
168:
169: _messageWriter.init(_writeStream);
170: IiopWriter writer = _writer10;
171:
172: if (!_reader.readRequest())
173: return false;
174:
175: switch (_reader.getMinorVersion()) {
176: case 0:
177: writer = _writer10;
178: break;
179: case 1:
180: writer = _writer11;
181: break;
182: case 2:
183: writer = _writer12;
184: break;
185: default:
186: writer = _writer10;
187: break;
188: }
189:
190: writer.init();
191: writer.setHost(_hostName);
192: writer.setPort(_port);
193:
194: String oid = _reader.getObjectKey().toString();
195:
196: if (log.isLoggable(Level.FINER))
197: log.finer("IIOP[" + _conn.getId() + "] OID: " + oid);
198:
199: XidImpl xid = _reader.getXid();
200:
201: try {
202: if (xid != null)
203: beginTransaction(xid);
204:
205: if (oid.equals("INIT")) {
206: String str = _reader.readString();
207:
208: writer.startReplyOk(_reader.getRequestId());
209:
210: if (str.equals("NameService")) {
211: String nameService = "IDL:omg.org/CosNaming/NamingContext:1.0";
212:
213: IOR ior = new IOR(nameService, _hostName,
214: _port, "/NameService");
215: byte[] bytes = ior.getByteArray();
216: writer.write(bytes, 0, bytes.length);
217: } else
218: writer.writeNullIOR();
219: } else if (oid.equals("/NameService")) {
220: /*
221: cos.service(reader, writer);
222: */
223: _cosSkel.service(_cosSkel.getObject(), _reader,
224: writer);
225: } else {
226: IiopSkeleton skel = _server.getService(_hostName,
227: _port, oid);
228:
229: if (skel != null) {
230: skel.service(skel.getObject(), _reader, writer);
231: } else {
232: log
233: .fine(dbgId() + "can't find service: "
234: + oid);
235:
236: throw new IOException("bad oid: " + oid);
237: }
238:
239: log.fine(dbgId() + "complete request");
240: }
241: } catch (org.omg.CORBA.SystemException e) {
242: log.log(Level.WARNING, e.toString(), e);
243:
244: writer.startReplySystemException(
245: _reader.getRequestId(), e.toString(), e.minor,
246: e.completed.value(), null);
247: } catch (org.omg.CORBA.UserException e) {
248: log.log(Level.WARNING, e.toString(), e);
249:
250: writer.startReplyUserException(_reader.getRequestId());
251:
252: try {
253: Class helperClass = Class.forName(e.getClass()
254: .getName()
255: + "Helper", false, e.getClass()
256: .getClassLoader());
257:
258: Method writeMethod = helperClass
259: .getMethod(
260: "write",
261: new Class[] {
262: org.omg.CORBA.portable.OutputStream.class,
263: e.getClass() });
264:
265: writeMethod.invoke(null, writer, e);
266: } catch (Exception e1) {
267: throw new RuntimeException(e1);
268: }
269: } catch (java.rmi.RemoteException e) {
270: log.log(Level.WARNING, e.toString(), e);
271:
272: String msg = e.toString();
273:
274: writer.startReplySystemException(
275: _reader.getRequestId(), e.toString(), 0, 0, e);
276: } catch (Throwable e) {
277: log.log(Level.WARNING, e.toString(), e);
278:
279: // ejb/1110 vs ejb/114p
280: //writer.startReplyUserException(_reader.getRequestId(), e.toString());
281: // ejb/1110
282:
283: writer.startReplyUserException(_reader.getRequestId());
284: String repId = _reader.getValueHandler()
285: .getRMIRepositoryID(e.getClass());
286:
287: /*
288: String exName = e.getClass().getName().replace('.', '/');
289: if (exName.length() > 20)
290: exName = exName.substring(0, 20);
291: writer.write_string("IDL:" + exName + ":1.0");
292:
293: //writer.write_string("RMI:" + exName + ":0");
294: */
295:
296: // The repId is written in IiopWriter.write_value()
297: // ejb/0fb9 writer.write_string(repId);
298: writer.write_value(e);
299: } finally {
300: if (xid != null)
301: endTransaction(xid);
302: }
303:
304: _messageWriter.close();
305:
306: _reader.completeRead();
307: /*
308: _messageWriter.start10Message(IiopReader.MSG_CLOSE_CONNECTION);
309: _messageWriter.close();
310: */
311:
312: return true;
313:
314: /*
315: if (log.isLoggable(Level.FINER))
316: log.finer(dbgId() + ": recycle");
317:
318: return true;
319: */
320: } catch (Throwable e) {
321: log.log(Level.WARNING, dbgId() + e.toString(), e);
322: return false;
323: } finally {
324: thread.setContextClassLoader(oldLoader);
325:
326: try {
327: _utm.abortTransaction();
328: } catch (Throwable e) {
329: log.log(Level.WARNING, e.toString(), e);
330: }
331: }
332: }
333:
334: String dbgId() {
335: return "Iiop[" + _conn.getId() + "] ";
336: }
337:
338: /**
339: * Handles a new connection. The controlling TcpServer may call
340: * handleConnection again after the connection completes, so
341: * the implementation must initialize any variables for each connection.
342: *
343: * @param conn Information about the connection, including buffered
344: * read and write streams.
345: */
346: public boolean handleResume() throws IOException {
347: return false;
348: }
349:
350: private void beginTransaction(XidImpl xid) throws Exception {
351: getUserTransaction().begin();
352: }
353:
354: private void endTransaction(XidImpl xid) {
355: try {
356: getUserTransaction().commit();
357: } catch (Exception e) {
358: log.log(Level.FINE, e.toString(), e);
359: }
360: }
361:
362: public void protocolCloseEvent() {
363: }
364:
365: private UserTransaction getUserTransaction() {
366: if (_ut == null) {
367: try {
368: _ut = (UserTransaction) new InitialContext()
369: .lookup("java:comp/UserTransaction");
370: } catch (Exception e) {
371: log.log(Level.FINER, e.toString());
372: }
373: }
374:
375: return _ut;
376: }
377: }
|