Index: java/trunk/build.xml =================================================================== --- java/trunk/build.xml (revision 409986) +++ java/trunk/build.xml (working copy) @@ -379,6 +379,7 @@ + @@ -386,7 +387,7 @@ - + Index: java/trunk/contrib/gdata-server/webroot/WEB-INF/web.xml =================================================================== --- java/trunk/contrib/gdata-server/webroot/WEB-INF/web.xml (revision 0) +++ java/trunk/contrib/gdata-server/webroot/WEB-INF/web.xml (revision 0) @@ -0,0 +1,19 @@ + + + + + Lucene GData Server + + GDATAControllerServlet + + org.apache.lucene.gdata.servlet.RequestControllerServlet + + + + GDATAControllerServlet + /feed/* + + Index: java/trunk/contrib/gdata-server/lib/easymock.jar =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: java/trunk/contrib/gdata-server/lib/easymock.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Index: java/trunk/contrib/gdata-server/lib/servlet-api.jar =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: java/trunk/contrib/gdata-server/lib/servlet-api.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Index: java/trunk/contrib/gdata-server/lib/commons-logging-1.1.jar =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: java/trunk/contrib/gdata-server/lib/commons-logging-1.1.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Index: java/trunk/contrib/gdata-server/lib/log4j-1.2.13.jar =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: java/trunk/contrib/gdata-server/lib/log4j-1.2.13.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Index: java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/servlet/TestAbstractGdataServlet.java =================================================================== --- java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/servlet/TestAbstractGdataServlet.java (revision 0) +++ java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/servlet/TestAbstractGdataServlet.java (revision 0) @@ -0,0 +1,282 @@ +package org.apache.lucene.gdata.servlet; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.easymock.MockControl; + +import junit.framework.TestCase; + +/** + * @author Simon Willnauer + * + */ +public class TestAbstractGdataServlet extends TestCase { + private static final String METHOD_DELETE = "DELETE"; + + private static final String METHOD_GET = "GET"; + + private static final String METHOD_POST = "POST"; + + private static final String METHOD_PUT = "PUT"; + + private static final String METHOD_HEADER_NAME = "x-http-method-override"; + + private HttpServletRequest mockRequest = null; + + private HttpServletResponse mockResponse = null; + + private AbstractGdataServlet servletInstance = null; + + private MockControl requestMockControl; + + private MockControl responseMockControl; + + protected void setUp() throws Exception { + this.requestMockControl = MockControl + .createControl(HttpServletRequest.class); + this.responseMockControl = MockControl + .createControl(HttpServletResponse.class); + this.mockRequest = (HttpServletRequest) this.requestMockControl + .getMock(); + this.mockResponse = (HttpServletResponse) this.responseMockControl + .getMock(); + this.servletInstance = new StubGDataServlet(); + } + + /** + * Test method for + * 'org.apache.lucene.gdata.servlet.AbstractGdataServlet.service(HttpServletRequest, + * HttpServletResponse)' + */ + public void testServiceHttpServletRequestHttpServletResponseDelete() { + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_DELETE); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_DELETE); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + this.requestMockControl.reset(); + + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_POST); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_DELETE); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + } + + /** + * + */ + public void testServiceNullOverrideHeader() { + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_POST); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), null); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + this.requestMockControl.reset(); + } + + /** + * Test method for + * 'org.apache.lucene.gdata.servlet.AbstractGdataServlet.service(HttpServletRequest, + * HttpServletResponse)' + */ + public void testServiceHttpServletRequestHttpServletResponsePOST() { + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_POST); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_POST); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + this.requestMockControl.reset(); + + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_PUT); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_POST); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + } + + /** + * Test method for + * 'org.apache.lucene.gdata.servlet.AbstractGdataServlet.service(HttpServletRequest, + * HttpServletResponse)' + */ + public void testServiceHttpServletRequestHttpServletResponsePUT() { + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_PUT); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_PUT); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + this.requestMockControl.reset(); + + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_POST); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_PUT); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + } + + /** + * Test method for + * 'org.apache.lucene.gdata.servlet.AbstractGdataServlet.service(HttpServletRequest, + * HttpServletResponse)' + */ + public void testServiceHttpServletRequestHttpServletResponseGET() { + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_GET); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_GET); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + this.requestMockControl.reset(); + + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_POST); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_GET); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + + } + /** + * Stub Implementation for AbstractGdataServlet + * @author Simon Willnauer + * + */ + static class StubGDataServlet extends AbstractGdataServlet { + + private static final long serialVersionUID = -6271464588547620925L; + + protected void doDelete(HttpServletRequest arg0, + HttpServletResponse arg1) { + if (arg0.getHeader(METHOD_HEADER_NAME) == null) + assertEquals("Http-Method --DELETE--", METHOD_DELETE, arg0 + .getMethod()); + else + assertEquals("Http-Method override --DELETE--", METHOD_DELETE, + arg0.getHeader(METHOD_HEADER_NAME)); + + } + + protected void doGet(HttpServletRequest arg0, HttpServletResponse arg1) { + if (arg0.getHeader(METHOD_HEADER_NAME) == null) + assertEquals("Http-Method --GET--", arg0.getMethod(), + METHOD_GET); + else + assertEquals("Http-Method override --GET--", arg0 + .getHeader(METHOD_HEADER_NAME), METHOD_GET); + } + + protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1) { + if (arg0.getHeader(METHOD_HEADER_NAME) == null) + assertEquals("Http-Method --POST--", arg0.getMethod(), + METHOD_POST); + else + assertEquals("Http-Method override --POST--", METHOD_POST, arg0 + .getHeader(METHOD_HEADER_NAME)); + + } + + protected void doPut(HttpServletRequest arg0, HttpServletResponse arg1) { + if (arg0.getHeader(METHOD_HEADER_NAME) == null) + assertEquals("Http-Method --PUT--", arg0.getMethod(), + METHOD_PUT); + else + assertEquals("Http-Method override --PUT--", arg0 + .getHeader(METHOD_HEADER_NAME), METHOD_PUT); + } + + } + +} Index: java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestFeedRequest.java =================================================================== --- java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestFeedRequest.java (revision 0) +++ java/trunk/contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestFeedRequest.java (revision 0) @@ -0,0 +1,123 @@ +package org.apache.lucene.gdata.server; + +import javax.servlet.http.HttpServletRequest; + +import org.easymock.MockControl; + +import junit.framework.TestCase; + +/** + * + * @author Simon Willnauer + * + */ +public class TestFeedRequest extends TestCase { + private HttpServletRequest request; + + private MockControl control; + + private FeedRequest feedRequest; + + protected void setUp() throws Exception { + this.control = MockControl.createControl(HttpServletRequest.class); + this.request = (HttpServletRequest) this.control.getMock(); + this.feedRequest = new FeedRequest(this.request); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + public void testGetFeedId() throws FeedRequestException { + + this.control.expectAndDefaultReturn(this.request.getPathInfo(), + "/feed/1/1"); + this.control.expectAndDefaultReturn(this.request.getParameter("alt"),null); + this.control.replay(); + this.feedRequest.initializeRequest(); + assertEquals("feedID", this.feedRequest.getFeedId(), "feed"); + this.control.reset(); + + } + + public void testEmptyPathInfo() { + this.control.expectAndDefaultReturn(this.request.getPathInfo(), "/"); + this.control.expectAndDefaultReturn(this.request.getParameter("alt"),null); + this.control.replay(); + try { + this.feedRequest.initializeRequest(); + + fail("FeedRequestException expected"); + } catch (FeedRequestException e) { + // expected + } catch (Exception e) { + fail("FeedRequestException expected"); + } + + } + + public void testGetFeedIdWithoutEntry() throws FeedRequestException { + this.control.expectAndDefaultReturn(this.request.getPathInfo(), "feed"); + this.control.expectAndDefaultReturn(this.request.getParameter("alt"),null); + this.control.replay(); + this.feedRequest.initializeRequest(); + assertEquals("feedID", this.feedRequest.getFeedId(), "feed"); + } + + public void testGetEntyId() throws FeedRequestException { + + this.control.expectAndDefaultReturn(this.request.getPathInfo(), + "/feed/1/15"); + this.control.expectAndDefaultReturn(this.request.getParameter("alt"),null); + this.control.replay(); + this.feedRequest.initializeRequest(); + assertEquals("entryid", this.feedRequest.getEntryId(), "1"); + assertEquals("feedId", this.feedRequest.getFeedId(), "feed"); + assertEquals("entryid", this.feedRequest.getEntryVersion(), "15"); + this.control.reset(); + + } + + public void testSetResponseFormatAtom() throws FeedRequestException { + this.control.expectAndDefaultReturn(this.request.getParameter("alt"), + "atom"); + this.control.expectAndDefaultReturn(this.request.getPathInfo(), "/feed"); + this.control.replay(); + this.feedRequest.initializeRequest(); + assertEquals("ResponseFromat Atom", this.feedRequest + .getRequestedResponseFormat(), FeedRequest.RESPONSE_FORMAT_ATOM); + this.control.reset(); + } + + public void testSetResponseFormatRSS() throws FeedRequestException { + this.control.expectAndDefaultReturn(this.request.getParameter("alt"), + "rss"); + this.control.expectAndDefaultReturn(this.request.getPathInfo(), "/feed"); + this.control.replay(); + this.feedRequest.initializeRequest(); + assertEquals("ResponseFromat RSS", this.feedRequest + .getRequestedResponseFormat(), FeedRequest.RESPONSE_FORMAT_RSS); + this.control.reset(); + } + + public void testSetResponseFormatKeepAtom() throws FeedRequestException { + this.control.expectAndDefaultReturn(this.request.getParameter("alt"), + "fooBar"); + this.control.expectAndDefaultReturn(this.request.getPathInfo(), "/feed"); + this.control.replay(); + this.feedRequest.initializeRequest(); + assertEquals("ResponseFromat Atom", this.feedRequest + .getRequestedResponseFormat(), FeedRequest.RESPONSE_FORMAT_ATOM); + this.control.reset(); + } + public void testSetResponseFormatNull() throws FeedRequestException { + this.control.expectAndDefaultReturn(this.request.getParameter("alt"), + null); + this.control.expectAndDefaultReturn(this.request.getPathInfo(), "/feed"); + this.control.replay(); + this.feedRequest.initializeRequest(); + assertEquals("ResponseFromat Atom", this.feedRequest + .getRequestedResponseFormat(), FeedRequest.RESPONSE_FORMAT_ATOM); + this.control.reset(); + } +} Index: java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/RequestControllerServlet.java =================================================================== --- java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/RequestControllerServlet.java (revision 0) +++ java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/RequestControllerServlet.java (revision 0) @@ -0,0 +1,102 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.servlet; + +import java.io.IOException; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.lucene.gdata.servlet.handler.DefaultRequestHandlerFactory; +import org.apache.lucene.gdata.servlet.handler.GDataRequestHandler; +import org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory; + +/** + * Provides a clean basic interface for GDATA Client API and requests to the + * GDATA Server. This Servlet dispatches the incoming requests to defined GDATA + * request handlers. Each of the handler processes the incoming request and + * responds according to the requested action. + * + * @author Simon Willnauer + * + */ +public class RequestControllerServlet extends AbstractGdataServlet { + private static RequestHandlerFactory HANDLER_FACTORY = null; + + /** + * Version ID since this class implements + * + * @see java.io.Serializable + */ + private static final long serialVersionUID = 7540810742476175576L; + + /** + * @see javax.servlet.http.HttpServlet#doDelete(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + protected void doDelete(HttpServletRequest arg0, HttpServletResponse arg1) + throws ServletException, IOException { + GDataRequestHandler hanlder = HANDLER_FACTORY.getDeleteHandler(); + hanlder.processRequest(arg0, arg1); + } + + /** + * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + protected void doGet(HttpServletRequest arg0, HttpServletResponse arg1) + throws ServletException, IOException { + GDataRequestHandler hanlder = HANDLER_FACTORY.getQueryHandler(); + hanlder.processRequest(arg0, arg1); + } + + /** + * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1) + throws ServletException, IOException { + GDataRequestHandler hanlder = HANDLER_FACTORY.getInsertHandler(); + hanlder.processRequest(arg0, arg1); + } + + /** + * @see javax.servlet.http.HttpServlet#doPut(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + protected void doPut(HttpServletRequest arg0, HttpServletResponse arg1) + throws ServletException, IOException { + GDataRequestHandler hanlder = HANDLER_FACTORY.getUpdateHandler(); + hanlder.processRequest(arg0, arg1); + } + + /** + * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig) + */ + public void init(ServletConfig arg0) throws ServletException { + /* + * The Factory implementation could be configured as an initial + * parameter or by an external config file. + * + */ + HANDLER_FACTORY = RequestHandlerFactory + .getInstance(DefaultRequestHandlerFactory.class); + + } +} Index: java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/AbstractGdataServlet.java =================================================================== --- java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/AbstractGdataServlet.java (revision 0) +++ java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/AbstractGdataServlet.java (revision 0) @@ -0,0 +1,96 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.servlet; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * Provides an abstract class to be subclassed to create an GDATA servlet + * suitable for a GDATA serverside implementation. + * + * @see javax.servlet.http.HttpServlet + * + * @author Simon Willnauer + * + */ +public abstract class AbstractGdataServlet extends HttpServlet { + private static final String METHOD_HEADER_NAME = "x-http-method-override"; + + private static final String METHOD_DELETE = "DELETE"; + + private static final String METHOD_GET = "GET"; + + private static final String METHOD_POST = "POST"; + + private static final String METHOD_PUT = "PUT"; + + /** + * This overwrites the protected service method to dispatch + * the request to the correponding do method. There is + * ususaly no need for overwriting this method. The GData protool and the + * Google GData API uses the x-http-method-override header to + * get through firewalls. The http method will be overritten by the + * x-http-method-override and dispatched to the + * doXxx methods defined in this class. This method + * is an GDATA-specific version of the {@link javax.servlet.Servlet#service} + * method. + * + * @see HttpServlet#service(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + protected void service(HttpServletRequest arg0, HttpServletResponse arg1) + throws ServletException, IOException { + if (arg0.getHeader(METHOD_HEADER_NAME) == null) { + super.service(arg0, arg1); + return; + } + overrideMethod(arg0, arg1); + + } + + private void overrideMethod(HttpServletRequest arg0, + HttpServletResponse arg1) throws ServletException, IOException { + final String method = arg0.getMethod(); + final String overrideHeaderMethod = arg0.getHeader(METHOD_HEADER_NAME); + if (overrideHeaderMethod.equals(method)) { + super.service(arg0, arg1); + return; + } + // These methodes are use by GDATA Client APIs + if (overrideHeaderMethod.equals(METHOD_DELETE)) { + doDelete(arg0, arg1); + } else if (overrideHeaderMethod.equals(METHOD_GET)) { + doGet(arg0, arg1); + } else if (overrideHeaderMethod.equals(METHOD_POST)) { + doPost(arg0, arg1); + } else if (overrideHeaderMethod.equals(METHOD_PUT)) { + doPut(arg0, arg1); + } else { + // if another method has been overwritten follow the HttpServlet + // implementation + super.service(arg0, arg1); + } + + } + +} Index: java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultRequestHandlerFactory.java =================================================================== --- java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultRequestHandlerFactory.java (revision 0) +++ java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultRequestHandlerFactory.java (revision 0) @@ -0,0 +1,69 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.servlet.handler; + + +/** + * Default implementation for RequestHandlerFactory + * @author Simon Willnauer + * + */ +public class DefaultRequestHandlerFactory extends RequestHandlerFactory { + + DefaultRequestHandlerFactory() { + // + } + + /** + * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getUpdateHandler() + */ + public GDataRequestHandler getUpdateHandler() { + + return null; + } + + /** + * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getDeleteHandler() + */ + public GDataRequestHandler getDeleteHandler() { + + return null; + } + + /** + * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getQueryHandler() + */ + public GDataRequestHandler getQueryHandler() { + + return null; + } + + /** + * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getInsertHandler() + */ + public GDataRequestHandler getInsertHandler() { + + return null; + } + + + + + + + +} Index: java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandlerException.java =================================================================== --- java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandlerException.java (revision 0) +++ java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandlerException.java (revision 0) @@ -0,0 +1,64 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.servlet.handler; + +/** + * @author Simon Willnauer + * + */ +public class GDataRequestHandlerException extends RuntimeException { + + /** + * + */ + private static final long serialVersionUID = -418225239671624153L; + + + /** + * + */ + public GDataRequestHandlerException() { + super(); + + } + + /** + * @param arg0 + */ + public GDataRequestHandlerException(String arg0) { + super(arg0); + + } + + /** + * @param arg0 + * @param arg1 + */ + public GDataRequestHandlerException(String arg0, Throwable arg1) { + super(arg0, arg1); + + } + + /** + * @param arg0 + */ + public GDataRequestHandlerException(Throwable arg0) { + super(arg0); + + } + +} Index: java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandler.java =================================================================== --- java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandler.java (revision 0) +++ java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandler.java (revision 0) @@ -0,0 +1,55 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.gdata.servlet.handler; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * Based on the Command pattern [GoF], the Command and Controller Strategy + * suggests providing a generic interface to the handler components to which the + * controller may delegate responsibility, minimizing the coupling among these + * components. + * + * Adding to or changing the work that needs to be completed by these handlers + * does not require any changes to the interface between the controller and the + * handlers, but rather to the type and/or content of the commands. This provides + * a flexible and easily extensible mechanism for developers to add request + * handling behaviors. + * + * The controller invokes the processRequest method from the corresponding servlet doXXX + * method to delegate the request to the handler. + * + * + * @author Simon Willnauer + * + */ +public interface GDataRequestHandler { + /** + * Processes the GDATA Client request + * + * @param request - the client request to be processed + * @param response - the response to the client request + * @throws ServletException - if a servlet exception is thrown by the request or response + * @throws IOException - if an input/output error occurs due to accessing an IO steam + */ + public abstract void processRequest(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException; +} Index: java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractGdataRequestHandler.java =================================================================== --- java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractGdataRequestHandler.java (revision 0) +++ java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractGdataRequestHandler.java (revision 0) @@ -0,0 +1,73 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.servlet.handler; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.gdata.server.FeedRequest; +import org.apache.lucene.gdata.server.FeedRequestException; +import org.apache.lucene.gdata.server.FeedResponse; + +/** + * @author Simon Willnauer + * + */ +public abstract class AbstractGdataRequestHandler implements + GDataRequestHandler { + private final static Log LOG = LogFactory + .getLog(AbstractGdataRequestHandler.class); + + + protected FeedRequest feedRequest; + protected FeedResponse feedResponse; + + /** + * @see org.apache.lucene.gdata.servlet.handler.GDataRequestHandler#processRequest(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + public abstract void processRequest(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException; + + protected void initializeRequestHandler(final HttpServletRequest request, final HttpServletResponse response) + throws FeedRequestException { + this.feedRequest = new FeedRequest(request); + this.feedResponse = new FeedResponse(response); + try { + this.feedRequest.initializeRequest(); + } catch (FeedRequestException e) { + this.feedResponse.setError(HttpServletResponse.SC_NOT_FOUND); + LOG.warn("Couldn't initialize FeedRequest - " + e.getMessage(), e); + throw e; + } + } + + + + protected void sendError() throws IOException { + this.feedResponse.sendError(); + + } + + + +} Index: java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/RequestHandlerFactory.java =================================================================== --- java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/RequestHandlerFactory.java (revision 0) +++ java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/RequestHandlerFactory.java (revision 0) @@ -0,0 +1,122 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.servlet.handler; + +/** + * @author Simon Willnauer + * + */ +public abstract class RequestHandlerFactory { + + private static RequestHandlerFactory INSTANCE = null; + + /** + * This method creates a singleton instance of the given type. The fist call + * will create an instance of the given class which will be returned in + * every subsequent call. Any subsequent call to this method will ignore the + * given class object. + * + * @param factoryImplementation - + * the factory implementation (must be a subtype of this Class) + * + * @return - a singleton instance of the given type + * + */ + public static synchronized RequestHandlerFactory getInstance( + Class factoryImplementation) { + if (INSTANCE == null) { + + INSTANCE = createInstance(factoryImplementation); + } + return INSTANCE; + } + + /** + * Singleton - Pattern using private constructor + * + */ + RequestHandlerFactory() { + super(); + + } + + private static RequestHandlerFactory createInstance( + final Class qualifiedClass) { + if (qualifiedClass == null) + throw new IllegalArgumentException( + "Factory class is null -- must be a implementation of org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory"); + try { + return (RequestHandlerFactory) qualifiedClass.newInstance(); + } catch (Exception e) { + FactoryImplementationException ex = new FactoryImplementationException( + "Factory implementation could not be created", e.getCause()); + ex.setStackTrace(e.getStackTrace()); + throw ex; + } + } + + /** + * Creates a UpdateHandler which processes a GDATA UPDATE request. + * @return - an RequestHandlerInstance + */ + public abstract GDataRequestHandler getUpdateHandler(); + + /** + * Creates a DeleteHandler which processes a GDATA DELETE request. + * @return - an RequestHandlerInstance + */ + public abstract GDataRequestHandler getDeleteHandler(); + + /** + * Creates a QueryHandler which processes a GDATA Query / Get request. + * @return - an RequestHandlerInstance + */ + public abstract GDataRequestHandler getQueryHandler(); + + /** + * Creates a InsertHandler which processes a GDATA Insert request. + * @return - an RequestHandlerInstance + */ + public abstract GDataRequestHandler getInsertHandler(); + + + + private static class FactoryImplementationException extends + RuntimeException { + + /** + * + */ + private static final long serialVersionUID = 3166033278825112569L; + + /** + * Constructs a new FactoryImplementationException with the specified + * cause and message + * + * @param arg0 - + * the detail message + * @param arg1 - + * the throw cause + */ + public FactoryImplementationException(String arg0, Throwable arg1) { + super(arg0, arg1); + + } + + } + +} Index: java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/package.html =================================================================== --- java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/package.html (revision 0) +++ java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/package.html (revision 0) @@ -0,0 +1,10 @@ + + + + + + + +GData Request Handler. + + Index: java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/package.html =================================================================== --- java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/package.html (revision 0) +++ java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/package.html (revision 0) @@ -0,0 +1,10 @@ + + + + + + + +Servlets acting as basic interfaces for gdata requests. + + Index: java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/ServiceException.java =================================================================== --- java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/ServiceException.java (revision 0) +++ java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/ServiceException.java (revision 0) @@ -0,0 +1,63 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.server; + +/** + * @author Simon Willnauer + * + */ +public class ServiceException extends Exception { + + /** + * + */ + private static final long serialVersionUID = -7099825107871876584L; + + /** + * + */ + public ServiceException() { + super(); + + } + + /** + * @param arg0 + */ + public ServiceException(String arg0) { + super(arg0); + + } + + /** + * @param arg0 + * @param arg1 + */ + public ServiceException(String arg0, Throwable arg1) { + super(arg0, arg1); + + } + + /** + * @param arg0 + */ + public ServiceException(Throwable arg0) { + super(arg0); + + } + +} Index: java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/Service.java =================================================================== --- java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/Service.java (revision 0) +++ java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/Service.java (revision 0) @@ -0,0 +1,149 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.server; + +import org.apache.lucene.gdata.data.Feed; + +/** + * The Service class represents an interface to access the GData service + * componentes of the GData-Server. It encapsulates all interactions with the + * GData client. + *

+ * This class provides the base level common functionality required to access + * the GData components. It is also designed to act as a base class that can be + * extended for specific types of underlaying server components as different + * indexing or storage components. + *

+ *

+ * It could also encapsulate caching mechanismn build on top of the storage to + * reduce load on the storage component + *

+ * + * @author Simon Willnauer + * + */ +public abstract class Service { + + /** + * Service method to create an entry in an already created and existing + * feed. This method will create the entry and passes the entry to the + * indexing component to make the new entry accessable via get-queries. + * The response and the corresponding http status code will be added to the + * given FeedResponse. + * + * @param request - + * the current FeedRequest + * @param response - + * the current FeedResponse + * @throws ServiceException - + * if the corresponding feed does not exist or the storage can + * not be accessed + */ + public abstract void createEntry(final FeedRequest request, + final FeedResponse response) throws ServiceException; + + /** + * Service Method to delete an entry specified in the given FeedRequest. + * This method will remove the entry permanently. There will be no + * possiblity to restore the entry. The response and the corresponding http + * status code will be added to the given FeedResponse. + * + * @param request - + * the current FeedRequest + * @param response - + * the current FeedResponse + * @throws ServiceException - + * if the entry does not exist or the storage can not be + * accessed + */ + public abstract void deleteEntry(FeedRequest request, final FeedResponse response) + throws ServiceException; + + /** + * Service method to update an existing entry in a existing feed context. + * The entry version will be checked and a ServiceException + * will be thrown if the version to update is outdated. The new entry will + * be passed to the indexing component to make the version accessable via + * get-queries. + * + * @param request - + * the current FeedRequest + * @param response - + * the current FeedResponse + * @throws ServiceException - + * if the corresponding feed does not exist, the storage can not + * be accessed or the version to update is out of date. + */ + public abstract void updateEntry(final FeedRequest request, + final FeedResponse response) throws ServiceException; + + /** + * Service method to retrieve a requested Feed. The feed will be added to + * the given FeedResponse instance and can also be accessed + * via the FeedResponse object. + * + * @param request - + * the current FeedRequest + * @param response - + * the current FeedResponse + * + * @throws ServiceException - + * If the storage can not be accessed or the requested feed does + * not exist. + */ + public abstract void getFeed(final FeedRequest request, final FeedResponse response) + throws ServiceException; + + /** + * Service method to write a requested feed + * + * @param request - + * the current FeedRequest + * @param response - + * the current FeedResponse + * + * @throws ServiceException - + * if an I/O Exception occures while writing the feed to the + * corresponding output - stream of the Feed can not be + * transformed + * + */ + public void writeFeed(final FeedRequest request, final FeedResponse response) + throws ServiceException { + Feed feed = response.getFeed(); + if(feed == null) + throw new ServiceException("Can't write feed, the feed reference is null"); + try { + int outputFormat = request.getRequestedResponseFormat(); + + switch (outputFormat) { + case FeedRequest.RESPONSE_FORMAT_RSS: + feed.writeRss(response.getOutputStream()); + break; + + default: + feed.writeAtom(response.getOutputStream()); + break; + } + + } catch (Exception e) { + throw new ServiceException("Could not write feed - " + + e.getMessage(), e); + } + } + +} Index: java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/FeedResponse.java =================================================================== --- java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/FeedResponse.java (revision 0) +++ java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/FeedResponse.java (revision 0) @@ -0,0 +1,128 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.server; + +import java.io.IOException; +import java.io.OutputStream; + +import javax.servlet.http.HttpServletResponse; + +import org.apache.lucene.gdata.data.Entry; +import org.apache.lucene.gdata.data.Feed; + +/** + * The FeedRequest Class wraps the curren HttpServletResponse. + * Any action on the HttpServletRequest will be executed via this class. + * + * @author Simon Willnauer + * + */ +public class FeedResponse { + private int error; + + private boolean isError = false; + + private Feed feed = null; + private Entry entry = null; + + private final HttpServletResponse response; + /** + * @param response + */ + public FeedResponse(HttpServletResponse response) { + if(response == null) + throw new IllegalArgumentException("response must not be null"); + this.response = response; + } + + /** + * Writes XML in the Rss Format into the HttpServletResponse outputstream; + * @param feed - the feed to write into the output stream + * @throws IOException + */ + public void writeRSSFeed(Feed feed)throws IOException{ + + } + + /** + * Writes XML in the ATOM Format into the HttpServletResponse outputstream; + * @param feed - the feed to write into the output stream + * @throws IOException - + */ + public void writeAtomFeed(Feed feed)throws IOException{ + + } + + + /** + * Sets an error code to this FeedResponse. + * + * @param errorCode + */ + public void setError(int errorCode) { + this.isError = true; + this.error = errorCode; + } + + + /** + * This method sends the specified error to the user if set + * @throws IOException + */ + public void sendError() throws IOException { + if(this.isError) + this.response.sendError(this.error); + } + + + /** + * @return - the HttpServletResponse outputstream + * @throws IOException - If an I/O exception occures + */ + public OutputStream getOutputStream() throws IOException{ + return this.response.getOutputStream(); + } + + /** + * @return - the entry for this response + */ + public Entry getEntry() { + return this.entry; + } + + /** + * @param entry - the Entry object if this response contains a entry otherwise it will return null + */ + public void setEntry(Entry entry) { + this.entry = entry; + } + + /** + * @return the Feed Object if this response contains a feed otherwise it will return null + */ + public Feed getFeed() { + return this.feed; + } + + /** + * @param feed - the feed for this response + */ + public void setFeed(Feed feed) { + this.feed = feed; + } + +} Index: java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/FeedRequestException.java =================================================================== --- java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/FeedRequestException.java (revision 0) +++ java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/FeedRequestException.java (revision 0) @@ -0,0 +1,58 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.server; + +/** + * @author Simon Willnauer + * + */ +public class FeedRequestException extends Exception { + + /** + * + */ + public FeedRequestException() { + super(); + + } + + /** + * @param arg0 + */ + public FeedRequestException(String arg0) { + super(arg0); + + } + + /** + * @param arg0 + * @param arg1 + */ + public FeedRequestException(String arg0, Throwable arg1) { + super(arg0, arg1); + + } + + /** + * @param arg0 + */ + public FeedRequestException(Throwable arg0) { + super(arg0); + + } + +} Index: java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/FeedRequest.java =================================================================== --- java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/FeedRequest.java (revision 0) +++ java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/FeedRequest.java (revision 0) @@ -0,0 +1,160 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.server; + +import java.io.IOException; +import java.io.InputStream; +import java.util.StringTokenizer; + +import javax.servlet.http.HttpServletRequest; + +/** + * The FeedRequest Class wraps the incoming HttpServletRequest. Needed + * information coming with the HttpServletRequest can be accessed directly. + * + * @author Simon Willnauer + * + */ +/* this class might be extracted as an interface in later development */ +public class FeedRequest { + /** + * Feed response format Atom. Atom it the default respose + * format. + */ + public static final int RESPONSE_FORMAT_ATOM = 1; + + /** + * Feed response format RSS + */ + public static final int RESPONSE_FORMAT_RSS = 2; + + private static final String RESPONSE_FORMAT_PARAMETER = "alt"; + + private static final String RESPONSE_FORMAT_PARAMETER_RSS = "rss"; + + private static final String RESPONSE_FORMAT_PARAMETER_ATOM = "atom"; + + // Atom is the default resopnse format + private int responseFormat = RESPONSE_FORMAT_ATOM; + + private final HttpServletRequest request; + + private String feedId = null; + + private String entryId = null; + + private String entryVersion = null; + + /** + * Creates a new FeedRequest + * + * @param requst - + * the incoming HttpServletReqeust + */ + public FeedRequest(final HttpServletRequest requst) { + if (requst == null) + throw new IllegalArgumentException("request must not be null "); + this.request = requst; + } + + /** + * @throws FeedRequestException + */ + public void initializeRequest() throws FeedRequestException { + generateIdentificationProperties(); + setOutputFormat(); + } + + /** + * @return - the id of the requested feed + */ + public String getFeedId() { + + return this.feedId; + } + + /** + * @return - the entry id of the requested Entry + */ + public String getEntryId() { + + return this.entryId; + } + + /** + * @return the version Id of the requested Entry + */ + public String getEntryVersion() { + return this.entryVersion; + } + + /** + * @return - the HttpServletRequest InputStream + * @throws IOException - + * if an I/O Exception occures + */ + public InputStream getInputStream() throws IOException { + return this.request.getInputStream(); + } + + /** + * Returns a lucene query string corresponding to the GET request + * parameter. + * + * @return the reqeust query string + */ + public String getQueryString() { + throw new RuntimeException("not implemented yet"); + } + + /** + * @return - an int value identifies the feed response type + */ + public int getRequestedResponseFormat() { + // TODO this might be changed to an Enum - Type (java 1.5) + return this.responseFormat; + } + + private void generateIdentificationProperties() throws FeedRequestException { + /* generate all needed data to identify the requested feed/entry */ + String pathInfo = this.request.getPathInfo(); + /* + * TODO this has to be changed to support the category queries. Category + * queries could also be rewrited in the Servlet. + */ + if (pathInfo.length() <= 1) + throw new FeedRequestException( + "No feed or entry specified for this request"); + StringTokenizer tokenizer = new StringTokenizer(pathInfo, "/"); + this.feedId = tokenizer.nextToken(); + this.entryId = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : ""; + this.entryVersion = tokenizer.hasMoreTokens() ? tokenizer.nextToken() + : ""; + + } + + private void setOutputFormat() { + String formatParameter = this.request + .getParameter(RESPONSE_FORMAT_PARAMETER); + if (formatParameter == null) + return; + if (formatParameter.equalsIgnoreCase(RESPONSE_FORMAT_PARAMETER_RSS)) + this.responseFormat = RESPONSE_FORMAT_RSS; + + } + +} Index: java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/package.html =================================================================== --- java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/package.html (revision 0) +++ java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/package.html (revision 0) @@ -0,0 +1,10 @@ + + + + + + + +GData-Server classes encapsulation all protocol-level interactions and underlaying GData components. + + \ No newline at end of file Index: java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/data/Entry.java =================================================================== --- java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/data/Entry.java (revision 0) +++ java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/data/Entry.java (revision 0) @@ -0,0 +1,104 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.data; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Date; + +/** + * + * @author Simon Willnauer + * + */ +//TODO Documentation of this important interface +public interface Entry { + + + /** + * This writes the entries XML representation to the given outputsteam. + * The format will be the defaul ATOM format. + * @param stream - the stream to write the entry + * @throws IOException - if an I/O Exception occurs, most likly when the stream has already been closed. + */ + public abstract void writeEntryToStream(final OutputStream stream)throws IOException; + + /** + * @return - the entry id + */ + public abstract String getEntryId(); + /** + * @return - the entry title + */ + public abstract String getTitle(); + /** + * @return - the authors name of this entry + */ + public abstract String getAuthorName(); + /** + * @return - the authors email address of this entry + */ + public abstract String getAuthorEmail(); + /** + * @return - the category of this entry + */ + public abstract String getCategory(); + /** + * @return - the category scheme of this entry + */ + public abstract String getCategoryScheme(); + /** + * @return - the publication Date + */ + public abstract Date getPublicationDate(); + /** + * @return - the date of the last update of this entry + */ + public abstract Date getLastUpdated(); + /** + * This method returns the content of the entry. + * content - elements can contain several content types as XHTML or base64 + * @return - the content of the entry + */ + public abstract Object getContent(); + /** + * @return - the summary of the entry + */ + public abstract String getSummary(); + /** + * @return - the entries version id + */ + public abstract String getVersionId(); + /** + * @return - the self link to this entry + * @throws MalformedURLException - if the url is not a valid URL + */ + public abstract URL getSelfLink() throws MalformedURLException; + + /** + * This method retrieves a custom fiel of an Entry described by a X-Path + * expression + * + * @param xpath - + * xpath expression to retrieve the custom field + * @return a custom fiel object or null if the xpath + * expression returns not value + */ + public CustomField getCustomField(String xpath); +} Index: java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/data/Feed.java =================================================================== --- java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/data/Feed.java (revision 0) +++ java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/data/Feed.java (revision 0) @@ -0,0 +1,129 @@ +package org.apache.lucene.gdata.data; + +import java.io.IOException; +import java.io.OutputStream; +import java.net.URL; +import java.util.Date; +import java.util.List; + +/** + * The Feed interface represents the main interface to access feed data. + *

+ * This interface is used to simplify internal representation of the feed and to + * decuple the internal structure of a feed representation. + *

+ * + * + * @author Simon Willnauer + * + */ +public interface Feed { + + /** + * @return the FeedID + */ + public abstract String getFeedId(); + + /** + * @return author of the feed + */ + public abstract String getAuthor(); + + /** + * @return title of the feed + */ + public abstract String getTitle(); + + /** + * @return last update of this feed + */ + public abstract Date getUpdated(); + + /** + * @return the link to the feed + */ + public abstract URL getSelfLink(); + + /** + * @return all entries of the feed + */ + public abstract List getEntries(); + + /** + * This method returns a sub list of the feed entries including the start + * and the end + * + * @param start - + * start id + * @param end - + * end id + * @return a entry sub list + */ + public abstract List getEntries(int start, int end); + + /** + * @param id - + * entry id + * @return - the entry for the given id or null if no enty has been found + */ + public abstract Entry getEntry(final int id); + + /** + * @return - the feed subtitle + */ + public abstract String getSubTitle(); + + /** + * @return - the feed language + */ + public abstract String getLanguage(); + + /** + * @return the feed category + */ + public abstract String getCategory(); + + /** + * Writes XML in the RSS Format into the given outputstream; + * + * @param stream - + * the outputstream to write the xml + * @throws IOException - + * if an I/O error occurs. In particular, an IOException is + * thrown if the output stream is closed. + */ + public abstract void writeRss(final OutputStream stream) throws IOException; + + /** + * Writes XML in the ATOM Format into the given outputstream; + * + * @param stream - + * the outputstream to write the xml + * @throws IOException - + * if an I/O error occurs. In particular, an IOException is + * thrown if the output stream is closed. + * + */ + public abstract void writeAtom(final OutputStream stream) + throws IOException; + + /** + * Writes the containig feed into a StringStream and returns the feed as a + * String. + * + * @return - the Feed content as a String + */ + public abstract String getStringRepresentation(); + + /** + * This method retrieves a custom fiel of a Feed described by a X-Path + * expression + * + * @param xpath - + * xpath expression to retrieve the custom field + * @return a custom fiel object or null if the xpath + * expression returns not value + */ + public CustomField getCustomField(String xpath); + +} Index: java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/data/CustomField.java =================================================================== --- java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/data/CustomField.java (revision 0) +++ java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/data/CustomField.java (revision 0) @@ -0,0 +1,30 @@ +package org.apache.lucene.gdata.data; + +/** + * As Atom e.g. GData allows custom - fields inside a {@link Feed} and / or {@link Entry} + * this Interface represents a general representation of a custom field. + *

+ * This interface is used to simplify internal representation of a custom field and to + * decuple the internal structure of a field representation. + *

+ * @author Simon Willnauer + * + */ +public interface CustomField { + /** + * @return the name of the field + */ + public abstract String getName(); + /** + * Feed field can contain serveral content types like xhtml or base46. + * @return content type of the field + */ + //TODO change the returnvalue later (maybe 1.5 Enum) + public abstract String getType(); + /** + * + * @return the value of the field + */ + public abstract Object getValue(); + +} Index: java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/data/package.html =================================================================== --- java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/data/package.html (revision 0) +++ java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/data/package.html (revision 0) @@ -0,0 +1,10 @@ + + + + + + + +Contains classes for the internal representation of GData feeds and entries. + + \ No newline at end of file Index: java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/package.html =================================================================== --- java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/package.html (revision 0) +++ java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/package.html (revision 0) @@ -0,0 +1 @@ +Top-level package. \ No newline at end of file Index: java/trunk/contrib/gdata-server/build.xml =================================================================== --- java/trunk/contrib/gdata-server/build.xml (revision 0) +++ java/trunk/contrib/gdata-server/build.xml (revision 0) @@ -0,0 +1,39 @@ + + + + + + Serverside Google Data API implementation + + + + + + + + + + + + + + + + + Prepare dist directory + + + + + Distributing GData War + + + + + + + + + + \ No newline at end of file