001: /*
002: * Copyright (c) 1998-2006 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 Emil Ong
028: */
029:
030: package com.caucho.soa.encoding;
031:
032: import com.caucho.hessian.io.AbstractHessianOutput;
033: import com.caucho.hessian.io.Hessian2Input;
034: import com.caucho.hessian.io.Hessian2Output;
035: import com.caucho.hessian.io.HessianOutput;
036: import com.caucho.hessian.io.SerializerFactory;
037: import com.caucho.hessian.server.HessianSkeleton;
038: import com.caucho.server.util.CauchoSystem;
039: import com.caucho.services.server.GenericService;
040: import com.caucho.util.L10N;
041:
042: import javax.annotation.PostConstruct;
043: import javax.jws.WebService;
044: import java.io.IOException;
045: import java.io.InputStream;
046: import java.io.OutputStream;
047: import java.util.logging.Level;
048: import java.util.logging.Logger;
049:
050: /**
051: * Invokes a service based on a Hessian-encoded request.
052: */
053: public class HessianEncoding implements ServiceEncoding {
054: protected static Logger log = Logger
055: .getLogger(HessianEncoding.class.getName());
056: private static final L10N L = new L10N(HessianEncoding.class);
057:
058: private Object _serviceImpl;
059:
060: private HessianSkeleton _skeleton;
061:
062: private SerializerFactory _serializerFactory;
063:
064: /**
065: * Sets the service class.
066: */
067: public void setService(Object serviceImpl) {
068: _serviceImpl = serviceImpl;
069: }
070:
071: /**
072: * Sets the serializer factory.
073: */
074: public void setSerializerFactory(SerializerFactory factory) {
075: _serializerFactory = factory;
076: }
077:
078: /**
079: * Gets the serializer factory.
080: */
081: public SerializerFactory getSerializerFactory() {
082: if (_serializerFactory == null)
083: _serializerFactory = new SerializerFactory();
084:
085: return _serializerFactory;
086: }
087:
088: /**
089: * Sets the serializer send collection java type.
090: */
091: public void setSendCollectionType(boolean sendType) {
092: getSerializerFactory().setSendCollectionType(sendType);
093: }
094:
095: @PostConstruct
096: public void init() throws Exception {
097: if (_serviceImpl == null)
098: _serviceImpl = this ;
099:
100: Class api = null;
101:
102: if (_serviceImpl != null) {
103: api = findWebServiceEndpointInterface(_serviceImpl
104: .getClass());
105:
106: if (api == null)
107: api = findRemoteAPI(_serviceImpl.getClass());
108:
109: if (api == null)
110: api = _serviceImpl.getClass();
111: }
112:
113: _skeleton = new HessianSkeleton(_serviceImpl, api);
114: }
115:
116: private Class findWebServiceEndpointInterface(Class implClass)
117: throws ClassNotFoundException {
118: if (implClass.isAnnotationPresent(javax.jws.WebService.class)) {
119: WebService webServiceAnnotation = (WebService) implClass
120: .getAnnotation(javax.jws.WebService.class);
121:
122: String endpoint = webServiceAnnotation.endpointInterface();
123: if (endpoint != null && !"".equals(endpoint))
124: return CauchoSystem.loadClass(endpoint);
125: }
126:
127: return null;
128: }
129:
130: private Class findRemoteAPI(Class implClass) {
131: if (implClass == null || implClass.equals(GenericService.class))
132: return null;
133:
134: Class[] interfaces = implClass.getInterfaces();
135:
136: if (interfaces.length == 1)
137: return interfaces[0];
138:
139: return findRemoteAPI(implClass.getSuperclass());
140: }
141:
142: public void invoke(InputStream is, OutputStream os) {
143: try {
144: Hessian2Input in = new Hessian2Input(is);
145: AbstractHessianOutput out;
146:
147: SerializerFactory serializerFactory = getSerializerFactory();
148:
149: in.setSerializerFactory(serializerFactory);
150:
151: int code = in.read();
152:
153: if (code != 'c') {
154: // XXX: deflate
155: throw new IOException(L.l(
156: "expected 'c' in hessian input at {0}", code));
157: }
158:
159: int major = in.read();
160: int minor = in.read();
161:
162: if (major >= 2)
163: out = new Hessian2Output(os);
164: else
165: out = new HessianOutput(os);
166:
167: out.setSerializerFactory(serializerFactory);
168:
169: if (_skeleton == null)
170: throw new Exception("skeleton is null!");
171:
172: _skeleton.invoke(in, out);
173:
174: out.close();
175: } catch (IOException e) {
176: log.log(Level.INFO, L.l("Unable to process request: "), e);
177: } catch (Throwable e) {
178: log.log(Level.INFO, L.l("Unable to process request: "), e);
179: }
180: }
181: }
|