001: /*
002: * Copyright (c) 1998-2007 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.rest;
031:
032: import com.caucho.jaxb.JAXBUtil;
033: import com.caucho.server.util.CauchoSystem;
034: import com.caucho.soa.servlet.ProtocolServlet;
035: import com.caucho.vfs.Vfs;
036: import com.caucho.vfs.WriteStream;
037: import com.caucho.xml.stream.XMLStreamWriterImpl;
038:
039: import javax.jws.WebMethod;
040: import javax.jws.WebParam;
041: import javax.jws.WebService;
042: import javax.servlet.GenericServlet;
043: import javax.servlet.ServletException;
044: import javax.servlet.ServletRequest;
045: import javax.servlet.ServletResponse;
046: import javax.servlet.http.HttpServletRequest;
047: import javax.servlet.http.HttpServletResponse;
048: import javax.xml.bind.JAXBContext;
049: import javax.xml.bind.JAXBException;
050: import javax.xml.bind.Marshaller;
051: import javax.xml.bind.Unmarshaller;
052: import javax.xml.namespace.QName;
053: import java.io.IOException;
054: import java.io.InputStream;
055: import java.io.OutputStream;
056: import java.lang.annotation.Annotation;
057: import java.lang.reflect.Method;
058: import java.lang.reflect.Modifier;
059: import java.util.ArrayList;
060: import java.util.HashMap;
061: import java.util.Map;
062: import java.util.logging.Logger;
063:
064: /**
065: * A binding for REST services.
066: */
067: public class JAXBRestProtocolServlet extends RestProtocolServlet {
068: private String _jaxbPackages;
069: private ArrayList<Class> _jaxbClasses = new ArrayList<Class>();
070: private Marshaller _marshaller;
071: private Unmarshaller _unmarshaller;
072: private JAXBContext _context = null;
073:
074: public JAXBRestProtocolServlet() {
075: super ();
076: }
077:
078: public void addJaxbPackage(String packageName) {
079: if (_jaxbPackages != null)
080: _jaxbPackages = _jaxbPackages + ";" + packageName;
081: else
082: _jaxbPackages = packageName;
083: }
084:
085: public void addJaxbClass(Class cl) {
086: _jaxbClasses.add(cl);
087: }
088:
089: public void init() throws ServletException {
090: super .init();
091:
092: try {
093: Class cl = _service.getClass();
094:
095: if (cl.isAnnotationPresent(WebService.class)) {
096: WebService webService = (WebService) cl
097: .getAnnotation(WebService.class);
098:
099: String endpoint = webService.endpointInterface();
100:
101: if (endpoint != null && !"".equals(endpoint))
102: cl = CauchoSystem.loadClass(webService
103: .endpointInterface());
104: }
105:
106: ArrayList<Class> jaxbClasses = _jaxbClasses;
107:
108: for (Method method : cl.getMethods()) {
109: if (method.getDeclaringClass().equals(Object.class))
110: continue;
111:
112: int modifiers = method.getModifiers();
113:
114: // Allow abstract for interfaces
115: if (Modifier.isStatic(modifiers)
116: || Modifier.isFinal(modifiers)
117: || !Modifier.isPublic(modifiers))
118: continue;
119:
120: if (_context == null)
121: JAXBUtil.introspectMethod(method, jaxbClasses);
122: }
123:
124: if (_context != null) {
125: } else if (_jaxbPackages != null) {
126: _context = JAXBContext.newInstance(_jaxbPackages);
127: } else {
128: Class[] classes = jaxbClasses
129: .toArray(new Class[jaxbClasses.size()]);
130: _context = JAXBContext.newInstance(classes);
131: }
132:
133: _marshaller = _context.createMarshaller();
134: _marshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,
135: Boolean.TRUE);
136: _unmarshaller = _context.createUnmarshaller();
137: } catch (Exception e) {
138: throw new ServletException(e);
139: }
140: }
141:
142: protected Object readPostData(InputStream in) throws IOException,
143: RestException {
144: try {
145: return _unmarshaller.unmarshal(in);
146: } catch (JAXBException e) {
147: throw new RestException(e);
148: }
149: }
150:
151: protected void writeResponse(OutputStream out, Object result)
152: throws IOException, RestException {
153: WriteStream ws = Vfs.openWrite(out);
154:
155: try {
156: XMLStreamWriterImpl writer = new XMLStreamWriterImpl(ws);
157:
158: _marshaller.marshal(result, writer);
159: } catch (JAXBException e) {
160: throw new RuntimeException(e);
161: } finally {
162: ws.close();
163: }
164: }
165:
166: public String toString() {
167: return getClass().getSimpleName() + "[]";
168: }
169: }
|