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);
+ }
+ }
+}