You are viewing a plain text version of this content. The canonical link for it is here.
Posted to java-commits@lucene.apache.org by cu...@apache.org on 2006/06/07 23:56:29 UTC

svn commit: r412574 [2/4] - in /lucene/java/trunk: ./ contrib/gdata-server/ contrib/gdata-server/lib/ contrib/gdata-server/src/ contrib/gdata-server/src/java/ contrib/gdata-server/src/java/org/ contrib/gdata-server/src/java/org/apache/ contrib/gdata-se...

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryContextListener.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryContextListener.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryContextListener.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryContextListener.java Wed Jun  7 14:56:25 2006
@@ -0,0 +1,65 @@
+/** 
+ * 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.registry; 
+ 
+import javax.servlet.ServletContextEvent; 
+import javax.servlet.ServletContextListener; 
+ 
+import org.apache.commons.logging.Log; 
+import org.apache.commons.logging.LogFactory; 
+ 
+/** 
+ * This Listener creates the 
+ * {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry} when the 
+ * context is loaded. The registry will be loaded before the 
+ * {@link org.apache.lucene.gdata.servlet.RequestControllerServlet} is loaded. 
+ * The Registry will be loaded and set up befor the REST interface is available. 
+ * <p> 
+ * This ContextListener has to be configured in the <code>web.xml</code> 
+ * deployment descriptor.</p> 
+ *  
+ *  
+ * @author Simon Willnauer 
+ *  
+ */ 
+public class RegistryContextListener implements ServletContextListener { 
+    private GDataServerRegistry serverRegistry; 
+ 
+    private static final Log LOG = LogFactory 
+            .getLog(RegistryContextListener.class); 
+ 
+   
+ 
+    /** 
+     * @see javax.servlet.ServletContextListener#contextInitialized(javax.servlet.ServletContextEvent) 
+     */ 
+    public void contextInitialized(ServletContextEvent arg0) { 
+        LOG.info("RegistryContextListener has been loaded"); 
+        RegistryBuilder.buildRegistry(); 
+        this.serverRegistry = GDataServerRegistry.getRegistry(); 
+    } 
+ 
+    /** 
+     * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent) 
+     */ 
+    public void contextDestroyed(ServletContextEvent arg0) { 
+        LOG.info("Destroying context"); 
+        this.serverRegistry.destroy(); 
+ 
+    } 
+ 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/package.html
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/package.html?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/package.html (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/package.html Wed Jun  7 14:56:25 2006
@@ -0,0 +1,10 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> 
+<html> 
+<head> 
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> 
+   <meta name="Author" content="Simon Willnauer"> 
+</head> 
+<body> 
+Internal registry - registering feeds and configurations 
+</body> 
+</html> 
\ No newline at end of file

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/AbstractGdataServlet.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/AbstractGdataServlet.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/AbstractGdataServlet.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/AbstractGdataServlet.java Wed Jun  7 14:56:25 2006
@@ -0,0 +1,97 @@
+/** 
+ * 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 <code>service</code> method to dispatch 
+     * the request to the correponding <code>do</code> method. There is 
+     * ususaly no need for overwriting this method. The GData protool and the 
+     * Google GData API uses the <code>x-http-method-override</code> header to 
+     * get through firewalls. The http method will be overritten by the 
+     * <code>x-http-method-override</code> and dispatched to the 
+     * <code>do</code><i>Xxx</i> 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) 
+     */ 
+    @Override 
+    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); 
+        } 
+ 
+    } 
+ 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/RequestControllerServlet.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/RequestControllerServlet.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/RequestControllerServlet.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/RequestControllerServlet.java Wed Jun  7 14:56:25 2006
@@ -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; 
+ 
+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.commons.logging.Log; 
+import org.apache.commons.logging.LogFactory; 
+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; 
+    private static final Log LOGGER = LogFactory.getLog(RequestControllerServlet.class); 
+ 
+    /** 
+     * 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) 
+     */ 
+    @Override 
+    protected void doDelete(HttpServletRequest arg0, HttpServletResponse arg1) 
+            throws ServletException, IOException { 
+        GDataRequestHandler hanlder = HANDLER_FACTORY.getDeleteHandler(); 
+        if(LOGGER.isInfoEnabled()) 
+            LOGGER.info("Process DELETE request"); 
+         
+        hanlder.processRequest(arg0, arg1); 
+    } 
+ 
+    /** 
+     * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, 
+     *      javax.servlet.http.HttpServletResponse) 
+     */ 
+    @Override 
+    protected void doGet(HttpServletRequest arg0, HttpServletResponse arg1) 
+            throws ServletException, IOException { 
+        GDataRequestHandler hanlder = HANDLER_FACTORY.getQueryHandler(); 
+        if(LOGGER.isInfoEnabled()) 
+            LOGGER.info("Process GET request"); 
+         
+        hanlder.processRequest(arg0, arg1); 
+    } 
+ 
+    /** 
+     * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, 
+     *      javax.servlet.http.HttpServletResponse) 
+     */ 
+    @Override 
+    protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1) 
+            throws ServletException, IOException { 
+        GDataRequestHandler hanlder = HANDLER_FACTORY.getInsertHandler(); 
+        if(LOGGER.isInfoEnabled()) 
+            LOGGER.info("Process POST request"); 
+        hanlder.processRequest(arg0, arg1); 
+    } 
+ 
+    /** 
+     * @see javax.servlet.http.HttpServlet#doPut(javax.servlet.http.HttpServletRequest, 
+     *      javax.servlet.http.HttpServletResponse) 
+     */ 
+    @Override 
+    protected void doPut(HttpServletRequest arg0, HttpServletResponse arg1) 
+            throws ServletException, IOException { 
+        GDataRequestHandler hanlder = HANDLER_FACTORY.getUpdateHandler(); 
+        if(LOGGER.isInfoEnabled()) 
+            LOGGER.info("Process PUT request"); 
+        hanlder.processRequest(arg0, arg1); 
+    } 
+ 
+    /** 
+     * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig) 
+     */ 
+    @Override 
+    public void init(ServletConfig arg0)  { 
+        /* 
+         * The Factory implementation could be configured as an initial 
+         * parameter or by an external config file. 
+         *  
+         */ 
+        HANDLER_FACTORY = RequestHandlerFactory 
+                .getInstance(DefaultRequestHandlerFactory.class); 
+         
+    } 
+     
+   
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractGdataRequestHandler.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractGdataRequestHandler.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractGdataRequestHandler.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractGdataRequestHandler.java Wed Jun  7 14:56:25 2006
@@ -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.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.GDataRequest; 
+import org.apache.lucene.gdata.server.GDataRequestException; 
+import org.apache.lucene.gdata.server.GDataResponse; 
+import org.apache.lucene.gdata.server.Service; 
+import org.apache.lucene.gdata.server.ServiceFactory; 
+import org.apache.lucene.gdata.server.GDataRequest.GDataRequestType; 
+ 
+/** 
+ * @author Simon Willnauer 
+ *  
+ */ 
+public abstract class AbstractGdataRequestHandler implements 
+        GDataRequestHandler { 
+    private final static Log LOG = LogFactory 
+            .getLog(AbstractGdataRequestHandler.class); 
+ 
+     
+    protected GDataRequest feedRequest; 
+    protected GDataResponse 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, final GDataRequestType type) 
+            throws GDataRequestException { 
+        this.feedRequest = new GDataRequest(request, type); 
+        this.feedResponse = new GDataResponse(response); 
+        try {        
+            this.feedRequest.initializeRequest(); 
+        } catch (GDataRequestException 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(); 
+         
+    } 
+ 
+    protected void setFeedResponseFormat() { 
+        this.feedResponse.setOutputFormat(this.feedRequest.getRequestedResponseFormat()); 
+    } 
+ 
+    protected void setFeedResponseStatus(int status) { 
+        this.feedResponse.setResponseCode(status); 
+    } 
+ 
+    protected void setError(int error) { 
+        this.feedResponse.setError(error); 
+    } 
+ 
+    protected Service getService() throws ServletException { 
+        ServiceFactory serviceFactory = ServiceFactory.getInstance(); 
+        Service service = serviceFactory.getService(); 
+        if(service == null) 
+            throw new ServletException("Service not available");  
+        return service; 
+    } 
+ 
+     
+ 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultDeleteHandler.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultDeleteHandler.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultDeleteHandler.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultDeleteHandler.java Wed Jun  7 14:56:25 2006
@@ -0,0 +1,84 @@
+/** 
+ * 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.FeedNotFoundException; 
+import org.apache.lucene.gdata.server.GDataRequestException; 
+import org.apache.lucene.gdata.server.Service; 
+import org.apache.lucene.gdata.server.ServiceException; 
+import org.apache.lucene.gdata.server.GDataRequest.GDataRequestType; 
+ 
+/** 
+ * Default Handler implementation. This handler processes the incoming 
+ * {@link org.apache.lucene.gdata.server.GDataRequest} and deletes the requested 
+ * feed entry from the storage and the search component. 
+ * <p> 
+ * The handler sends following response to the client: 
+ * </p> 
+ * <ol> 
+ * <li>if the entry could be deleted - HTTP status code <i>200 OK</i></li> 
+ * <li>if an error occures - HTTP status code <i>500 INTERNAL SERVER ERROR</i></li> 
+ * <li>if the resource could not found - HTTP status code <i>404 NOT FOUND</i></li> 
+ * </ol> 
+ *  
+ * @author Simon Willnauer 
+ *  
+ */ 
+public class DefaultDeleteHandler extends AbstractGdataRequestHandler { 
+    private static final Log LOG = LogFactory 
+            .getLog(DefaultDeleteHandler.class); 
+ 
+    /** 
+     * @throws ServletException  
+     * @see org.apache.lucene.gdata.servlet.handler.AbstractGdataRequestHandler#processRequest(javax.servlet.http.HttpServletRequest, 
+     *      javax.servlet.http.HttpServletResponse) 
+     */ 
+    @Override 
+    public void processRequest(HttpServletRequest request, 
+            HttpServletResponse response) throws IOException, ServletException { 
+        try { 
+            initializeRequestHandler(request, response,GDataRequestType.DELETE); 
+        } catch (GDataRequestException e) { 
+            sendError(); 
+            return; 
+        } 
+         
+        Service service = getService(); 
+        try { 
+            service.deleteEntry(this.feedRequest, this.feedResponse); 
+        } catch (FeedNotFoundException e) { 
+            LOG.error("Could not process DeleteFeed request Feed Not Found- " 
+                    + e.getMessage(), e); 
+            setError(HttpServletResponse.SC_NOT_FOUND); 
+            sendError(); 
+        } catch (ServiceException e) { 
+            LOG.error("Could not process DeleteFeed request - " 
+                    + e.getMessage(), e); 
+            setError(HttpServletResponse.SC_BAD_REQUEST); 
+            sendError(); 
+        } 
+ 
+    } 
+ 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultGetHandler.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultGetHandler.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultGetHandler.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultGetHandler.java Wed Jun  7 14:56:25 2006
@@ -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.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.GDataRequestException; 
+import org.apache.lucene.gdata.server.Service; 
+import org.apache.lucene.gdata.server.ServiceException; 
+import org.apache.lucene.gdata.server.GDataRequest.GDataRequestType; 
+ 
+import com.google.gdata.data.BaseEntry; 
+import com.google.gdata.data.BaseFeed; 
+ 
+/** 
+ * Default Handler implementation. This handler processes the incoming 
+ * {@link org.apache.lucene.gdata.server.GDataRequest} and retrieves the 
+ * requested feed from the underlaying storage. 
+ * <p> 
+ * This hander also processes search queries and retrives the search hits from 
+ * the underlaying search component. The user query will be accessed via the 
+ * {@link org.apache.lucene.gdata.server.GDataRequest} instance passed to the 
+ * {@link Service} class. 
+ * </p> 
+ *  
+ *  
+ * @author Simon Willnauer 
+ *  
+ */ 
+public class DefaultGetHandler extends AbstractGdataRequestHandler { 
+    private static final Log LOG = LogFactory.getLog(DefaultGetHandler.class); 
+ 
+    /** 
+     * @see org.apache.lucene.gdata.servlet.handler.AbstractGdataRequestHandler#processRequest(javax.servlet.http.HttpServletRequest, 
+     *      javax.servlet.http.HttpServletResponse) 
+     */ 
+    @Override 
+    public void processRequest(HttpServletRequest request, 
+            HttpServletResponse response) throws IOException, ServletException { 
+        try { 
+            initializeRequestHandler(request, response, GDataRequestType.GET); 
+        } catch (GDataRequestException e) { 
+            sendError(); 
+            return; 
+        } 
+        Service service = getService(); 
+        try { 
+            if (LOG.isInfoEnabled()) 
+                LOG.info("Requested output formate: " 
+                        + this.feedRequest.getRequestedResponseFormat()); 
+            this.feedResponse.setOutputFormat(this.feedRequest 
+                    .getRequestedResponseFormat()); 
+            if(this.feedRequest.isFeedRequested()){ 
+            BaseFeed feed = service 
+                    .getFeed(this.feedRequest, this.feedResponse); 
+         
+            this.feedResponse.sendResponse(feed, this.feedRequest.getExtensionProfile()); 
+            }else{ 
+             BaseEntry entry = service.getSingleEntry(this.feedRequest,this.feedResponse); 
+             if(entry == null){ 
+                 this.feedResponse.setError(HttpServletResponse.SC_NOT_FOUND); 
+                 sendError(); 
+             } 
+             this.feedResponse.sendResponse(entry, this.feedRequest.getExtensionProfile()); 
+            } 
+             
+             
+        } catch (ServiceException e) { // TODO handle exceptions to send exact 
+            // response 
+            LOG.error("Could not process GetFeed request - " + e.getMessage(), 
+                    e); 
+            this.feedResponse.setError(HttpServletResponse.SC_BAD_REQUEST); // TODO 
+            // change 
+            // this 
+            sendError(); 
+        } 
+         
+         
+ 
+    } 
+     
+     
+ 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultInsertHandler.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultInsertHandler.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultInsertHandler.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultInsertHandler.java Wed Jun  7 14:56:25 2006
@@ -0,0 +1,83 @@
+/** 
+ * 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.GDataRequestException; 
+import org.apache.lucene.gdata.server.Service; 
+import org.apache.lucene.gdata.server.ServiceException; 
+import org.apache.lucene.gdata.server.GDataRequest.GDataRequestType; 
+ 
+import com.google.gdata.data.BaseEntry; 
+ 
+/** 
+ * Default Handler implementation. This handler processes the incoming 
+ * {@link org.apache.lucene.gdata.server.GDataRequest} and inserts the requested 
+ * feed entry into the storage and the search component. 
+ * <p> 
+ * The handler sends following response to the client: 
+ * </p> 
+ * <ol> 
+ * <li>if the entry was added - HTTP status code <i>200 OK</i></li> 
+ * <li>if an error occures - HTTP status code <i>500 INTERNAL SERVER ERROR</i></li> 
+ * <li>if the resource could not found - HTTP status code <i>404 NOT FOUND</i></li> 
+ * </ol> 
+ * <p>The added entry will be send back to the client if the insert request was successful.</p> 
+ *  
+ * @author Simon Willnauer 
+ * 
+ */ 
+public class DefaultInsertHandler extends AbstractGdataRequestHandler { 
+    private static final Log LOG = LogFactory.getLog(DefaultInsertHandler.class); 
+    /** 
+     * @throws ServletException  
+     * @see org.apache.lucene.gdata.servlet.handler.GDataRequestHandler#processRequest(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) 
+     */ 
+    @Override 
+    public void processRequest(HttpServletRequest request, 
+            HttpServletResponse response) throws IOException, ServletException { 
+        try { 
+            initializeRequestHandler(request,response,GDataRequestType.INSERT);             
+        } catch (GDataRequestException e) { 
+            sendError(); 
+            return; 
+        } 
+         
+        Service service = getService(); 
+        try{         
+        BaseEntry entry = service.createEntry(this.feedRequest,this.feedResponse); 
+        setFeedResponseFormat(); 
+        setFeedResponseStatus(HttpServletResponse.SC_CREATED);         
+        this.feedResponse.sendResponse(entry, this.feedRequest.getExtensionProfile()); 
+         
+        }catch (ServiceException e) { 
+           LOG.error("Could not process GetFeed request - "+e.getMessage(),e); 
+           setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 
+           this.feedResponse.sendError(); 
+        } 
+         
+         
+    } 
+ 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultRequestHandlerFactory.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultRequestHandlerFactory.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultRequestHandlerFactory.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultRequestHandlerFactory.java Wed Jun  7 14:56:25 2006
@@ -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 Builds the 
+ * {@link org.apache.lucene.gdata.servlet.handler.GDataRequestHandler} 
+ * instances. 
+ *  
+ * @author Simon Willnauer 
+ *  
+ */ 
+public class DefaultRequestHandlerFactory extends RequestHandlerFactory { 
+ 
+    DefaultRequestHandlerFactory() { 
+        // 
+    } 
+ 
+    /** 
+     * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getUpdateHandler() 
+     */ 
+    @Override 
+    public GDataRequestHandler getUpdateHandler() { 
+ 
+        return new DefaultUpdateHandler(); 
+    } 
+ 
+    /** 
+     * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getDeleteHandler() 
+     */ 
+    @Override 
+    public GDataRequestHandler getDeleteHandler() { 
+ 
+        return new DefaultDeleteHandler(); 
+    } 
+ 
+    /** 
+     * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getQueryHandler() 
+     */ 
+    @Override 
+    public GDataRequestHandler getQueryHandler() { 
+ 
+        return new DefaultGetHandler(); 
+    } 
+ 
+    /** 
+     * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getInsertHandler() 
+     */ 
+    @Override 
+    public GDataRequestHandler getInsertHandler() { 
+ 
+        return new DefaultInsertHandler(); 
+    } 
+ 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultUpdateHandler.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultUpdateHandler.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultUpdateHandler.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultUpdateHandler.java Wed Jun  7 14:56:25 2006
@@ -0,0 +1,94 @@
+/** 
+ * 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.FeedNotFoundException; 
+import org.apache.lucene.gdata.server.GDataRequestException; 
+import org.apache.lucene.gdata.server.Service; 
+import org.apache.lucene.gdata.server.ServiceException; 
+import org.apache.lucene.gdata.server.GDataRequest.GDataRequestType; 
+ 
+import com.google.gdata.data.BaseEntry; 
+ 
+/** 
+ * Default Handler implementation. This handler processes the incoming 
+ * {@link org.apache.lucene.gdata.server.GDataRequest} and updates the requested 
+ * feed entry in the storage and the search component. 
+ * <p> 
+ * The handler sends following response to the client: 
+ * </p> 
+ * <ol> 
+ * <li>if the entry was successfully updated - HTTP status code <i>200 OK</i></li> 
+ * <li>if an error occures - HTTP status code <i>500 INTERNAL SERVER ERROR</i></li> 
+ * <li>if the resource could not found - HTTP status code <i>404 NOT FOUND</i></li> 
+ * </ol> 
+ *  
+ * @author Simon Willnauer 
+ *  
+ */ 
+public class DefaultUpdateHandler extends AbstractGdataRequestHandler { 
+    private static final Log LOG = LogFactory 
+            .getLog(DefaultUpdateHandler.class); 
+ 
+    /** 
+     * @throws ServletException  
+     * @see org.apache.lucene.gdata.servlet.handler.AbstractGdataRequestHandler#processRequest(javax.servlet.http.HttpServletRequest, 
+     *      javax.servlet.http.HttpServletResponse) 
+     */ 
+    @Override 
+    public void processRequest(HttpServletRequest request, 
+            HttpServletResponse response) throws  IOException, ServletException { 
+        try { 
+            initializeRequestHandler(request, response,GDataRequestType.UPDATE); 
+        } catch (GDataRequestException e) { 
+            sendError(); 
+            return; 
+        } 
+         
+        Service service = getService(); 
+        try { 
+            BaseEntry entry = service.updateEntry(this.feedRequest, 
+                    this.feedResponse); 
+            setFeedResponseFormat(); 
+            setFeedResponseStatus(HttpServletResponse.SC_OK); 
+            this.feedResponse.sendResponse(entry, this.feedRequest.getExtensionProfile()); 
+        }catch (FeedNotFoundException e) { 
+            LOG.error("Could not process UpdateFeed request - " 
+                    + e.getMessage(), e); 
+            setError(HttpServletResponse.SC_NOT_FOUND); 
+             
+            sendError(); 
+        } 
+        catch (ServiceException e) { 
+             
+            LOG.error("Could not process UpdateFeed request - " 
+                    + e.getMessage(), e); 
+            setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); 
+             
+            sendError(); 
+        } 
+ 
+    } 
+ 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandler.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandler.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandler.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandler.java Wed Jun  7 14:56:25 2006
@@ -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 <i>doXXX</i> 
+ * 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; 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandlerException.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandlerException.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandlerException.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandlerException.java Wed Jun  7 14:56:25 2006
@@ -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); 
+        
+    } 
+ 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/RequestHandlerFactory.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/RequestHandlerFactory.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/RequestHandlerFactory.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/RequestHandlerFactory.java Wed Jun  7 14:56:25 2006
@@ -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); 
+ 
+        } 
+ 
+    } 
+ 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/package.html
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/package.html?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/package.html (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/package.html Wed Jun  7 14:56:25 2006
@@ -0,0 +1,10 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> 
+<html> 
+<head> 
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> 
+   <meta name="Author" content="Simon Willnauer"> 
+</head> 
+<body> 
+GData Request Handler. 
+</body> 
+</html> 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/package.html
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/package.html?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/package.html (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/package.html Wed Jun  7 14:56:25 2006
@@ -0,0 +1,10 @@
+<!doctype html public "-//w3c//dtd html 4.0 transitional//en"> 
+<html> 
+<head> 
+   <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1"> 
+   <meta name="Author" content="Simon Willnauer"> 
+</head> 
+<body> 
+Servlets acting as basic interfaces for gdata requests. 
+</body> 
+</html> 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/IDGenerator.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/IDGenerator.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/IDGenerator.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/IDGenerator.java Wed Jun  7 14:56:25 2006
@@ -0,0 +1,171 @@
+/** 
+ * 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.storage; 
+ 
+import java.security.MessageDigest; 
+import java.security.NoSuchAlgorithmException; 
+import java.security.SecureRandom; 
+import java.util.concurrent.ArrayBlockingQueue; 
+import java.util.concurrent.BlockingQueue; 
+ 
+import org.apache.commons.logging.Log; 
+import org.apache.commons.logging.LogFactory; 
+ 
+/** 
+ * This is the main entry ID generator to generate unique ids for each entry. 
+ * The Generator uses {@link java.security.SecureRandom} Numbers and the 
+ * {@link java.lang.System#currentTimeMillis()} to create a semi-unique sting; 
+ * The string will be digested by a {@link java.security.MessageDigest} which 
+ * returns a byte array. The generator encodes the byte array as a hex string. 
+ * <p> 
+ * The generated Id's will cached in a 
+ * {@link java.util.concurrent.BlockingQueue} and reproduced if an id has been 
+ * removed. 
+ * </p> 
+ *  
+ * @author Simon Willnauer 
+ *  
+ */ 
+public class IDGenerator { 
+    private final SecureRandom secureRandom; 
+ 
+    private final MessageDigest mdigest; 
+ 
+    private final BlockingQueue<String> blockingQueue; 
+ 
+    private Thread runner; 
+ 
+    private static final int DEFAULT_CAPACITY = 10; 
+ 
+    protected static final Log LOGGER = LogFactory.getLog(IDGenerator.class); 
+ 
+    /** 
+     * Constructs a new ID generator. with a fixed capacity of prebuild ids. The 
+     * default capacity is 10. Every given parameter less than 10 will be 
+     * ignored. 
+     *  
+     * @param capacity - 
+     *            capacity of the prebuild id queue 
+     * @throws NoSuchAlgorithmException - 
+     *             if the algorithm does not exist 
+     */ 
+    public IDGenerator(int capacity) throws NoSuchAlgorithmException { 
+ 
+        this.secureRandom = SecureRandom.getInstance("SHA1PRNG"); 
+        this.mdigest = MessageDigest.getInstance("SHA-1"); 
+        this.blockingQueue = new ArrayBlockingQueue<String>( 
+                (capacity < DEFAULT_CAPACITY ? DEFAULT_CAPACITY : capacity), 
+                false); 
+        startIDProducer(); 
+ 
+    } 
+ 
+    /** 
+     * This method takes a gnerated id from the IDProducer queue and retruns it. 
+     * If no ID is available this method will wait until an ID is produced. This 
+     * implementation is thread-safe. 
+     *  
+     * @return a UID 
+     * @throws InterruptedException - 
+     *             if interrupted while waiting 
+     */ 
+    public String getUID() throws InterruptedException { 
+        return this.blockingQueue.take(); 
+    } 
+ 
+    private void startIDProducer() { 
+        if (this.runner == null) { 
+            UIDProducer producer = new UIDProducer(this.blockingQueue, 
+                    this.secureRandom, this.mdigest); 
+            this.runner = new Thread(producer); 
+            this.runner.start(); 
+        } 
+    } 
+ 
+    /** 
+     * @return the current size of the queue 
+     */ 
+    public int getQueueSize() { 
+        return this.blockingQueue.size(); 
+    } 
+ 
+    /** 
+     * Stops the id-producer 
+     */ 
+    public void stopIDGenerator() { 
+        this.runner.interrupt(); 
+    } 
+ 
+    private class UIDProducer implements Runnable { 
+        SecureRandom random; 
+ 
+        BlockingQueue<String> queue; 
+ 
+        MessageDigest digest; 
+ 
+        UIDProducer(BlockingQueue<String> queue, SecureRandom random, 
+                MessageDigest digest) { 
+            this.queue = queue; 
+            this.random = random; 
+            this.digest = digest; 
+ 
+        } 
+ 
+        /** 
+         * @see java.lang.Runnable#run() 
+         */ 
+        public void run() { 
+ 
+            while (true) { 
+                try { 
+                    this.queue.put(produce()); 
+                } catch (InterruptedException e) { 
+                    LOGGER 
+                            .warn("UIDProducer has been interrupted -- runner is going down"); 
+                    return; 
+                } 
+            } 
+ 
+        } 
+ 
+        private String produce() { 
+            String randomNumber = new Integer(this.random.nextInt()).toString(); 
+            byte[] byteResult = this.digest.digest(randomNumber.getBytes()); 
+            return hexEncode(byteResult); 
+        } 
+ 
+    } 
+ 
+    /** 
+     * Encodes a given byte array into a hex string. 
+     *  
+     * @param input - 
+     *            the byte array to encode 
+     * @return hex string representation of the given byte array 
+     */ 
+    static String hexEncode(byte[] input) { 
+        StringBuffer result = new StringBuffer(); 
+        char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 
+                'a', 'b', 'c', 'd', 'e', 'f' }; 
+        for (int idx = 0; idx < input.length; ++idx) { 
+            byte b = input[idx]; 
+            result.append(digits[(b & 0xf0) >> 4]); 
+            result.append(digits[b & 0x0f]); 
+        } 
+        return result.toString(); 
+    } 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/Storage.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/Storage.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/Storage.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/Storage.java Wed Jun  7 14:56:25 2006
@@ -0,0 +1,100 @@
+/** 
+ * 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.storage; 
+ 
+import java.util.List; 
+ 
+import com.google.gdata.data.BaseEntry; 
+import com.google.gdata.data.BaseFeed; 
+import com.google.gdata.data.ExtensionProfile; 
+ 
+/** 
+ * This is the main storage interface. The Storage represents the internal 
+ * server storage. It acts as a Database to persist the feed data. 
+ * This inferface is not public yet!! 
+ *  
+ * @author Simon Willnauer 
+ *  
+ */ 
+public interface Storage { 
+ 
+    /** 
+     * This stores an incoming entry for a later retrival. 
+     * The Entry will be associated with the feedid. 
+     * @param entry - the entry 
+     * @param feedId - the feedID 
+     * @return - the stored Entry 
+     * @throws StorageException 
+     */ 
+    public abstract BaseEntry storeEntry(BaseEntry entry, String feedId) 
+            throws StorageException; 
+ 
+    /** 
+     * @param entryId 
+     * @param feedId 
+     * @throws StorageException 
+     */ 
+    public abstract void deleteEntry(String entryId, String feedId) 
+            throws StorageException; 
+ 
+    /** 
+     * @param entry 
+     * @param feedId 
+     * @return  
+     * @throws StorageException 
+     */ 
+    public abstract BaseEntry updateEntry(BaseEntry entry, String feedId) 
+            throws StorageException; 
+ 
+    /** 
+     * @param feedId 
+     * @param startIndex 
+     * @param resultCount 
+     * @return 
+     * @throws StorageException 
+     */ 
+    public abstract BaseFeed getFeed(String feedId, int startIndex, 
+            int resultCount) throws StorageException; 
+ 
+    /** 
+     * @param entryId 
+     * @param feedId 
+     * @return 
+     * @throws StorageException 
+     */ 
+    public abstract BaseEntry getEntry(String entryId, String feedId) 
+            throws StorageException; 
+ 
+    /** 
+     * @param entryIdList 
+     * @param feedId 
+     * @return 
+     * @throws StorageException 
+     */ 
+    public abstract List<BaseEntry> getEntries(List<String> entryIdList, 
+            String feedId) throws StorageException; 
+ 
+    /** 
+     * @param profile 
+     */ 
+    public abstract void setExtensionProfile(final ExtensionProfile profile); 
+ 
+    /** 
+     * close this storage instance 
+     */ 
+    public abstract void close(); 
+ 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageController.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageController.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageController.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageController.java Wed Jun  7 14:56:25 2006
@@ -0,0 +1,27 @@
+/** 
+ * 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.storage; 
+ 
+/** 
+ * @author Simon Willnauer 
+ * 
+ */ 
+public interface StorageController { 
+/** 
+ * Destroys the controller 
+ */ 
+public abstract void destroy(); 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageException.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageException.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageException.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageException.java Wed Jun  7 14:56:25 2006
@@ -0,0 +1,76 @@
+/** 
+ * 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.storage; 
+ 
+/** 
+ * The StorageException will be throw if any error or exception inside the 
+ * storage implementation occures. This exception hides all other exceptions 
+ * from inside the storage. 
+ *  
+ * @author Simon Willnauer 
+ *  
+ */ 
+public class StorageException extends Exception { 
+ 
+    /** 
+     *  
+     */ 
+    private static final long serialVersionUID = -4997572416934126511L; 
+ 
+    /** 
+     * Constructs a new StorageException 
+     */ 
+    public StorageException() { 
+        super(); 
+ 
+    } 
+ 
+    /** 
+     * Constructs a new StorageException 
+     *  
+     * @param message - 
+     *            the exception message 
+     */ 
+    public StorageException(String message) { 
+        super(message); 
+ 
+    } 
+ 
+    /** 
+     * Constructs a new StorageException 
+     *  
+     * @param message - 
+     *            the exception message 
+     * @param cause - 
+     *            the root cause of this exception 
+     */ 
+    public StorageException(String message, Throwable cause) { 
+        super(message, cause); 
+ 
+    } 
+ 
+    /** 
+     * Constructs a new StorageException 
+     *  
+     * @param cause - 
+     *            the root cause of this exception 
+     */ 
+    public StorageException(Throwable cause) { 
+        super(cause); 
+ 
+    } 
+ 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageFactory.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageFactory.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageFactory.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageFactory.java Wed Jun  7 14:56:25 2006
@@ -0,0 +1,44 @@
+/** 
+ * 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.storage; 
+ 
+import java.io.IOException; 
+ 
+import org.apache.lucene.gdata.storage.lucenestorage.StorageImplementation; 
+ 
+/** 
+ *TODO document me 
+ * @author Simon Willnauer 
+ * 
+ */ 
+public class StorageFactory { 
+    /** 
+     * Creates a {@link Storage} instance 
+     * @return - a storage instance 
+     * @throws StorageException  - if the storage can not be created 
+     */ 
+    public static Storage getStorage()throws StorageException{ 
+        try { 
+            return new StorageImplementation(); 
+        } catch (IOException e) { 
+            StorageException ex = new StorageException("Can't create Storage instance -- " 
+                    + e.getMessage(), e); 
+            ex.setStackTrace(e.getStackTrace()); 
+            throw ex;  
+             
+        }  
+    } 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/ModifiedEntryFilter.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/ModifiedEntryFilter.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/ModifiedEntryFilter.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/ModifiedEntryFilter.java Wed Jun  7 14:56:25 2006
@@ -0,0 +1,80 @@
+/** 
+ * 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.storage.lucenestorage; 
+ 
+import java.io.IOException; 
+import java.util.BitSet; 
+import java.util.List; 
+ 
+import org.apache.lucene.index.IndexReader; 
+import org.apache.lucene.index.Term; 
+import org.apache.lucene.index.TermDocs; 
+import org.apache.lucene.search.Filter; 
+ 
+/** 
+ * The {@link ModifiedEntryFilter} filters the given entryIds from the lucene 
+ * {@link org.apache.lucene.search.Hits} set. This filter is used to prevent the 
+ * storage from retrieving already deleted or updated entries still remainig in 
+ * the {@link org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer}. 
+ *  
+ * @see org.apache.lucene.search.Filter 
+ *  
+ * @author Simon Willnauer 
+ *  
+ */ 
+public class ModifiedEntryFilter extends Filter { 
+    /** 
+     * impl Serializable 
+     */ 
+    private static final long serialVersionUID = -1551686287704213591L; 
+ 
+    private final List<String> entyIds; 
+ 
+    /** 
+     * Creates a new {@link ModifiedEntryFilter} 
+     * @param entryIds the entry id's to filter  
+     *  
+     */ 
+    public ModifiedEntryFilter(List<String> entryIds) { 
+        super(); 
+        this.entyIds = entryIds; 
+    } 
+ 
+    /** 
+     * @see org.apache.lucene.search.Filter#bits(org.apache.lucene.index.IndexReader) 
+     */ 
+    @Override 
+    public BitSet bits(IndexReader reader) throws IOException { 
+        BitSet bitSet = new BitSet(reader.maxDoc()); 
+        bitSet.flip(0, reader.maxDoc()); // set all docs  
+        int[] docs = new int[1]; 
+        int[] freq = new int[1]; 
+        for (String id : this.entyIds) { 
+            if (id != null) { 
+                TermDocs termDocs = reader.termDocs(new Term( 
+                        StorageEntryWrapper.FIELD_ENTRY_ID, id)); 
+                int count = termDocs.read(docs, freq); 
+                if (count == 1) 
+                    bitSet.flip(docs[0]); 
+ 
+            } 
+        } 
+ 
+        return bitSet; 
+    } 
+ 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageBuffer.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageBuffer.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageBuffer.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageBuffer.java Wed Jun  7 14:56:25 2006
@@ -0,0 +1,249 @@
+/** 
+ * 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.storage.lucenestorage; 
+ 
+import java.util.ArrayList; 
+import java.util.Collection; 
+import java.util.Collections; 
+import java.util.HashMap; 
+import java.util.List; 
+import java.util.Map; 
+import java.util.concurrent.locks.Lock; 
+import java.util.concurrent.locks.ReadWriteLock; 
+import java.util.concurrent.locks.ReentrantReadWriteLock; 
+ 
+import org.apache.commons.logging.Log; 
+import org.apache.commons.logging.LogFactory; 
+import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation; 
+ 
+/** 
+ * The StorageBuffer is used to buffer incoming updates, deletes and inserts to 
+ * the storage. The storage uses an lucene index to store the enries. As 
+ * modifying the index all the time an altering request comes in is not 
+ * efficent. The entries will be added to the buffer to be available for 
+ * incoming storage queries. If the loadfactor for the 
+ * {@link org.apache.lucene.gdata.storage.lucenestorage.StorageModifier} is 
+ * reached the modifier will perform a batch update on the index. Each entry 
+ * will be associated with a feed id inside a associative datastructure to 
+ * return a requested entry efficiently. 
+ * <p> 
+ * This implementation uses {@link java.util.concurrent.locks.ReadWriteLock}. 
+ * The read lock may be held simultaneously by multiple reader threads, so long 
+ * as there are no writers. The write lock is exclusive.</p> 
+ *  
+ * @see java.util.concurrent.locks.ReentrantReadWriteLock 
+ * @see org.apache.lucene.gdata.storage.lucenestorage.StorageModifier 
+ * @see org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController 
+ *  
+ * @author Simon Willnauer 
+ *  
+ */ 
+public class StorageBuffer { 
+    private static final Log LOG = LogFactory.getLog(StorageBuffer.class); 
+ 
+    private final Map<String, Map<String, StorageEntryWrapper>> bufferMap; 
+ 
+    private final List<String> excludeList; 
+ 
+    private final ReadWriteLock lock = new ReentrantReadWriteLock(true); 
+ 
+    private final Lock readLock = this.lock.readLock(); 
+ 
+    private final Lock writeLock = this.lock.writeLock(); 
+ 
+    private final static int DEFAULT_BUFFER_COUNT = 10; 
+ 
+    /** 
+     * Constructs a new StorageBuffer. 
+     * <p> 
+     * The expectedBufferCount sould be higher than the maximum of entries added 
+     * to the buffer, resizing the buffer is very efficient. For detailed 
+     * infomation {@link HashMap} as this is used inside the buffer 
+     * </p> 
+     *  
+     * @param expectedBufferCount - 
+     *            the expected size of the buffer 
+     *  
+     */ 
+    protected StorageBuffer(final int expectedBufferCount) { 
+        this.bufferMap = new HashMap<String, Map<String, StorageEntryWrapper>>( 
+                expectedBufferCount < DEFAULT_BUFFER_COUNT ? DEFAULT_BUFFER_COUNT 
+                        : expectedBufferCount); 
+        this.excludeList = new ArrayList<String>( 
+                expectedBufferCount < DEFAULT_BUFFER_COUNT ? DEFAULT_BUFFER_COUNT 
+                        : expectedBufferCount); 
+    } 
+ 
+    /** 
+     * Adds a {@link StorageEntryWrapper} to the buffer. If a wrapper 
+     * representing the same entry are already in the buffer the wrapper will be 
+     * replaced. 
+     *  
+     * @param wrapper - 
+     *            the wrapper to buffer 
+     */ 
+    public void addEntry(final StorageEntryWrapper wrapper) { 
+        this.writeLock.lock(); 
+        try { 
+            if (LOG.isInfoEnabled()) 
+                LOG.info(" Buffering wrapper - " + wrapper.getOperation() 
+                        + " ID: " + wrapper.getEntryId() + " FeedID: " 
+                        + wrapper.getFeedId()); 
+            if (wrapper.getOperation().equals(StorageOperation.DELETE)) 
+                return; 
+ 
+            String feedId = wrapper.getFeedId(); 
+            if (this.bufferMap.containsKey(feedId)) 
+                this.bufferMap.get(feedId).put(wrapper.getEntryId(), wrapper); 
+            else { 
+                Map<String, StorageEntryWrapper> newFeedMap = new HashMap<String, StorageEntryWrapper>( 
+                        20); 
+                newFeedMap.put(wrapper.getEntryId(), wrapper); 
+                this.bufferMap.put(feedId, newFeedMap); 
+            } 
+        } finally { 
+            /* 
+             * add all to exclude from searches doc will be available via the 
+             * buffer 
+             */ 
+            this.excludeList.add(wrapper.getEntryId()); 
+            this.writeLock.unlock(); 
+        } 
+    } 
+ 
+    /** 
+     * Returns all entries for the given feed id sorted by the update timestamp 
+     * desc. 
+     *  
+     * @param feedId - 
+     *            the feed id 
+     * @return a {@link List} of all {@link StorageEntryWrapper} object buffered 
+     *         in this buffer or an empty list if not entry has been buffered 
+     *         for the given feed 
+     */ 
+    public List<StorageEntryWrapper> getSortedEntries(String feedId) { 
+        this.readLock.lock(); 
+        try { 
+            if (!this.bufferMap.containsKey(feedId)) 
+                return null; 
+            Map<String, StorageEntryWrapper> tempMap = this.bufferMap 
+                    .get(feedId); 
+            if (tempMap == null) 
+                return null; 
+            Collection<StorageEntryWrapper> col = tempMap.values(); 
+            List<StorageEntryWrapper> returnList = new ArrayList<StorageEntryWrapper>( 
+                    col); 
+            Collections.sort(returnList); 
+            return returnList; 
+ 
+        } finally { 
+            this.readLock.unlock(); 
+        } 
+ 
+    } 
+ 
+    /** 
+     * Adds a deleted entry to the buffer. 
+     *  
+     * @param entryId - 
+     *            the deleted entry id 
+     * @param feedId - 
+     *            the feed of the entry 
+     */ 
+    public void addDeleted(final String entryId, final String feedId) { 
+        this.writeLock.lock(); 
+        try { 
+            this.excludeList.add(entryId); 
+            Map<String, StorageEntryWrapper> tempMap = this.bufferMap 
+                    .get(feedId); 
+            if (tempMap == null) 
+                return; 
+            tempMap.remove(entryId); 
+        } finally { 
+            this.writeLock.unlock(); 
+ 
+        } 
+ 
+    } 
+ 
+    /** 
+     * Returns an entry for the given entry id in the feed context spezified by 
+     * the feed id; 
+     *  
+     * @param entryId - 
+     *            the id of the entry to return 
+     * @param feedId - 
+     *            the feed containing the entry 
+     * @return - the entry or <code>null</code> if the corresponding entry is 
+     *         not in the buffer. 
+     */ 
+    public StorageEntryWrapper getEntry(final String entryId, 
+            final String feedId) { 
+        this.readLock.lock(); 
+        try { 
+ 
+            if (this.bufferMap.containsKey(feedId)) 
+                return this.bufferMap.get(feedId).get(entryId); 
+            return null; 
+ 
+        } finally { 
+            this.readLock.unlock(); 
+        } 
+    } 
+ 
+    /** 
+     * The buffer contains updated and delete entries. These entries are already 
+     * available in the lucene index but should not be found during search. 
+     *  
+     * <p> 
+     * this list contains all entries should not be found by the index searcher 
+     * </p> 
+     *  
+     * @see ModifiedEntryFilter 
+     * @return - a {@link List} of entries to be omitted from a lucene index 
+     *         search 
+     */ 
+    public List<String> getExculdList() { 
+        this.readLock.lock(); 
+        try { 
+            return this.excludeList; 
+        } finally { 
+            this.readLock.unlock(); 
+        } 
+    } 
+ 
+    // not synchronized 
+    private void clearBuffer() { 
+        this.bufferMap.clear(); 
+        this.excludeList.clear(); 
+ 
+    } 
+ 
+    /** 
+     * clears the buffer - 
+     */ 
+    public void close() { 
+        this.writeLock.lock(); 
+        try { 
+            clearBuffer(); 
+        } finally { 
+            this.writeLock.unlock(); 
+        } 
+ 
+    } 
+ 
+} 

Added: lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageCoreController.java
URL: http://svn.apache.org/viewvc/lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageCoreController.java?rev=412574&view=auto
==============================================================================
--- lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageCoreController.java (added)
+++ lucene/java/trunk/contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageCoreController.java Wed Jun  7 14:56:25 2006
@@ -0,0 +1,286 @@
+package org.apache.lucene.gdata.storage.lucenestorage; 
+ 
+import java.io.File; 
+import java.io.IOException; 
+ 
+import org.apache.commons.logging.Log; 
+import org.apache.commons.logging.LogFactory; 
+import org.apache.lucene.analysis.standard.StandardAnalyzer; 
+import org.apache.lucene.gdata.server.registry.GDataServerRegistry; 
+import org.apache.lucene.gdata.storage.IDGenerator; 
+import org.apache.lucene.gdata.storage.StorageController; 
+import org.apache.lucene.gdata.storage.StorageException; 
+import org.apache.lucene.gdata.storage.lucenestorage.configuration.StorageConfigurator; 
+import org.apache.lucene.gdata.storage.lucenestorage.util.ReferenceCounter; 
+import org.apache.lucene.index.IndexModifier; 
+import org.apache.lucene.search.IndexSearcher; 
+import org.apache.lucene.store.Directory; 
+import org.apache.lucene.store.FSDirectory; 
+ 
+/** 
+ * TODO document this 
+ * @author Simon Willnauer 
+ * 
+ */ 
+public class StorageCoreController implements StorageController{ 
+    protected static final Log LOG = LogFactory.getLog(StorageCoreController.class); 
+    private IndexSearcher searcher; 
+    private static StorageCoreController coreController; 
+    private final Directory storageDir; 
+    private final StorageModifier modifier; 
+    private ReferenceCounter<StorageQuery> storageQuery; 
+    private StorageBuffer currentBuffer; 
+    private Object storageControllerLock = new Object(); 
+    private static final int DEFAULT_STORAGE_BUFFER_SIZE = 10; 
+    private static final int DEFAULT_STORAGE_PERSIST_FACTOR = 10; 
+    private static final String STORAGELOG = ".lucenestorage"; 
+    private int storageBufferSize; 
+    private int storagePersistFactor; 
+    private StorageConfigurator configurator; 
+    private IDGenerator idGenerator; 
+    private int indexOptimizeInterval; 
+     
+   private StorageCoreController()throws IOException, StorageException{ 
+       this(null); 
+   } 
+    
+    
+    
+    
+    private StorageCoreController(final Directory dir) throws IOException, StorageException { 
+        synchronized (StorageCoreController.class) { 
+            try{ 
+                this.idGenerator = new IDGenerator(10); 
+            }catch (Exception e) { 
+                throw new StorageException("Can't create ID Generator",e); 
+            } 
+             
+            boolean createNewStorage = false; 
+             
+            if(dir == null){ 
+            this.configurator = StorageConfigurator.getStorageConfigurator(); 
+            String storageDirPath = this.configurator.getStorageDirectory(); 
+            File storeDir = new File(storageDirPath); 
+            File storageLog = new File(storeDir.getAbsolutePath()+System.getProperty("file.separator")+STORAGELOG); 
+            try{ 
+            if(storeDir.isDirectory() && !storageLog.exists()){ 
+                 
+                if(createLuceneStorageLog(storeDir)){ 
+                    this.storageDir = FSDirectory.getDirectory(storeDir,true); 
+                    createNewStorage = true; 
+                } 
+                else 
+                    throw new StorageException("could not create storage log file in "+storageDirPath); 
+                 
+            }else 
+                this.storageDir = FSDirectory.getDirectory(storeDir,false); 
+            }catch (IOException e) { 
+                storageLog.delete(); 
+                throw e; 
+            } 
+            this.indexOptimizeInterval = this.configurator.getIndexOptimizeInterval(); 
+            this.storageBufferSize = this.configurator.getStorageBufferSize() < DEFAULT_STORAGE_BUFFER_SIZE?DEFAULT_STORAGE_BUFFER_SIZE:this.configurator.getStorageBufferSize(); 
+            this.storagePersistFactor = this.configurator.getStoragepersistFactor() < DEFAULT_STORAGE_PERSIST_FACTOR? DEFAULT_STORAGE_PERSIST_FACTOR:this.configurator.getStoragepersistFactor(); 
+             
+            } 
+            else 
+                this.storageDir = dir; 
+             
+            this.currentBuffer = new StorageBuffer(this.storageBufferSize); 
+            this.modifier = createStorageModifier(createNewStorage); 
+            this.searcher = new IndexSearcher(this.storageDir); 
+             
+ 
+            GDataServerRegistry.getRegistry().registerStorage(this);// TODO reverse dependency here 
+            
+                 
+             
+     } 
+         
+    } 
+    private StorageModifier createStorageModifier(boolean create) throws IOException{ 
+        IndexModifier indexModifier = new IndexModifier(this.storageDir,new StandardAnalyzer(),create); 
+        return new StorageModifier(indexModifier,this.currentBuffer,this.storagePersistFactor,this.indexOptimizeInterval); 
+    } 
+    /**TODO document this 
+     * @return 
+     */ 
+    public StorageModifier getStorageModifier(){ 
+        return this.modifier; 
+    } 
+     
+    /**TODO document this 
+     * @return 
+     * @throws IOException 
+     * @throws StorageException 
+     */ 
+    public static StorageCoreController getStorageCoreController() throws IOException, StorageException{ 
+        synchronized (StorageCoreController.class) { 
+            if(coreController == null) 
+            coreController = new StorageCoreController(); 
+            return coreController; 
+        } 
+    } 
+    /**TODO document this 
+     * @param dir 
+     * @return 
+     * @throws IOException 
+     * @throws StorageException 
+     */ 
+    protected static StorageCoreController getStorageCoreController(final Directory dir) throws IOException, StorageException{ 
+        synchronized (StorageCoreController.class) { 
+            if(coreController == null) 
+            coreController = new StorageCoreController(dir); 
+            return coreController; 
+        } 
+    } 
+ 
+    /**TODO document this 
+     * @return 
+     * @throws IOException 
+     */ 
+    public  ReferenceCounter<StorageQuery> getStorageQuery() throws IOException { 
+        synchronized (this.storageControllerLock) { 
+ 
+        if(this.storageQuery == null){ 
+            this.storageQuery = getNewStorageQueryHolder(new StorageQuery(this.currentBuffer,this.searcher)); 
+            if(LOG.isInfoEnabled()) 
+                LOG.info("Relese new StorageQuery"); 
+        } 
+        this.storageQuery.increamentReference(); 
+        return this.storageQuery; 
+        } 
+    } 
+     
+    private ReferenceCounter<StorageQuery> getNewStorageQueryHolder(final StorageQuery query){ 
+        ReferenceCounter<StorageQuery> holder = new ReferenceCounter<StorageQuery>(query){ 
+            public void close(){ 
+                try{ 
+                    if(LOG.isInfoEnabled()) 
+                        LOG.info("close StorageQuery -- zero references remaining"); 
+                    this.resource.close(); 
+                }catch (IOException e) { 
+                    LOG.warn("Error during close call on StorageQuery"+e.getMessage(),e); 
+                } 
+            } 
+        }; 
+        holder.increamentReference(); 
+        return holder; 
+    } 
+     
+   
+     
+    protected void registerNewStorageQuery() throws IOException{ 
+        if(LOG.isInfoEnabled()) 
+            LOG.info("new StorageQuery requested -- create new storage buffer"); 
+        synchronized (this.storageControllerLock) { 
+            if(this.storageQuery != null) 
+                this.storageQuery.decrementRef(); 
+            this.searcher = new IndexSearcher(this.storageDir); 
+            this.storageQuery = null; 
+            this.currentBuffer = new StorageBuffer(this.storageBufferSize); 
+             
+        } 
+         
+    } 
+ 
+     
+    protected StorageBuffer releaseNewStorageBuffer() { 
+        synchronized (this.storageControllerLock) { 
+            return this.currentBuffer; 
+        } 
+    } 
+ 
+    /**TODO document this 
+     * @return 
+     * @throws IOException 
+     */ 
+    public IndexModifier createIndexModifier() throws IOException { 
+        if(LOG.isInfoEnabled()) 
+            LOG.info("new IndexModifier created - release to StorageModifier"); 
+        synchronized (this.storageControllerLock) { 
+           return new IndexModifier(this.storageDir,new StandardAnalyzer(),false); 
+        } 
+    } 
+     
+    private void close() throws IOException{ 
+        synchronized (this.storageControllerLock) { 
+        if(LOG.isInfoEnabled()) 
+            LOG.info("StorageController has been closed -- server is shutting down -- release all resources"); 
+        if(this.storageQuery != null) 
+            this.storageQuery.decrementRef(); 
+        coreController = null; 
+        this.modifier.close(); 
+        //TODO make sure all resources will be released 
+        } 
+    } 
+    /**TODO document this 
+     * @return 
+     */ 
+    public int getStorageBufferSize() { 
+        return this.storageBufferSize; 
+    } 
+    /** 
+     * @param storageBufferSize 
+     */ 
+    public void setStorageBufferSize(int storageBufferSize) { 
+        this.storageBufferSize = storageBufferSize; 
+    } 
+    /**TODO document this 
+     * @return 
+     */ 
+    public int getStoragePersistFactor() { 
+        return this.storagePersistFactor; 
+    } 
+    /** 
+     * @param storagePersistFactor 
+     */ 
+    public void setStoragePersistFactor(int storagePersistFactor) { 
+        this.storagePersistFactor = storagePersistFactor; 
+    } 
+    /** 
+     * @throws IOException 
+     * @throws StorageException 
+     */ 
+    public void forceWrite()throws IOException, StorageException{ 
+        this.modifier.forceWrite(); 
+    } 
+     
+     
+    private boolean createLuceneStorageLog(File storageDirectory) throws IOException{ 
+        if(storageDirectory.isDirectory() && !storageDirectory.exists()){ 
+            storageDirectory.createNewFile(); 
+        } 
+        File file = new File(storageDirectory.getAbsolutePath()+System.getProperty("file.separator")+STORAGELOG); 
+        return file.createNewFile(); 
+         
+         
+    }    
+     
+    
+    /**TODO document this 
+     * @return 
+     * @throws StorageException 
+     */ 
+    public synchronized String releaseID() throws StorageException{ 
+        try{ 
+        return this.idGenerator.getUID(); 
+        }catch (InterruptedException e) { 
+            throw new StorageException("Can't release new ID",e); 
+        } 
+         
+    } 
+ 
+ 
+ 
+    /** 
+     * @see org.apache.lucene.gdata.storage.StorageController#destroy() 
+     */ 
+    public void destroy() { 
+        try{ 
+        close(); 
+        }catch (Exception e) { 
+            LOG.error("Closing StorageCoreController failed -- "+e.getMessage(),e); 
+        } 
+    } 
+}