Index: gdata-server/webroot/meta-inf/context.xml
===================================================================
--- gdata-server/webroot/meta-inf/context.xml (revision 0)
+++ gdata-server/webroot/meta-inf/context.xml (revision 0)
@@ -0,0 +1,12 @@
+
+
+
+
+
+
+
+
+
Property changes on: gdata-server/webroot/meta-inf/context.xml
___________________________________________________________________
Name: svn:executable
+ *
Index: gdata-server/webroot/WEB-INF/web.xml
===================================================================
--- gdata-server/webroot/WEB-INF/web.xml (revision 417093)
+++ gdata-server/webroot/WEB-INF/web.xml (working copy)
@@ -1,24 +1,57 @@
-
-
- Lucene GData - Server
-
- Server-side implementation of the GData protocol based on Apache
- - Lucene
-
-
- org.apache.lucene.gdata.server.registry.RegistryContextListener
-
-
- ControllerServlet
-
- org.apache.lucene.gdata.servlet.RequestControllerServlet
-
-
-
- ControllerServlet
- /*
-
-
\ No newline at end of file
+
+
+ Lucene GData - Server
+
+ Server-side implementation of the GData protocol based on Apache
+ - Lucene
+
+
+
+ org.apache.lucene.gdata.server.registry.RegistryContextListener
+
+
+
+ ControllerServlet
+
+ org.apache.lucene.gdata.servlet.RequestControllerServlet
+
+
+
+ ControllerServlet
+ /*
+
+
+ AuthenticationServlet
+
+ org.apache.lucene.gdata.servlet.AuthenticationServlet
+
+
+
+ AuthenticationServlet
+ /accounts/ClientLogin
+
+
+ FeedAdminServlet
+
+ org.apache.lucene.gdata.servlet.FeedAdministrationServlet
+
+
+
+ FeedAdminServlet
+ /admin/feed
+
+
+ AccountAdminServlet
+
+ org.apache.lucene.gdata.servlet.AccountAdministrationServlet
+
+
+
+ AccountAdminServlet
+ /admin/account
+
+
+
\ No newline at end of file
Index: gdata-server/webroot/WEB-INF/classes/gdata-config.xml
===================================================================
--- gdata-server/webroot/WEB-INF/classes/gdata-config.xml (revision 0)
+++ gdata-server/webroot/WEB-INF/classes/gdata-config.xml (revision 0)
@@ -0,0 +1,35 @@
+
+
+
+ com.google.gdata.data.Feed
+ com.google.gdata.data.Entry
+
+ com.google.gdata.data.ExtensionProfile
+
+
+
+
+ com.google.gdata.data.extensions.EventFeed
+
+
+ com.google.gdata.data.extensions.EventEntry
+
+
+ com.google.gdata.data.ExtensionProfile
+
+
+
+
+ org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController
+
+
+ org.apache.lucene.gdata.servlet.handler.DefaultRequestHandlerFactory
+
+
+ org.apache.lucene.gdata.server.ServiceFactory
+
+
+ org.apache.lucene.gdata.server.authentication.BlowfishAuthenticationController
+
+
+
\ No newline at end of file
Index: gdata-server/webroot/WEB-INF/classes/gdata-account.xsd
===================================================================
--- gdata-server/webroot/WEB-INF/classes/gdata-account.xsd (revision 0)
+++ gdata-server/webroot/WEB-INF/classes/gdata-account.xsd (revision 0)
@@ -0,0 +1,50 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
Index: gdata-server/lib/commons-collections-3.2.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: gdata-server/lib/commons-collections-3.2.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Index: gdata-server/lib/commons-beanutils.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: gdata-server/lib/commons-beanutils.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Index: gdata-server/lib/commons-digester-1.7.jar
===================================================================
Cannot display: file marked as a binary type.
svn:mime-type = application/octet-stream
Property changes on: gdata-server/lib/commons-digester-1.7.jar
___________________________________________________________________
Name: svn:mime-type
+ application/octet-stream
Index: gdata-server/src/test/gdata-config.xml
===================================================================
--- gdata-server/src/test/gdata-config.xml (revision 0)
+++ gdata-server/src/test/gdata-config.xml (revision 0)
@@ -0,0 +1,35 @@
+
+
+
+ com.google.gdata.data.Feed
+ com.google.gdata.data.Entry
+
+ com.google.gdata.data.ExtensionProfile
+
+
+
+
+ com.google.gdata.data.extensions.EventFeed
+
+
+ com.google.gdata.data.extensions.EventEntry
+
+
+ com.google.gdata.data.ExtensionProfile
+
+
+
+
+ org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController
+
+
+ org.apache.lucene.gdata.servlet.handler.DefaultRequestHandlerFactory
+
+
+ org.apache.lucene.gdata.server.ServiceFactory
+
+
+ org.apache.lucene.gdata.server.authentication.BlowfishAuthenticationController
+
+
+
\ No newline at end of file
Index: gdata-server/src/test/org/apache/lucene/gdata/utils/AuthenticationContorllerStub.java
===================================================================
--- gdata-server/src/test/org/apache/lucene/gdata/utils/AuthenticationContorllerStub.java (revision 0)
+++ gdata-server/src/test/org/apache/lucene/gdata/utils/AuthenticationContorllerStub.java (revision 0)
@@ -0,0 +1,70 @@
+/**
+ * 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.utils;
+
+import org.apache.lucene.gdata.data.GDataAccount;
+import org.apache.lucene.gdata.data.GDataAccount.AccountRole;
+import org.apache.lucene.gdata.server.authentication.AuthenticationController;
+import org.apache.lucene.gdata.server.registry.Component;
+import org.apache.lucene.gdata.server.registry.ComponentType;
+
+/**
+ * @author Simon Willnauer
+ *
+ */
+@Component(componentType=ComponentType.AUTHENTICATIONCONTROLLER)
+public class AuthenticationContorllerStub implements AuthenticationController {
+ public static AuthenticationController controller;
+ /**
+ *
+ */
+ public AuthenticationContorllerStub() {
+ super();
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.authentication.AuthenticationController#authenticatAccount(org.apache.lucene.gdata.data.GDataAccount, java.lang.String, java.lang.String)
+ */
+ public String authenticatAccount(GDataAccount account, String requestIp
+ ) {
+
+ return controller.authenticatAccount(account,requestIp);
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.authentication.AuthenticationController#authenticateToken(java.lang.String, java.lang.String, org.apache.lucene.gdata.data.GDataAccount.AccountRole, java.lang.String)
+ */
+ public boolean authenticateToken(String token, String requestIp,
+ AccountRole role, String serviceName) {
+
+ return controller.authenticateToken(token,requestIp,role,serviceName);
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.registry.ServerComponent#initialize()
+ */
+ public void initialize() {
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.registry.ServerComponent#destroy()
+ */
+ public void destroy() {
+ }
+
+}
Index: gdata-server/src/test/org/apache/lucene/gdata/utils/StorageStub.java
===================================================================
--- gdata-server/src/test/org/apache/lucene/gdata/utils/StorageStub.java (revision 0)
+++ gdata-server/src/test/org/apache/lucene/gdata/utils/StorageStub.java (revision 0)
@@ -0,0 +1,173 @@
+/**
+ * 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.utils;
+
+import java.util.Date;
+
+import org.apache.lucene.gdata.data.GDataAccount;
+import org.apache.lucene.gdata.data.ServerBaseEntry;
+import org.apache.lucene.gdata.data.ServerBaseFeed;
+import org.apache.lucene.gdata.server.registry.Component;
+import org.apache.lucene.gdata.server.registry.ComponentType;
+import org.apache.lucene.gdata.storage.Storage;
+import org.apache.lucene.gdata.storage.StorageController;
+import org.apache.lucene.gdata.storage.StorageException;
+
+import com.google.gdata.data.BaseEntry;
+import com.google.gdata.data.BaseFeed;
+
+/**
+ * @author Simon Willnauer
+ *
+ */
+@Component(componentType=ComponentType.STORAGECONTROLLER)
+public class StorageStub implements Storage, StorageController {
+public static String SERVICE_TYPE_RETURN = "service";
+ /**
+ *
+ */
+ public StorageStub() {
+ super();
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#storeEntry(org.apache.lucene.gdata.data.ServerBaseEntry)
+ */
+ public BaseEntry storeEntry(ServerBaseEntry entry)
+ throws StorageException {
+
+ return null;
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#deleteEntry(org.apache.lucene.gdata.data.ServerBaseEntry)
+ */
+ public void deleteEntry(ServerBaseEntry entry) throws StorageException {
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#updateEntry(org.apache.lucene.gdata.data.ServerBaseEntry)
+ */
+ public BaseEntry updateEntry(ServerBaseEntry entry)
+ throws StorageException {
+
+ return null;
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#getFeed(org.apache.lucene.gdata.data.ServerBaseFeed)
+ */
+ public BaseFeed getFeed(ServerBaseFeed feed) throws StorageException {
+
+ return null;
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#getEntry(org.apache.lucene.gdata.data.ServerBaseEntry)
+ */
+ public BaseEntry getEntry(ServerBaseEntry entry)
+ throws StorageException {
+
+ return null;
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#storeAccount(org.apache.lucene.gdata.data.GDataAccount)
+ */
+ public void storeAccount(GDataAccount Account) throws StorageException {
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#updateAccount(org.apache.lucene.gdata.data.GDataAccount)
+ */
+ public void updateAccount(GDataAccount Account) throws StorageException {
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#deleteAccount(java.lang.String)
+ */
+ public void deleteAccount(String Accountname) throws StorageException {
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#storeFeed(org.apache.lucene.gdata.data.ServerBaseFeed, java.lang.String)
+ */
+ public void storeFeed(ServerBaseFeed feed, String accountname)
+ throws StorageException {
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#deleteFeed(java.lang.String)
+ */
+ public void deleteFeed(String feedId) throws StorageException {
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#updateFeed(org.apache.lucene.gdata.data.ServerBaseFeed, java.lang.String)
+ */
+ public void updateFeed(ServerBaseFeed feed, String accountname)
+ throws StorageException {
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#close()
+ */
+ public void close() {
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#getServiceForFeed(java.lang.String)
+ */
+ public String getServiceForFeed(String feedId) throws StorageException {
+
+ return SERVICE_TYPE_RETURN;
+ }
+
+ public void destroy() {
+ }
+
+ public Storage getStorage() throws StorageException {
+
+ return new StorageStub();
+ }
+
+ public GDataAccount getAccount(String accountName) throws StorageException {
+
+ return null;
+ }
+
+ public String getAccountNameForFeedId(String feedId) throws StorageException {
+
+ return null;
+ }
+
+ public void initialize() {
+ }
+
+
+ public Long getFeedLastModified(String feedId) throws StorageException {
+
+ return null;
+ }
+
+ public Long getEntryLastModified(String entryId, String feedId) throws StorageException {
+
+ return null;
+ }
+
+}
Index: gdata-server/src/test/org/apache/lucene/gdata/utils/ServiceFactoryStub.java
===================================================================
--- gdata-server/src/test/org/apache/lucene/gdata/utils/ServiceFactoryStub.java (revision 0)
+++ gdata-server/src/test/org/apache/lucene/gdata/utils/ServiceFactoryStub.java (revision 0)
@@ -0,0 +1,60 @@
+/**
+ * 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.utils;
+
+import org.apache.lucene.gdata.server.Service;
+import org.apache.lucene.gdata.server.ServiceFactory;
+import org.apache.lucene.gdata.server.administration.AdminService;
+import org.apache.lucene.gdata.server.registry.Component;
+import org.apache.lucene.gdata.server.registry.ComponentType;
+
+/**
+ * @author Simon Willnauer
+ *
+ */
+@Component(componentType=ComponentType.SERVICEFACTORY)
+public class ServiceFactoryStub extends ServiceFactory {
+
+ public Service service;
+ public AdminService adminService;
+ /**
+ * @see org.apache.lucene.gdata.server.ServiceFactory#getAdminService()
+ */
+ @Override
+ public AdminService getAdminService() {
+
+ return adminService;
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.ServiceFactory#getService()
+ */
+ @Override
+ public Service getService() {
+
+ return service;
+ }
+
+ public void setAdminService(AdminService service) {
+ this.adminService = service;
+ }
+ public void setService(Service service) {
+ this.service = service;
+ }
+
+
+}
Index: gdata-server/src/test/org/apache/lucene/gdata/utils/ProvidedServiceStub.java
===================================================================
--- gdata-server/src/test/org/apache/lucene/gdata/utils/ProvidedServiceStub.java (revision 0)
+++ gdata-server/src/test/org/apache/lucene/gdata/utils/ProvidedServiceStub.java (revision 0)
@@ -0,0 +1,38 @@
+package org.apache.lucene.gdata.utils;
+
+import org.apache.lucene.gdata.server.registry.ProvidedService;
+
+import com.google.gdata.data.Entry;
+import com.google.gdata.data.ExtensionProfile;
+import com.google.gdata.data.Feed;
+
+public class ProvidedServiceStub implements ProvidedService {
+
+ public static final String SERVICE_NAME = "service";
+
+ public ProvidedServiceStub() {
+ super();
+ // TODO Auto-generated constructor stub
+ }
+
+ public Class getFeedType() {
+
+ return Feed.class;
+ }
+
+ public ExtensionProfile getExtensionProfile() {
+
+ return new ExtensionProfile();
+ }
+
+ public Class getEntryType() {
+
+ return Entry.class;
+ }
+
+ public String getName() {
+
+ return SERVICE_NAME;
+ }
+
+}
Index: gdata-server/src/test/org/apache/lucene/gdata/servlet/handler/TestRequestAuthenticator.java
===================================================================
--- gdata-server/src/test/org/apache/lucene/gdata/servlet/handler/TestRequestAuthenticator.java (revision 0)
+++ gdata-server/src/test/org/apache/lucene/gdata/servlet/handler/TestRequestAuthenticator.java (revision 0)
@@ -0,0 +1,79 @@
+package org.apache.lucene.gdata.servlet.handler;
+
+import javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+
+import junit.framework.TestCase;
+
+import org.apache.lucene.gdata.server.authentication.AuthenticationController;
+import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
+import org.easymock.MockControl;
+
+public class TestRequestAuthenticator extends TestCase {
+ private MockControl requestMock;
+ private HttpServletRequest request;
+ private RequestAuthenticator authenticator;
+ private String tokenHeader;
+ private String token;
+ private Cookie authCookie;
+
+ protected void setUp() throws Exception {
+ createMocks();
+ this.authenticator = new RequestAuthenticator();
+ this.token = "myToken";
+ this.tokenHeader = "GoogleLogin auth="+this.token;
+ this.authCookie = new Cookie("Auth",this.token);
+ }
+ protected void createMocks() {
+ this.requestMock = MockControl.createControl(HttpServletRequest.class);
+ this.request = (HttpServletRequest)this.requestMock.getMock();
+
+ }
+ protected void tearDown() throws Exception {
+ GDataServerRegistry.getRegistry().destroy();
+ }
+ /*
+ * Test method for 'org.apache.lucene.gdata.servlet.handler.RequestAuthenticator.authenticateAccount(GDataRequest, AccountRole)'
+ */
+ public void testGetTokenFromRequest() {
+ // test token present
+ this.requestMock.expectAndDefaultReturn(this.request.getHeader(AuthenticationController.AUTHORIZATION_HEADER), this.tokenHeader);
+ this.requestMock.replay();
+ assertEquals(this.token,this.authenticator.getTokenFromRequest(this.request));
+ this.requestMock.verify();
+ this.requestMock.reset();
+
+ // test token null / cookie present
+ this.requestMock.expectAndDefaultReturn(this.request.getHeader(AuthenticationController.AUTHORIZATION_HEADER), null);
+ this.requestMock.expectAndDefaultReturn(this.request.getCookies(), new Cookie[]{this.authCookie});
+ this.requestMock.replay();
+ assertEquals(this.token,this.authenticator.getTokenFromRequest(this.request));
+ this.requestMock.verify();
+ this.requestMock.reset();
+
+ // test token null / cookie not present
+ this.requestMock.expectAndDefaultReturn(this.request.getHeader(AuthenticationController.AUTHORIZATION_HEADER), null);
+ this.requestMock.expectAndDefaultReturn(this.request.getCookies(), new Cookie[]{new Cookie("somekey","someValue")});
+ this.requestMock.replay();
+ assertNull(this.authenticator.getTokenFromRequest(this.request));
+ this.requestMock.verify();
+ this.requestMock.reset();
+
+// test token null / cookie array emtpy
+ this.requestMock.expectAndDefaultReturn(this.request.getHeader(AuthenticationController.AUTHORIZATION_HEADER), null);
+ this.requestMock.expectAndDefaultReturn(this.request.getCookies(), new Cookie[]{});
+ this.requestMock.replay();
+ assertNull(this.authenticator.getTokenFromRequest(this.request));
+ this.requestMock.verify();
+ this.requestMock.reset();
+
+// test token null / cookie array null
+ this.requestMock.expectAndDefaultReturn(this.request.getHeader(AuthenticationController.AUTHORIZATION_HEADER), null);
+ this.requestMock.expectAndDefaultReturn(this.request.getCookies(), null);
+ this.requestMock.replay();
+ assertNull(this.authenticator.getTokenFromRequest(this.request));
+ this.requestMock.verify();
+ this.requestMock.reset();
+ }
+
+}
Index: gdata-server/src/test/org/apache/lucene/gdata/servlet/handler/TestAbstractFeedHandler.java
===================================================================
--- gdata-server/src/test/org/apache/lucene/gdata/servlet/handler/TestAbstractFeedHandler.java (revision 0)
+++ gdata-server/src/test/org/apache/lucene/gdata/servlet/handler/TestAbstractFeedHandler.java (revision 0)
@@ -0,0 +1,213 @@
+/**
+ * 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.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+
+import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletResponse;
+
+import junit.framework.TestCase;
+
+import org.apache.lucene.gdata.data.GDataAccount;
+import org.apache.lucene.gdata.data.ServerBaseFeed;
+import org.apache.lucene.gdata.server.ServiceException;
+import org.apache.lucene.gdata.server.ServiceFactory;
+import org.apache.lucene.gdata.server.administration.AdminService;
+import org.apache.lucene.gdata.server.registry.ComponentType;
+import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
+import org.apache.lucene.gdata.server.registry.RegistryException;
+import org.apache.lucene.gdata.servlet.handler.AbstractFeedHandler.FeedHandlerException;
+import org.apache.lucene.gdata.utils.ProvidedServiceStub;
+import org.apache.lucene.gdata.utils.ServiceFactoryStub;
+import org.apache.lucene.gdata.utils.StorageStub;
+import org.easymock.MockControl;
+
+import com.google.gdata.util.ParseException;
+
+/**
+ * @author Simon Willnauer
+ *
+ */
+public class TestAbstractFeedHandler extends TestCase {
+ private MockControl requestMockControl;
+
+ private HttpServletRequest mockRequest = null;
+
+ private String accountName = "acc";
+ private MockControl adminServiceMockControl;
+ private AdminService adminService = null;
+ private ServiceFactoryStub stub;
+ private String serviceName = StorageStub.SERVICE_TYPE_RETURN;
+ private static File incomingFeed = new File("src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingFeed.xml");
+ BufferedReader reader;
+ static{
+
+ try {
+
+ GDataServerRegistry.getRegistry().registerComponent(StorageStub.class);
+ GDataServerRegistry.getRegistry().registerComponent(ServiceFactoryStub.class);
+ } catch (RegistryException e) {
+
+ e.printStackTrace();
+ }
+ }
+ protected void setUp() throws Exception {
+ super.setUp();
+
+ GDataServerRegistry.getRegistry().registerService(new ProvidedServiceStub());
+ this.requestMockControl = MockControl.createControl(HttpServletRequest.class);
+ this.adminServiceMockControl = MockControl.createControl(AdminService.class);
+ this.adminService = (AdminService)this.adminServiceMockControl.getMock();
+ this.mockRequest = (HttpServletRequest)this.requestMockControl.getMock();
+ this.stub = (ServiceFactoryStub)GDataServerRegistry.getRegistry().lookup(ServiceFactory.class,ComponentType.SERVICEFACTORY);
+ this.stub.setAdminService(this.adminService);
+ this.reader = new BufferedReader(new FileReader(incomingFeed));
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ /*
+ * Test method for 'org.apache.lucene.gdata.servlet.handler.AbstractFeedHandler.createFeedFromRequest(HttpServletRequest)'
+ */
+ public void testCreateFeedFromRequest() throws ParseException, IOException, FeedHandlerException {
+
+ this.requestMockControl.expectAndDefaultReturn(this.mockRequest
+ .getParameter("service"), this.serviceName);
+ this.requestMockControl.expectAndReturn(this.mockRequest.getReader(),this.reader);
+ this.requestMockControl.replay();
+ AbstractFeedHandler handler = new InsertFeedHandler();
+ try{
+ ServerBaseFeed feed = handler.createFeedFromRequest(this.mockRequest);
+ assertNotNull(feed.getId());
+
+ }catch (Exception e) {
+ e.printStackTrace();
+ fail("unexpected exception -- "+e.getMessage());
+
+ }
+ this.requestMockControl.verify();
+ this.requestMockControl.reset();
+ /*
+ * Test for not registered service
+ */
+ this.requestMockControl.expectAndDefaultReturn(this.mockRequest
+ .getParameter("service"), "some other service");
+ this.requestMockControl.replay();
+ handler = new InsertFeedHandler();
+ try{
+ ServerBaseFeed feed = handler.createFeedFromRequest(this.mockRequest);
+
+ fail(" exception expected");
+ }catch (FeedHandlerException e) {
+ e.printStackTrace();
+ assertEquals(HttpServletResponse.SC_NOT_FOUND,handler.getErrorCode());
+ }
+ this.requestMockControl.verify();
+
+ this.requestMockControl.reset();
+ /*
+ * Test for IOException
+ */
+ this.requestMockControl.expectAndDefaultReturn(this.mockRequest
+ .getParameter("service"), this.serviceName);
+ this.reader.close();
+ this.requestMockControl.expectAndReturn(this.mockRequest.getReader(),this.reader);
+ this.requestMockControl.replay();
+ handler = new InsertFeedHandler();
+ try{
+ ServerBaseFeed feed = handler.createFeedFromRequest(this.mockRequest);
+
+ fail(" exception expected");
+ }catch (IOException e) {
+ e.printStackTrace();
+ assertEquals(HttpServletResponse.SC_BAD_REQUEST,handler.getErrorCode());
+ }
+ this.requestMockControl.verify();
+
+
+
+
+ }
+
+ /*
+ * Test method for 'org.apache.lucene.gdata.servlet.handler.AbstractFeedHandler.createRequestedAccount(HttpServletRequest)'
+ */
+ public void testCreateRequestedAccount() throws IOException, ParseException, ServiceException {
+ this.requestMockControl.expectAndDefaultReturn(this.mockRequest
+ .getParameter(AbstractFeedHandler.PARAMETER_ACCOUNT), this.accountName);
+ GDataAccount a = new GDataAccount();
+ a.setName("helloworld");
+ this.adminServiceMockControl.expectAndReturn(this.adminService.getAccount(this.accountName),a );
+ this.requestMockControl.replay();
+ this.adminServiceMockControl.replay();
+ AbstractFeedHandler handler = new InsertFeedHandler();
+ try{
+
+ GDataAccount account = handler.createRequestedAccount(this.mockRequest);
+
+ assertEquals(a,account);
+
+ }catch (Exception e) {
+ e.printStackTrace();
+ fail("unexpected exception -- "+e.getMessage());
+
+ }
+ this.requestMockControl.verify();
+ this.requestMockControl.reset();
+ this.adminServiceMockControl.verify();
+ this.adminServiceMockControl.reset();
+
+ /*
+ *Test for service exception
+ */
+
+ this.requestMockControl.expectAndDefaultReturn(this.mockRequest
+ .getParameter(AbstractFeedHandler.PARAMETER_ACCOUNT), this.accountName);
+
+ a.setName("helloworld");
+ this.adminServiceMockControl.expectAndDefaultThrow(this.adminService.getAccount(this.accountName),new ServiceException() );
+ this.requestMockControl.replay();
+ this.adminServiceMockControl.replay();
+ handler = new InsertFeedHandler();
+ try{
+
+ GDataAccount account = handler.createRequestedAccount(this.mockRequest);
+
+ fail(" exception expected ");
+
+ }catch (Exception e) {
+ e.printStackTrace();
+ assertEquals(HttpServletResponse.SC_BAD_REQUEST,handler.getErrorCode());
+
+ }
+ this.requestMockControl.verify();
+ this.requestMockControl.reset();
+ this.adminServiceMockControl.verify();
+ this.adminServiceMockControl.reset();
+
+
+
+
+
+ }
+
+}
Index: gdata-server/src/test/org/apache/lucene/gdata/storage/lucenestorage/TestStorageModifier.java
===================================================================
--- gdata-server/src/test/org/apache/lucene/gdata/storage/lucenestorage/TestStorageModifier.java (revision 417093)
+++ gdata-server/src/test/org/apache/lucene/gdata/storage/lucenestorage/TestStorageModifier.java (working copy)
@@ -1,247 +1,387 @@
-package org.apache.lucene.gdata.storage.lucenestorage;
-
-import java.io.IOException;
-import java.util.Date;
-
-import junit.framework.TestCase;
-
-import org.apache.lucene.analysis.standard.StandardAnalyzer;
-import org.apache.lucene.gdata.server.FeedNotFoundException;
-import org.apache.lucene.gdata.server.registry.FeedInstanceConfigurator;
-import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
-import org.apache.lucene.gdata.server.registry.RegistryBuilder;
-import org.apache.lucene.gdata.storage.StorageException;
-import org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController;
-import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper;
-import org.apache.lucene.gdata.storage.lucenestorage.StorageModifier;
-import org.apache.lucene.gdata.storage.lucenestorage.StorageQuery;
-import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation;
-import org.apache.lucene.gdata.storage.lucenestorage.util.ReferenceCounter;
-import org.apache.lucene.index.IndexWriter;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.search.Hits;
-import org.apache.lucene.search.IndexSearcher;
-import org.apache.lucene.search.Query;
-import org.apache.lucene.search.TermQuery;
-import org.apache.lucene.store.Directory;
-import org.apache.lucene.store.RAMDirectory;
-
-import com.google.gdata.data.BaseEntry;
-import com.google.gdata.data.DateTime;
-import com.google.gdata.data.Entry;
-import com.google.gdata.data.ExtensionProfile;
-import com.google.gdata.data.Feed;
-import com.google.gdata.data.PlainTextConstruct;
-import com.google.gdata.data.TextConstruct;
-import com.google.gdata.data.TextContent;
-import com.google.gdata.util.ParseException;
-
-public class TestStorageModifier extends TestCase {
- private StorageModifier modifier;
- private int count = 1;
-
- private ExtensionProfile profile;
- private Directory dir;
-
-
- private static String feedId = "myFeed";
-
- protected void setUp() throws Exception {
- FeedInstanceConfigurator configurator = new FeedInstanceConfigurator();
- configurator.setFeedType(Feed.class);
- configurator.setFeedId(feedId);
- configurator.setExtensionProfileClass(ExtensionProfile.class);
- GDataServerRegistry.getRegistry().registerFeed(configurator);
- dir = new RAMDirectory();
- this.profile = new ExtensionProfile();
- IndexWriter writer;
-
- writer = new IndexWriter(dir,new StandardAnalyzer(),true);
- writer.close();
- modifier = StorageCoreController.getStorageCoreController(dir).getStorageModifier();
-
+package org.apache.lucene.gdata.storage.lucenestorage;
+
+import java.io.IOException;
+
+import junit.framework.TestCase;
+
+import org.apache.lucene.gdata.data.GDataAccount;
+import org.apache.lucene.gdata.data.ServerBaseEntry;
+import org.apache.lucene.gdata.data.ServerBaseFeed;
+import org.apache.lucene.gdata.server.registry.ComponentType;
+import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
+import org.apache.lucene.gdata.server.registry.ProvidedService;
+import org.apache.lucene.gdata.storage.StorageController;
+import org.apache.lucene.gdata.storage.StorageException;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation;
+import org.apache.lucene.gdata.storage.lucenestorage.util.ReferenceCounter;
+import org.apache.lucene.gdata.utils.ProvidedServiceStub;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.Hits;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.search.Query;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.store.Directory;
+
+import com.google.gdata.data.BaseEntry;
+import com.google.gdata.data.DateTime;
+import com.google.gdata.data.Entry;
+import com.google.gdata.data.PlainTextConstruct;
+import com.google.gdata.data.TextContent;
+import com.google.gdata.util.ParseException;
+
+public class TestStorageModifier extends TestCase {
+ private StorageModifier modifier;
+
+ private int count = 1;
+
+ private ProvidedService configurator;
+
+ private Directory dir;
+
+ private StorageCoreController controller;
+
+ private static String feedId = "myFeed";
+
+ private static String username = "simon";
+
+ private static String password = "test";
+ private static String service = "myService";
+
+ protected void setUp() throws Exception {
+ GDataServerRegistry.getRegistry().registerComponent(
+ StorageCoreController.class);
+ this.configurator = new ProvidedServiceStub();
+ GDataServerRegistry.getRegistry().registerService(this.configurator);
+ this.controller = (StorageCoreController) GDataServerRegistry
+ .getRegistry().lookup(StorageController.class,
+ ComponentType.STORAGECONTROLLER);
+ this.modifier = this.controller.getStorageModifier();
+ this.dir = this.controller.getDirectory();
+
+ }
+
+ protected void tearDown() throws Exception {
+ this.count = 1;
+ // destroy all resources
+ GDataServerRegistry.getRegistry().destroy();// TODO remove dependency
+ // here
+
+ }
+
+ /*
+ * Test method for
+ * 'org.apache.lucene.storage.lucenestorage.StorageModifier.updateEntry(StroageEntryWrapper)'
+ */
+ public void testUpdateEntry() throws IOException, InterruptedException,
+ ParseException, StorageException {
+ testInsertEntry();
+ for (int i = 1; i < this.count; i++) {
+ Entry e = new Entry();
+ e.setId("" + i);
+ String insertString = "Hello world" + i;
+ e.setTitle(new PlainTextConstruct(insertString));
+ ServerBaseEntry en = getServerEntry(e);
+ StorageEntryWrapper wrapper = new StorageEntryWrapper(en,
+ StorageOperation.UPDATE);
+ this.modifier.updateEntry(wrapper);
+ ReferenceCounter innerQuery = this.controller
+ .getStorageQuery();
+ BaseEntry fetchedEntry = innerQuery.get().singleEntryQuery("" + i,
+ feedId, this.configurator);
+ assertEquals("updated Title:", insertString, fetchedEntry
+ .getTitle().getPlainText());
+ }
+ // double updates
+ for (int i = 1; i < this.count; i++) {
+ Entry e = new Entry();
+ e.setId("" + i);
+ String insertString = "Hello world" + i;
+ e.setTitle(new PlainTextConstruct(insertString));
+ ServerBaseEntry en = getServerEntry(e);
+ StorageEntryWrapper wrapper = new StorageEntryWrapper(en,
+ StorageOperation.UPDATE);
+ this.modifier.updateEntry(wrapper);
+
+ e = new Entry();
+ e.setId("" + i);
+ insertString = "Foo Bar" + i;
+ e.setTitle(new PlainTextConstruct(insertString));
+ en = getServerEntry(e);
+ wrapper = new StorageEntryWrapper(en,
+ StorageOperation.UPDATE);
+ this.modifier.updateEntry(wrapper);
+
+ ReferenceCounter innerQuery = this.controller
+ .getStorageQuery();
+
+ BaseEntry fetchedEntry = innerQuery.get().singleEntryQuery("" + i,
+ feedId, this.configurator);
+ assertEquals("updated Title:", insertString, fetchedEntry
+ .getTitle().getPlainText());
+ }
+
+ }
+
+ /*
+ * Test method for
+ * 'org.apache.lucene.storage.lucenestorage.StorageModifier.insertEntry(StroageEntryWrapper)'
+ */
+ public void testInsertEntry() throws IOException, InterruptedException,
+ ParseException, StorageException {
+
+ Thread a = getRunnerThread(this.count);
+ a.start();
+
+ Thread b = getRunnerThread((this.count += 10));
+ b.start();
+ a.join();
+ for (int i = 1; i < this.count; i++) {
+ ReferenceCounter innerQuery = this.controller
+ .getStorageQuery();
+ BaseEntry e = innerQuery.get().singleEntryQuery("" + i, feedId,
+ this.configurator);
+ assertEquals("get entry for id" + i, "" + i, e.getId());
+
+ }
+ b.join();
+ ReferenceCounter query = this.controller
+ .getStorageQuery();
+
+ this.count += 10;
+ for (int i = 1; i < this.count; i++) {
+ BaseEntry e = query.get().singleEntryQuery("" + i, feedId,
+ this.configurator);
+ assertEquals("get entry for id" + i, "" + i, e.getId());
+ }
+
+ BaseEntry e = query.get().singleEntryQuery("" + this.count, feedId,
+ this.configurator);
+ assertNull("not entry for ID", e);
+ query.decrementRef();
+
+ }
+
+ /*
+ * Test method for
+ * 'org.apache.lucene.storage.lucenestorage.StorageModifier.deleteEntry(String)'
+ */
+ public void testDeleteEntry() throws IOException, InterruptedException,
+ ParseException, StorageException {
+ testInsertEntry();
+ for (int i = 1; i < this.count; i++) {
+ if (i % 2 == 0 || i < 10) {
+ ServerBaseEntry entry = new ServerBaseEntry();
+ entry.setId("" + i);
+ entry.setFeedId(feedId);
+ this.modifier.deleteEntry(new StorageEntryWrapper(entry,StorageOperation.DELETE));
+ }
+ ReferenceCounter query = this.controller
+ .getStorageQuery();
+ if (i % 2 == 0 || i < 10) {
+ assertNull(query.get().singleEntryQuery("" + i, feedId,
+ this.configurator));
+ } else
+ assertEquals("" + i, query.get().singleEntryQuery("" + i,
+ feedId, this.configurator).getId());
+ query.decrementRef();
+ }
+
+ this.controller.forceWrite();
+ IndexSearcher searcher = new IndexSearcher(this.dir);
+
+ for (int i = 1; i < this.count; i++) {
+ Query luceneQuery = new TermQuery(new Term(
+ StorageEntryWrapper.FIELD_ENTRY_ID, "" + i));
+ Hits hits = searcher.search(luceneQuery);
+ if (i % 2 == 0 || i < 10) {
+
+ assertEquals(0, hits.length());
+ } else
+ assertEquals(1, hits.length());
+ }
+ searcher.close();
+
+ }
+
+ public void testSaveUser() throws StorageException, IOException {
+
+ GDataAccount user = new GDataAccount();
+ user.setName(username);
+ user.setPassword(password);
+ StorageAccountWrapper wrapper = new StorageAccountWrapper(user);
+ this.modifier.createAccount(wrapper);
+ IndexSearcher searcher = new IndexSearcher(this.dir);
+ Query q = new TermQuery(new Term(StorageAccountWrapper.FIELD_ACCOUNTNAME,
+ username));
+ Hits h = searcher.search(q);
+ assertEquals("length == 1", 1, h.length());
+ GDataAccount storedUser = StorageAccountWrapper.buildEntity(h.doc(0));
+ assertTrue(storedUser.equals(user));
+ searcher.close();
+ }
+
+ public void testDeleteUser() throws StorageException, IOException {
+ testSaveUser();
+ this.modifier.deleteAccount(username);
+ IndexSearcher searcher = new IndexSearcher(this.dir);
+ Query q = new TermQuery(new Term(StorageAccountWrapper.FIELD_ACCOUNTNAME,
+ username));
+ Hits h = searcher.search(q);
+ assertEquals("length == 0", 0, h.length());
+ searcher.close();
+ }
+
+ public void testUpdateUser() throws StorageException, IOException {
+ testSaveUser();
+ GDataAccount user = new GDataAccount();
+ user.setName(username);
+ user.setPassword("newPass");
+ StorageAccountWrapper wrapper = new StorageAccountWrapper(user);
+ this.modifier.updateAccount(wrapper);
+ IndexSearcher searcher = new IndexSearcher(this.dir);
+ Query q = new TermQuery(new Term(StorageAccountWrapper.FIELD_ACCOUNTNAME,
+ username));
+ Hits h = searcher.search(q);
+ assertEquals("length == 1", 1, h.length());
+ GDataAccount storedUser = StorageAccountWrapper.buildEntity(h.doc(0));
+ assertTrue(storedUser.equals(user));
+
+ assertFalse(storedUser.getPassword().equals(password));
+ searcher.close();
+ }
+
+ public void testSaveFeed() throws IOException, StorageException {
+ String title = "myTitle";
+ ServerBaseFeed feed = new ServerBaseFeed();
+ feed.setId(feedId);
+ feed.setTitle(new PlainTextConstruct(title));
+ feed.setServiceType(service);
+ feed.setServiceConfig(this.configurator);
+ StorageFeedWrapper wrapper = new StorageFeedWrapper(feed,username);
+ this.modifier.createFeed(wrapper);
- }
-
- protected void tearDown() throws Exception {
- this.count = 1;
- // destroy all resources
- GDataServerRegistry.getRegistry().destroy();//TODO remove dependency here
-
- }
-
- /*
- * Test method for
- * 'org.apache.lucene.storage.lucenestorage.StorageModifier.StorageModifier(Directory,
- * int)'
- */
- public void testStorageModifier() {
-
- }
-
- /*
- * Test method for
- * 'org.apache.lucene.storage.lucenestorage.StorageModifier.updateEntry(StroageEntryWrapper)'
- */
- public void testUpdateEntry() throws IOException, InterruptedException, FeedNotFoundException, ParseException, StorageException {
- testInsertEntry();
- for(int i = 1; i < this.count; i++){
- Entry e = new Entry();
- e.setId(""+i);
- String insertString = "Hello world"+i;
- e.setTitle(new PlainTextConstruct(insertString));
- StorageEntryWrapper wrapper = new StorageEntryWrapper(e,feedId,StorageOperation.UPDATE,this.profile);
- this.modifier.updateEntry(wrapper);
- ReferenceCounter innerQuery = StorageCoreController.getStorageCoreController().getStorageQuery();
- BaseEntry fetchedEntry = innerQuery.get().singleEntryQuery(""+i,feedId,this.profile);
- assertEquals("updated Title:",insertString,fetchedEntry.getTitle().getPlainText());
- }
- // double updates
- for(int i = 1; i < this.count; i++){
- Entry e = new Entry();
- e.setId(""+i);
- String insertString = "Hello world"+i;
- e.setTitle(new PlainTextConstruct(insertString));
- StorageEntryWrapper wrapper = new StorageEntryWrapper(e,feedId,StorageOperation.UPDATE,this.profile);
- this.modifier.updateEntry(wrapper);
-
- e = new Entry();
- e.setId(""+i);
- insertString = "Foo Bar"+i;
- e.setTitle(new PlainTextConstruct(insertString));
- wrapper = new StorageEntryWrapper(e,feedId,StorageOperation.UPDATE,this.profile);
- this.modifier.updateEntry(wrapper);
-
- ReferenceCounter innerQuery = StorageCoreController.getStorageCoreController().getStorageQuery();
-
- BaseEntry fetchedEntry = innerQuery.get().singleEntryQuery(""+i,feedId,this.profile);
- assertEquals("updated Title:",insertString,fetchedEntry.getTitle().getPlainText());
- }
-
-
-
- }
-
- /*
- * Test method for
- * 'org.apache.lucene.storage.lucenestorage.StorageModifier.insertEntry(StroageEntryWrapper)'
- */
- public void testInsertEntry() throws IOException, InterruptedException, FeedNotFoundException, ParseException, StorageException {
+ IndexSearcher searcher = new IndexSearcher(this.dir);
+ Query q = new TermQuery(new Term(StorageFeedWrapper.FIELD_FEED_ID,
+ feedId));
+ Hits h = searcher.search(q);
+ assertEquals("length == 1", 1, h.length());
+ searcher.close();
- Thread a = getRunnerThread(this.count);
- a.start();
-
- Thread b = getRunnerThread((this.count+=10));
- b.start();
- a.join();
- for (int i = 1; i < this.count ; i++) {
- ReferenceCounter innerQuery = StorageCoreController.getStorageCoreController().getStorageQuery();
- BaseEntry e = innerQuery.get().singleEntryQuery(""+i,feedId,this.profile);
- assertEquals("get entry for id"+i,""+i,e.getId());
-
-
- }
- b.join();
- ReferenceCounter query = StorageCoreController.getStorageCoreController().getStorageQuery();
-
- this.count+=10;
- for (int i = 1; i < this.count ; i++) {
- BaseEntry e = query.get().singleEntryQuery(""+i,feedId,this.profile);
- assertEquals("get entry for id"+i,""+i,e.getId());
- }
+ }
+
+ public void testDeleteFeed() throws IOException, StorageException {
+ testSaveFeed();
+ Entry e = new Entry();
+ e.setTitle(new PlainTextConstruct("hello world"));
+ ServerBaseEntry entry = new ServerBaseEntry(e);
+ entry.setFeedId(feedId);
+ entry.setId("testme");
+ entry.setServiceConfig(this.configurator);
+ StorageEntryWrapper entryWrapper = new StorageEntryWrapper(entry,StorageOperation.INSERT);
+ this.modifier.insertEntry(entryWrapper);
+ this.modifier.forceWrite();
+ this.modifier.deleteFeed(feedId);
+ IndexSearcher searcher = new IndexSearcher(this.dir);
+ Query q = new TermQuery(new Term(StorageFeedWrapper.FIELD_FEED_ID,
+ feedId));
+ Query q1 = new TermQuery(new Term(StorageEntryWrapper.FIELD_FEED_REFERENCE,
+ feedId));
+ BooleanQuery boolQuery = new BooleanQuery();
+ boolQuery.add(q,BooleanClause.Occur.SHOULD);
+ boolQuery.add(q1,BooleanClause.Occur.SHOULD);
+ Hits h = searcher.search(boolQuery);
+ assertEquals("length == 0", 0, h.length());
+ searcher.close();
- BaseEntry e = query.get().singleEntryQuery(""+this.count,feedId,this.profile);
- assertNull("not entry for ID",e);
- query.decrementRef();
-
- }
-
- /*
- * Test method for
- * 'org.apache.lucene.storage.lucenestorage.StorageModifier.deleteEntry(String)'
- */
- public void testDeleteEntry() throws IOException, InterruptedException, FeedNotFoundException, ParseException, StorageException {
- testInsertEntry();
- for (int i = 1; i < this.count ; i++) {
- if(i%2 == 0 || i< 10){
- this.modifier.deleteEntry(""+i,feedId);
- }
- ReferenceCounter query = StorageCoreController.getStorageCoreController().getStorageQuery();
- if(i%2 == 0 || i< 10){
- assertNull(query.get().singleEntryQuery(""+i,feedId,this.profile));
- }
- else
- assertEquals(""+i,query.get().singleEntryQuery(""+i,feedId,this.profile).getId());
- query.decrementRef();
- }
-
- StorageCoreController.getStorageCoreController().forceWrite();
- IndexSearcher searcher = new IndexSearcher(this.dir);
-
- for (int i = 1; i < this.count ; i++) {
- Query luceneQuery = new TermQuery(new Term(StorageEntryWrapper.FIELD_ENTRY_ID,""+i));
- Hits hits = searcher.search(luceneQuery);
- if(i%2 == 0 || i< 10){
-
- assertEquals(0,hits.length());
- }
- else
- assertEquals(1,hits.length());
- }
- searcher.close();
-
- }
-
-
- private Thread getRunnerThread(int idIndex){
- Thread t = new Thread(new Runner(idIndex));
- return t;
- }
-
- private class Runner implements Runnable{
- private int idIndex;
- public Runner(int idIndex){
- this.idIndex = idIndex;
- }
- public void run() {
- for (int i = idIndex; i < idIndex+10; i++) {
-
- BaseEntry e = buildEntry(""+i);
- try {
- StorageEntryWrapper wrapper = new StorageEntryWrapper(e,feedId,StorageOperation.INSERT,new ExtensionProfile());
- modifier.insertEntry(wrapper);
- } catch (Exception e1) {
-
- e1.printStackTrace();
- }
-
-
-
-
- }
-
-
- }//end run
-
- private BaseEntry buildEntry(String id){
- Entry e = new Entry();
- e.setId(id);
- e.setTitle(new PlainTextConstruct("Monty Python"));
-
- e.setPublished(DateTime.now());
-
- e.setUpdated(DateTime.now());
- String content = "1st soldier with a keen interest in birds: Who goes there?" +
- "King Arthur: It is I, Arthur, son of Uther Pendragon, from the castle of Camelot. King of the Britons, defeater of the Saxons, Sovereign of all England!" +
- "1st soldier with a keen interest in birds: Pull the other one!" +
- "King Arthur: I am, and this is my trusty servant Patsy. We have ridden the length and breadth of the land in search of knights who will join me in my court at Camelot. I must speak with your lord and master." +
- "1st soldier with a keen interest in birds: What? Ridden on a horse?" +
- "King Arthur: Yes!";
- e.setContent(new TextContent(new PlainTextConstruct(content)));
- e.setSummary(new PlainTextConstruct("The Holy Grail"));
- return e;
- }
-
- }
-
-}
+
+
+ }
+
+ /**
+ * @throws IOException
+ * @throws StorageException
+ */
+ public void testUpdateFeed() throws IOException, StorageException {
+ testSaveFeed();
+ ServerBaseFeed feed = new ServerBaseFeed();
+ String title = "myTitle";
+ String newusername = "doug";
+ feed.setTitle(new PlainTextConstruct(title));
+ feed.setId(feedId);
+ feed.setServiceType(service);
+ feed.setServiceConfig(this.configurator);
+ StorageFeedWrapper wrapper = new StorageFeedWrapper(feed,newusername);
+ this.modifier.updateFeed(wrapper);
+ IndexSearcher searcher = new IndexSearcher(this.dir);
+ Query q = new TermQuery(new Term(StorageFeedWrapper.FIELD_FEED_ID,
+ feedId));
+ Hits h = searcher.search(q);
+ assertEquals("length == 1", 1, h.length());
+ assertTrue(h.doc(0).get(StorageFeedWrapper.FIELD_ACCOUNTREFERENCE).equals(newusername));
+ searcher.close();
+
+ }
+
+ private Thread getRunnerThread(int idIndex) {
+ Thread t = new Thread(new Runner(idIndex));
+ return t;
+ }
+
+ private class Runner implements Runnable {
+ private int idIndex;
+
+ public Runner(int idIndex) {
+ this.idIndex = idIndex;
+ }
+
+ public void run() {
+ for (int i = idIndex; i < idIndex + 10; i++) {
+
+ BaseEntry e = buildEntry("" + i);
+ try {
+ ServerBaseEntry en = new ServerBaseEntry(e);
+ en.setFeedId(feedId);
+ en.setServiceConfig(configurator);
+ StorageEntryWrapper wrapper = new StorageEntryWrapper(en,
+ StorageOperation.INSERT);
+ modifier.insertEntry(wrapper);
+ } catch (Exception e1) {
+
+ e1.printStackTrace();
+ }
+
+ }
+
+ }// end run
+
+ private BaseEntry buildEntry(String id) {
+ Entry e = new Entry();
+ e.setId(id);
+ e.setTitle(new PlainTextConstruct("Monty Python"));
+
+ e.setPublished(DateTime.now());
+
+ e.setUpdated(DateTime.now());
+ String content = "1st soldier with a keen interest in birds: Who goes there?"
+ + "King Arthur: It is I, Arthur, son of Uther Pendragon, from the castle of Camelot. King of the Britons, defeater of the Saxons, Sovereign of all England!"
+ + "1st soldier with a keen interest in birds: Pull the other one!"
+ + "King Arthur: I am, and this is my trusty servant Patsy. We have ridden the length and breadth of the land in search of knights who will join me in my court at Camelot. I must speak with your lord and master."
+ + "1st soldier with a keen interest in birds: What? Ridden on a horse?"
+ + "King Arthur: Yes!";
+ e.setContent(new TextContent(new PlainTextConstruct(content)));
+ e.setSummary(new PlainTextConstruct("The Holy Grail"));
+ return e;
+ }
+
+ }
+
+ private ServerBaseEntry getServerEntry(BaseEntry e){
+ ServerBaseEntry en = new ServerBaseEntry(e);
+ en.setFeedId(feedId);
+ en.setServiceConfig(this.configurator);
+ return en;
+ }
+
+}
Index: gdata-server/src/test/org/apache/lucene/gdata/storage/lucenestorage/recover/TestRecoverWriter.java
===================================================================
--- gdata-server/src/test/org/apache/lucene/gdata/storage/lucenestorage/recover/TestRecoverWriter.java (revision 0)
+++ gdata-server/src/test/org/apache/lucene/gdata/storage/lucenestorage/recover/TestRecoverWriter.java (revision 0)
@@ -0,0 +1,75 @@
+package org.apache.lucene.gdata.storage.lucenestorage.recover;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import junit.framework.TestCase;
+
+import org.apache.lucene.gdata.data.ServerBaseEntry;
+import org.apache.lucene.gdata.server.registry.ProvidedService;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation;
+import org.apache.lucene.gdata.utils.ProvidedServiceStub;
+
+import com.google.gdata.data.DateTime;
+import com.google.gdata.data.Entry;
+import com.google.gdata.data.PlainTextConstruct;
+
+public class TestRecoverWriter extends TestCase {
+ private static final String ENTRYID = "myID";
+ private static final String TITLE = "title";
+ private static final String FEEDID = "myFeed";
+
+ private static final Long TIMESTAMP = 132326657L;
+ private DateTime dateTime = new DateTime(TIMESTAMP,0);
+ String compareEntry = "I;"+FEEDID+";"+ENTRYID+";"+TIMESTAMP+";" +ProvidedServiceStub.SERVICE_NAME+";"+RecoverWriter.META_DATA_ENTRY_SEPARATOR+
+ ""+ENTRYID+""+this.dateTime.toString()+"" + TITLE+
+ ""+RecoverWriter.META_DATA_ENTRY_SEPARATOR+RecoverWriter.STORAGE_OPERATION_SEPARATOR+RecoverWriter.META_DATA_ENTRY_SEPARATOR;
+ String compareDelete = "D;"+FEEDID+";"+ENTRYID+";"+TIMESTAMP+";"+RecoverWriter.META_DATA_ENTRY_SEPARATOR+RecoverWriter.STORAGE_OPERATION_SEPARATOR+RecoverWriter.META_DATA_ENTRY_SEPARATOR;
+ StorageEntryWrapper wrapper;
+ StorageEntryWrapper deleteWrapper;
+
+ protected void setUp() throws Exception {
+ ServerBaseEntry entry = new ServerBaseEntry(new Entry());
+ entry.setId(ENTRYID);
+
+ entry.setUpdated(new DateTime(TIMESTAMP,0));
+ entry.setTitle(new PlainTextConstruct(TITLE));
+ ProvidedService config = new ProvidedServiceStub();
+ entry.setFeedId(FEEDID);
+ entry.setServiceConfig(config);
+ this.wrapper = new StorageEntryWrapper(entry,StorageOperation.INSERT);
+ this.deleteWrapper = new StorageEntryWrapper(entry,StorageOperation.DELETE);
+
+
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+
+ }
+
+ /*
+ * Test method for 'org.apache.lucene.gdata.storage.lucenestorage.recover.RecoverWriter.writeEntry(StorageEntryWrapper, Writer)'
+ */
+ public void testWriteEntry() throws IOException {
+ RecoverWriter wr = new RecoverWriter();
+ StringWriter writer = new StringWriter();
+ wr.writeEntry(this.wrapper,writer);
+ assertEquals(compareEntry,writer.toString());
+ writer.close();
+ }
+
+ /*
+ * Test method for 'org.apache.lucene.gdata.storage.lucenestorage.recover.RecoverWriter.writeDelete(String, String, Writer)'
+ */
+ public void testWriteDelete() throws IOException {
+ RecoverWriter wr = new RecoverWriter();
+ StringWriter writer = new StringWriter();
+ wr.writeEntry(this.deleteWrapper,writer);
+ System.out.println(writer.toString());
+ assertEquals(compareDelete,writer.toString());
+ writer.close();
+ }
+
+}
Index: gdata-server/src/test/org/apache/lucene/gdata/storage/lucenestorage/recover/TestRevocerReader.java
===================================================================
--- gdata-server/src/test/org/apache/lucene/gdata/storage/lucenestorage/recover/TestRevocerReader.java (revision 0)
+++ gdata-server/src/test/org/apache/lucene/gdata/storage/lucenestorage/recover/TestRevocerReader.java (revision 0)
@@ -0,0 +1,82 @@
+package org.apache.lucene.gdata.storage.lucenestorage.recover;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
+import org.apache.lucene.gdata.server.registry.ProvidedService;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation;
+import org.apache.lucene.gdata.utils.ProvidedServiceStub;
+
+import com.google.gdata.data.DateTime;
+
+public class TestRevocerReader extends TestCase {
+ private RecoverReader recReader;
+ private static final String feedId = "myFeed";
+ private static final String entryId = "myID";
+ private static final Long timestamp = System.currentTimeMillis();
+ private String title = "myTitle";
+ private static final DateTime dateTime = DateTime.now();
+ private String delete = "D;"+feedId+";"+entryId+";"+timestamp+";\n###########\n";
+ private String insert = "I;"+feedId+";"+entryId+";"+timestamp+";" +ProvidedServiceStub.SERVICE_NAME+";"+RecoverWriter.META_DATA_ENTRY_SEPARATOR+
+ ""+entryId+""+dateTime.toString()+"" + this.title+
+ ""+RecoverWriter.META_DATA_ENTRY_SEPARATOR+RecoverWriter.STORAGE_OPERATION_SEPARATOR+RecoverWriter.META_DATA_ENTRY_SEPARATOR;
+ protected void setUp() throws Exception {
+ this.recReader = new RecoverReader();
+ GDataServerRegistry.getRegistry().registerService(new ProvidedServiceStub());
+
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ /*
+ * Test method for 'org.apache.lucene.gdata.storage.lucenestorage.recover.RecoverReader.getNonDeleteEntries(Reader)'
+ */
+ public void testRecoverDeletedEntries() throws IOException {
+ StringReader reader = new StringReader(this.delete);
+ assertNotNull(this.recReader.recoverEntries(new BufferedReader(reader)));
+ reader = new StringReader(this.delete);
+ List recList = this.recReader.recoverEntries(new BufferedReader(reader));
+ assertEquals(1,recList.size());
+ StorageEntryWrapper delWrapper = recList.get(0);
+ assertEquals(StorageOperation.DELETE,delWrapper.getOperation());
+ assertEquals(feedId,delWrapper.getFeedId());
+ assertEquals(entryId,delWrapper.getEntryId());
+
+ }
+ public void testRecoverInsertedEntries() throws IOException {
+
+ StringReader reader = new StringReader(this.insert);
+ List recList = this.recReader.recoverEntries(new BufferedReader(reader));
+ assertEquals(1,recList.size());
+ StorageEntryWrapper insWrapper = recList.get(0);
+ assertEquals(StorageOperation.INSERT,insWrapper.getOperation());
+ assertEquals(feedId,insWrapper.getFeedId());
+ assertEquals(entryId,insWrapper.getEntryId());
+ assertEquals(dateTime,insWrapper.getEntry().getUpdated());
+ assertEquals(this.title,insWrapper.getEntry().getTitle().getPlainText());
+
+
+ }
+
+ public void testRecoverReader()throws IOException{
+ StringReader reader = new StringReader(this.insert+this.delete);
+ List recList = this.recReader.recoverEntries(new BufferedReader(reader));
+ assertEquals(2,recList.size());
+ assertEquals(StorageOperation.INSERT,recList.get(0).getOperation());
+ assertEquals(StorageOperation.DELETE,recList.get(1).getOperation());
+
+ reader = new StringReader("some corrupted\n###########\n"+this.insert);
+ recList = this.recReader.recoverEntries(new BufferedReader(reader));
+ assertEquals(1,recList.size());
+ assertEquals(StorageOperation.INSERT,recList.get(0).getOperation());
+
+ }
+}
Index: gdata-server/src/test/org/apache/lucene/gdata/storage/lucenestorage/recover/TestRecoverController.java
===================================================================
--- gdata-server/src/test/org/apache/lucene/gdata/storage/lucenestorage/recover/TestRecoverController.java (revision 0)
+++ gdata-server/src/test/org/apache/lucene/gdata/storage/lucenestorage/recover/TestRecoverController.java (revision 0)
@@ -0,0 +1,105 @@
+package org.apache.lucene.gdata.storage.lucenestorage.recover;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.rmi.registry.Registry;
+
+import org.apache.lucene.gdata.data.ServerBaseEntry;
+import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
+import org.apache.lucene.gdata.storage.StorageException;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageModifier;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageModifierStub;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation;
+import org.apache.lucene.gdata.utils.ProvidedServiceStub;
+import org.easymock.MockControl;
+
+import com.google.gdata.data.DateTime;
+
+import junit.framework.TestCase;
+
+public class TestRecoverController extends TestCase {
+ private RecoverController writeController;
+ private RecoverController readController;
+ private File recDir = new File("./temp/");
+ private String feedId = "feedid";
+ private String entryId = "entryId";
+
+ protected void setUp() throws Exception {
+ if(!this.recDir.exists())
+ this.recDir.mkdir();
+ GDataServerRegistry.getRegistry().registerService(new ProvidedServiceStub());
+ this.writeController = new RecoverController(this.recDir,false,false);
+ this.readController = new RecoverController(this.recDir,true,false);
+
+
+
+
+ }
+
+ protected void tearDown() throws Exception {
+
+
+
+ File[] files = this.recDir.listFiles();
+ for (int i = 0; i < files.length; i++) {
+ files[i].delete();
+ }
+ this.recDir.delete();
+ GDataServerRegistry.getRegistry().destroy();
+ }
+
+ /*
+ * Test method for 'org.apache.lucene.gdata.storage.lucenestorage.recover.RecoverController.storageModified(StorageEntryWrapper)'
+ */
+ public void testStorageModified() throws IOException, RecoverException {
+ this.writeController.initialize();
+ ServerBaseEntry entry = new ServerBaseEntry();
+ entry.setFeedId(this.feedId);
+ entry.setId(entryId);
+ entry.setUpdated(DateTime.now());
+ entry.setServiceConfig(new ProvidedServiceStub());
+ StorageEntryWrapper wrapper = new StorageEntryWrapper(entry,StorageOperation.INSERT);
+ this.writeController.storageModified(wrapper);
+ assertEquals(1,this.recDir.listFiles().length);
+ this.writeController.destroy();
+ }
+
+ /*
+ * Test method for 'org.apache.lucene.gdata.storage.lucenestorage.recover.RecoverController.recoverEntries(StorageModifier)'
+ */
+ public void testRecoverEntries() throws IOException, StorageException, RecoverException {
+ testStorageModified();
+
+ int length = this.recDir.listFiles().length;
+ assertEquals(1,length);
+
+ this.readController.initialize();
+ try{
+ this.readController.recoverEntries(new StorageModifierStub(null,null,null,0,0));
+ }catch (Exception e) {
+ fail("unexpected exception"+e.getMessage());
+ }
+ this.readController.destroy();
+ assertEquals(0,this.recDir.listFiles().length);
+ assertNotSame(length,this.recDir.listFiles().length);
+ createCorruptedFile();
+ this.readController.initialize();
+ try{
+ this.readController.recoverEntries(new StorageModifierStub(null,null,null,0,0));
+ }catch (Exception e) {
+ fail("unexpected exception"+e.getMessage());
+ }
+ this.readController.destroy();
+ assertEquals(1,this.recDir.listFiles().length);
+ }
+
+
+ private void createCorruptedFile() throws IOException{
+ FileWriter writer = new FileWriter(new File(this.recDir,"somefile.rec"));
+ writer.write("someString\nSomeOtherString");
+ writer.close();
+ }
+
+}
Index: gdata-server/src/test/org/apache/lucene/gdata/storage/lucenestorage/TestStorageQuery.java
===================================================================
--- gdata-server/src/test/org/apache/lucene/gdata/storage/lucenestorage/TestStorageQuery.java (revision 417093)
+++ gdata-server/src/test/org/apache/lucene/gdata/storage/lucenestorage/TestStorageQuery.java (working copy)
@@ -1,175 +1,266 @@
-package org.apache.lucene.gdata.storage.lucenestorage;
-
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.List;
-
-import junit.framework.TestCase;
-
-import org.apache.lucene.analysis.standard.StandardAnalyzer;
-import org.apache.lucene.gdata.server.FeedNotFoundException;
-import org.apache.lucene.gdata.server.registry.FeedInstanceConfigurator;
-import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
-import org.apache.lucene.gdata.server.registry.RegistryBuilder;
-import org.apache.lucene.gdata.storage.StorageException;
-import org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController;
-import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper;
-import org.apache.lucene.gdata.storage.lucenestorage.StorageModifier;
-import org.apache.lucene.gdata.storage.lucenestorage.StorageQuery;
-import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation;
-import org.apache.lucene.gdata.storage.lucenestorage.util.ReferenceCounter;
-import org.apache.lucene.index.IndexWriter;
-import org.apache.lucene.store.Directory;
-import org.apache.lucene.store.RAMDirectory;
-
-import com.google.gdata.data.BaseEntry;
-import com.google.gdata.data.DateTime;
-import com.google.gdata.data.Entry;
-import com.google.gdata.data.ExtensionProfile;
-import com.google.gdata.data.Feed;
-import com.google.gdata.util.ParseException;
-
-public class TestStorageQuery extends TestCase {
- private StorageModifier modifier;
- private int count = 30;
- private ReferenceCounter query;
- private ExtensionProfile profile;
-
- private Directory dir;
- private static String feedId = "myFeed";
- protected void setUp() throws Exception {
- FeedInstanceConfigurator configurator = new FeedInstanceConfigurator();
- configurator.setFeedType(Feed.class);
- configurator.setFeedId(feedId);
- configurator.setExtensionProfileClass(ExtensionProfile.class);
- GDataServerRegistry.getRegistry().registerFeed(configurator);
- this.profile = new ExtensionProfile();
- this.dir = new RAMDirectory();
- IndexWriter writer;
- writer = new IndexWriter(this.dir,new StandardAnalyzer(),true);
- writer.close();
- this.modifier = StorageCoreController.getStorageCoreController(this.dir).getStorageModifier();
- insertEntries(this.count);
- this.query = StorageCoreController.getStorageCoreController().getStorageQuery();
+package org.apache.lucene.gdata.storage.lucenestorage;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+
+import junit.framework.TestCase;
+
+import org.apache.lucene.gdata.data.GDataAccount;
+import org.apache.lucene.gdata.data.ServerBaseEntry;
+import org.apache.lucene.gdata.data.ServerBaseFeed;
+import org.apache.lucene.gdata.server.registry.ComponentType;
+import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
+import org.apache.lucene.gdata.server.registry.ProvidedService;
+import org.apache.lucene.gdata.storage.StorageController;
+import org.apache.lucene.gdata.storage.StorageException;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation;
+import org.apache.lucene.gdata.storage.lucenestorage.util.ReferenceCounter;
+import org.apache.lucene.gdata.utils.ProvidedServiceStub;
+import org.apache.lucene.store.Directory;
+
+import com.google.gdata.data.BaseEntry;
+import com.google.gdata.data.BaseFeed;
+import com.google.gdata.data.DateTime;
+import com.google.gdata.data.Entry;
+import com.google.gdata.util.ParseException;
+
+public class TestStorageQuery extends TestCase {
+ private StorageModifier modifier;
+ private int count = 30;
+ private ReferenceCounter query;
+ private ProvidedService configurator;
+ private StorageCoreController controller;
+ private Directory dir;
+ private static String feedId = "myFeed";
+ private static String accountName = "simon";
+ private static String service = ProvidedServiceStub.SERVICE_NAME;
+ protected void setUp() throws Exception {
+ GDataServerRegistry.getRegistry().registerComponent(StorageCoreController.class);
+ this.configurator = new ProvidedServiceStub();
+
+
+ GDataServerRegistry.getRegistry().registerService(this.configurator);
+ this.controller = (StorageCoreController)GDataServerRegistry.getRegistry().lookup(StorageController.class,ComponentType.STORAGECONTROLLER);
+ this.modifier = this.controller.getStorageModifier();
+ this.dir = this.controller.getDirectory();
+ ServerBaseFeed feed = new ServerBaseFeed();
+ feed.setId(feedId);
+ feed.setServiceType(service);
+ feed.setServiceConfig(this.configurator);
+
+ StorageFeedWrapper wrapper = new StorageFeedWrapper(feed,accountName);
+ this.modifier.createFeed(wrapper);
+ insertEntries(this.count);
+ this.query = this.controller.getStorageQuery();
+
-
-
- }
-
-
- public void insertEntries(int count) throws IOException,InterruptedException, StorageException{
- List tempList = new ArrayList();
- for (int i = 0; i <= count ; i++) {
- Entry entry = new Entry();
- entry.setId(""+i);
-
- entry.setUpdated(new DateTime(System.currentTimeMillis(),0));
- StorageEntryWrapper wrapper = new StorageEntryWrapper(entry,feedId,StorageOperation.INSERT,this.profile);
- tempList.add(i,wrapper);
-
- // force different timestamps --> DateTime 2006-06-05T13:37:55.724Z
- Thread.sleep(50);
-
- }
- for (StorageEntryWrapper entry : tempList) {
- this.modifier.insertEntry(entry);
- }
-
-
-
-
- }
-
- protected void tearDown() throws Exception {
- this.query.decrementRef();
- GDataServerRegistry.getRegistry().destroy();//TODO remove dependency here
- }
-
- /*
- * Test method for 'org.apache.lucene.storage.lucenestorage.StorageQuery.feedQuery(String, int, int)'
- */
- public void testFeedQuery() throws IOException, FeedNotFoundException, ParseException, StorageException {
- FeedQueryHelper(this.query);
- StorageCoreController.getStorageCoreController().forceWrite();
- ReferenceCounter queryAssureWritten = StorageCoreController.getStorageCoreController().getStorageQuery();
- assertNotSame(queryAssureWritten,this.query);
- FeedQueryHelper(queryAssureWritten);
- queryAssureWritten.decrementRef();
- }
- private void FeedQueryHelper(ReferenceCounter currentQuery) throws IOException, FeedNotFoundException, ParseException{
- List entryList = currentQuery.get().getLatestFeedQuery(feedId,25,1,this.profile);
-
- assertTrue("listSize: "+entryList.size(),entryList.size() == 25);
-
- BaseEntry tempEntry = null;
- for (BaseEntry entry : entryList) {
+
+ }
+
+
+ /**
+ * @param entrycount
+ * @throws IOException
+ * @throws InterruptedException
+ * @throws StorageException
+ */
+ public void insertEntries(int entrycount) throws IOException,InterruptedException, StorageException{
+ List tempList = new ArrayList();
+ for (int i = 0; i <= entrycount ; i++) {
+ ServerBaseEntry entry = new ServerBaseEntry(new Entry());
+ entry.setId(""+i);
+ entry.setServiceConfig(this.configurator);
+ entry.setUpdated(new DateTime(System.currentTimeMillis(),0));
+ entry.setFeedId(feedId);
+ StorageEntryWrapper wrapper = new StorageEntryWrapper(entry,StorageOperation.INSERT);
+ tempList.add(i,wrapper);
- assertNotNull("entry",entry);
- if(tempEntry != null){
- assertTrue(tempEntry.getUpdated().compareTo(entry.getUpdated())>=0) ;
- tempEntry = entry;
- }else
- tempEntry = entry;
-
- }
- // test sub retrieve sublist
- int offset = 15;
- int resultCount = 5;
- List entrySubList = currentQuery.get().getLatestFeedQuery(feedId,resultCount,offset,this.profile);
-
- assertTrue("listSize: "+entrySubList.size(),entrySubList.size() == resultCount);
- offset--;
- for (BaseEntry entry : entrySubList) {
-
- assertEquals(entry.getId(),entryList.get(offset).getId());
- offset++;
-
- }
-
-
-
- }
-
- /*
- * Test method for 'org.apache.lucene.storage.lucenestorage.StorageQuery.singleEntryQuery(String, String)'
- */
- public void testSingleEntryQuery() throws FeedNotFoundException, ParseException, IOException {
- for (int i = 1; i <= this.count; i++) {
- BaseEntry entry = this.query.get().singleEntryQuery(""+i,feedId,this.profile);
- assertEquals(""+i,entry.getId());
- }
-
- }
-
- /*
- * Test method for 'org.apache.lucene.storage.lucenestorage.StorageQuery.entryQuery(List, String)'
- */
- public void testEntryQuery() throws FeedNotFoundException, ParseException, IOException, StorageException {
- entryQueryHelper(this.query);
- StorageCoreController.getStorageCoreController().forceWrite();
- ReferenceCounter queryAssureWritten = StorageCoreController.getStorageCoreController().getStorageQuery();
+ // force different timestamps --> DateTime 2006-06-05T13:37:55.724Z
+ Thread.sleep(10);
+
+ }
+ for (StorageEntryWrapper entry : tempList) {
+ this.modifier.insertEntry(entry);
+ }
- assertNotSame(queryAssureWritten,query);
- entryQueryHelper(queryAssureWritten);
- queryAssureWritten.decrementRef();
- }
+
+
+
+ }
+
+ protected void tearDown() throws Exception {
+ this.query.decrementRef();
+ GDataServerRegistry.getRegistry().destroy();
+ }
+
+ /*
+ *
+ */
+ public void testAccountNameQuery() throws IOException, StorageException{
+ ReferenceCounter query = this.controller.getStorageQuery();
+ assertEquals(accountName,query.get().getAccountNameForFeedId(feedId));
+ assertNull(query.get().getAccountNameForFeedId("someId"));
+ }
+
+ /*
+ * Test method for 'org.apache.lucene.storage.lucenestorage.StorageQuery.feedQuery(String, int, int)'
+ */
+ public void testFeedQuery() throws IOException, ParseException, StorageException {
+ feedQueryHelper(this.query);
+ this.controller.forceWrite();
+ ReferenceCounter queryAssureWritten = this.controller.getStorageQuery();
+
+ assertNotSame(queryAssureWritten,this.query);
+ feedQueryHelper(queryAssureWritten);
+ queryAssureWritten.decrementRef();
+ }
+ private void feedQueryHelper(ReferenceCounter currentQuery) throws IOException, ParseException{
+ BaseFeed feed = currentQuery.get().getLatestFeedQuery(feedId,25,1,this.configurator);
+ List entryList = feed.getEntries();
+ assertTrue("listSize: "+entryList.size(),entryList.size() == 25);
+
+ BaseEntry tempEntry = null;
+ for (BaseEntry entry : entryList) {
+
+ assertNotNull("entry",entry);
+ if(tempEntry != null){
+ assertTrue(tempEntry.getUpdated().compareTo(entry.getUpdated())>=0) ;
+ tempEntry = entry;
+ }else
+ tempEntry = entry;
+
+ }
+ // test sub retrieve sublist
+ int offset = 15;
+ int resultCount = 5;
+ feed = currentQuery.get().getLatestFeedQuery(feedId,resultCount,offset,this.configurator);
+ List entrySubList = feed.getEntries();
+
+ assertTrue("listSize: "+entrySubList.size(),entrySubList.size() == resultCount);
+ offset--;
+ for (BaseEntry entry : entrySubList) {
+
+ assertEquals(entry.getId(),entryList.get(offset).getId());
+ offset++;
+
+ }
+
+
+
+ }
+
+ /*
+ * Test method for 'org.apache.lucene.storage.lucenestorage.StorageQuery.singleEntryQuery(String, String)'
+ */
+ public void testSingleEntryQuery() throws ParseException, IOException {
+ for (int i = 1; i <= this.count; i++) {
+ BaseEntry entry = this.query.get().singleEntryQuery(""+i,feedId,this.configurator);
+ assertEquals(""+i,entry.getId());
+ }
+
+ }
+
+ /*
+ * Test method for 'org.apache.lucene.storage.lucenestorage.StorageQuery.entryQuery(List, String)'
+ */
+ public void testEntryQuery() throws ParseException, IOException, StorageException {
+ entryQueryHelper(this.query);
+ this.controller.forceWrite();
+ ReferenceCounter queryAssureWritten = this.controller.getStorageQuery();
+
+ assertNotSame(queryAssureWritten,query);
+ entryQueryHelper(queryAssureWritten);
+ queryAssureWritten.decrementRef();
+ }
+ public void testGetUser() throws StorageException, IOException{
+ this.modifier.forceWrite();
+ GDataAccount user = new GDataAccount();
+ user.setName("simon");
+ user.setPassword("pass");
+ user.setAuthorname("simon willnauer");
+ user.setAuthorMail("simon@apache.org");
+ user.setAuthorLink(new URL("http://www.apache.org"));
+
+
-
- private void entryQueryHelper(ReferenceCounter currentQuery) throws IOException, FeedNotFoundException, ParseException{
-
- List entryIdList = new ArrayList();
- for (int i = 1; i <= this.count; i++) {
- entryIdList.add(""+i);
- }
- List entryList = currentQuery.get().entryQuery(entryIdList,feedId,this.profile);
- assertEquals(entryIdList.size(),entryList.size());
- List entryIdCompare = new ArrayList();
- for (BaseEntry entry : entryList) {
- entryIdCompare.add(entry.getId());
- }
- assertTrue(entryIdList.containsAll(entryIdCompare));
-
- }
-
-}
+ this.modifier.createAccount(new StorageAccountWrapper(user));
+ GDataAccount queriedUser = this.query.get().getUser("simon");
+ assertNull(queriedUser);
+ ReferenceCounter tempQuery = this.controller.getStorageQuery();
+ queriedUser = tempQuery.get().getUser("simon");
+ assertTrue(queriedUser.equals(user));
+ assertTrue(queriedUser.getAuthorMail().equals(user.getAuthorMail()));
+ assertTrue(queriedUser.getAuthorLink().equals(user.getAuthorLink()));
+ assertTrue(queriedUser.getAuthorname().equals(user.getAuthorname()));
+ assertTrue(queriedUser.getPassword().equals(user.getPassword()));
+ }
+
+ public void testIsEntryStored() throws IOException{
+
+ assertTrue(this.query.get().isEntryStored(""+(this.count-1),feedId));
+ assertFalse(this.query.get().isEntryStored("someOther",feedId));
+ this.modifier.forceWrite();
+ assertTrue(this.query.get().isEntryStored(""+(this.count-1),feedId));
+ this.query = this.controller.getStorageQuery();
+ assertTrue(this.query.get().isEntryStored(""+(this.count-1),feedId));
+ assertFalse(this.query.get().isEntryStored("someOther",feedId));
+ }
+
+ public void testGetEntryLastModied() throws IOException, StorageException{
+ ServerBaseEntry entry = new ServerBaseEntry(new Entry());
+ entry.setId("test");
+ entry.setServiceConfig(this.configurator);
+ entry.setUpdated(new DateTime(System.currentTimeMillis(),0));
+ entry.setFeedId(feedId);
+ StorageEntryWrapper wrapper = new StorageEntryWrapper(entry,StorageOperation.INSERT);
+
+ this.modifier.insertEntry(wrapper);
+ assertEquals(entry.getUpdated().getValue(),this.query.get().getEntryLastModified("test",feedId));
+ this.modifier.forceWrite();
+ assertEquals(entry.getUpdated().getValue(),this.query.get().getEntryLastModified("test",feedId));
+ this.query = this.controller.getStorageQuery();
+ assertEquals(entry.getUpdated().getValue(),this.query.get().getEntryLastModified("test",feedId));
+ try{
+ this.query.get().getEntryLastModified("some",feedId);
+ fail("exception expected");
+ }catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public void testGetFeedLastModified() throws StorageException, IOException{
+ ServerBaseEntry entry = new ServerBaseEntry(new Entry());
+ entry.setId("test");
+ entry.setServiceConfig(this.configurator);
+ entry.setUpdated(new DateTime(System.currentTimeMillis(),0));
+ entry.setFeedId(feedId);
+ StorageEntryWrapper wrapper = new StorageEntryWrapper(entry,StorageOperation.INSERT);
+ this.modifier.insertEntry(wrapper);
+ assertEquals(entry.getUpdated().getValue(),this.query.get().getFeedLastModified(feedId));
+ this.modifier.forceWrite();
+ assertEquals(entry.getUpdated().getValue(),this.query.get().getFeedLastModified(feedId));
+ this.query = this.controller.getStorageQuery();
+ assertEquals(entry.getUpdated().getValue(),this.query.get().getFeedLastModified(feedId));
+ }
+ private void entryQueryHelper(ReferenceCounter currentQuery) throws IOException, ParseException{
+
+ List entryIdList = new ArrayList();
+ for (int i = 1; i <= this.count; i++) {
+ entryIdList.add(""+i);
+ }
+ List entryList = currentQuery.get().entryQuery(entryIdList,feedId,this.configurator);
+ assertEquals(entryIdList.size(),entryList.size());
+ List entryIdCompare = new ArrayList();
+ for (BaseEntry entry : entryList) {
+ entryIdCompare.add(entry.getId());
+ }
+ assertTrue(entryIdList.containsAll(entryIdCompare));
+
+ }
+
+
+
+}
Index: gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataResponse.java
===================================================================
--- gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataResponse.java (revision 417093)
+++ gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataResponse.java (working copy)
@@ -70,12 +70,12 @@
StringWriter stringWriter = new StringWriter();
PrintWriter writer = new PrintWriter(stringWriter);
- this.control.expectAndReturn(this.httpResponse.getWriter(),writer);
+ this.control.expectAndReturn(this.httpResponse.getWriter(),writer);
+ this.httpResponse.setContentType(GDataResponse.XMLMIME_ATOM);
this.response.setOutputFormat(OutputFormat.ATOM);
this.control.replay();
- this.response.sendResponse(createFeed(),new ExtensionProfile
- ());
+ this.response.sendResponse(createFeed(),new ExtensionProfile());
assertEquals("Simple XML representation",stringWriter.toString(),generatedFeedAtom);
this.control.reset();
@@ -84,6 +84,7 @@
this.control.expectAndReturn(this.httpResponse.getWriter(),writer);
this.response.setOutputFormat(OutputFormat.RSS);
+ this.httpResponse.setContentType(GDataResponse.XMLMIME_RSS);
this.control.replay();
this.response.sendResponse(createFeed(),new ExtensionProfile
Index: gdata-server/src/test/org/apache/lucene/gdata/server/authentication/TestBlowfishAuthenticationController.java
===================================================================
--- gdata-server/src/test/org/apache/lucene/gdata/server/authentication/TestBlowfishAuthenticationController.java (revision 0)
+++ gdata-server/src/test/org/apache/lucene/gdata/server/authentication/TestBlowfishAuthenticationController.java (revision 0)
@@ -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.server.authentication;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+
+import org.apache.lucene.gdata.data.GDataAccount;
+import org.apache.lucene.gdata.data.GDataAccount.AccountRole;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Simon Willnauer
+ *
+ */
+public class TestBlowfishAuthenticationController extends TestCase {
+ private BlowfishAuthenticationController controller;
+ private String key = "myKey";
+ private String accountName = "simon";
+
+ private String clientIp = "192.168.0.127";
+ protected void setUp() throws Exception {
+ this.controller = new BlowfishAuthenticationController();
+ this.controller.setKey(this.key);
+
+ this.controller.initialize();
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ /*
+ * Test method for 'org.apache.lucene.gdata.server.authentication.AuthenticationController.authenticatAccount(HttpServletRequest)'
+ */
+ public void testAuthenticatAccount() throws IllegalBlockSizeException, BadPaddingException, AuthenticationException, IOException {
+ GDataAccount account = new GDataAccount();
+ account.setName(accountName);
+ account.setPassword("testme");
+ account.setRole(AccountRole.ENTRYAMINISTRATOR);
+
+ String token = this.controller.authenticatAccount(account,this.clientIp);
+ String notSame = this.controller.calculateAuthToken("192.168.0",Integer.toString(account.getRolesAsInt()),this.accountName);
+ assertNotSame(notSame,token);
+ String authString = "192.168.0#"+this.accountName +"#"+account.getRolesAsInt()+"#";
+ assertTrue(this.controller.deCryptAuthToken(token).startsWith(authString));
+ assertTrue(this.controller.deCryptAuthToken(notSame).startsWith(authString));
+ }
+
+ /*
+ * Test method for 'org.apache.lucene.gdata.server.authentication.AuthenticationController.authenticateToken(String)'
+ */
+ public void testAuthenticateToken() throws IllegalBlockSizeException, BadPaddingException, UnsupportedEncodingException, AuthenticationException {
+ GDataAccount account = new GDataAccount();
+ account.setName("simon");
+ account.setPassword("testme");
+ account.setRole(AccountRole.ENTRYAMINISTRATOR);
+ String token = this.controller.calculateAuthToken("192.168.0",Integer.toString(account.getRolesAsInt()),this.accountName);
+
+ assertTrue(this.controller.authenticateToken(token,this.clientIp,AccountRole.ENTRYAMINISTRATOR,this.accountName));
+ assertTrue(this.controller.authenticateToken(token,this.clientIp,AccountRole.USER,this.accountName));
+ assertFalse(this.controller.authenticateToken(token,this.clientIp,AccountRole.USERADMINISTRATOR,"someOtherAccount"));
+ try{
+ this.controller.authenticateToken(token+"test",this.clientIp,AccountRole.ENTRYAMINISTRATOR,this.accountName);
+ fail("exception expected");
+ }catch (Exception e) {
+ // TODO: handle exception
+ }
+ this.controller.setMinuteOffset(0);
+ assertFalse(this.controller.authenticateToken(token,this.clientIp,AccountRole.ENTRYAMINISTRATOR,this.accountName));
+
+ }
+
+
+
+}
Index: gdata-server/src/test/org/apache/lucene/gdata/server/administration/TestAccountBuilder.java
===================================================================
--- gdata-server/src/test/org/apache/lucene/gdata/server/administration/TestAccountBuilder.java (revision 0)
+++ gdata-server/src/test/org/apache/lucene/gdata/server/administration/TestAccountBuilder.java (revision 0)
@@ -0,0 +1,54 @@
+package org.apache.lucene.gdata.server.administration;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.net.URL;
+
+import junit.framework.TestCase;
+
+import org.apache.lucene.gdata.data.GDataAccount;
+import org.apache.lucene.gdata.data.GDataAccount.AccountRole;
+import org.xml.sax.SAXException;
+
+public class TestAccountBuilder extends TestCase {
+ private StringReader reader;
+ private String inputXML;
+ protected void setUp() throws Exception {
+ this.inputXML = "" +
+ "" +
+ "simon" +
+ "simon" +
+ "6" +
+ "" +
+ "simon willnauer" +
+ "simon@gmail.com" +
+ "http://www.javawithchopsticks.de" +
+ "" +
+ "";
+
+ this.reader = new StringReader(this.inputXML);
+
+ }
+
+ protected void tearDown() throws Exception {
+ super.tearDown();
+ }
+
+ /*
+ * Test method for 'org.apache.lucene.gdata.server.administration.AdminEntityBuilder.buildUser(Reader)'
+ */
+ public void testBuildUser() throws IOException, SAXException {
+
+ GDataAccount user = AccountBuilder.buildAccount(this.reader);
+ assertEquals("simon",user.getName());
+ assertEquals("simon willnauer",user.getAuthorname());
+ assertEquals("simon@gmail.com",user.getAuthorMail());
+ assertEquals("simon",user.getPassword());
+ assertEquals(new URL("http://www.javawithchopsticks.de"),user.getAuthorLink());
+ assertTrue(user.isUserInRole(AccountRole.ENTRYAMINISTRATOR));
+ assertTrue(user.isUserInRole(AccountRole.FEEDAMINISTRATOR));
+ assertFalse(user.isUserInRole(AccountRole.USERADMINISTRATOR));
+
+ }
+
+}
Index: gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestGDataEntityBuilder.java
===================================================================
--- gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestGDataEntityBuilder.java (revision 417093)
+++ gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestGDataEntityBuilder.java (working copy)
@@ -15,23 +15,25 @@
*/
package org.apache.lucene.gdata.server.registry;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.Reader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.Reader;
+
+import junit.framework.TestCase;
+
+import org.apache.lucene.gdata.data.ServerBaseEntry;
+import org.apache.lucene.gdata.data.ServerBaseFeed;
+import org.apache.lucene.gdata.server.GDataEntityBuilder;
+
+import com.google.gdata.data.BaseEntry;
+import com.google.gdata.data.BaseFeed;
+import com.google.gdata.data.Entry;
+import com.google.gdata.data.ExtensionProfile;
+import com.google.gdata.data.Feed;
+import com.google.gdata.data.Source;
+import com.google.gdata.util.ParseException;
-import junit.framework.TestCase;
-
-import org.apache.lucene.gdata.server.FeedNotFoundException;
-import org.apache.lucene.gdata.server.GDataEntityBuilder;
-
-import com.google.gdata.data.BaseEntry;
-import com.google.gdata.data.BaseFeed;
-import com.google.gdata.data.Entry;
-import com.google.gdata.data.ExtensionProfile;
-import com.google.gdata.data.Feed;
-import com.google.gdata.util.ParseException;
-
/**
* @author Simon Willnauer
*
@@ -44,8 +46,9 @@
private static GDataServerRegistry reg = GDataServerRegistry.getRegistry();
private Reader reader;
private static String feedID = "myFeed";
- private ExtensionProfile profile;
+ private ProvidedServiceConfig config;
private static Class feedType = Feed.class;
+ private static Class entryType = Entry.class;
/**
@@ -53,11 +56,12 @@
*/
@Override
protected void setUp() throws Exception {
- FeedInstanceConfigurator config = new FeedInstanceConfigurator();
- config.setFeedId(feedID);
- config.setFeedType(feedType);
- this.profile = new ExtensionProfile();
- reg.registerFeed(config);
+ this.config = new ProvidedServiceConfig();
+
+ this.config.setFeedType(feedType);
+ this.config.setEntryType(entryType);
+ this.config.setExtensionProfile(new ExtensionProfile());
+ reg.registerService(this.config);
}
/**
@@ -72,24 +76,27 @@
/**
* Test method for 'org.apache.lucene.gdata.data.GDataEntityBuilder.buildFeed(String, Reader)'
*/
- public void testBuildFeedStringReader() throws FeedNotFoundException, ParseException, IOException {
+ public void testBuildFeedStringReader() throws ParseException, IOException {
this.reader = new FileReader(incomingFeed);
- BaseFeed feed = GDataEntityBuilder.buildFeed(feedID,this.reader,this.profile);
+ BaseFeed feed = GDataEntityBuilder.buildFeed(this.reader,this.config);
assertNotNull(feed);
- assertEquals("feed title",feed.getTitle().getPlainText(), feedTitleFromXML);
- assertTrue( feed instanceof Feed);
+ assertEquals("feed title",feed.getTitle().getPlainText(), feedTitleFromXML);
+
+
}
- /*
+ /**
* Test method for 'org.apache.lucene.gdata.data.GDataEntityBuilder.buildEntry(String, Reader)'
*/
- public void testBuildEntryStringReader() throws FeedNotFoundException, ParseException, IOException {
+ public void testBuildEntryStringReader() throws ParseException, IOException {
this.reader = new FileReader(incomingEntry);
- BaseEntry entry = GDataEntityBuilder.buildEntry(feedID,this.reader,this.profile);
+ BaseEntry entry = GDataEntityBuilder.buildEntry(this.reader,this.config);
assertNotNull(entry);
assertEquals("entry summary",entry.getSummary().getPlainText(),entrySummaryFromXML);
- assertTrue(entry instanceof Entry);
+
+
+
}
Index: gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestFeedRegistry.java
===================================================================
--- gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestFeedRegistry.java (revision 417093)
+++ gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestFeedRegistry.java (working copy)
@@ -1,98 +1,132 @@
-/**
- * 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 com.google.gdata.data.Feed;
-
-import junit.framework.TestCase;
-
-/**
- * @author Simon Willnauer
- *
- */
-public class TestFeedRegistry extends TestCase {
- private GDataServerRegistry reg;
- private FeedInstanceConfigurator configurator;
- @Override
- protected void setUp(){
- this.reg = GDataServerRegistry.getRegistry();
- this.configurator = new FeedInstanceConfigurator();
- }
- /**
- * @see junit.framework.TestCase#tearDown()
- */
- @Override
- protected void tearDown() throws Exception {
- this.reg.flushRegistry();
- }
- /**
- * Test method for 'org.apache.lucene.gdata.server.registry.FeedRegistry.getRegistry()'
- */
- public void testGetRegistry() {
-
- GDataServerRegistry reg1 = GDataServerRegistry.getRegistry();
- assertEquals("test singleton",this.reg,reg1);
- }
-
- /**
- * Test method for 'org.apache.lucene.gdata.server.registry.FeedRegistry.registerFeed(FeedInstanceConfigurator)'
- */
- public void testRegisterFeed() {
- String feedURL = "myFeed";
- registerFeed(feedURL);
- assertEquals("Registered Configurator",this.configurator,this.reg.getFeedConfigurator(feedURL));
- assertNull("not registered Configurator",this.reg.getFeedConfigurator("somethingElse"));
- try{
- this.reg.getFeedConfigurator(null);
- fail("Exception expected");
- }catch (IllegalArgumentException e) {
- //
- }
- }
-
- /**
- * Test method for 'org.apache.lucene.gdata.server.registry.FeedRegistry.getFeedConfigurator(String)'
- */
- public void testFlushRegistry() {
- String feedURL = "testFeed";
- registerFeed(feedURL);
- assertEquals("Registered Configurator",this.configurator,this.reg.getFeedConfigurator(feedURL));
- this.reg.flushRegistry();
- assertNull("Registry flushed",this.reg.getFeedConfigurator(feedURL));
-
-
- }
-
- /**
- *
- */
- public void testIsFeedRegistered(){
- String myFeed = "myFeed";
- registerFeed(myFeed);
- assertTrue("Feed is registerd",this.reg.isFeedRegistered(myFeed));
- assertFalse("null Feed is not registerd",this.reg.isFeedRegistered(null));
- assertFalse("Feed is not registerd",this.reg.isFeedRegistered("someOtherFeed"));
-
- }
-
- private void registerFeed(String feedURL){
-
- this.configurator.setFeedType(Feed.class);
- this.configurator.setFeedId(feedURL);
- this.reg.registerFeed(this.configurator);
- }
-
-}
+/**
+ * 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 org.apache.lucene.gdata.server.ServiceFactory;
+import org.apache.lucene.gdata.servlet.handler.DefaultRequestHandlerFactory;
+import org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory;
+import org.apache.lucene.gdata.storage.StorageController;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController;
+
+import com.google.gdata.data.Entry;
+import com.google.gdata.data.Feed;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Simon Willnauer
+ *
+ */
+public class TestFeedRegistry extends TestCase {
+ private GDataServerRegistry reg;
+ private ProvidedServiceConfig configurator;
+ @Override
+ protected void setUp(){
+ this.reg = GDataServerRegistry.getRegistry();
+ this.configurator = new ProvidedServiceConfig();
+ this.configurator.setEntryType(Entry.class);
+ this.configurator.setFeedType(Feed.class);
+ }
+ /**
+ * @see junit.framework.TestCase#tearDown()
+ */
+ @Override
+ protected void tearDown() throws Exception {
+ this.reg.flushRegistry();
+ }
+ /**
+ * Test method for 'org.apache.lucene.gdata.server.registry.FeedRegistry.getRegistry()'
+ */
+ public void testGetRegistry() {
+
+ GDataServerRegistry reg1 = GDataServerRegistry.getRegistry();
+ assertEquals("test singleton",this.reg,reg1);
+ }
+
+ /**
+ * Test method for 'org.apache.lucene.gdata.server.registry.FeedRegistry.registerFeed(FeedInstanceConfigurator)'
+ */
+ public void testRegisterService() {
+ String service = "service";
+ registerService(service);
+ assertEquals("Registered Configurator",this.configurator,this.reg.getProvidedService(service));
+ assertNull("not registered Configurator",this.reg.getProvidedService("something"));
+ try{
+ this.reg.getProvidedService(null);
+ fail("Exception expected");
+ }catch (IllegalArgumentException e) {
+ //
+ }
+ }
+
+ /**
+ * Test method for 'org.apache.lucene.gdata.server.registry.FeedRegistry.getFeedConfigurator(String)'
+ */
+ public void testFlushRegistry() {
+ String service = "service";
+ registerService(service);
+
+ assertEquals("Registered Configurator",this.configurator,this.reg.getProvidedService(service));
+ this.reg.flushRegistry();
+ assertNull("Registry flushed",this.reg.getProvidedService(service));
+
+
+ }
+
+ /**
+ *
+ */
+ public void testIsFeedRegistered(){
+ String service = "service";
+ registerService(service);
+ assertTrue("Feed is registerd",this.reg.isServiceRegistered(service));
+ assertFalse("null Feed is not registerd",this.reg.isServiceRegistered(null));
+ assertFalse("Feed is not registerd",this.reg.isServiceRegistered("something"));
+
+ }
+
+ private void registerService(String servicename){
+
+ this.configurator.setName(servicename);
+ this.reg.registerService(this.configurator);
+ }
+
+ public void testRegisterComponent() throws RegistryException{
+ try {
+ this.reg.registerComponent(StorageController.class);
+ fail("RegistryException expected");
+ } catch (RegistryException e) {
+ //
+ }
+ this.reg.registerComponent(StorageCoreController.class);
+
+ this.reg.registerComponent(DefaultRequestHandlerFactory.class);
+ RequestHandlerFactory factory = this.reg.lookup(RequestHandlerFactory.class,ComponentType.REQUESTHANDLERFACTORY);
+ try{
+ this.reg.registerComponent(DefaultRequestHandlerFactory.class);
+ fail("RegistryException expected");
+ } catch (RegistryException e) {
+ //
+ }
+ this.reg.registerComponent(ServiceFactory.class);
+ ServiceFactory servicefactory = this.reg.lookup(ServiceFactory.class,ComponentType.SERVICEFACTORY);
+ assertNotNull(servicefactory);
+ assertNotNull(factory);
+
+
+ }
+
+}
Index: gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataRequest.java
===================================================================
--- gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataRequest.java (revision 417093)
+++ gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataRequest.java (working copy)
@@ -15,19 +15,19 @@
*/
package org.apache.lucene.gdata.server;
-import javax.servlet.http.HttpServletRequest;
+import javax.servlet.http.HttpServletRequest;
+
+import junit.framework.TestCase;
+
+import org.apache.lucene.gdata.server.GDataRequest.GDataRequestType;
+import org.apache.lucene.gdata.server.GDataRequest.OutputFormat;
+import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
+import org.apache.lucene.gdata.server.registry.ProvidedService;
+import org.apache.lucene.gdata.server.registry.RegistryException;
+import org.apache.lucene.gdata.utils.ProvidedServiceStub;
+import org.apache.lucene.gdata.utils.StorageStub;
+import org.easymock.MockControl;
-import junit.framework.TestCase;
-
-import org.apache.lucene.gdata.server.GDataRequest.GDataRequestType;
-import org.apache.lucene.gdata.server.GDataRequest.OutputFormat;
-import org.apache.lucene.gdata.server.registry.FeedInstanceConfigurator;
-import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
-import org.easymock.MockControl;
-
-import com.google.gdata.data.ExtensionProfile;
-import com.google.gdata.data.Feed;
-
/**
*
* @author Simon Willnauer
@@ -39,14 +39,21 @@
private MockControl control;
private GDataRequest feedRequest;
-
+ static{
+ try {
+ GDataServerRegistry.getRegistry().registerComponent(StorageStub.class);
+ } catch (RegistryException e) {
+
+ e.printStackTrace();
+ }
+ }
+
@Override
protected void setUp() throws Exception {
- FeedInstanceConfigurator configurator = new FeedInstanceConfigurator();
- configurator.setFeedType(Feed.class);
- configurator.setFeedId("feed");
- configurator.setExtensionProfileClass(ExtensionProfile.class);
- GDataServerRegistry.getRegistry().registerFeed(configurator);
+ ProvidedService configurator = new ProvidedServiceStub();
+ GDataServerRegistry.getRegistry().registerService(configurator);
+
+
this.control = MockControl.createControl(HttpServletRequest.class);
this.request = (HttpServletRequest) this.control.getMock();
this.feedRequest = new GDataRequest(this.request,GDataRequestType.GET);
@@ -216,7 +223,7 @@
public void testGetSelfId() throws GDataRequestException{
String host = "www.apache.org";
String feedAndEntryID = "/feed/entryid";
- String queryString = "?max-results=25";
+ String queryString = "max-results=25";
this.control.expectAndDefaultReturn(this.request.getHeader("Host"),host);
this.control.expectAndDefaultReturn(this.request.getRequestURI(),"/host/feed/entryId/15");
this.control.expectAndDefaultReturn(this.request.getPathInfo(),"/feed/entryId/15");
@@ -227,13 +234,13 @@
queryString);
this.control.replay();
this.feedRequest.initializeRequest();
- String selfID = "http://"+host+"/host/feed/entryId/15"+queryString;
+ String selfID = "http://"+host+"/host/feed/entryId/15?"+queryString;
assertEquals("Self ID",selfID,this.feedRequest.getSelfId());
this.control.reset();
- queryString = "?alt=rss&max-results=25";
+ queryString = "alt=rss&max-results=25";
this.control.expectAndDefaultReturn(this.request.getHeader("Host"),host);
this.control.expectAndDefaultReturn(this.request.getRequestURI(),"/host/feed/entryId/15");
this.control.expectAndDefaultReturn(this.request.getPathInfo(),"/feed/entryId/15");
@@ -244,7 +251,7 @@
queryString);
this.control.replay();
this.feedRequest.initializeRequest();
- selfID = "http://"+host+"/host/feed/entryId/15"+queryString;
+ selfID = "http://"+host+"/host/feed/entryId/15?"+queryString;
assertEquals("Self ID",selfID,this.feedRequest.getSelfId());
this.control.reset();
@@ -296,7 +303,7 @@
queryString);
this.control.replay();
- assertEquals("?"+maxResults,this.feedRequest.getQueryString());
+ assertEquals(maxResults,this.feedRequest.getQueryString());
this.control.reset();
}
@@ -342,8 +349,12 @@
}
- public void testIsEntryRequest(){
-
+ public void testgetAuthToken(){
+ this.control.expectAndDefaultReturn(this.request.getHeader("Authentication"),"GoogleLogin auth=bla");
+ this.control.replay();
+ assertEquals("bla",this.feedRequest.getAuthToken());
+ this.control.verify();
+
}
public void testGetNextId() throws GDataRequestException{
@@ -352,7 +363,8 @@
// String queryString = "?max-results=25";
// String startIndex = "&start-index=26";
// this.control.expectAndDefaultReturn(this.request.getHeader("Host"),host);
-// this.control.expectAndDefaultReturn(this.request.getPathInfo(),"/feed/entryId/15");
+// this.control.expectAndDefaultReturn(this.request.getRequestURI(),"/feed/");
+// this.control.expectAndDefaultReturn(this.request.getPathInfo(),"/feed/");
// this.control.expectAndReturn(this.request.getParameter("max-results"),"25",2);
// this.control.expectAndReturn(this.request.getParameter("start-index"),null);
// this.control.expectAndDefaultReturn(this.request.getParameter("alt"),
@@ -361,22 +373,27 @@
// queryString);
// this.control.replay();
// this.feedRequest.initializeRequest();
-// String nextID = "http://"+host+"/feed"+queryString+startIndex;
+// String nextID = "http://"+host+"/feed/"+queryString+startIndex;
//
// assertEquals("Next ID",nextID,this.feedRequest.getNextId());
// this.control.reset();
-//
-//
+
+
// queryString = "?alt=rss&max-results=25";
//
// this.control.expectAndDefaultReturn(this.request.getHeader("Host"),host);
-// this.control.expectAndDefaultReturn(this.request.getPathInfo(),"/feed/entryId/15");
+// this.control.expectAndDefaultReturn(this.request.getRequestURI(),"/feed/");
+// this.control.expectAndDefaultReturn(this.request.getPathInfo(),"/feed/");
// this.control.expectAndReturn(this.request.getParameter("max-results"),"25",2);
// this.control.expectAndReturn(this.request.getParameter("start-index"),"26",2);
// this.control.expectAndDefaultReturn(this.request.getParameter("alt"),
// null);
// this.control.expectAndDefaultReturn(this.request.getQueryString(),
// queryString+startIndex);
+// Enumeration e =
+// this.control.expectAndDefaultReturn(this.request.getParameterNames(),)
+//
+//
// this.control.replay();
// this.feedRequest.initializeRequest();
// startIndex = "&start-index=51";
@@ -395,7 +412,7 @@
// null);
// this.control.replay();
// this.feedRequest.initializeRequest();
-// selfID = "http://"+host+"/feed"+"?max-results=25";
+// String selfID = "http://"+host+"/feed"+"?max-results=25";
//
// assertEquals("Self ID",selfID,this.feedRequest.getSelfId());
// this.control.reset();
Index: gdata-server/src/test/org/apache/lucene/gdata/data/TestGDataUser.java
===================================================================
--- gdata-server/src/test/org/apache/lucene/gdata/data/TestGDataUser.java (revision 0)
+++ gdata-server/src/test/org/apache/lucene/gdata/data/TestGDataUser.java (revision 0)
@@ -0,0 +1,65 @@
+package org.apache.lucene.gdata.data;
+
+import org.apache.lucene.gdata.data.GDataAccount.AccountRole;
+
+import junit.framework.TestCase;
+
+public class TestGDataUser extends TestCase {
+ private GDataAccount user;
+ @Override
+ protected void setUp() throws Exception {
+ this.user = new GDataAccount();
+ this.user.setName("simon");
+ super.setUp();
+ }
+
+ @Override
+ protected void tearDown() throws Exception {
+
+ super.tearDown();
+ }
+
+ /*
+ * Test method for 'org.apache.lucene.gdata.data.GDataUser.isUserInRole(UserRole)'
+ */
+ public void testIsUserInRole() {
+ assertTrue(this.user.isUserInRole(AccountRole.USER));
+ assertFalse(this.user.isUserInRole(AccountRole.ENTRYAMINISTRATOR));
+ this.user.setRole(AccountRole.ENTRYAMINISTRATOR);
+ assertTrue(this.user.isUserInRole(AccountRole.ENTRYAMINISTRATOR));
+ }
+
+ /*
+ * Test method for 'org.apache.lucene.gdata.data.GDataUser.getRolesAsInt()'
+ */
+ public void testGetRolesAsInt() {
+ assertEquals(1,this.user.getRolesAsInt());
+ this.user.setRole(AccountRole.ENTRYAMINISTRATOR);
+ assertEquals(3,this.user.getRolesAsInt());
+ this.user.setRole(AccountRole.FEEDAMINISTRATOR);
+ assertEquals(7,this.user.getRolesAsInt());
+ this.user.setRole(AccountRole.USERADMINISTRATOR);
+ assertEquals(15,this.user.getRolesAsInt());
+
+ }
+
+ /*
+ * Test method for 'org.apache.lucene.gdata.data.GDataUser.setRolesAsInt(int)'
+ */
+ public void testSetRolesAsInt() {
+ this.user.setRolesAsInt(2);
+ this.user.setRolesAsInt(4);
+ this.user.setRolesAsInt(8);
+ assertEquals(4,this.user.getRoles().size());
+ this.user.setRolesAsInt(15);
+ assertEquals(4,this.user.getRoles().size());
+ this.user = new GDataAccount();
+ this.user.setName("simon");
+ this.user.setRolesAsInt(15);
+ assertEquals(4,this.user.getRoles().size());
+
+ }
+
+
+
+}
Index: gdata-server/src/test/lucenestorage.properties.xml
===================================================================
--- gdata-server/src/test/lucenestorage.properties.xml (revision 0)
+++ gdata-server/src/test/lucenestorage.properties.xml (revision 0)
@@ -0,0 +1,12 @@
+
+
+
+Lucene Storage Properties
+20
+20
+20
+true
+/tmp/storage/
+true
+false
+
Index: gdata-server/src/java/org/apache/lucene/gdata/utils/DateFormater.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/utils/DateFormater.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/utils/DateFormater.java (revision 0)
@@ -0,0 +1,125 @@
+/**
+ * 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.utils;
+
+import java.text.ParseException;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+import java.util.Stack;
+
+/**
+ * This class uses the {@link java.text.SimpleDateFormat} class to format dates
+ * into strings according to given date pattern.
+ *
+ * As the creation of SimpleDateFormat objects is quiet expensive and
+ * formating dates is used quiet fequently the objects will be cached and reused
+ * in subsequent calls.
+ *
+ *
+ * This implementation is thread safe as it uses {@link java.util.Stack} as a
+ * cache
+ *
+ *
+ * @author Simon Willnauer
+ *
+ */
+public class DateFormater {
+ private final Stack objectStack = new Stack();
+
+ private static final DateFormater formater = new DateFormater();
+
+ /**
+ * Date format as it is used in Http Last modified header (Tue, 15 Nov 1994
+ * 12:45:26 GMT)
+ */
+ public static String HTTP_HEADER_DATE_FORMAT = "EEE, d MMM yyyy HH:mm:ss z";
+ /**
+ * Date format as it is used in Http Last modified header (Tue, 15 Nov 1994
+ * 12:45:26 +0000)
+ */
+ public static String HTTP_HEADER_DATE_FORMAT_TIME_OFFSET = "EEE, d MMM yyyy HH:mm:ss Z";
+
+ private DateFormater() {
+ super();
+ }
+
+ /**
+ * Formats the given Date into the given date pattern.
+ *
+ * @param date -
+ * the date to format
+ * @param format -
+ * date pattern
+ * @return - the string representation of the given Date
+ * according to the given pattern
+ */
+ public static String formatDate(final Date date, String format) {
+ if (date == null || format == null)
+ throw new IllegalArgumentException(
+ "given parameters must not be null");
+ SimpleDateFormat inst = formater.getFormater();
+ inst.applyPattern(format);
+ formater.returnFomater(inst);
+ return inst.format(date);
+ }
+ /**
+ * Parses the given string into one of the specified formates
+ * @param date - the string to parse
+ * @param formates - formates
+ * @return a {@link Date} instance representing the given string
+ * @throws ParseException - if the string can not be parsed
+ */
+ public static Date parseDate(final String date, final String...formates) throws ParseException{
+ for (int i = 0; i < formates.length; i++) {
+ try {
+ return parseDate(date,formates[i]);
+ } catch (ParseException e) {
+ //
+ }
+ }
+ throw new ParseException("Unparseable date: "+date,0);
+
+ }
+
+ /**
+ * Parses the given string into the specified formate
+ * @param dateString - the string to parse
+ * @param pattern - the expected formate
+ * @return a {@link Date} instance representing the given string
+ * @throws ParseException - if the string can not be parsed
+ */
+ public static Date parseDate(final String dateString,String pattern) throws ParseException{
+ if(dateString == null|| pattern == null)
+ throw new IllegalArgumentException(
+ "given parameters must not be null");
+ SimpleDateFormat inst = formater.getFormater();
+ inst.applyPattern(pattern);
+ return inst.parse(dateString);
+ }
+
+ private SimpleDateFormat getFormater() {
+ if (this.objectStack.empty())
+ return new SimpleDateFormat();
+ return this.objectStack.pop();
+ }
+
+ private void returnFomater(final SimpleDateFormat format) {
+ if (this.objectStack.size() <= 25)
+ this.objectStack.push(format);
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/utils/package.html
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/utils/package.html (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/utils/package.html (revision 0)
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+Utils package
+
+
Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/RequestControllerServlet.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/servlet/RequestControllerServlet.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/servlet/RequestControllerServlet.java (working copy)
@@ -1,122 +1,102 @@
-/**
- * Copyright 2004 The Apache Software Foundation
+/**
+ * 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.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.GDataRequestHandler;
+
+/**
+ * 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.
*
- * 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
+ * @author Simon Willnauer
*
- * 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);
-
- }
-
-
-}
+ */
+public class RequestControllerServlet extends AbstractGdataServlet {
+ 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.getEntryDeleteHandler();
+ 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.getFeedQueryHandler();
+ 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.getEntryInsertHandler();
+ 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.getEntryUpdateHandler();
+ if(LOGGER.isInfoEnabled())
+ LOGGER.info("Process PUT request");
+ hanlder.processRequest(arg0, arg1);
+ }
+
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/AuthenticationServlet.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/servlet/AuthenticationServlet.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/servlet/AuthenticationServlet.java (revision 0)
@@ -0,0 +1,50 @@
+/**
+ * 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;
+
+import org.apache.lucene.gdata.servlet.handler.AuthenticationHandler;
+
+/**
+ * REST interface for handling authentification requests from clients to get a
+ * auth token either as a cookie or as a plain auth token. This Servlet uses a
+ * single {@link org.apache.lucene.gdata.servlet.handler.AuthenticationHandler}
+ * instance to handle the incoming requests.
+ *
+ * @author Simon Willnauer
+ *
+ */
+public class AuthenticationServlet extends HttpServlet {
+
+ private final AuthenticationHandler handler = new AuthenticationHandler();
+
+ private static final long serialVersionUID = 7132478125868917848L;
+
+ @SuppressWarnings("unused")
+ @Override
+ protected void doPost(HttpServletRequest request,
+ HttpServletResponse response) throws ServletException, IOException {
+ this.handler.processRequest(request, response);
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/AccountAdministrationServlet.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/servlet/AccountAdministrationServlet.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/servlet/AccountAdministrationServlet.java (revision 0)
@@ -0,0 +1,73 @@
+/**
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.gdata.servlet;
+
+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.servlet.handler.GDataRequestHandler;
+
+/**
+ * This Servlet provides an REST interface to create / update and delete user instances.
+ * @author Simon Willnauer
+ *
+ */
+public class AccountAdministrationServlet extends AbstractGdataServlet {
+
+ private static final Log LOGGER = LogFactory.getLog(AccountAdministrationServlet.class);
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 8215863212137543185L;
+
+ @Override
+ protected void doDelete(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
+ GDataRequestHandler handler = HANDLER_FACTORY.getDeleteAccountHandler();
+ if(LOGGER.isInfoEnabled())
+ LOGGER.info("Process delete Account request");
+ handler.processRequest(arg0,arg1);
+
+ }
+
+ @Override
+ protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
+ GDataRequestHandler handler = HANDLER_FACTORY.getInsertAccountHandler();
+ if(LOGGER.isInfoEnabled())
+ LOGGER.info("Process insert Account request");
+ handler.processRequest(arg0,arg1);
+
+ }
+
+ @Override
+ protected void doPut(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
+
+ GDataRequestHandler handler = HANDLER_FACTORY.getUpdateAccountHandler();
+ if(LOGGER.isInfoEnabled())
+ LOGGER.info("Process update Account request");
+ handler.processRequest(arg0,arg1);
+ }
+
+
+
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/AbstractGdataServlet.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/servlet/AbstractGdataServlet.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/servlet/AbstractGdataServlet.java (working copy)
@@ -18,10 +18,15 @@
import java.io.IOException;
+import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
+
+import org.apache.lucene.gdata.server.registry.ComponentType;
+import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
+import org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory;
/**
*
@@ -42,7 +47,9 @@
private static final String METHOD_POST = "POST";
- private static final String METHOD_PUT = "PUT";
+ private static final String METHOD_PUT = "PUT";
+
+ protected static RequestHandlerFactory HANDLER_FACTORY = null;
/**
* This overwrites the protected service method to dispatch
@@ -92,6 +99,17 @@
super.service(arg0, arg1);
}
+ }
+
+ /**
+ *
+ * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig)
+ */
+ public void init(ServletConfig arg0) throws ServletException {
+ HANDLER_FACTORY = GDataServerRegistry.getRegistry().lookup(RequestHandlerFactory.class,ComponentType.REQUESTHANDLERFACTORY);
+ if(HANDLER_FACTORY == null)
+ throw new ServletException("service not available");
+
}
}
Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DeleteAccountStrategy.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DeleteAccountStrategy.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DeleteAccountStrategy.java (revision 0)
@@ -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.servlet.handler;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.lucene.gdata.data.GDataAccount;
+import org.apache.lucene.gdata.server.ServiceException;
+
+/**
+ * @author Simon Willnauer
+ *
+ */
+public class DeleteAccountStrategy extends AbstractAccountHandler {
+
+ private static final Log LOG = LogFactory.getLog(DefaultDeleteHandler.class);
+
+
+
+ @Override
+ protected void processServiceAction(GDataAccount account) throws ServiceException {
+ try{
+ this.service.deleteAccount(account);
+ }catch (ServiceException e) {
+ LOG.error("Can't delete account -- "+e.getMessage(),e);
+ throw e;
+ }
+
+ }
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/InsertAccountStrategy.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/InsertAccountStrategy.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/InsertAccountStrategy.java (revision 0)
@@ -0,0 +1,48 @@
+/**
+ * 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 org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.lucene.gdata.data.GDataAccount;
+import org.apache.lucene.gdata.server.ServiceException;
+
+/**
+ * @author Simon Willnauer
+ *
+ */
+public class InsertAccountStrategy extends AbstractAccountHandler {
+ private static final Log LOG = LogFactory.getLog(InsertAccountStrategy.class);
+
+
+
+ @Override
+ protected void processServiceAction(GDataAccount account) throws ServiceException {
+ try{
+ this.service.createAccount(account);
+ }catch (ServiceException e) {
+ LOG.error("Can't create account -- "+e.getMessage(),e);
+ throw e;
+ }
+
+ }
+
+
+
+
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/UpdateFeedHandler.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/UpdateFeedHandler.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/UpdateFeedHandler.java (revision 0)
@@ -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.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.data.GDataAccount;
+import org.apache.lucene.gdata.data.ServerBaseFeed;
+import org.apache.lucene.gdata.server.ServiceException;
+import org.apache.lucene.gdata.server.ServiceFactory;
+import org.apache.lucene.gdata.server.registry.ComponentType;
+import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
+
+/**
+ * @author Simon Willnauer
+ *
+ */
+public class UpdateFeedHandler extends AbstractFeedHandler {
+ private static final Log LOG = LogFactory.getLog(UpdateFeedHandler.class);
+
+ /**
+ * @see org.apache.lucene.gdata.servlet.handler.AbstractFeedHandler#processRequest(javax.servlet.http.HttpServletRequest,
+ * javax.servlet.http.HttpServletResponse)
+ */
+ @SuppressWarnings("unused")
+ @Override
+ public void processRequest(HttpServletRequest request,
+ HttpServletResponse response) throws ServletException, IOException {
+ super.processRequest(request, response);
+ if (this.authenticated) {
+ try {
+ ServerBaseFeed feed = createFeedFromRequest(request);
+ GDataAccount account = createRequestedAccount(request);
+
+ GDataServerRegistry registry = GDataServerRegistry
+ .getRegistry();
+ ServiceFactory serviceFactory = registry.lookup(
+ ServiceFactory.class, ComponentType.SERVICEFACTORY);
+ if (serviceFactory == null) {
+ setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+ "required component is not available");
+ throw new FeedHandlerException(
+ "Can't update feed - ServiceFactory is null");
+ }
+ serviceFactory.getAdminService().updateFeed(feed, account);
+ } catch (ServiceException e) {
+ setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+ "can not update feed");
+ LOG.error("Can not update feed -- " + e.getMessage(), e);
+ } catch (Exception e) {
+
+ LOG.error("Can not update feed -- " + e.getMessage(), e);
+
+ }
+ }
+ sendResponse(response);
+
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultDeleteHandler.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultDeleteHandler.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultDeleteHandler.java (working copy)
@@ -1,84 +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.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.
- *
- * The handler sends following response to the client:
- *
- *
- *
if the entry could be deleted - HTTP status code 200 OK
- *
if an error occures - HTTP status code 500 INTERNAL SERVER ERROR
- *
if the resource could not found - HTTP status code 404 NOT FOUND
- *
- *
- * @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();
- }
-
- }
-
-}
+/**
+ * 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.data.GDataAccount.AccountRole;
+import org.apache.lucene.gdata.server.GDataRequestException;
+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.
+ *
+ * The handler sends following response to the client:
+ *
+ *
+ *
if the entry could be deleted - HTTP status code 200 OK
+ *
if an error occures - HTTP status code 500 INTERNAL SERVER ERROR
+ *
if the resource could not found - HTTP status code 404 NOT FOUND
+ *
+ *
+ * @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;
+ }
+ if(!authenticateAccount(request,AccountRole.ENTRYAMINISTRATOR)){
+ setError(HttpServletResponse.SC_UNAUTHORIZED);
+ sendError();
+ return;
+ }
+
+ try {
+ this.service.deleteEntry(this.feedRequest, this.feedResponse);
+
+ } catch (ServiceException e) {
+ LOG.error("Could not process DeleteFeed request - "
+ + e.getMessage(), e);
+ sendError();
+ }
+ closeService();
+
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultInsertHandler.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultInsertHandler.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultInsertHandler.java (working copy)
@@ -1,83 +1,86 @@
-/**
- * Copyright 2004 The Apache Software Foundation
+/**
+ * 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.data.GDataAccount.AccountRole;
+import org.apache.lucene.gdata.server.GDataRequestException;
+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.
+ *
+ * The handler sends following response to the client:
+ *
+ *
+ *
if the entry was added - HTTP status code 200 OK
+ *
if an error occures - HTTP status code 500 INTERNAL SERVER ERROR
+ *
if the resource could not found - HTTP status code 404 NOT FOUND
+ *
+ *
The added entry will be send back to the client if the insert request was successful.
*
- * 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.
- *
- * The handler sends following response to the client:
- *
- *
- *
if the entry was added - HTTP status code 200 OK
- *
if an error occures - HTTP status code 500 INTERNAL SERVER ERROR
- *
if the resource could not found - HTTP status code 404 NOT FOUND
- *
- *
The added entry will be send back to the client if the insert request was successful.
- *
- * @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();
- }
-
-
- }
-
-}
+ * @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;
+ }
+ if(!authenticateAccount(this.feedRequest,AccountRole.ENTRYAMINISTRATOR)){
+ setError(HttpServletResponse.SC_UNAUTHORIZED);
+ sendError();
+ return;
+ }
+
+ try{
+ BaseEntry entry = this.service.createEntry(this.feedRequest,this.feedResponse);
+ setFeedResponseFormat();
+ setFeedResponseStatus(HttpServletResponse.SC_CREATED);
+ this.feedResponse.sendResponse(entry, this.feedRequest.getConfigurator().getExtensionProfile());
+
+ }catch (ServiceException e) {
+ LOG.error("Could not process GetFeed request - "+e.getMessage(),e);
+ this.feedResponse.sendError();
+ }
+ closeService();
+
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractGdataRequestHandler.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractGdataRequestHandler.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractGdataRequestHandler.java (working copy)
@@ -1,96 +1,104 @@
-/**
- * Copyright 2004 The Apache Software Foundation
+/**
+ * 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;
+import org.apache.lucene.gdata.server.registry.ComponentType;
+import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
+
+/**
+ * @author Simon Willnauer
*
- * 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;
- }
-
-
-
-}
+ */
+public abstract class AbstractGdataRequestHandler extends RequestAuthenticator implements
+ GDataRequestHandler {
+ private final static Log LOG = LogFactory
+ .getLog(AbstractGdataRequestHandler.class);
+
+ protected Service service;
+ 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, ServletException {
+ this.feedRequest = new GDataRequest(request, type);
+ this.feedResponse = new GDataResponse(response);
+ getService();
+ 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);
+ }
+
+ private void getService() throws ServletException {
+ GDataServerRegistry registry = GDataServerRegistry.getRegistry();
+ ServiceFactory serviceFactory = registry.lookup(ServiceFactory.class,ComponentType.SERVICEFACTORY);
+ this.service = serviceFactory.getService();
+ if(this.service == null)
+ throw new ServletException("Service not available");
+
+ }
+
+ protected void closeService(){
+ this.service.close();
+ }
+
+
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AuthenticationHandler.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AuthenticationHandler.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AuthenticationHandler.java (revision 0)
@@ -0,0 +1,124 @@
+/**
+ * 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 java.io.Writer;
+
+import javax.servlet.ServletException;
+import javax.servlet.http.Cookie;
+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.data.GDataAccount;
+import org.apache.lucene.gdata.server.ServiceException;
+import org.apache.lucene.gdata.server.ServiceFactory;
+import org.apache.lucene.gdata.server.administration.AdminService;
+import org.apache.lucene.gdata.server.authentication.AuthenticationController;
+import org.apache.lucene.gdata.server.authentication.AuthenticationException;
+import org.apache.lucene.gdata.server.registry.ComponentType;
+import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
+
+
+
+/**
+ * @author Simon Willnauer
+ *
+ */
+public class AuthenticationHandler implements GDataRequestHandler {
+ private static final Log LOG = LogFactory.getLog(AuthenticationHandler.class);
+ private final AuthenticationController controller;
+ private final static String errorKey = "Error";
+ private final static char seperatory = '=';
+ private final ServiceFactory serviceFactory;
+ private final GDataServerRegistry registry;
+ /**
+ *
+ */
+ public AuthenticationHandler() {
+ this.registry = GDataServerRegistry.getRegistry();
+ this.controller = this.registry.lookup(AuthenticationController.class, ComponentType.AUTHENTICATIONCONTROLLER);
+ this.serviceFactory = this.registry.lookup(ServiceFactory.class, ComponentType.SERVICEFACTORY);
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.servlet.handler.GDataRequestHandler#processRequest(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ @SuppressWarnings("unused")
+ public void processRequest(HttpServletRequest request,
+ HttpServletResponse response) throws ServletException, IOException {
+
+ try {
+ String serviceName = request.getParameter(AuthenticationController.SERVICE_PARAMETER);
+ if(LOG.isInfoEnabled()){
+ String application = request.getParameter(AuthenticationController.APPLICATION_PARAMETER);
+ LOG.info("Authentication request for service: "+serviceName+"; Application name: "+application);
+ }
+
+ if(!this.registry.isServiceRegistered(serviceName))
+ throw new AuthenticationException("requested Service "+serviceName+"is not registered");
+ String password = request.getParameter(AuthenticationController.PASSWORD_PARAMETER);
+ String accountName = request.getParameter(AuthenticationController.ACCOUNT_PARAMETER);
+ String clientIp = request.getRemoteHost();
+
+
+
+ GDataAccount account = getAccount(accountName);
+ if(account == null || !account.getPassword().equals(password))
+ throw new AuthenticationException("Account is null or password does not match");
+
+ String token = this.controller.authenticatAccount(account,clientIp);
+ sendToken(response,token);
+ if(LOG.isInfoEnabled()){
+
+ LOG.info("Account authenticated -- "+account);
+ }
+ } catch (AuthenticationException e){
+ LOG.error("BadAuthentication -- "+e.getMessage(),e);
+ sendError(response, HttpServletResponse.SC_FORBIDDEN,"BadAuthentication");
+ }catch (Exception e) {
+ LOG.error("Unexpected Exception -- SERVERERROR -- "+e.getMessage(),e);
+ sendError(response,HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Service not available");
+ }
+ }
+
+
+ private GDataAccount getAccount(String accountName) throws ServiceException{
+ AdminService service = this.serviceFactory.getAdminService();
+ return service.getAccount(accountName);
+
+ }
+ private void sendError(HttpServletResponse response, int code, String message)throws IOException{
+ Writer writer = response.getWriter();
+ writer.write(errorKey);
+ writer.write(seperatory);
+ writer.write(message);
+ response.sendError(code);
+ }
+
+ private void sendToken(HttpServletResponse response, String token) throws IOException{
+ Writer responseWriter = response.getWriter();
+ Cookie cookie = new Cookie(AuthenticationController.TOKEN_KEY,token);
+ response.addCookie(cookie);
+ responseWriter.write(AuthenticationController.TOKEN_KEY);
+ responseWriter.write(seperatory);
+ responseWriter.write(token);
+ responseWriter.close();
+ }
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractAccountHandler.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractAccountHandler.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractAccountHandler.java (revision 0)
@@ -0,0 +1,186 @@
+/**
+ * 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.data.GDataAccount;
+import org.apache.lucene.gdata.data.GDataAccount.AccountRole;
+import org.apache.lucene.gdata.server.ServiceException;
+import org.apache.lucene.gdata.server.ServiceFactory;
+import org.apache.lucene.gdata.server.administration.AccountBuilder;
+import org.apache.lucene.gdata.server.administration.AdminService;
+import org.apache.lucene.gdata.server.registry.ComponentType;
+import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
+import org.xml.sax.SAXException;
+
+/**
+ * @author Simon Willnauer
+ *
+ */
+public abstract class AbstractAccountHandler extends RequestAuthenticator
+ implements GDataRequestHandler {
+ private static final Log LOG = LogFactory
+ .getLog(AbstractAccountHandler.class);
+
+ private boolean authenticated = false;
+
+ private int error;
+
+ private String errorMessage = "";
+
+ private boolean isError = false;
+
+ protected AdminService service;
+
+ /**
+ * @see org.apache.lucene.gdata.servlet.handler.GDataRequestHandler#processRequest(javax.servlet.http.HttpServletRequest,
+ * javax.servlet.http.HttpServletResponse)
+ */
+ @SuppressWarnings("unused")
+ public void processRequest(HttpServletRequest request,
+ HttpServletResponse response) throws ServletException, IOException {
+
+ this.authenticated = authenticateAccount(request,
+ AccountRole.USERADMINISTRATOR);
+
+ if (this.authenticated) {
+ GDataServerRegistry registry = GDataServerRegistry.getRegistry();
+ ServiceFactory factory = registry.lookup(ServiceFactory.class,
+ ComponentType.SERVICEFACTORY);
+ try {
+
+ GDataAccount account = getAccountFromRequest(request);
+ if (!account.requiredValuesSet()) {
+ setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+ "requiered server component not available");
+ throw new AccountHandlerException(
+ "requiered values are not set -- account can not be saved -- "
+ + account);
+ }
+ this.service = factory.getAdminService();
+ processServiceAction(account);
+ } catch (ServiceException e) {
+ LOG.error("Can't process account action -- " + e.getMessage(),
+ e);
+ setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "");
+ } catch (Exception e) {
+ LOG.error("Can't process account action -- " + e.getMessage(),
+ e);
+ }
+ }else{
+ setError(HttpServletResponse.SC_UNAUTHORIZED,"Authorization failed");
+ }
+ sendResponse(response);
+
+ }
+
+
+
+
+ protected GDataAccount getAccountFromRequest(
+ final HttpServletRequest request) throws AccountHandlerException {
+ try {
+ GDataAccount account = AccountBuilder.buildAccount(request
+ .getReader());
+ if (account == null) {
+ setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "");
+ throw new AccountHandlerException(
+ "unexpected value -- parsed account is null");
+ }
+ return account;
+ } catch (IOException e) {
+ setError(HttpServletResponse.SC_BAD_REQUEST, "can not read input");
+ throw new AccountHandlerException("Can't read from request reader",
+ e);
+ } catch (SAXException e) {
+ setError(HttpServletResponse.SC_BAD_REQUEST,
+ "can not parse gdata account");
+ throw new AccountHandlerException(
+ "Can not parse incoming gdata account", e);
+ }
+ }
+
+ protected void sendResponse(HttpServletResponse response) {
+
+ if (!this.isError)
+ return;
+ try {
+ response.sendError(this.error, this.errorMessage);
+ } catch (IOException e) {
+ LOG.warn("can send error in RequestHandler ", e);
+ }
+ }
+
+ protected void setError(int error, String message) {
+ this.error = error;
+ this.errorMessage = message;
+ this.isError = true;
+ }
+
+ protected int getErrorCode() {
+ return this.error;
+ }
+
+ protected String getErrorMessage() {
+ return this.errorMessage;
+ }
+
+ protected abstract void processServiceAction(final GDataAccount account)
+ throws ServiceException;
+
+ static class AccountHandlerException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 3140463271122190694L;
+
+ /**
+ * Constructs a new AccountHandlerException with an exception
+ * message and the exception caused this exception.
+ *
+ * @param arg0 -
+ * the exception message
+ * @param arg1 -
+ * the exception cause
+ */
+ public AccountHandlerException(String arg0, Throwable arg1) {
+ super(arg0, arg1);
+
+ }
+
+ /**
+ * Constructs a new AccountHandlerException with an exception
+ * message.
+ *
+ * @param arg0 -
+ * the exception message
+ */
+ public AccountHandlerException(String arg0) {
+ super(arg0);
+
+ }
+
+ }
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/RequestHandlerFactory.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/RequestHandlerFactory.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/RequestHandlerFactory.java (working copy)
@@ -1,122 +1,98 @@
-/**
- * Copyright 2004 The Apache Software Foundation
+/**
+ * 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 org.apache.lucene.gdata.server.registry.ServerComponent;
+
+/**
+ * Abstract Superclass for RequestHandlerFactories
+ * @author Simon Willnauer
*
- * 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);
-
- }
-
- }
-
-}
+ */
+public abstract class RequestHandlerFactory implements ServerComponent {
+
+
+
+
+ /**
+ * public constructor to enable loading via the registry
+ * @see org.apache.lucene.gdata.server.registry.Component
+ * @see org.apache.lucene.gdata.server.registry.GDataServerRegistry
+ */
+ public RequestHandlerFactory() {
+ super();
+
+ }
+
+
+ /**
+ * Creates a EntryUpdateHandler which processes a GDATA UPDATE request.
+ * @return - a RequestHandlerInstance
+ */
+ public abstract GDataRequestHandler getEntryUpdateHandler();
+
+ /**
+ * Creates a EntryDeleteHandler which processes a GDATA DELETE request.
+ * @return - a RequestHandlerInstance
+ */
+ public abstract GDataRequestHandler getEntryDeleteHandler();
+
+ /**
+ * Creates a FeedQueryHandler which processes a GDATA Query / Get request.
+ * @return - a RequestHandlerInstance
+ */
+ public abstract GDataRequestHandler getFeedQueryHandler();
+
+ /**
+ * Creates a EntryInsertHandler which processes a GDATA Insert request.
+ * @return - a RequestHandlerInstance
+ */
+ public abstract GDataRequestHandler getEntryInsertHandler();
+ /**
+ * Creates a InsertAccountHandler which processes a Account Insert request.
+ * @return - a RequestHandlerInstance
+ */
+ public abstract GDataRequestHandler getInsertAccountHandler();
+ /**
+ * Creates a DeleteAccountHandler which processes a Account Delete request.
+ * @return - a RequestHandlerInstance
+ */
+ public abstract GDataRequestHandler getDeleteAccountHandler();
+ /**
+ * Creates a UpdateAccountHandler which processes a Account Update request.
+ * @return - a RequestHandlerInstance
+ */
+ public abstract GDataRequestHandler getUpdateAccountHandler();
+ /**
+ * Creates a InsertFeedHandler which processes a Feed Insert request.
+ * @return - a RequestHandlerInstance
+ */
+ public abstract GDataRequestHandler getInsertFeedHandler();
+ /**
+ * Creates a UpdateFeedHandler which processes a Feed Insert request.
+ * @return - a RequestHandlerInstance
+ */
+ public abstract GDataRequestHandler getUpdateFeedHandler();
+ /**
+ * Creates a DeleteFeedHandler which processes a Feed Insert request.
+ * @return - a RequestHandlerInstance
+ */
+ public abstract GDataRequestHandler getDeleteFeedHandler();
+
+
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/UpdataAccountStrategy.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/UpdataAccountStrategy.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/UpdataAccountStrategy.java (revision 0)
@@ -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.servlet.handler;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.lucene.gdata.data.GDataAccount;
+import org.apache.lucene.gdata.server.ServiceException;
+
+/**
+ * @author Simon Willnauer
+ *
+ */
+public class UpdataAccountStrategy extends AbstractAccountHandler {
+
+ private static final Log LOG = LogFactory.getLog(UpdataAccountStrategy.class);
+
+
+
+ @Override
+ protected void processServiceAction(GDataAccount account) throws ServiceException {
+ try{
+ this.service.updateAccount(account);
+ }catch (ServiceException e) {
+ LOG.error("Can't update account -- "+e.getMessage(),e);
+ throw e;
+ }
+
+ }
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultGetHandler.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultGetHandler.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultGetHandler.java (working copy)
@@ -1,104 +1,138 @@
-/**
- * Copyright 2004 The Apache Software Foundation
+/**
+ * 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 java.util.Date;
+
+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 org.apache.lucene.gdata.utils.DateFormater;
+
+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.
+ *
+ * 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.
+ *
+ *
+ * The DefaultGetHandler supports HTTP Conditional GET. It set the Last-Modified
+ * response header based upon the value of the element in the
+ * returned feed or entry. A client can send this value back as the value of the
+ * If-Modified-Since request header to avoid retrieving the content again if it
+ * hasn't changed. If the content hasn't changed since the If-Modified-Since
+ * time, then the GData service returns a 304 (Not Modified) HTTP response.
*
- * 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
+ * @author Simon Willnauer
*
- * 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.
- *
- * 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.
- *
- *
- *
- * @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();
- }
-
-
-
- }
-
-
-
-}
+ */
+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;
+ }
+
+ try {
+ String modifiedSince = this.feedRequest.getModifiedSince();
+ if (!checkIsModified(modifiedSince)) {
+ this.feedResponse
+ .setStatus(HttpServletResponse.SC_NOT_MODIFIED);
+ return;
+ }
+ if (LOG.isInfoEnabled())
+ LOG.info("Requested output formate: "
+ + this.feedRequest.getRequestedResponseFormat());
+ this.feedResponse.setOutputFormat(this.feedRequest
+ .getRequestedResponseFormat());
+ if (this.feedRequest.isFeedRequested()) {
+ BaseFeed feed = this.service.getFeed(this.feedRequest,
+ this.feedResponse);
+
+ this.feedResponse.sendResponse(feed, this.feedRequest
+ .getConfigurator().getExtensionProfile());
+ } else {
+ BaseEntry entry = this.service.getSingleEntry(this.feedRequest,
+ this.feedResponse);
+ this.feedResponse.sendResponse(entry, this.feedRequest
+ .getConfigurator().getExtensionProfile());
+ }
+
+ } catch (ServiceException e) {
+ LOG.error("Could not process GetFeed request - " + e.getMessage(),
+ e);
+ sendError();
+ }
+ closeService();
+
+ }
+
+ /**
+ *
+ * returns true if the resource has been modified since the specified
+ * reqeust header value
+ */
+ private boolean checkIsModified(String lastModified)
+ throws ServiceException {
+ if (lastModified == null)
+ return true;
+ try {
+ Date clientDate = DateFormater.parseDate(lastModified,DateFormater.HTTP_HEADER_DATE_FORMAT,DateFormater.HTTP_HEADER_DATE_FORMAT_TIME_OFFSET);
+ Date entityDate;
+ if (this.feedRequest.isFeedRequested())
+ entityDate = this.service.getFeedLastModified(this.feedRequest
+ .getFeedId());
+ else
+ entityDate = this.service.getEntryLastModified(this.feedRequest
+ .getEntryId(),this.feedRequest.getFeedId());
+ if(LOG.isInfoEnabled())
+ LOG.info("comparing date clientDate: "+clientDate+"; lastmodified: "+entityDate);
+ return (entityDate.getTime()-clientDate.getTime() > 1000);
+ } catch (java.text.ParseException e) {
+ LOG.info("Couldn't parse Last-Modified header -- "+lastModified,e);
+
+ }
+ return true;
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultRequestHandlerFactory.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultRequestHandlerFactory.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultRequestHandlerFactory.java (working copy)
@@ -1,69 +1,149 @@
-/**
- * Copyright 2004 The Apache Software Foundation
+/**
+ * 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 org.apache.lucene.gdata.server.registry.Component;
+import org.apache.lucene.gdata.server.registry.ComponentType;
+
+/**
+ * Default implementation for RequestHandlerFactory Builds the
+ * {@link org.apache.lucene.gdata.servlet.handler.GDataRequestHandler}
+ * instances.
+ * This class should not be access directy. The class will be registered in the {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry}.
+ * Use {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry#lookup(Class, ComponentType)}
*
- * 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
+ * @author Simon Willnauer
*
- * 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();
- }
-
-}
+ */
+@Component(componentType=ComponentType.REQUESTHANDLERFACTORY)
+public class DefaultRequestHandlerFactory extends RequestHandlerFactory {
+
+
+ /**
+ * public constructor to enable loading via the registry
+ * @see org.apache.lucene.gdata.server.registry.Component
+ * @see org.apache.lucene.gdata.server.registry.GDataServerRegistry
+ */
+ public DefaultRequestHandlerFactory() {
+ //
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getEntryUpdateHandler()
+ */
+ @Override
+ public GDataRequestHandler getEntryUpdateHandler() {
+
+ return new DefaultUpdateHandler();
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getEntryDeleteHandler()
+ */
+ @Override
+ public GDataRequestHandler getEntryDeleteHandler() {
+
+ return new DefaultDeleteHandler();
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getFeedQueryHandler()
+ */
+ @Override
+ public GDataRequestHandler getFeedQueryHandler() {
+
+ return new DefaultGetHandler();
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getEntryInsertHandler()
+ */
+ @Override
+ public GDataRequestHandler getEntryInsertHandler() {
+
+ return new DefaultInsertHandler();
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getInsertAccountHandler()
+ */
+ @Override
+ public GDataRequestHandler getInsertAccountHandler() {
+
+ return new InsertAccountStrategy();
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getDeleteAccountHandler()
+ */
+ @Override
+ public GDataRequestHandler getDeleteAccountHandler() {
+
+ return new DeleteAccountStrategy();
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getUpdateAccountHandler()
+ */
+ @Override
+ public GDataRequestHandler getUpdateAccountHandler() {
+
+ return new UpdataAccountStrategy();
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getInsertFeedHandler()
+ */
+ @Override
+ public GDataRequestHandler getInsertFeedHandler() {
+
+ return new InsertFeedHandler();
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getUpdateFeedHandler()
+ */
+ @Override
+ public GDataRequestHandler getUpdateFeedHandler() {
+
+ return new UpdateFeedHandler();
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getDeleteFeedHandler()
+ */
+ @Override
+ public GDataRequestHandler getDeleteFeedHandler() {
+
+ return new DeleteFeedHandler();
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.registry.ServerComponent#initialize()
+ */
+ public void initialize() {
+ //
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.registry.ServerComponent#destroy()
+ */
+ public void destroy() {
+ //
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/RequestAuthenticator.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/RequestAuthenticator.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/RequestAuthenticator.java (revision 0)
@@ -0,0 +1,145 @@
+/**
+ * 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 javax.servlet.http.Cookie;
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.lucene.gdata.data.GDataAccount;
+import org.apache.lucene.gdata.data.GDataAccount.AccountRole;
+import org.apache.lucene.gdata.server.GDataRequest;
+import org.apache.lucene.gdata.server.ServiceException;
+import org.apache.lucene.gdata.server.ServiceFactory;
+import org.apache.lucene.gdata.server.administration.AdminService;
+import org.apache.lucene.gdata.server.authentication.AuthenticationController;
+import org.apache.lucene.gdata.server.authentication.AuthenticatorException;
+import org.apache.lucene.gdata.server.authentication.GDataHttpAuthenticator;
+import org.apache.lucene.gdata.server.registry.ComponentType;
+import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
+
+/**
+ * The RequestAuthenticator provides access to the registered
+ * {@link org.apache.lucene.gdata.server.authentication.AuthenticationController}
+ * as a super class for all request handler requiereing authentication for
+ * access. This class implements the
+ * {@link org.apache.lucene.gdata.server.authentication.GDataHttpAuthenticator}
+ * to get the auth token from the given request and call the needed Components
+ * to authenticat the client.
+ *
+ * For request handler handling common requests like entry insert or update the
+ * authentication will be based on the account name verified as the owner of the
+ * feed to alter. If the accountname in the token does not match the name of the
+ * account which belongs to the feed the given role will be used for
+ * autentication. Authentication using the
+ * {@link RequestAuthenticator#authenticateAccount(HttpServletRequest, AccountRole)}
+ * method, the account name will be ignored, authentication will be based on the
+ * given AccountRole
+ *
+ *
+ * @author Simon Willnauer
+ *
+ */
+public class RequestAuthenticator implements GDataHttpAuthenticator {
+ private static final Log LOG = LogFactory
+ .getLog(RequestAuthenticator.class);
+
+ /**
+ * @see org.apache.lucene.gdata.server.authentication.GDataHttpAuthenticator#authenticateAccount(org.apache.lucene.gdata.server.GDataRequest,
+ * org.apache.lucene.gdata.data.GDataAccount.AccountRole)
+ */
+ public boolean authenticateAccount(GDataRequest request, AccountRole role) {
+ String clientIp = request.getRemoteAddress();
+ if (LOG.isDebugEnabled())
+ LOG
+ .debug("Authenticating Account for GDataRequest -- modifying entries -- Role: "
+ + role + "; ClientIp: " + clientIp);
+
+ AuthenticationController controller = GDataServerRegistry.getRegistry()
+ .lookup(AuthenticationController.class,
+ ComponentType.AUTHENTICATIONCONTROLLER);
+ ServiceFactory factory = GDataServerRegistry.getRegistry().lookup(
+ ServiceFactory.class, ComponentType.SERVICEFACTORY);
+ AdminService adminService = factory.getAdminService();
+ GDataAccount account;
+ try {
+ account = adminService.getFeedOwningAccount(request.getFeedId());
+ String token = getTokenFromRequest(request.getHttpServletRequest());
+ if (LOG.isDebugEnabled())
+ LOG.debug("Got Token: " + token + "; for requesting account: "
+ + account);
+ if (account != null && token != null)
+ return controller.authenticateToken(token, clientIp,
+ AccountRole.ENTRYAMINISTRATOR, account.getName());
+
+ } catch (ServiceException e) {
+ LOG.error("can get GDataAccount for feedID -- "
+ + request.getFeedId(), e);
+ throw new AuthenticatorException(" Service exception occured", e);
+
+ }
+
+ return false;
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.authentication.GDataHttpAuthenticator#authenticateAccount(javax.servlet.http.HttpServletRequest,
+ * org.apache.lucene.gdata.data.GDataAccount.AccountRole)
+ */
+ public boolean authenticateAccount(HttpServletRequest request,
+ AccountRole role) {
+ String clientIp = request.getRemoteAddr();
+ if (LOG.isDebugEnabled())
+ LOG
+ .debug("Authenticating Account for GDataRequest -- modifying entries -- Role: "
+ + role + "; ClientIp: " + clientIp);
+ AuthenticationController controller = GDataServerRegistry.getRegistry()
+ .lookup(AuthenticationController.class,
+ ComponentType.AUTHENTICATIONCONTROLLER);
+ String token = getTokenFromRequest(request);
+ if (LOG.isDebugEnabled())
+ LOG.debug("Got Token: " + token + ";");
+ if (token == null)
+ return false;
+ return controller.authenticateToken(token, clientIp, role, null);
+
+ }
+
+ protected String getTokenFromRequest(HttpServletRequest request) {
+ String token = request
+ .getHeader(AuthenticationController.AUTHORIZATION_HEADER);
+ if (token == null || !token.startsWith("GoogleLogin")) {
+ Cookie[] cookies = request.getCookies();
+ if (cookies == null) {
+ return null;
+ }
+ for (int i = 0; i < cookies.length; i++) {
+ if (cookies[i].getName().equals(
+ AuthenticationController.TOKEN_KEY)) {
+ token = cookies[i].getValue();
+ break;
+ }
+
+ }
+ }
+ if (token != null)
+ token = token.substring(token.indexOf("=") + 1);
+ return token;
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DeleteFeedHandler.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DeleteFeedHandler.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DeleteFeedHandler.java (revision 0)
@@ -0,0 +1,81 @@
+/**
+ * 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.data.ServerBaseFeed;
+import org.apache.lucene.gdata.server.ServiceFactory;
+import org.apache.lucene.gdata.server.registry.ComponentType;
+import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
+
+/**
+ * @author Simon Willnauer
+ *
+ */
+public class DeleteFeedHandler extends AbstractFeedHandler{
+ private static final Log LOG = LogFactory.getLog(DeleteFeedHandler.class);
+
+ /**
+ * @throws IOException
+ * @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 ServletException, IOException {
+ super.processRequest(request,response);
+ if(this.authenticated){
+ try {
+ ServerBaseFeed feed = createDeleteFeed(request);
+
+ GDataServerRegistry registry = GDataServerRegistry.getRegistry();
+ ServiceFactory serviceFactory = registry.lookup(ServiceFactory.class,ComponentType.SERVICEFACTORY);
+ if(serviceFactory == null){
+ setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,"required component is not available");
+ throw new FeedHandlerException("Can't save feed - ServiceFactory is null");
+ }
+ serviceFactory.getAdminService().deleteFeed(feed);
+ } catch (FeedHandlerException e) {
+ LOG.error("Can not delete feed -- "+e.getMessage(),e);
+ }catch (Exception e) {
+ LOG.error("Can not delete feed -- "+e.getMessage(),e);
+ setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,"can not create feed");
+ }
+ }
+ sendResponse(response);
+
+
+
+ }
+
+ private ServerBaseFeed createDeleteFeed(final HttpServletRequest request) throws FeedHandlerException {
+ String feedId = request.getParameter("feedid");
+ if(feedId == null){
+ setError(HttpServletResponse.SC_BAD_REQUEST,"No feed id specified");
+ throw new FeedHandlerException("no feed Id specified");
+ }
+ ServerBaseFeed retVal = new ServerBaseFeed();
+ retVal.setId(feedId);
+ return retVal;
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultUpdateHandler.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultUpdateHandler.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultUpdateHandler.java (working copy)
@@ -1,94 +1,89 @@
-/**
- * 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.
- *
- * The handler sends following response to the client:
- *
- *
- *
if the entry was successfully updated - HTTP status code 200 OK
- *
if an error occures - HTTP status code 500 INTERNAL SERVER ERROR
- *
if the resource could not found - HTTP status code 404 NOT FOUND
- *
- *
- * @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();
- }
-
- }
-
-}
+/**
+ * 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.data.GDataAccount.AccountRole;
+import org.apache.lucene.gdata.server.GDataRequestException;
+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.
+ *
+ * The handler sends following response to the client:
+ *
+ *
+ *
if the entry was successfully updated - HTTP status code 200 OK
+ *
if an error occures - HTTP status code 500 INTERNAL SERVER ERROR
+ *
if the resource could not found - HTTP status code 404 NOT FOUND
+ *
+ *
+ * @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) {
+ setError(HttpServletResponse.SC_UNAUTHORIZED);
+ sendError();
+ return;
+ }
+ if(!authenticateAccount(request,AccountRole.ENTRYAMINISTRATOR)){
+ sendError();
+ return;
+ }
+
+ try {
+ BaseEntry entry = this.service.updateEntry(this.feedRequest,
+ this.feedResponse);
+ setFeedResponseFormat();
+ setFeedResponseStatus(HttpServletResponse.SC_OK);
+ this.feedResponse.sendResponse(entry, this.feedRequest.getConfigurator().getExtensionProfile());
+
+ }
+ catch (ServiceException e) {
+ LOG.error("Could not process UpdateFeed request - "
+ + e.getMessage(), e);
+ sendError();
+ }
+ closeService();
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractFeedHandler.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractFeedHandler.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractFeedHandler.java (revision 0)
@@ -0,0 +1,173 @@
+/**
+ * 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.data.GDataAccount;
+import org.apache.lucene.gdata.data.ServerBaseFeed;
+import org.apache.lucene.gdata.data.GDataAccount.AccountRole;
+import org.apache.lucene.gdata.server.GDataEntityBuilder;
+import org.apache.lucene.gdata.server.ServiceException;
+import org.apache.lucene.gdata.server.ServiceFactory;
+import org.apache.lucene.gdata.server.administration.AdminService;
+import org.apache.lucene.gdata.server.registry.ComponentType;
+import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
+import org.apache.lucene.gdata.server.registry.ProvidedService;
+
+import com.google.gdata.util.ParseException;
+
+/**
+ *
+ * @author Simon Willnauer
+ *
+ */
+public abstract class AbstractFeedHandler extends RequestAuthenticator implements GDataRequestHandler {
+ private static final Log LOG = LogFactory.getLog(AbstractFeedHandler.class);
+
+ protected static final String PARAMETER_ACCOUNT = "account";
+
+ protected static final String PARAMETER_SERVICE = "service";
+ private int error;
+ protected boolean authenticated = false;
+
+ private String errorMessage = "";
+ private boolean isError = false;
+
+ /**
+ * @see org.apache.lucene.gdata.servlet.handler.GDataRequestHandler#processRequest(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
+ */
+ @SuppressWarnings("unused")
+ public void processRequest(HttpServletRequest request,
+ HttpServletResponse response) throws ServletException, IOException {
+ this.authenticated = authenticateAccount(request,AccountRole.FEEDAMINISTRATOR);
+ if(!this.authenticated)
+ setError(HttpServletResponse.SC_UNAUTHORIZED,"Authorization failed");
+
+ }
+
+ protected ServerBaseFeed createFeedFromRequest(HttpServletRequest request) throws ParseException, IOException, FeedHandlerException{
+ GDataServerRegistry registry = GDataServerRegistry.getRegistry();
+ String providedService = request.getParameter(PARAMETER_SERVICE);
+ if(!registry.isServiceRegistered(providedService)){
+ setError(HttpServletResponse.SC_NOT_FOUND,"no such service");
+ throw new FeedHandlerException("ProvicdedService is not registered -- Name: "+providedService);
+ }
+ ProvidedService provServiceInstance = registry.getProvidedService(providedService);
+ if(providedService == null){
+ setError(HttpServletResponse.SC_BAD_REQUEST,"no such service");
+ throw new FeedHandlerException("no such service registered -- "+providedService);
+ }
+ try{
+ ServerBaseFeed retVal = new ServerBaseFeed(GDataEntityBuilder.buildFeed(request.getReader(),provServiceInstance));
+ retVal.setServiceConfig(provServiceInstance);
+ return retVal;
+ }catch (IOException e) {
+ if(LOG.isInfoEnabled())
+ LOG.info("Can not read from input stream - ",e);
+ setError(HttpServletResponse.SC_BAD_REQUEST,"Can not read from input stream");
+ throw e;
+ }catch (ParseException e) {
+ if(LOG.isInfoEnabled())
+ LOG.info("feed can not be parsed - ",e);
+ setError(HttpServletResponse.SC_BAD_REQUEST,"incoming feed can not be parsed");
+ throw e;
+ }
+
+ }
+
+
+ protected GDataAccount createRequestedAccount(HttpServletRequest request) throws FeedHandlerException{
+ GDataServerRegistry registry = GDataServerRegistry.getRegistry();
+ ServiceFactory serviceFactory = registry.lookup(ServiceFactory.class,ComponentType.SERVICEFACTORY);
+
+ if(serviceFactory == null){
+ setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Required server component not available");
+ throw new FeedHandlerException("Required server component not available -- "+ServiceFactory.class.getName());
+ }
+ AdminService service = serviceFactory.getAdminService();
+ String account = request.getParameter(PARAMETER_ACCOUNT);
+ try{
+ return service.getAccount(account);
+ }catch (ServiceException e) {
+ if(LOG.isInfoEnabled())
+ LOG.info("no account for requested account - "+account,e);
+ setError(HttpServletResponse.SC_BAD_REQUEST,"no such account");
+ throw new FeedHandlerException(e.getMessage(),e);
+ }
+ }
+
+ protected void sendResponse(HttpServletResponse response){
+
+ if(!this.isError)
+ return;
+ try{
+ response.sendError(this.error,this.errorMessage);
+ }catch (IOException e) {
+ LOG.warn("can send error in RequestHandler ",e);
+ }
+ }
+
+ protected void setError(int error, String message){
+ this.error = error;
+ this.errorMessage = message;
+ this.isError = true;
+ }
+ protected int getErrorCode(){
+ return this.error;
+ }
+
+ protected String getErrorMessage(){
+ return this.errorMessage;
+ }
+
+ class FeedHandlerException extends Exception{
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 1L;
+
+ /**
+ * Creates a new FeedHandlerException with a exception message and the exception cause this ex.
+ * @param arg0 - the message
+ * @param arg1 - the cause
+ */
+ public FeedHandlerException(String arg0, Throwable arg1) {
+ super(arg0, arg1);
+
+ }
+
+ /**
+ * Creates a new FeedHandlerException with a exception message.
+ * @param arg0 - message
+ */
+ public FeedHandlerException(String arg0) {
+ super(arg0 );
+
+ }
+
+ }
+
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/InsertFeedHandler.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/InsertFeedHandler.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/InsertFeedHandler.java (revision 0)
@@ -0,0 +1,78 @@
+/**
+ * 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.data.GDataAccount;
+import org.apache.lucene.gdata.data.ServerBaseFeed;
+import org.apache.lucene.gdata.server.ServiceException;
+import org.apache.lucene.gdata.server.ServiceFactory;
+import org.apache.lucene.gdata.server.registry.ComponentType;
+import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
+
+/**
+ * @author Simon Willnauer
+ *
+ */
+public class InsertFeedHandler extends AbstractFeedHandler {
+ private static final Log LOG = LogFactory.getLog(InsertFeedHandler.class);
+
+ /**
+ * @see org.apache.lucene.gdata.servlet.handler.GDataRequestHandler#processRequest(javax.servlet.http.HttpServletRequest,
+ * javax.servlet.http.HttpServletResponse)
+ */
+ @SuppressWarnings("unused")
+ public void processRequest(HttpServletRequest request,
+ HttpServletResponse response) throws ServletException, IOException {
+ super.processRequest(request, response);
+ if (this.authenticated) {
+ try {
+ ServerBaseFeed feed = createFeedFromRequest(request);
+ GDataAccount account = createRequestedAccount(request);
+
+ GDataServerRegistry registry = GDataServerRegistry
+ .getRegistry();
+ ServiceFactory serviceFactory = registry.lookup(
+ ServiceFactory.class, ComponentType.SERVICEFACTORY);
+ if (serviceFactory == null) {
+ setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+ "required component is not available");
+ throw new FeedHandlerException(
+ "Can't save feed - ServiceFactory is null");
+ }
+ serviceFactory.getAdminService().createFeed(feed, account);
+ } catch (ServiceException e) {
+ setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,
+ "can not create feed");
+ LOG.error("Can not create feed -- " + e.getMessage(), e);
+ } catch (Exception e) {
+ LOG.error("Can not create feed -- " + e.getMessage(), e);
+
+ }
+
+ }
+ sendResponse(response);
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/FeedAdministrationServlet.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/servlet/FeedAdministrationServlet.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/servlet/FeedAdministrationServlet.java (revision 0)
@@ -0,0 +1,71 @@
+/**
+ * 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.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.GDataRequestHandler;
+
+/**
+ * This Servlet provides an REST interface to create / update and delete Feed instances.
+ *
+ * @author Simon Willnauer
+ *
+ */
+public class FeedAdministrationServlet extends AbstractGdataServlet {
+ private static final Log LOGGER = LogFactory.getLog(FeedAdministrationServlet.class);
+ /**
+ *
+ */
+ private static final long serialVersionUID = -905586350743277032L;
+
+ @Override
+ protected void doDelete(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
+ GDataRequestHandler handler = HANDLER_FACTORY.getDeleteFeedHandler();
+ if(LOGGER.isInfoEnabled())
+ LOGGER.info("Process delete feed request");
+ handler.processRequest(arg0,arg1);
+
+ }
+
+ @Override
+ protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
+ GDataRequestHandler handler = HANDLER_FACTORY.getInsertFeedHandler();
+ if(LOGGER.isInfoEnabled())
+ LOGGER.info("Process insert feed request");
+ handler.processRequest(arg0,arg1);
+
+ }
+
+ @Override
+ protected void doPut(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException {
+ GDataRequestHandler handler = HANDLER_FACTORY.getUpdateFeedHandler();
+ if(LOGGER.isInfoEnabled())
+ LOGGER.info("Process update feed request");
+ handler.processRequest(arg0,arg1);
+
+ }
+
+
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageCoreController.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageCoreController.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageCoreController.java (working copy)
@@ -1,286 +1,398 @@
-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
+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.data.GDataAccount;
+import org.apache.lucene.gdata.server.registry.Component;
+import org.apache.lucene.gdata.server.registry.ComponentType;
+import org.apache.lucene.gdata.storage.IDGenerator;
+import org.apache.lucene.gdata.storage.Storage;
+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.index.IndexWriter;
+import org.apache.lucene.search.IndexSearcher;
+import org.apache.lucene.store.Directory;
+import org.apache.lucene.store.FSDirectory;
+import org.apache.lucene.store.RAMDirectory;
+
+/**
+ *
*
- */
-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;
- 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);
- }
+ * @author Simon Willnauer
+ *
+ */
+@Component(componentType = ComponentType.STORAGECONTROLLER)
+public class StorageCoreController implements StorageController {
+ protected static final Log LOG = LogFactory
+ .getLog(StorageCoreController.class);
+
+ private IndexSearcher searcher;
+
+ private final Directory storageDir;
+
+ private final StorageModifier modifier;
+
+ private ReferenceCounter 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 RecoverController recoverController;
+
+ /**
+ * Creates a new StoragCoreController and sets up the storage
+ * environment reading the configuration file.
+ *
+ *
+ *
+ * @throws IOException -
+ * if an IOException occures
+ * @throws StorageException -
+ * if the storage lock can not be created or the
+ * {@link IDGenerator} can not be loaded
+ */
+ public StorageCoreController() 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;
+ this.configurator = StorageConfigurator.getStorageConfigurator();
+ if (!this.configurator.isRamDirectory()) {
+
+ 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 lock 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 = getRamDirectory();
+
+ this.currentBuffer = new StorageBuffer(this.storageBufferSize);
+ this.modifier = createStorageModifier(createNewStorage);
+ this.searcher = new IndexSearcher(this.storageDir);
+// this.recoverController = new RecoverController(null,this.configurator.isRecover(),this.configurator.isKeepRecoveredFiles());
+ if(createNewStorage)
+ createAdminAccount();
+
+ }
+
+ }
+
+ private StorageModifier createStorageModifier(boolean create)
+ throws IOException {
+ IndexModifier indexModifier = new IndexModifier(this.storageDir,
+ new StandardAnalyzer(), create);
+ return new StorageModifier(this, indexModifier, this.currentBuffer,
+ this.storagePersistFactor, this.indexOptimizeInterval);
+ }
+
+ /**
+ * returns the current storage modifier
+ *
+ * @return - the current storage modifier
+ */
+ protected StorageModifier getStorageModifier() {
+ return this.modifier;
+ }
+
+ /**
+ * returns a StorageQuery to query the storage index. The
+ * returned object is a reference counter to keep track of the references to
+ * the StorageQuery. The reference is already incremented before
+ * returned from this method.
+ *
+ * if the reference counter has no remaining references the resource e.g.
+ * the StorageQuery will be closed. This ensures that a
+ * StorageQuery instance will be arround as long as needed and
+ * the resources will be released. The reference counter should be
+ * decremented by clients after finished using the query instance.
+ *
+ *
+ * @return a {@link ReferenceCounter} instance holding the StorageQuery as a
+ * resource.
+ *
+ */
+ protected ReferenceCounter getStorageQuery() {
+ 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 getNewStorageQueryHolder(
+ final StorageQuery query) {
+ ReferenceCounter holder = new ReferenceCounter(
+ 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;
+ }
+
+ /**
+ * Forces the controller to register a new StorageQuery instance.
+ * This method will be called after an index has been modified to make the
+ * changes available for searching.
+ *
+ * @throws IOException -
+ * if an IO exception occures
+ */
+ 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);
+
+ }
+
+ }
+
+ /**
+ * Creates a new StorageBuffer
+ *
+ * @return the new StorageBuffer
+ */
+ protected StorageBuffer releaseNewStorageBuffer() {
+ synchronized (this.storageControllerLock) {
+ return this.currentBuffer;
+ }
+ }
+
+ /**
+ * Creates a new IndexModifier on the storage index
+ *
+ * @return - a new modifier
+ * @throws IOException -
+ * if an IO exception occures
+ */
+ protected 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();
+ this.modifier.close();
+ // TODO make sure all resources will be released
+ }
+ }
+
+ /**
+ * The size of the StorageBuffer.
+ *
+ * @return - storage buffer size
+ */
+ public int getStorageBufferSize() {
+ return this.storageBufferSize;
+ }
+
+ /**
+ * The size of the StorageBuffer. This size should be at least
+ * as big as the persist factor to prevent the StorageBuffer from
+ * resizing
+ *
+ * @param storageBufferSize
+ */
+ public void setStorageBufferSize(int storageBufferSize) {
+ this.storageBufferSize = storageBufferSize;
+ }
+
+ /**
+ * An integer value after how many changes to the StorageModifier the
+ * buffered changes will be persisted / wirtten to the index
+ *
+ * @return - the persist factor
+ */
+ public int getStoragePersistFactor() {
+ return this.storagePersistFactor;
+ }
+
+ /**
+ * @param storagePersistFactor
+ */
+ public void setStoragePersistFactor(int storagePersistFactor) {
+ this.storagePersistFactor = storagePersistFactor;
+ }
+
+ /**
+ * Forces the StorageModifier to write all buffered changes.
+ *
+ * @throws IOException -
+ * if an IO exception occures
+ *
+ */
+ public void forceWrite() throws IOException {
+ 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();
+
+ }
+
+ /**
+ * Creates a unique ID to store as an id for
+ * {@link org.apache.lucene.gdata.data.ServerBaseEntry} instances
+ *
+ * @return - a unique id
+ * @throws StorageException -
+ * if no id can be released
+ */
+ 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);
+ }
+ }
+
+ /**
+ *
+ * @return - the lucene directory used as a storage
+ */
+ protected Directory getDirectory() {
+ return this.storageDir;
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.StorageController#getStorage()
+ */
+ public Storage getStorage() throws StorageException {
+ try {
+ return new StorageImplementation();
+ } catch (StorageException e) {
+ StorageException ex = new StorageException(
+ "Can't create Storage instance -- " + e.getMessage(), e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+
+ }
+ }
+
+ // TODO Try to remove this --> testcases
+ private RAMDirectory getRamDirectory() throws IOException {
+ IndexWriter writer;
+ RAMDirectory retVal = new RAMDirectory();
+ writer = new IndexWriter(retVal, new StandardAnalyzer(), true);
+ writer.close();
+ return retVal;
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.registry.ServerComponent#initialize()
+ */
+ public void initialize() {
+ //
+ }
-
-
- 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 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 getNewStorageQueryHolder(final StorageQuery query){
- ReferenceCounter holder = new ReferenceCounter(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);
- }
- }
-}
+ private void createAdminAccount() throws StorageException{
+ GDataAccount adminAccount = GDataAccount.createAdminAccount();
+ StorageAccountWrapper wrapper = new StorageAccountWrapper(adminAccount);
+ this.getStorageModifier().createAccount(wrapper);
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageAccountWrapper.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageAccountWrapper.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageAccountWrapper.java (revision 0)
@@ -0,0 +1,111 @@
+package org.apache.lucene.gdata.storage.lucenestorage;
+
+import java.net.MalformedURLException;
+import java.net.URL;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.gdata.data.GDataAccount;
+
+/**
+ * Wrapps a User Object.
+ * The wrapper provides also a Lucene repesentation of the user;
+ * User Objects will not be Buffered in the lucene storage component. Each User will be written imidialtely.
+ * @author Simon Willnauer
+ *
+ */
+public class StorageAccountWrapper implements StorageWrapper{
+ private static final Log LOG = LogFactory.getLog(StorageAccountWrapper.class);
+
+ /**
+ * Lucene field for the username
+ */
+ public static final String FIELD_ACCOUNTNAME = "accountName";
+ /**
+ * Lucene field for the password
+ */
+ public static final String FIELD_PASSWORD = "passwd";
+ /**
+ * Lucene field for the author name
+ */
+ public static final String FIELD_AUTHORNAME = "author";
+ /**
+ * Lucene field for the author mail address
+ */
+ public static final String FIELD_AUTHORMAIL = "authorMail";
+ /**
+ * Lucene field for the author link
+ */
+ public static final String FIELD_AUTHORHREF = "authorHref";
+ /**
+ * Lucene field fot the userroles
+ */
+ public static final String FIELD_ROLES = "userroles";
+ private final GDataAccount user;
+ /**
+ * @param user - the user to be wrapped
+ */
+ public StorageAccountWrapper(final GDataAccount user) {
+ if(user == null)
+ throw new IllegalArgumentException("user must not be null");
+ this.user = user;
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.lucenestorage.StorageWrapper#getLuceneDocument()
+ */
+ public Document getLuceneDocument() {
+ Document doc = new Document();
+
+ doc.add(new Field(FIELD_ACCOUNTNAME,this.user.getName(),Field.Store.YES,Field.Index.UN_TOKENIZED));
+ doc.add(new Field(FIELD_PASSWORD,this.user.getPassword()==null?"":this.user.getPassword(),Field.Store.YES,Field.Index.NO));
+ doc.add(new Field(FIELD_AUTHORNAME,this.user.getAuthorname()==null?"":this.user.getAuthorname(),Field.Store.YES,Field.Index.NO));
+ doc.add(new Field(FIELD_AUTHORMAIL,this.user.getAuthorMail()==null?"":this.user.getAuthorMail(),Field.Store.YES,Field.Index.NO));
+ doc.add(new Field(FIELD_AUTHORHREF,this.user.getAuthorLink()==null?"":this.user.getAuthorLink().toString(),Field.Store.YES,Field.Index.NO));
+ doc.add(new Field(FIELD_ROLES, Integer.toString(this.user.getRolesAsInt()),Field.Store.YES,Field.Index.NO));
+
+ return doc;
+ }
+
+
+
+
+ /**
+ * @param doc - a lucene document representation of an user
+ * @return - the user to build from the document. or null if the document is null
+ */
+ public static GDataAccount buildEntity(final Document doc){
+ if(doc == null)
+ return null;
+
+ GDataAccount user = new GDataAccount();
+ user.setName(doc.get(FIELD_ACCOUNTNAME));
+ user.setPassword(doc.get(FIELD_PASSWORD));
+ user.setAuthorname(doc.get(FIELD_AUTHORNAME));
+ user.setAuthorMail(doc.get(FIELD_AUTHORMAIL));
+ try{
+ user.setRolesAsInt(Integer.parseInt(doc.get(FIELD_ROLES)));
+ }catch (NumberFormatException e) {
+ LOG.info("Can't parse userroles: "+user.getName()+" throws NumberFormatException. -- skipping --",e);
+ }
+ try {
+ if(doc.get(FIELD_AUTHORHREF)!= null)
+ user.setAuthorLink(new URL(doc.get(FIELD_AUTHORHREF)));
+ } catch (MalformedURLException e) {
+ LOG.info("SPECIFIED URL for user: "+user.getName()+" throws MalformedURLException. -- skipping --",e);
+ }
+ return user;
+ }
+
+
+
+ /**
+ * @return - the wrapped user
+ */
+ public GDataAccount getUser() {
+ return this.user;
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageModifier.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageModifier.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageModifier.java (working copy)
@@ -1,236 +1,445 @@
-package org.apache.lucene.gdata.storage.lucenestorage;
-
-import java.io.IOException;
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.concurrent.locks.Lock;
-import java.util.concurrent.locks.ReentrantReadWriteLock;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.lucene.document.Document;
-import org.apache.lucene.gdata.storage.StorageException;
-import org.apache.lucene.index.IndexModifier;
-import org.apache.lucene.index.Term;
-
-/**
- * TODO document this
- * @author Simon Willnauer
+package org.apache.lucene.gdata.storage.lucenestorage;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantReadWriteLock;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.gdata.storage.StorageException;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation;
+import org.apache.lucene.index.IndexModifier;
+import org.apache.lucene.index.Term;
+
+/**
+ * The StorageModifier is the a Singleton component of the LuceneStorage. There
+ * is one single instance of this class modifying the index used to store all
+ * the gdata Entities as Entries, Feeds and Users. This class contains an
+ * instance of {@link org.apache.lucene.index.IndexModifier} used to manage all
+ * delete and add actions to the storage.
+ *
+ * To prevent the storage component from opening and closing the
+ * {@link org.apache.lucene.index.IndexModifier} for every modifying operation
+ * the incoming entry actions (DELETE, UPDATE, INSERT) will be buffered in a
+ * registered instance of
+ * {@link org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer}. When a
+ * certain amout (specified as the persistfactor in the configuration file) of
+ * modifications have been executed the StorageModifier will persist the
+ * buffered entries.
+ *
+ *
+ * Feed and User operations won't be buffered. These actions occure not very
+ * often compared to entry actions. Every call of an user / feed modifying
+ * operation forces all changes to be written to the storage index.
+ *
*
- */
-public class StorageModifier {
- protected static final Log LOG = LogFactory.getLog(StorageModifier.class);
-
- private final List deletedDocumentQueue;
- private final List deletedForUpdateDocumentQueue;
-
- private final Map documentMap;
-
-
- private volatile int persistFactor;
-
- private volatile int modifiedCounter = 0;
-
- private static int DEFAULT_PERSIST_FACTOR = 10;
-
- private StorageBuffer buffer;
-
- private IndexModifier modifier;
-
- private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(false);
-
- private Lock readLock = this.lock.readLock();
-
- private Lock writeLock = this.lock.writeLock();
- private final static int DEFAULT_OPTIMIZE_INTERVAL = 10;
- private final int optimizeInterval;
- private int optimizeCounter = 0;
-
- /**
- * TODO document this
- * @param modifier
- * @param buffer
- * @param persitsFactor
- * @param optimizeInterval
- */
- public StorageModifier(final IndexModifier modifier,
- final StorageBuffer buffer, int persitsFactor,int optimizeInterval) {
- this.deletedDocumentQueue = new LinkedList();
- this.deletedForUpdateDocumentQueue = new LinkedList();
- this.documentMap = new HashMap(persitsFactor);
- this.buffer = buffer;
-
- this.persistFactor = persitsFactor > 0 ? persitsFactor
- : DEFAULT_PERSIST_FACTOR;
- this.modifier = modifier;
- this.optimizeInterval = optimizeInterval < DEFAULT_OPTIMIZE_INTERVAL?DEFAULT_OPTIMIZE_INTERVAL:optimizeInterval;
-
- }
-
- /**
- * TODO document this
- * @param wrapper
- * @throws StorageException
- */
- public void updateEntry(StorageEntryWrapper wrapper)
- throws StorageException {
- try {
- this.readLock.lock();
- Term tempTerm = new Term(StorageEntryWrapper.FIELD_ENTRY_ID, wrapper.getEntryId());
- this.buffer.addEntry(wrapper);
- this.deletedForUpdateDocumentQueue.add(tempTerm);
- this.documentMap.put(wrapper.getEntryId(),wrapper.getLuceneDocument());
- storageModified();
- } finally {
- this.readLock.unlock();
- }
- }
-
- /**
- * TODO document this
- * @param wrapper
- * @throws StorageException
- */
- public void insertEntry(StorageEntryWrapper wrapper) throws StorageException {
- this.readLock.lock();
- try {
-
- this.buffer.addEntry(wrapper);
- this.documentMap.put(wrapper.getEntryId(),wrapper.getLuceneDocument());
- storageModified();
- } finally {
- this.readLock.unlock();
- }
- }
-
- /**
- *TODO document this
- * @param entryId
- * @param feedId
- * @throws StorageException
+ * @author Simon Willnauer
+ *
+ */
+public class StorageModifier {
+ protected static final Log LOG = LogFactory.getLog(StorageModifier.class);
+
+ private final List deletedDocumentQueue;
+
+ private final List deletedForUpdateDocumentQueue;
+
+ private final Map documentMap;
+
+ private final List forceWriteDocuments;
+
+ private final List forceWriteTerms;
+
+ private volatile int persistFactor;
+
+ private volatile int modifiedCounter = 0;
+
+ private static int DEFAULT_PERSIST_FACTOR = 10;
+
+ private StorageBuffer buffer;
+
+ private IndexModifier modifier;
+
+ private ReentrantReadWriteLock lock = new ReentrantReadWriteLock(false);
+
+ private Lock readLock = this.lock.readLock();
+
+ private Lock writeLock = this.lock.writeLock();
+
+ private final static int DEFAULT_OPTIMIZE_INTERVAL = 10;
+
+ private final int optimizeInterval;
+
+ private volatile int optimizeCounter = 0;
+
+ private final StorageCoreController controller;
+
+ /**
+ * Creates a new StorageModifier
*
- */
- public void deleteEntry(final String entryId, final String feedId) throws StorageException {
- try {
- this.readLock.lock();
- Term tempTerm = new Term(StorageEntryWrapper.FIELD_ENTRY_ID, entryId);
- this.buffer.addDeleted(entryId, feedId);
- this.deletedDocumentQueue.add(tempTerm);
- storageModified();
- } finally {
- this.readLock.unlock();
- }
- }
-
- private void storageModified() throws StorageException {
- this.readLock.unlock();
- this.writeLock.lock();
-
- try {
- incrementCounter();
- if (this.persistFactor > this.modifiedCounter)
- return;
-
- if (LOG.isInfoEnabled())
- LOG.info("Storage modified for " + this.modifiedCounter
- + " times. Write Persistent index");
- writePersistentIndex((this.optimizeCounter >= this.optimizeInterval));
- requestNewIndexModifier();
-
- this.modifiedCounter = 0;
- } catch (IOException e) {
- LOG.error("Writing persistent index failed - Recovering", e);
- } finally {
- this.readLock.lock();
- this.writeLock.unlock();
- }
-
- }
-
- protected void forceWrite() throws IOException, StorageException {
- this.writeLock.lock();
- try {
- if (LOG.isInfoEnabled())
- LOG.info("ForceWrite called -- current modifiedCounter: "
- + this.modifiedCounter + " - persisting changes");
- writePersistentIndex(true);
- requestNewIndexModifier();
- this.modifiedCounter = 0;
- } finally {
- this.writeLock.unlock();
- }
- }
-
- private void requestNewIndexModifier() throws IOException, StorageException {
- StorageCoreController controller = StorageCoreController
- .getStorageCoreController();
- controller.registerNewStorageQuery();
- this.buffer = controller.releaseNewStorageBuffer();
- this.modifier = controller.createIndexModifier();
- }
-
- private void writePersistentIndex(final boolean optimize) throws IOException {
- try {
- /*
- * first delete all updated documents
- */
- for(Term entryIdTerm : this.deletedForUpdateDocumentQueue) {
- this.modifier.deleteDocuments(entryIdTerm);
- }
- /*
- * add all documents
- */
- Collection documents = this.documentMap.values();
- for (Document doc : documents) {
- this.modifier.addDocument(doc);
- }
- /*
- * delete all documents marked as deleted. As the DocumentIDs are
- * unique the document marked as deleted must not persist after the
- * index has been written.
- * In the case of an update of a document and a previous delete the concurrency component will not allow an update.
- * new inserted entries can not be deleted accidently-
- */
- for (Term entryIdTerm : this.deletedDocumentQueue) {
- this.modifier.deleteDocuments(entryIdTerm);
- }
- this.modifier.flush();
- if(optimize){
- if(LOG.isInfoEnabled())
- LOG.info("Optimizing index -- optimize interval "+this.optimizeInterval);
- this.modifier.optimize();
- }
-
- } finally {
- if(optimize)
- this.optimizeCounter = 0;
- this.modifier.close();
- this.deletedForUpdateDocumentQueue.clear();
- this.deletedDocumentQueue.clear();
- this.documentMap.clear();
- }
- }
-
- protected void close()throws IOException{
- this.writeLock.lock();
- try {
- if (LOG.isInfoEnabled())
- LOG.info("ForceWrite called -- current modifiedCounter: "
- + this.modifiedCounter + " - persisting changes");
-
- writePersistentIndex(true);
- this.modifiedCounter = 0;
- } finally {
- this.writeLock.unlock();
- }
- }
-
- private void incrementCounter(){
- this.optimizeCounter++;
- this.modifiedCounter++;
- }
-
-}
+ * @param controller -
+ * the registered StorageController
+ * @param modifier -
+ * the IndexModifier
+ * @param buffer -
+ * the StorageBuffer
+ * @param persitsFactor -
+ * the factor when the changes will be persisted to the storage
+ * index
+ * @param optimizeInterval -
+ * after how many storage operations the index will be optimized
+ */
+ protected StorageModifier(final StorageCoreController controller,
+ final IndexModifier modifier, final StorageBuffer buffer,
+ int persitsFactor, int optimizeInterval) {
+ this.deletedDocumentQueue = new LinkedList();
+ this.deletedForUpdateDocumentQueue = new LinkedList();
+ this.documentMap = new HashMap(persitsFactor);
+ this.forceWriteDocuments = new ArrayList(5);
+ this.forceWriteTerms = new ArrayList(5);
+ this.buffer = buffer;
+ this.controller = controller;
+
+ this.persistFactor = persitsFactor > 0 ? persitsFactor
+ : DEFAULT_PERSIST_FACTOR;
+ this.modifier = modifier;
+ this.optimizeInterval = optimizeInterval < DEFAULT_OPTIMIZE_INTERVAL ? DEFAULT_OPTIMIZE_INTERVAL
+ : optimizeInterval;
+
+ }
+
+ /**
+ * Updates the given entry. First the alredy persisted entry will be
+ * removed, after marking as deleted the new Entry will be written.
+ *
+ * @param wrapper -
+ * the wrapper containing the entry
+ * @throws StorageException -
+ * if the entry can not be stored
+ */
+ public void updateEntry(StorageEntryWrapper wrapper)
+ throws StorageException {
+ if(wrapper.getOperation() != StorageOperation.UPDATE)
+ throw new StorageException("Illegal method call -- updateEntry does not accept other storageOperations than update");
+ this.readLock.lock();
+ try {
+ Term tempTerm = new Term(StorageEntryWrapper.FIELD_ENTRY_ID,
+ wrapper.getEntryId());
+ this.documentMap.put(wrapper.getEntryId(), wrapper
+ .getLuceneDocument());
+ this.deletedForUpdateDocumentQueue.add(tempTerm);
+ this.buffer.addEntry(wrapper);
+ storageModified();
+ } finally {
+ this.readLock.unlock();
+ }
+ }
+
+ /**
+ * Inserts a new Entry to the Lucene index storage
+ *
+ * @param wrapper -
+ * the wrapper containing the entry
+ * @throws StorageException -
+ * if the entry can not be stored
+ */
+ public void insertEntry(StorageEntryWrapper wrapper)
+ throws StorageException {
+ if(wrapper.getOperation() != StorageOperation.INSERT)
+ throw new StorageException("Illegal method call -- insertEntry does not accept other storage operations than insert");
+ this.readLock.lock();
+ try {
+ this.documentMap.put(wrapper.getEntryId(), wrapper
+ .getLuceneDocument());
+ this.buffer.addEntry(wrapper);
+ storageModified();
+ } finally {
+ this.readLock.unlock();
+ }
+ }
+
+ /**
+ * Deletes the entry for the given entry id.
+ * @param wrapper - the wrapper containing the information to delete
+ *
+ * @throws StorageException -
+ * if the entry can not be deleted
+ *
+ */
+ public void deleteEntry(final StorageEntryWrapper wrapper)
+ throws StorageException {
+ if(wrapper.getOperation() != StorageOperation.DELETE)
+ throw new StorageException("Illegal method call -- insertEntry does not accept other storage operations than delete");
+ this.readLock.lock();
+ try {
+ Term tempTerm = new Term(StorageEntryWrapper.FIELD_ENTRY_ID,
+ wrapper.getEntryId());
+ this.deletedDocumentQueue.add(tempTerm);
+ this.buffer.addDeleted(wrapper.getEntryId(), wrapper.getFeedId());
+ storageModified();
+ } finally {
+ this.readLock.unlock();
+ }
+ }
+
+ /**
+ * Adds a new Feed to the storage. Feed action will be not buffered. Call to
+ * this method forces the index to be written.
+ *
+ * @param wrapper -
+ * the wrapper containing the feed;
+ * @throws StorageException -
+ * if the feed can not be written
+ */
+ public void createFeed(StorageFeedWrapper wrapper) throws StorageException {
+ this.readLock.lock();
+ try {
+ this.forceWriteDocuments.add(wrapper.getLuceneDocument());
+ storageModified();
+ } finally {
+ this.readLock.unlock();
+ }
+ }
+
+ /**
+ * Adds a new accountr to the storage. User action will be not buffered. Call to
+ * this method forces the index to be written.
+ *
+ * @param account
+ * -the wrapper containig the user to be persisted
+ * @throws StorageException -
+ * if the user can not be persisted.
+ */
+ public void createAccount(StorageAccountWrapper account) throws StorageException {
+ this.readLock.lock();
+ try {
+ this.forceWriteDocuments.add(account.getLuceneDocument());
+ storageModified();
+ } finally {
+ this.readLock.unlock();
+ }
+ }
+
+ /**
+ * Deletes the user with the given username. User action will be not
+ * buffered. Call to this method forces the index to be written.
+ *
+ * @param accountName -
+ * the user to be deleted
+ * @throws StorageException -
+ * If the user could not be deleted
+ */
+ public void deleteAccount(String accountName) throws StorageException {
+ this.readLock.lock();
+ try {
+ //TODO delete all feeds and entries of this account
+ this.forceWriteTerms.add(new Term(
+ StorageAccountWrapper.FIELD_ACCOUNTNAME, accountName));
+ storageModified();
+ } finally {
+ this.readLock.unlock();
+ }
+ }
+
+ /**
+ * User action will be not buffered. Call to this method forces the index to
+ * be written.
+ *
+ * @param user
+ * -the wrapper containig the user to be persisted
+ * @throws StorageException -
+ * if the user can not be persisted.
+ */
+ public void updateAccount(final StorageAccountWrapper user)
+ throws StorageException {
+ this.readLock.lock();
+ try {
+ this.forceWriteTerms.add(new Term(
+ StorageAccountWrapper.FIELD_ACCOUNTNAME, user.getUser()
+ .getName()));
+ this.forceWriteDocuments.add(user.getLuceneDocument());
+ storageModified();
+ } finally {
+ this.readLock.unlock();
+ }
+ }
+
+ /**
+ * Feed action will be not buffered. Call to this method forces the index to
+ * be written.
+ *
+ * @param wrapper -
+ * the wrapper containig the feed
+ * @throws StorageException -
+ * if the feed can not be persisted
+ */
+ public void updateFeed(final StorageFeedWrapper wrapper)
+ throws StorageException {
+ this.readLock.lock();
+ try {
+ this.forceWriteTerms.add(new Term(StorageFeedWrapper.FIELD_FEED_ID,
+ wrapper.getFeed().getId()));
+ this.forceWriteDocuments.add(wrapper.getLuceneDocument());
+ storageModified();
+ } finally {
+ this.readLock.unlock();
+ }
+ }
+
+ /**
+ * Deletes the feed with the given feed id Feed action will be not buffered.
+ * Call to this method forces the index to be written.
+ * All entries referencing the given feed id will be deleted as well!
+ * @param feedId -
+ * the id of the feed to delete
+ * @throws StorageException -
+ * if the feed can not be deleted
+ */
+ public void deleteFeed(final String feedId) throws StorageException {
+ this.readLock.lock();
+ try {
+ this.deletedDocumentQueue.add(new Term(StorageEntryWrapper.FIELD_FEED_REFERENCE,feedId));
+ this.forceWriteTerms.add(new Term(StorageFeedWrapper.FIELD_FEED_ID,
+ feedId));
+
+ storageModified();
+ } finally {
+ this.readLock.unlock();
+ }
+ }
+
+ private void storageModified() throws StorageException {
+ this.readLock.unlock();
+ this.writeLock.lock();
+
+ try {
+ incrementCounter();
+ if (this.persistFactor > this.modifiedCounter
+ && this.forceWriteDocuments.size() <= 0
+ && this.forceWriteTerms.size() <= 0)
+ return;
+
+ if (LOG.isInfoEnabled())
+ LOG.info("Storage modified for " + this.modifiedCounter
+ + " times. Write Persistent index");
+ writePersistentIndex((this.optimizeCounter >= this.optimizeInterval));
+ requestNewIndexModifier();
+
+ this.modifiedCounter = 0;
+ } catch (IOException e) {
+
+ LOG.error("Writing persistent index failed - Recovering", e);
+ throw new StorageException("could not write to storage index -- "+e.getMessage(),e);
+
+ } finally {
+ this.readLock.lock();
+ this.writeLock.unlock();
+ }
+
+ }
+
+ protected void forceWrite() throws IOException {
+ this.writeLock.lock();
+ try {
+ if (LOG.isInfoEnabled())
+ LOG.info("ForceWrite called -- current modifiedCounter: "
+ + this.modifiedCounter + " - persisting changes");
+ writePersistentIndex(true);
+ requestNewIndexModifier();
+ this.modifiedCounter = 0;
+ } finally {
+ this.writeLock.unlock();
+ }
+ }
+
+ private void requestNewIndexModifier() throws IOException {
+
+ this.controller.registerNewStorageQuery();
+ this.buffer = this.controller.releaseNewStorageBuffer();
+ this.modifier = this.controller.createIndexModifier();
+ }
+
+ private void writePersistentIndex(final boolean optimize)
+ throws IOException {
+ try {
+
+ /*
+ * first delete all updated documents
+ */
+ for (Term entryIdTerm : this.deletedForUpdateDocumentQueue) {
+ this.modifier.deleteDocuments(entryIdTerm);
+ }
+
+ for (Term term : this.forceWriteTerms) {
+ this.modifier.deleteDocuments(term);
+ }
+ /*
+ * add all documents
+ */
+ Collection documents = this.documentMap.values();
+ for (Document doc : documents) {
+ this.modifier.addDocument(doc);
+ }
+ /*
+ * write all users or feeds
+ */
+ for (Document docs : this.forceWriteDocuments) {
+ this.modifier.addDocument(docs);
+ }
+
+ /*
+ * delete all documents marked as deleted. As the DocumentIDs are
+ * unique the document marked as deleted must not persist after the
+ * index has been written. In the case of an update of a document
+ * and a previous delete the concurrency component will not allow an
+ * update. new inserted entries can not be deleted accidently-
+ */
+ for (Term entryIdTerm : this.deletedDocumentQueue) {
+ this.modifier.deleteDocuments(entryIdTerm);
+ }
+ this.modifier.flush();
+ if (optimize) {
+ if (LOG.isInfoEnabled())
+ LOG.info("Optimizing index -- optimize interval "
+ + this.optimizeInterval);
+ this.modifier.optimize();
+ }
+
+ } finally {
+ if (optimize)
+ this.optimizeCounter = 0;
+ this.modifier.close();
+ this.deletedForUpdateDocumentQueue.clear();
+ this.deletedDocumentQueue.clear();
+ this.documentMap.clear();
+ this.forceWriteDocuments.clear();
+ this.forceWriteTerms.clear();
+ }
+ }
+
+ protected void close() throws IOException {
+ this.writeLock.lock();
+ try {
+ if (LOG.isInfoEnabled())
+ LOG.info("ForceWrite called -- current modifiedCounter: "
+ + this.modifiedCounter + " - persisting changes");
+
+ writePersistentIndex(true);
+ this.modifiedCounter = 0;
+ } finally {
+ this.writeLock.unlock();
+ }
+ }
+
+ private void incrementCounter() {
+ this.optimizeCounter++;
+ this.modifiedCounter++;
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageWrapper.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageWrapper.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageWrapper.java (revision 0)
@@ -0,0 +1,38 @@
+/**
+ * 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 org.apache.lucene.document.Document;
+
+/**
+ * A interface to be implemented by StorageWrapper sub classes to
+ * provide a lucene document for each entity wrapped.
+ *
+ * @see org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper
+ * @see org.apache.lucene.gdata.storage.lucenestorage.StorageAccountWrapper
+ * @see org.apache.lucene.gdata.storage.lucenestorage.StorageFeedWrapper
+ * @author Simon Willnauer
+ *
+ */
+public interface StorageWrapper {
+ /**
+ * Returns a Lucene document representing the Wrapped Entry
+ *
+ * @return a Lucene Document
+ */
+ public abstract Document getLuceneDocument();
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/RecoverWriter.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/RecoverWriter.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/RecoverWriter.java (revision 0)
@@ -0,0 +1,104 @@
+/**
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.gdata.storage.lucenestorage.recover;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.apache.lucene.gdata.server.registry.ProvidedService;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation;
+
+import com.google.gdata.data.BaseEntry;
+import com.google.gdata.util.common.xml.XmlWriter;
+
+/**
+ * Writes the recover objects to the hard disc.
+ * @author Simon Willnauer
+ *
+ */
+public class RecoverWriter {
+ protected static final String META_DATA_SEPARATOR = ";";
+ protected static final String META_DATA_ENTRY_SEPARATOR = System.getProperty("line.separator");
+ protected static final String STORAGE_OPERATION_SEPARATOR = "###########";
+ protected static final String OPERATION_DELETE = "D";
+ protected static final String OPERATION_UPDATE = "U";
+ protected static final String OPERATION_INSERT = "I";
+ protected static final String FILE_PREFIX = ".strg";
+
+
+
+ /**
+ * @param wrapper
+ * @throws IOException
+ *
+ *
+ *
+ */
+ public void writeEntry(StorageEntryWrapper wrapper,Writer writer)throws IOException{
+
+ writeOperation(wrapper.getOperation(),writer);
+ writeFeedID(wrapper.getFeedId(),writer);
+ writeEntryID(wrapper.getEntryId(),writer);
+ writeTimeStamp(wrapper.getTimestamp().toString(),writer);
+ if(!wrapper.getOperation().equals(StorageOperation.DELETE)){
+ writeService(wrapper,writer);
+ writer.write(META_DATA_ENTRY_SEPARATOR);
+ BaseEntry entry = wrapper.getEntry();
+ XmlWriter xmlWriter = new XmlWriter(writer);
+ entry.generateAtom(xmlWriter,wrapper.getConfigurator().getExtensionProfile());
+ }
+ writer.write(META_DATA_ENTRY_SEPARATOR);
+ writer.write(STORAGE_OPERATION_SEPARATOR);
+ writer.write(META_DATA_ENTRY_SEPARATOR);
+ }
+
+
+
+ private void writeTimeStamp(String timestamp, Writer writer) throws IOException{
+ writer.write(timestamp);
+ writer.write(META_DATA_SEPARATOR);
+ }
+ private void writeFeedID(String feedId,Writer writer) throws IOException{
+ writer.write(feedId);
+ writer.write(META_DATA_SEPARATOR);
+ }
+ private void writeEntryID(String entryId,Writer writer) throws IOException{
+ writer.write(entryId);
+ writer.write(META_DATA_SEPARATOR);
+ }
+
+ private void writeService(StorageEntryWrapper wrapper, Writer writer) throws IOException{
+ ProvidedService config = wrapper.getConfigurator();
+ writer.write(config.getName());
+ writer.write(META_DATA_SEPARATOR);
+ }
+
+ private void writeOperation(StorageOperation operation, Writer writer) throws IOException{
+ if(operation.equals(StorageOperation.INSERT))
+ writer.write(OPERATION_INSERT);
+ else if (operation.equals(StorageOperation.UPDATE))
+ writer.write(OPERATION_UPDATE);
+ else if (operation.equals(StorageOperation.DELETE))
+ writer.write(OPERATION_DELETE);
+ writer.write(META_DATA_SEPARATOR);
+ }
+
+
+
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/RecoverException.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/RecoverException.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/RecoverException.java (revision 0)
@@ -0,0 +1,63 @@
+/**
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.gdata.storage.lucenestorage.recover;
+
+/**
+ * @author Simon Willnauer
+ *
+ */
+public class RecoverException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1862309520257024464L;
+
+ /**
+ *
+ */
+ public RecoverException() {
+ super();
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * @param arg0
+ */
+ public RecoverException(String arg0) {
+ super(arg0);
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * @param arg0
+ * @param arg1
+ */
+ public RecoverException(String arg0, Throwable arg1) {
+ super(arg0, arg1);
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * @param arg0
+ */
+ public RecoverException(Throwable arg0) {
+ super(arg0);
+ // TODO Auto-generated constructor stub
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/RecoverReader.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/RecoverReader.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/RecoverReader.java (revision 0)
@@ -0,0 +1,174 @@
+/**
+ * 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.recover;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.lucene.gdata.data.ServerBaseEntry;
+import org.apache.lucene.gdata.server.GDataEntityBuilder;
+import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
+import org.apache.lucene.gdata.server.registry.ProvidedService;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation;
+
+import com.google.gdata.data.BaseEntry;
+import com.google.gdata.util.ParseException;
+
+/**
+ * Recovers the written object from the harddisc
+ * @author Simon Willnauer
+ *
+ */
+public class RecoverReader {
+
+ private static final Log LOG = LogFactory.getLog(RecoverReader.class);
+ private RecoverStrategy strategy;
+ protected RecoverReader(){
+ this.strategy = new RecoverStrategy();
+ }
+ /**
+ * @param reader
+ * @return
+ * @throws IOException
+ */
+ public List recoverEntries(final BufferedReader reader) throws IOException{
+ List actionList = new ArrayList();
+ this.strategy = new RecoverStrategy();
+ String input = null;
+ String metaData = null;
+ String entryData = null;
+ while((input=reader.readLine())!= null){
+ if(metaData == null){
+ metaData = input;
+ continue;
+ }
+ if(input.equals(RecoverWriter.STORAGE_OPERATION_SEPARATOR)){
+ try{
+ actionList.add(this.strategy.recover(metaData,entryData));
+ }catch (RecoverException e) {
+ LOG.error("Skipping recover entry for metadata: "+metaData,e);
+ }
+ this.strategy = new RecoverStrategy();
+ metaData = null;
+ entryData = null;
+ continue;
+ }
+ if(entryData == null){
+ entryData = input;
+ }
+
+ }
+
+
+
+ return actionList;
+
+ }
+
+
+
+
+
+
+
+
+ private static class RecoverStrategy{
+ private StorageOperation operation;
+ private ProvidedService config;
+ private String feedId;
+ private String entryId;
+ private long timestamp;
+ /**
+ * @param metaData
+ * @param entry
+ * @return
+ * @throws RecoverException
+ */
+ public StorageEntryWrapper recover(String metaData, String entry) throws RecoverException{
+ fillMetaData(metaData);
+ ServerBaseEntry retVal = null;
+ if(entry != null && this.operation == StorageOperation.DELETE)
+ throw new RecoverException("Can not recover -- Delete operation has entry part");
+ if(entry != null)
+ try {
+ retVal = new ServerBaseEntry(buildEntry(entry,this.config));
+ } catch (Exception e) {
+ throw new RecoverException("Exception occured while building entry -- "+e.getMessage(),e);
+ }
+ else
+ retVal = new ServerBaseEntry();
+ retVal.setId(this.entryId);
+ retVal.setFeedId(this.feedId);
+ retVal.setServiceConfig(this.config);
+
+ try{
+ return new StorageEntryWrapper(retVal,this.operation);
+ }catch (IOException e) {
+ throw new RecoverException("Can't create StorageWrapper -- "+e.getMessage(),e);
+ }
+ }
+ private void fillMetaData(String recoverString) throws RecoverException{
+ StringTokenizer tokenizer = new StringTokenizer(recoverString,RecoverWriter.META_DATA_SEPARATOR);
+ String temp = tokenizer.nextToken();
+ if(temp.equals("D"))
+ this.operation = StorageOperation.DELETE;
+ else if(temp.equals("U"))
+ this.operation = StorageOperation.UPDATE;
+ else if(temp.equals("I"))
+ this.operation = StorageOperation.INSERT;
+ else
+ throw new RecoverException("Illegal metadata --- "+recoverString);
+ temp = tokenizer.nextToken();
+ if(temp == null)
+ throw new RecoverException("Can't recover feed Id -- "+temp);
+ this.feedId = temp;
+ temp = tokenizer.nextToken();
+ if(temp == null)
+ throw new RecoverException("Can't recover entry Id -- "+temp);
+ this.entryId = temp;
+
+ temp = tokenizer.nextToken();
+ try{
+ this.timestamp = Long.parseLong(temp);
+ }catch (Exception e) {
+ throw new RecoverException("Can't recover timestamp -- "+temp,e);
+ }
+
+ if(this.operation != StorageOperation.DELETE){
+ temp = tokenizer.nextToken();
+ if(temp == null)
+ throw new RecoverException("Can't recover service -- "+temp);
+ if(!GDataServerRegistry.getRegistry().isServiceRegistered(temp))
+ throw new RecoverException("Service in recover metadata is not registered - "+temp);
+ this.config = GDataServerRegistry.getRegistry().getProvidedService(temp);
+
+ }
+
+ }
+
+ private BaseEntry buildEntry(String entry, ProvidedService serviceConfig) throws ParseException, IOException{
+ StringReader reader = new StringReader(entry);
+ return GDataEntityBuilder.buildEntry(reader,serviceConfig);
+ }
+ }
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/RecoverController.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/RecoverController.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/RecoverController.java (revision 0)
@@ -0,0 +1,169 @@
+/**
+ * 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.recover;
+
+import java.io.BufferedReader;
+import java.io.BufferedWriter;
+import java.io.File;
+import java.io.FileReader;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.Writer;
+import java.util.List;
+import java.util.concurrent.locks.Lock;
+import java.util.concurrent.locks.ReentrantLock;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.lucene.gdata.storage.StorageException;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageModifier;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation;
+
+
+/**
+ * @author Simon Willnauer
+ *
+ */
+public class RecoverController {
+ private static final Log LOG = LogFactory.getLog(RecoverController.class);
+ private final File recoverDirectory;
+
+ private static final String FILE_SUFFIX = ".rec";
+
+ private File currentRecoverFile;
+
+ private RecoverWriter writer;
+
+ private Writer fileWriter;
+
+ private BufferedReader fileReader;
+
+ private RecoverReader reader;
+
+ private Lock lock = new ReentrantLock();
+
+ private final boolean recover;
+ private final boolean keepRecoverFiles;
+
+ public RecoverController(final File recoverDirectory, boolean recover, boolean keepRecoverFiles) {
+ if (recoverDirectory == null)
+ throw new IllegalArgumentException("directory must not be null");
+ if (!recoverDirectory.isDirectory())
+ throw new IllegalStateException("the given File is not a directory");
+ this.recover = recover;
+ this.keepRecoverFiles = keepRecoverFiles;
+ this.recoverDirectory = recoverDirectory;
+
+ }
+
+ public void storageModified(StorageEntryWrapper wrapper)
+ throws RecoverException {
+ // prevent deadlock either recovering or writing
+ if(this.recover){
+ LOG.warn("Can't write entry, Recovercontroller is initialized in recover mode");
+ return;
+ }
+ this.lock.lock();
+ try {
+
+ this.writer.writeEntry(wrapper, this.fileWriter);
+ } catch (Exception e) {
+ LOG.error("Writing entry failed -- create new recover file",e);
+ throw new RecoverException(
+ "Writing entry failed -- create new recover file",e);
+
+ } finally {
+ this.lock.unlock();
+ }
+ }
+
+ public void recoverEntries(final StorageModifier modifier){
+ // prevent deadlock either recovering or writing
+ if(!this.recover){
+ LOG.warn("Can't recover entries, Recovercontroller is initialized in write mode");
+ return;
+ }
+ this.lock.lock();
+ try{
+ this.reader = new RecoverReader();
+ File[] files = this.recoverDirectory.listFiles();
+ for (int i = 0; i < files.length; i++) {
+ if(!files[i].isDirectory()){
+ try{
+ this.fileReader = new BufferedReader(new FileReader(files[i]));
+ List entryList = this.reader.recoverEntries(this.fileReader);
+ if(entryList.size() == 0)
+ continue;
+ storeEntries(entryList,modifier);
+ this.fileReader.close();
+ if(!this.keepRecoverFiles)
+ files[i].delete();
+ }catch (StorageException e) {
+ LOG.error("Can't store recover entries for file: "+files[i].getName()+" -- keep file "+e.getMessage(),e);
+ }catch (IOException e) {
+ LOG.error("Can't recover entries for file: "+files[i].getName()+" -- keep file",e);
+ }
+ }
+ }
+
+ }finally{
+ this.lock.unlock();
+ }
+ }
+
+ protected void storeEntries(final List entries, final StorageModifier modifier) throws StorageException{
+ for (StorageEntryWrapper wrapper : entries) {
+ if(wrapper.getOperation() == StorageOperation.DELETE)
+ modifier.deleteEntry(wrapper);
+ else if(wrapper.getOperation() == StorageOperation.INSERT)
+ modifier.insertEntry(wrapper);
+ else if(wrapper.getOperation() == StorageOperation.UPDATE)
+ modifier.updateEntry(wrapper);
+
+
+ }
+ }
+
+ protected synchronized void initialize() throws IOException {
+ if(this.recover)
+ return;
+ String filename = System.currentTimeMillis() + FILE_SUFFIX;
+ this.currentRecoverFile = new File(this.recoverDirectory, filename);
+ this.writer = new RecoverWriter();
+ this.fileWriter = new BufferedWriter(new FileWriter(
+ this.currentRecoverFile));
+
+ }
+
+ protected void destroy() throws RecoverException {
+ if (this.fileWriter != null) {
+ this.lock.lock();
+ try {
+ this.fileWriter.flush();
+ this.fileWriter.close();
+ } catch (IOException e) {
+ throw new RecoverException("Can't close recover writer ", e);
+ } finally {
+ this.lock.unlock();
+ }
+ }
+ }
+
+
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/package.html
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/package.html (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/package.html (revision 0)
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+Recovering component for the lucene storage
+
+
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageEntryWrapper.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageEntryWrapper.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageEntryWrapper.java (working copy)
@@ -12,177 +12,215 @@
* 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.io.StringWriter;
-
-import org.apache.lucene.document.Document;
-import org.apache.lucene.document.Field;
-
-import com.google.gdata.data.BaseEntry;
-import com.google.gdata.data.ExtensionProfile;
-import com.google.gdata.util.common.xml.XmlWriter;
-
-/**
- * This immutable class wrapps Entries for an internal Storage representation of
- * an entry. This class also acts as a Documentfactory for lucene documents to
- * be stored inside the index.
- *
- * @author Simon Willnauer
- *
- */
-public class StorageEntryWrapper implements Comparable {
- private static final String INTERNAL_ENCODING = "UTF-8";
-
- /**
- * lucene field name Entry id
- */
- public final static String FIELD_ENTRY_ID = "entryId";
-
- /**
- * lucene field name feed id
- */
- public final static String FIELD_FEED_ID = "feedId";
-
- /**
- * lucene field name entry content
- */
- public final static String FIELD_CONTENT = "content";
-
- /**
- * lucene field name creating timestamp
- */
- public final static String FIELD_TIMESTAMP = "timestamp";
-
- private final String entryId;
-
- private final String feedId;
-
- private final String content;
-
- private final transient BaseEntry entry;
-
- private final Long timestamp;
-
- private transient Document document;
-
- private StorageOperation operation;
-
- private final ExtensionProfile profile;
-
- /**
- * Creates a new StorageEntryWrapper.
- *
- * @param entry -
- * the entry to wrap
- * @param feedId -
- * the feed id
- * @param operation -
- * the StorageOperation
- * @param profile -
- * the ExtensionProfil for the given entry
- * @throws IOException -
- * if the entry content can not be generated
- */
- protected StorageEntryWrapper(final BaseEntry entry, final String feedId,
- StorageOperation operation, final ExtensionProfile profile)
- throws IOException {
- this.entry = entry;
- this.operation = operation;
- this.entryId = entry.getId();
- this.feedId = feedId;
- this.profile = profile;
- this.content = buildContent();
- this.timestamp = new Long(System.currentTimeMillis());
-
- }
-
- private String buildContent() throws IOException {
- StringWriter writer = new StringWriter();
- XmlWriter xmlWriter = new XmlWriter(writer, INTERNAL_ENCODING);
- this.entry.generateAtom(xmlWriter, this.profile);
- return writer.toString();
-
- }
-
- /**
- * @return - the lucene document representing the entry
- */
- public Document getLuceneDocument() {
- if (this.document != null)
- return this.document;
- this.document = new Document();
- this.document.add(new Field("entryId", this.entryId, Field.Store.YES,
- Field.Index.UN_TOKENIZED));
- this.document.add(new Field("feedId", this.feedId, Field.Store.YES,
- Field.Index.UN_TOKENIZED));
- this.document.add(new Field("content", this.content,
- Field.Store.COMPRESS, Field.Index.UN_TOKENIZED));
- this.document.add(new Field("timestamp", this.timestamp.toString(),
- Field.Store.YES, Field.Index.UN_TOKENIZED));
-
- return this.document;
-
- }
-
- /**
- * @return - the wrapped entry
- */
- public BaseEntry getEntry() {
- return this.entry;
- }
-
- /**
- * @return - the entry id
- */
- public String getEntryId() {
- return this.entryId;
- }
-
- /**
- * @return - the feed id
- */
- public String getFeedId() {
- return this.feedId;
- }
-
- /**
- * Storage operations
- *
- * @author Simon Willnauer
- *
- */
- public static enum StorageOperation {
- /**
- * delete
- */
- DELETE,
- /**
- * update
- */
- UPDATE,
- /**
- * insert
- */
- INSERT
- }
-
- /**
- * @return the specified storage operation
- */
- public StorageOperation getOperation() {
- return this.operation;
- }
-
- /**
- * @see java.lang.Comparable#compareTo(T)
- */
- public int compareTo(StorageEntryWrapper arg0) {
- return arg0.timestamp == this.timestamp ? 0
- : (arg0.timestamp > this.timestamp ? 1 : -1);
- }
-
-}
+ */
+
+package org.apache.lucene.gdata.storage.lucenestorage;
+
+import java.io.IOException;
+import java.io.StringWriter;
+
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.gdata.data.ServerBaseEntry;
+import org.apache.lucene.gdata.server.registry.ProvidedService;
+import org.apache.lucene.gdata.server.registry.ProvidedServiceConfig;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer.BufferableEntry;
+
+import com.google.gdata.data.BaseEntry;
+import com.google.gdata.util.common.xml.XmlWriter;
+
+/**
+ * This immutable class wrapps ServerBaseEntry for an internal
+ * Storage representation of an entry. This class also acts as a Documentfactory
+ * for lucene documents to be stored inside the index.
+ *
+ * @author Simon Willnauer
+ *
+ */
+public class StorageEntryWrapper implements Comparable,
+ StorageWrapper {
+
+ private static final long serialVersionUID = -4619985652059888526L;
+
+ private static final String INTERNAL_ENCODING = "UTF-8";
+
+ /**
+ * lucene field name Entry id
+ */
+ public final static String FIELD_ENTRY_ID = "entryId";
+
+ /**
+ * lucene field name feed id
+ */
+ public final static String FIELD_FEED_REFERENCE = "feedReference";
+
+ /**
+ * lucene field name entry content
+ */
+ public final static String FIELD_CONTENT = "content";
+
+ /**
+ * lucene field name creating timestamp
+ */
+ public final static String FIELD_TIMESTAMP = "timestamp";
+
+ private final String entryId;
+
+ private final String feedId;
+
+ private String content;
+
+ private final ServerBaseEntry entry;
+
+ private Long timestamp;
+
+ private transient Document document;
+
+ private StorageOperation operation;
+
+ private ProvidedService config;
+
+ /**
+ * Creates a new StorageEntryWrapper.
+ *
+ * @param entry -
+ * the entry to wrap
+ *
+ * @param operation -
+ * the StorageOperation
+ *
+ * @throws IOException -
+ * if the entry content can not be generated
+ */
+ public StorageEntryWrapper(final ServerBaseEntry entry,
+ StorageOperation operation) throws IOException {
+
+ this.entry = entry;
+ this.operation = operation;
+ this.entryId = entry.getId();
+ this.feedId = entry.getFeedId();
+ if (operation != StorageOperation.DELETE) {
+ this.config = entry.getServiceConfig();
+ this.content = buildContent();
+
+ }
+ this.timestamp = new Long(
+ this.entry.getUpdated() != null ? this.entry.getUpdated()
+ .getValue() : System.currentTimeMillis());
+
+
+ }
+
+ private String buildContent() throws IOException {
+ StringWriter writer = new StringWriter();
+ XmlWriter xmlWriter = new XmlWriter(writer, INTERNAL_ENCODING);
+ this.entry.generateAtom(xmlWriter, this.config.getExtensionProfile());
+ return writer.toString();
+
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.lucenestorage.StorageWrapper#getLuceneDocument()
+ */
+ public Document getLuceneDocument() {
+ if(this.operation == StorageOperation.DELETE)
+ return null;
+ if (this.document != null)
+ return this.document;
+ this.document = new Document();
+ this.document.add(new Field(FIELD_ENTRY_ID, this.entryId,
+ Field.Store.YES, Field.Index.UN_TOKENIZED));
+ this.document.add(new Field(FIELD_FEED_REFERENCE, this.feedId,
+ Field.Store.YES, Field.Index.UN_TOKENIZED));
+ this.document.add(new Field(FIELD_CONTENT, this.content,
+ Field.Store.COMPRESS, Field.Index.NO));
+ this.document.add(new Field(FIELD_TIMESTAMP, this.timestamp.toString(),
+ Field.Store.YES, Field.Index.UN_TOKENIZED));
+
+ return this.document;
+
+ }
+
+ /**
+ * @return - the wrapped entry
+ */
+ public BaseEntry getEntry() {
+ /*
+ * this wrapps the entry again. BufferableEntry creates a new instance
+ * for the dynamic element like links.
+ */
+ return new BufferableEntry(this.entry.getEntry());
+ }
+
+ /**
+ * @return - the entry id
+ */
+ public String getEntryId() {
+ return this.entryId;
+ }
+
+ /**
+ * @return - the feed id
+ */
+ public String getFeedId() {
+ return this.feedId;
+ }
+
+ /**
+ * Storage operations
+ *
+ * @author Simon Willnauer
+ *
+ */
+ public static enum StorageOperation {
+ /**
+ * delete
+ */
+ DELETE,
+ /**
+ * update
+ */
+ UPDATE,
+ /**
+ * insert
+ */
+ INSERT
+ }
+
+ /**
+ * @return the specified storage operation
+ */
+ public StorageOperation getOperation() {
+ return this.operation;
+ }
+
+ /**
+ * This compare method compares the timestamps of the wrapper instances.
+ *
+ * @param arg0 -
+ * the wrapper to compare
+ * @par
+ * @return - 0 if the wrappers timestamp are the same, an integer > 0 if the
+ * given wrapper is after this wrapper
+ *
+ */
+ public int compareTo(StorageEntryWrapper arg0) {
+ return arg0.timestamp == this.timestamp ? 0
+ : (arg0.timestamp > this.timestamp ? 1 : -1);
+ }
+
+ /**
+ * @return - the specified {@link ProvidedServiceConfig}
+ */
+ public ProvidedService getConfigurator() {
+ return this.config;
+ }
+
+ /**
+ * @return Returns the timestamp.
+ */
+ public Long getTimestamp() {
+ return this.timestamp;
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/configuration/StorageConfigurator.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/configuration/StorageConfigurator.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/configuration/StorageConfigurator.java (working copy)
@@ -37,7 +37,8 @@
private final boolean keepRecoveredFiles;
private final boolean recover;
-
+
+ private final boolean ramDirectory;
private static StorageConfigurator INSTANCE = null;
private final int indexOptimizeInterval;
@@ -64,7 +65,8 @@
.getProperty("gdata.server.storage.lucene.directory");
this.indexOptimizeInterval = Integer.parseInt(properties
.getProperty("gdata.server.storage.lucene.optimizeInterval"));
-
+ this.ramDirectory = Boolean.parseBoolean(properties
+ .getProperty("gdata.server.storage.lucene.directory.ramDirectory"));
}
/**
@@ -139,6 +141,13 @@
public int getIndexOptimizeInterval() {
return this.indexOptimizeInterval;
+ }
+
+ /**
+ * @return Returns the ramDirectory.
+ */
+ public boolean isRamDirectory() {
+ return this.ramDirectory;
}
}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageFeedWrapper.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageFeedWrapper.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageFeedWrapper.java (revision 0)
@@ -0,0 +1,106 @@
+/**
+ * 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.io.StringWriter;
+
+import org.apache.lucene.document.Document;
+import org.apache.lucene.document.Field;
+import org.apache.lucene.gdata.data.ServerBaseFeed;
+import org.apache.lucene.gdata.server.registry.ProvidedService;
+
+import com.google.gdata.data.BaseFeed;
+import com.google.gdata.util.common.xml.XmlWriter;
+
+/**
+ * This immutable class wrapps GDataAccount instances for an internal Storage representation of
+ * an account. This class also acts as a Documentfactory for lucene documents to
+ * be stored inside the index.
+ * @author Simon Willnauer
+ *
+ */
+public class StorageFeedWrapper implements StorageWrapper {
+
+ private static final String INTERNAL_ENCODING = "UTF-8";
+ /**
+ * the account who owns the feed
+ */
+ public static final String FIELD_ACCOUNTREFERENCE = "accountReference";
+ /**
+ * the id of the feed
+ */
+ public static final String FIELD_FEED_ID = "feedId";
+ /**
+ * The xml feed representation
+ */
+ public static final String FIELD_CONTENT = "content";
+
+ /**
+ * The creation timestamp
+ */
+ public static final String FIELD_TIMESTAMP = "timestamp";
+
+ /**
+ * The Service this feed belongs to.
+ */
+ public static final String FIELD_SERVICE_ID = "serviceId";
+ private final ServerBaseFeed feed;
+ private final String accountName;
+ private final ProvidedService config;
+ private final String content;
+
+
+ /**
+ * @param feed
+ * @param accountname
+ * @throws IOException
+ *
+ */
+ public StorageFeedWrapper(final ServerBaseFeed feed, final String accountname) throws IOException {
+ this.feed = feed;
+ this.accountName = accountname;
+ this.config = feed.getServiceConfig();
+ this.content = buildContent();
+
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.lucenestorage.StorageWrapper#getLuceneDocument()
+ */
+ public Document getLuceneDocument() {
+ Document doc = new Document();
+ doc.add(new Field(FIELD_ACCOUNTREFERENCE,this.accountName,Field.Store.YES,Field.Index.UN_TOKENIZED));
+ doc.add(new Field(FIELD_FEED_ID,this.feed.getId(),Field.Store.YES,Field.Index.UN_TOKENIZED));
+ doc.add(new Field(FIELD_CONTENT,this.content,Field.Store.COMPRESS,Field.Index.NO));
+ doc.add(new Field(FIELD_SERVICE_ID,this.feed.getServiceType(),Field.Store.YES,Field.Index.NO));
+ return doc;
+ }
+
+ private String buildContent() throws IOException {
+ StringWriter writer = new StringWriter();
+ XmlWriter xmlWriter = new XmlWriter(writer, INTERNAL_ENCODING);
+ this.feed.generateAtom(xmlWriter,this.config.getExtensionProfile());
+ return writer.toString();
+ }
+ /**
+ * @return - the wrapped feed
+ */
+ public BaseFeed getFeed(){
+ return this.feed.getFeed();
+ }
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageImplementation.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageImplementation.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageImplementation.java (working copy)
@@ -1,259 +1,526 @@
-/**
- * Copyright 2004 The Apache Software Foundation
+/**
+ * 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 org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.lucene.gdata.data.GDataAccount;
+import org.apache.lucene.gdata.data.ServerBaseEntry;
+import org.apache.lucene.gdata.data.ServerBaseFeed;
+import org.apache.lucene.gdata.server.registry.ComponentType;
+import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
+import org.apache.lucene.gdata.storage.ResourceNotFoundException;
+import org.apache.lucene.gdata.storage.Storage;
+import org.apache.lucene.gdata.storage.StorageController;
+import org.apache.lucene.gdata.storage.StorageException;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation;
+import org.apache.lucene.gdata.storage.lucenestorage.util.ReferenceCounter;
+
+import com.google.gdata.data.BaseEntry;
+import com.google.gdata.data.BaseFeed;
+
+/**
+ * This is an implementation of the
+ * {@link org.apache.lucene.gdata.storage.Storage} interface. The
+ * StorageImplementation provides access to the
+ * {@link org.apache.lucene.gdata.storage.lucenestorage.StorageQuery} and the
+ * {@link org.apache.lucene.gdata.storage.lucenestorage.StorageModifier}. This
+ * class will be instanciated per client request.
*
- * 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.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.lucene.gdata.storage.Storage;
-import org.apache.lucene.gdata.storage.StorageException;
-import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation;
-import org.apache.lucene.gdata.storage.lucenestorage.util.ReferenceCounter;
-
-import com.google.gdata.data.BaseEntry;
-import com.google.gdata.data.BaseFeed;
-import com.google.gdata.data.ExtensionProfile;
-import com.google.gdata.data.Feed;
-
-/**
- * This is an implementation of the
- * {@link org.apache.lucene.gdata.storage.Storage} interface. The
- * StorageImplementation provides access to the
- * {@link org.apache.lucene.gdata.storage.lucenestorage.StorageQuery} and the
- * {@link org.apache.lucene.gdata.storage.lucenestorage.StorageModifier}. This
- * class will be instanciated per client request.
- *
- *
- *
- * @author Simon Willnauer
- *
- */
-public class StorageImplementation implements Storage {
- private final StorageCoreController controller;
-
- private ExtensionProfile profile;
-
- private static final Log LOG = LogFactory
- .getLog(StorageImplementation.class);
-
- /**
- * Creates a new StorageImplementation
- *
- * @throws StorageException -
- * if the
- * {@link org.apache.lucene.gdata.storage.StorageController} can
- * not be created
- * @throws IOException -
- * if the
- * {@link org.apache.lucene.gdata.storage.StorageController} can
- * not be created
- * @see StorageCoreController#getStorageCoreController()
- *
- */
- public StorageImplementation() throws IOException, StorageException {
- this.controller = StorageCoreController.getStorageCoreController();
- }
-
- /**
- * @see org.apache.lucene.gdata.storage.Storage#storeEntry(com.google.gdata.data.BaseEntry,
- * java.lang.String)
- */
- public BaseEntry storeEntry(BaseEntry entry, String feedId)
- throws StorageException {
- if (this.profile == null)
- throw new StorageException(
- "Can process ExtensionProfile not set -- is null");
- if (feedId == null)
- throw new StorageException("No feed ID specified -- is null");
- StorageModifier modifier = this.controller.getStorageModifier();
- String id = this.controller.releaseID();
- entry.setId(feedId + id);
- if (LOG.isInfoEnabled())
- LOG.info("Store entry " + id + " -- feed: " + feedId);
-
- try {
- StorageEntryWrapper wrapper = new StorageEntryWrapper(entry,
- feedId, StorageOperation.INSERT, this.profile);
- modifier.insertEntry(wrapper);
- } catch (IOException e) {
- StorageException ex = new StorageException("Can't create Entry -- "
- + e.getMessage(), e);
- ex.setStackTrace(e.getStackTrace());
- throw ex;
-
- }
-
- return entry;
- }
-
- /**
- * @see org.apache.lucene.gdata.storage.Storage#deleteEntry(java.lang.String,
- * java.lang.String)
- */
- public void deleteEntry(String entryId, String feedId)
- throws StorageException {
- if (this.profile == null)
- throw new StorageException(
- "Can process ExtensionProfile not set -- is null");
- if (feedId == null)
- throw new StorageException("No feed ID specified -- is null");
- if (entryId == null)
- throw new StorageException("No entry ID specified -- is null");
- if (LOG.isInfoEnabled())
- LOG.info("delete entry " + entryId + " -- feed: " + feedId);
- StorageModifier modifier = this.controller.getStorageModifier();
- modifier.deleteEntry(entryId, feedId);
- }
-
- /**
- * @see org.apache.lucene.gdata.storage.Storage#updateEntry(com.google.gdata.data.BaseEntry,
- * java.lang.String)
- */
- public BaseEntry updateEntry(BaseEntry entry, String feedId)
- throws StorageException {
- if (this.profile == null)
- throw new StorageException(
- "Can process ExtensionProfile not set -- is null");
- if (feedId == null)
- throw new StorageException("No feed ID specified -- is null");
- if (entry == null)
- throw new StorageException("enrty is null");
- if (entry.getId() == null)
- throw new StorageException("No entry ID specified -- is null");
- if (LOG.isInfoEnabled())
- LOG.info("update entry " + entry.getId() + " -- feed: " + feedId);
- StorageModifier modifier = this.controller.getStorageModifier();
-
- try {
- StorageEntryWrapper wrapper = new StorageEntryWrapper(entry,
- feedId, StorageOperation.UPDATE, this.profile);
- modifier.updateEntry(wrapper);
- } catch (IOException e) {
- LOG.error("Can't update entry for feedID: " + feedId
- + "; entryId: " + entry.getId() + " -- " + e.getMessage(),
- e);
- StorageException ex = new StorageException("Can't create Entry -- "
- + e.getMessage(), e);
- ex.setStackTrace(e.getStackTrace());
- throw ex;
-
- }
-
- return entry;
-
- }
-
- /**
- * @see org.apache.lucene.gdata.storage.Storage#getFeed(java.lang.String,
- * int, int)
- */
- @SuppressWarnings("unchecked")
- public BaseFeed getFeed(String feedId, int startIndex, int resultCount)
- throws StorageException {
- if (this.profile == null)
- throw new StorageException(
- "Can process ExtensionProfile not set -- is null");
- if (feedId == null)
- throw new StorageException("No feed ID specified -- is null");
- if (LOG.isInfoEnabled())
- LOG.info("get feed: " + feedId + " startindex: " + startIndex
- + " resultCount: " + resultCount);
- ReferenceCounter query = null;
- try {
- query = this.controller.getStorageQuery();
- List resultList = query.get().getLatestFeedQuery(feedId,
- resultCount, startIndex, this.profile);
- BaseFeed feed = new Feed();
- feed.getEntries().addAll(resultList);
- return feed;
- } catch (Exception e) {
- LOG.error("Can't get latest feed for feedID: " + feedId + " -- "
- + e.getMessage(), e);
- StorageException ex = new StorageException("Can't create Entry -- "
- + e.getMessage(), e);
- ex.setStackTrace(e.getStackTrace());
- throw ex;
-
- } finally {
- if (query != null)
- query.decrementRef();
- }
-
- }
-
- /**
- * @see org.apache.lucene.gdata.storage.Storage#getEntry(java.lang.String,
- * java.lang.String)
- */
- public BaseEntry getEntry(String entryId, String feedId)
- throws StorageException {
- if (this.profile == null)
- throw new StorageException(
- "Can process ExtensionProfile not set -- is null");
- if (feedId == null)
- throw new StorageException("No feed ID specified -- is null");
- if (entryId == null)
- throw new StorageException("No entry ID specified -- is null");
- if (LOG.isInfoEnabled())
- LOG.info("get entry " + entryId + " -- feed: " + feedId);
- ReferenceCounter query = null;
- try {
- query = this.controller.getStorageQuery();
- return query.get().singleEntryQuery(entryId, feedId, this.profile);
- } catch (Exception e) {
- LOG.error("Can't get entry for feedID: " + feedId + "; entryId: "
- + entryId + " -- " + e.getMessage(), e);
- StorageException ex = new StorageException("Can't create Entry -- "
- + e.getMessage(), e);
- ex.setStackTrace(e.getStackTrace());
- throw ex;
-
- } finally {
- if (query != null)
- query.decrementRef();
- }
-
- }
-
- /**
- * @see org.apache.lucene.gdata.storage.Storage#getEntries(java.util.List,
- * java.lang.String)
- */
- public List getEntries(List entryIdList, String feedId)
- throws StorageException {
- throw new StorageException("not implemented yet");
- // TODO implement this
-
- }
-
- /**
- * @see org.apache.lucene.gdata.storage.Storage#close()
- */
- public void close() {
- //
- }
-
- /**
- * @see org.apache.lucene.gdata.storage.Storage#setExtensionProfile(com.google.gdata.data.ExtensionProfile)
- */
- public void setExtensionProfile(ExtensionProfile profile) {
- this.profile = profile;
- }
-
-}
+ * @author Simon Willnauer
+ *
+ */
+public class StorageImplementation implements Storage {
+ private final StorageCoreController controller;
+
+ private static final Log LOG = LogFactory
+ .getLog(StorageImplementation.class);
+
+ /**
+ * Creates a new StorageImplementation
+ *
+ * @throws StorageException -
+ * if the storage controller can not be obtained
+ *
+ *
+ *
+ */
+ public StorageImplementation() throws StorageException {
+ this.controller = (StorageCoreController) GDataServerRegistry
+ .getRegistry().lookup(StorageController.class,
+ ComponentType.STORAGECONTROLLER);
+ if (this.controller == null)
+ throw new StorageException("Can't get registered StorageController");
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#storeEntry(org.apache.lucene.gdata.data.ServerBaseEntry)
+ */
+ public BaseEntry storeEntry(final ServerBaseEntry entry)
+ throws StorageException {
+
+ if (entry == null)
+ throw new StorageException("entry is null");
+ StorageModifier modifier = this.controller.getStorageModifier();
+ String id = this.controller.releaseID();
+ entry.setId(entry.getFeedId() + id);
+ if (LOG.isInfoEnabled())
+ LOG.info("Store entry " + id + " -- feed: " + entry.getFeedId());
+
+ try {
+ StorageEntryWrapper wrapper = new StorageEntryWrapper(entry,
+ StorageOperation.INSERT);
+ modifier.insertEntry(wrapper);
+ } catch (IOException e) {
+ StorageException ex = new StorageException("Can't create Entry -- "
+ + e.getMessage(), e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+
+ }
+
+ return entry.getEntry();
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#deleteEntry(org.apache.lucene.gdata.data.ServerBaseEntry)
+ */
+ public void deleteEntry(final ServerBaseEntry entry)
+ throws StorageException {
+
+ if (entry == null)
+ throw new StorageException("Entry is null");
+
+ if (LOG.isInfoEnabled())
+ LOG.info("delete entry " + entry.getId() + " -- feed: "
+ + entry.getFeedId());
+ StorageModifier modifier = this.controller.getStorageModifier();
+ ReferenceCounter query = this.controller.getStorageQuery();
+ try{
+ if(query.get().isEntryStored(entry.getId(),entry.getFeedId())){
+
+ modifier.deleteEntry(new StorageEntryWrapper(entry,StorageOperation.DELETE));
+ }
+ else
+ throw new ResourceNotFoundException("Entry for entry id: "+entry.getId()+" is not stored");
+ }catch (IOException e) {
+ throw new StorageException("Can not access storage");
+ }finally{
+ query.decrementRef();
+ }
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#updateEntry(org.apache.lucene.gdata.data.ServerBaseEntry)
+ */
+ public BaseEntry updateEntry(ServerBaseEntry entry) throws StorageException {
+
+ if (entry == null)
+ throw new StorageException("entry is null");
+ if(entry.getId() == null)
+ throw new StorageException("entry id is null");
+ if(entry.getFeedId() == null)
+ throw new StorageException("feed id is null");
+ if (LOG.isInfoEnabled())
+ LOG.info("update entry " + entry.getId() + " -- feed: "
+ + entry.getFeedId());
+ StorageModifier modifier = this.controller.getStorageModifier();
+ ReferenceCounter query = this.controller.getStorageQuery();
+ try {
+ StorageEntryWrapper wrapper = new StorageEntryWrapper(entry,
+ StorageOperation.UPDATE);
+ if(query.get().isEntryStored(entry.getId(),entry.getFeedId()))
+ modifier.updateEntry(wrapper);
+ else
+ throw new ResourceNotFoundException("Entry for entry id: "+entry.getId()+" is not stored");
+
+ } catch (IOException e) {
+ LOG.error("Can't update entry for feedID: " + entry.getFeedId()
+ + "; entryId: " + entry.getId() + " -- " + e.getMessage(),
+ e);
+ StorageException ex = new StorageException("Can't create Entry -- "
+ + e.getMessage(), e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+
+ }
+
+ return entry.getEntry();
+
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#getFeed(org.apache.lucene.gdata.data.ServerBaseFeed)
+ */
+ @SuppressWarnings("unchecked")
+ public BaseFeed getFeed(final ServerBaseFeed feed) throws StorageException {
+
+ if (feed == null)
+ throw new StorageException("feed is null");
+ if (LOG.isInfoEnabled())
+ LOG.info("get feed: " + feed.getId() + " startindex: "
+ + feed.getStartIndex() + " resultCount: "
+ + feed.getItemsPerPage());
+ ReferenceCounter query = null;
+ try {
+ query = this.controller.getStorageQuery();
+ BaseFeed retVal = query.get().getLatestFeedQuery(feed.getId(),
+ feed.getItemsPerPage(), feed.getStartIndex(),
+ feed.getServiceConfig());
+ return retVal;
+ } catch (Exception e) {
+ LOG.error("Can't get latest feed for feedID: " + feed.getId()
+ + " -- " + e.getMessage(), e);
+ StorageException ex = new StorageException("Can't create Entry -- "
+ + e.getMessage(), e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+
+ } finally {
+ if (query != null)
+ query.decrementRef();
+ }
+
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#getEntry(org.apache.lucene.gdata.data.ServerBaseEntry)
+ */
+ public BaseEntry getEntry(final ServerBaseEntry entry)
+ throws StorageException {
+
+ if (entry == null)
+ throw new StorageException("No entry specified -- is null");
+ if (LOG.isInfoEnabled())
+ LOG.info("get entry " + entry.getId() + " -- feed: "
+ + entry.getFeedId());
+ ReferenceCounter query = null;
+ try {
+ query = this.controller.getStorageQuery();
+ BaseEntry retVal = query.get().singleEntryQuery(entry.getId(),
+ entry.getFeedId(), entry.getServiceConfig());
+ if(retVal == null)
+ throw new ResourceNotFoundException("can not get entry for entry ID "+entry.getId());
+ return retVal;
+ } catch (Exception e) {
+ LOG.error("Can't get entry for feedID: " + entry.getFeedId()
+ + "; entryId: " + entry.getId() + " -- " + e.getMessage(),
+ e);
+ StorageException ex = new StorageException("Can't create Entry -- "
+ + e.getMessage(), e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+
+ } finally {
+ if (query != null)
+ query.decrementRef();
+ }
+
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#close()
+ */
+ public void close() {
+ //
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#storeAccount(org.apache.lucene.gdata.data.GDataAccount)
+ */
+ public void storeAccount(GDataAccount Account) throws StorageException {
+ if (Account == null)
+ throw new StorageException("Can not save null Account");
+ ReferenceCounter query = null;
+ try {
+ query = this.controller.getStorageQuery();
+ if (query.get().getUser(Account.getName()) != null)
+ throw new StorageException("Account already exists");
+ StorageModifier modifier = this.controller.getStorageModifier();
+ StorageAccountWrapper wrapper = new StorageAccountWrapper(Account);
+ modifier.createAccount(wrapper);
+ } catch (Exception e) {
+ LOG.error("Can't save Account -- " + e.getMessage(), e);
+ StorageException ex = new StorageException("Can't save Account -- "
+ + e.getMessage(), e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+
+ } finally {
+ if (query != null)
+ query.decrementRef();
+ }
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#updateAccount(org.apache.lucene.gdata.data.GDataAccount)
+ */
+ public void updateAccount(GDataAccount Account) throws StorageException {
+ if (Account == null)
+ throw new StorageException("Can not update null Account");
+ ReferenceCounter query = null;
+ try {
+ query = this.controller.getStorageQuery();
+ if (query.get().getUser(Account.getName()) == null)
+ throw new StorageException("Account does not exist");
+ StorageModifier modifier = this.controller.getStorageModifier();
+ StorageAccountWrapper wrapper = new StorageAccountWrapper(Account);
+ modifier.updateAccount(wrapper);
+ } catch (Exception e) {
+ LOG.error("Can't update Account -- " + e.getMessage(), e);
+ StorageException ex = new StorageException(
+ "Can't update Account -- " + e.getMessage(), e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+
+ } finally {
+ if (query != null)
+ query.decrementRef();
+ }
+
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#deleteAccount(java.lang.String)
+ */
+ public void deleteAccount(String Accountname) throws StorageException {
+ if (Accountname == null)
+ throw new StorageException("can not delete null Account");
+ ReferenceCounter query = null;
+ try {
+ query = this.controller.getStorageQuery();
+ if (query.get().getUser(Accountname) == null)
+ throw new StorageException("Account does not exist");
+ StorageModifier modifier = this.controller.getStorageModifier();
+ modifier.deleteAccount(Accountname);
+ } catch (Exception e) {
+ LOG.error("Can't update Account -- " + e.getMessage(), e);
+ StorageException ex = new StorageException(
+ "Can't update Account -- " + e.getMessage(), e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+
+ } finally {
+ if (query != null)
+ query.decrementRef();
+ }
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#storeFeed(org.apache.lucene.gdata.data.ServerBaseFeed,
+ * java.lang.String)
+ */
+ public void storeFeed(ServerBaseFeed feed, String accountName)
+ throws StorageException {
+ if (feed == null)
+ throw new StorageException("can not insert null feed");
+ if (accountName == null)
+ throw new StorageException("accountName must not be null");
+ ReferenceCounter query = null;
+ try {
+ query = this.controller.getStorageQuery();
+ if (query.get().isFeedStored(feed.getId()))
+ throw new StorageException("feed with feedID " + feed.getId()
+ + " is already stored");
+ StorageModifier modifier = this.controller.getStorageModifier();
+ StorageFeedWrapper wrapper = new StorageFeedWrapper(feed,
+ accountName);
+ modifier.createFeed(wrapper);
+
+ } catch (Exception e) {
+ LOG.error("Can't create feed -- " + e.getMessage(), e);
+ StorageException ex = new StorageException("Can't create feed -- "
+ + e.getMessage(), e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+
+ } finally {
+ if (query != null)
+ query.decrementRef();
+ }
+
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#deleteFeed(java.lang.String)
+ */
+ public void deleteFeed(String feedId) throws StorageException {
+ if (feedId == null)
+ throw new StorageException("can not delete feed id is null ");
+ ReferenceCounter query = null;
+ try {
+ query = this.controller.getStorageQuery();
+ if (!query.get().isFeedStored(feedId))
+ throw new StorageException("Account does not exist");
+ StorageModifier modifier = this.controller.getStorageModifier();
+
+ modifier.deleteFeed(feedId);
+
+ } catch (Exception e) {
+ LOG.error("Can't delete feed -- " + e.getMessage(), e);
+ StorageException ex = new StorageException("Can't create feed -- "
+ + e.getMessage(), e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+
+ } finally {
+ if (query == null)
+ query.decrementRef();
+ }
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#updateFeed(org.apache.lucene.gdata.data.ServerBaseFeed,
+ * java.lang.String)
+ */
+ public void updateFeed(ServerBaseFeed feed, String accountName)
+ throws StorageException {
+ if (feed == null)
+ throw new StorageException("can not update null feed");
+ if (accountName == null)
+ throw new StorageException("accountName must not be null");
+ ReferenceCounter query = null;
+ try {
+ query = this.controller.getStorageQuery();
+ if (!query.get().isFeedStored(feed.getId()))
+ throw new StorageException("Account does not exist");
+ StorageModifier modifier = this.controller.getStorageModifier();
+ StorageFeedWrapper wrapper = new StorageFeedWrapper(feed,
+ accountName);
+ modifier.updateFeed(wrapper);
+
+ } catch (Exception e) {
+ LOG.error("Can't create feed -- " + e.getMessage(), e);
+ StorageException ex = new StorageException("Can't create feed -- "
+ + e.getMessage(), e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+
+ } finally {
+ if (query == null)
+ query.decrementRef();
+ }
+
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#getServiceForFeed(java.lang.String)
+ */
+ public String getServiceForFeed(String feedId) throws StorageException {
+ if (feedId == null)
+ throw new StorageException("no feed for the feedID == null");
+ ReferenceCounter query = null;
+ try {
+ query = this.controller.getStorageQuery();
+ String type = query.get().getService(feedId);
+ if (type == null)
+ throw new StorageException("no feed for the feedID == "
+ + feedId + " found");
+ return type;
+ } catch (Exception e) {
+ throw new StorageException("Can not access storage", e);
+ } finally {
+ if (query != null)
+ query.decrementRef();
+ }
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#getAccount(java.lang.String)
+ */
+ public GDataAccount getAccount(String accountName) throws StorageException {
+ if (accountName == null)
+ throw new StorageException("account name must not be null");
+ ReferenceCounter query = null;
+ try {
+ query = this.controller.getStorageQuery();
+ return query.get().getUser(accountName);
+ } catch (Exception e) {
+ throw new StorageException("Can not access storage", e);
+ } finally {
+ if (query != null)
+ query.decrementRef();
+ }
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#getAccountNameForFeedId(java.lang.String)
+ */
+ public String getAccountNameForFeedId(String feedId)
+ throws StorageException {
+ if (feedId == null)
+ throw new StorageException("feedid must not be null");
+ ReferenceCounter query = null;
+ try {
+ query = this.controller.getStorageQuery();
+ String accountName = query.get().getAccountNameForFeedId(feedId);
+ if (accountName == null)
+ throw new StorageException("no feed for feedId " + feedId
+ + " found");
+ return accountName;
+ } catch (IOException e) {
+ throw new StorageException("Can not access storage - "
+ + e.getMessage(), e);
+ } finally {
+ if (query != null)
+ query.decrementRef();
+ }
+
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#getEntryLastModified(java.lang.String, java.lang.String)
+ */
+ public Long getEntryLastModified(String entryId,String feedId) throws StorageException {
+ ReferenceCounter query = null;
+ try {
+ query = this.controller.getStorageQuery();
+ return new Long(query.get().getEntryLastModified(entryId,feedId));
+ } catch (IOException e) {
+ throw new StorageException("Can not access storage - "
+ + e.getMessage(), e);
+ } finally {
+ if (query != null)
+ query.decrementRef();
+ }
+
+
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.storage.Storage#getFeedLastModified(java.lang.String)
+ */
+ public Long getFeedLastModified(String feedId) throws StorageException {
+ ReferenceCounter query = null;
+ try {
+ query = this.controller.getStorageQuery();
+ return new Long(query.get().getFeedLastModified(feedId));
+ } catch (IOException e) {
+ throw new StorageException("Can not access storage - "
+ + e.getMessage(), e);
+ } finally {
+ if (query != null)
+ query.decrementRef();
+ }
+
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageQuery.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageQuery.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageQuery.java (working copy)
@@ -12,331 +12,481 @@
* 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.io.StringReader;
-import java.util.ArrayList;
-import java.util.Iterator;
-import java.util.List;
-
-import org.apache.lucene.document.Document;
-import org.apache.lucene.gdata.server.FeedNotFoundException;
-import org.apache.lucene.gdata.server.GDataEntityBuilder;
-import org.apache.lucene.index.Term;
-import org.apache.lucene.search.BooleanClause;
-import org.apache.lucene.search.BooleanQuery;
-import org.apache.lucene.search.Hit;
-import org.apache.lucene.search.Hits;
-import org.apache.lucene.search.Searcher;
-import org.apache.lucene.search.Sort;
-import org.apache.lucene.search.SortField;
-import org.apache.lucene.search.TermQuery;
-import org.apache.lucene.search.BooleanClause.Occur;
-
-import com.google.gdata.data.BaseEntry;
-import com.google.gdata.data.ExtensionProfile;
-import com.google.gdata.util.ParseException;
-
-/**
- * StorageQuery wrapps a Lucene {@link org.apache.lucene.search.IndexSearcher}
- * and a {@link org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer} to
- * perform all request on the lucene storage.
- * The wrapped components are thread - safe.
- *
- * An instance of this class will serve all client requests. To obtain the
- * current instance of the {@link StorageQuery} the method
- * {@link org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController#getStorageQuery()}
- * has to be invoked. This method will release the current StorageQuery.
- *
- * @see org.apache.lucene.search.IndexSearcher
- * @see org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController
- * @see org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer
- *
- * @author Simon Willnauer
- *
- */
-public class StorageQuery {
- private final StorageBuffer buffer;
-
- private final Searcher searcher;
-
- /*
- * Sort the result by timestamp desc
- */
- private final Sort timeStampSort = new Sort(new SortField(StorageEntryWrapper.FIELD_TIMESTAMP,
- SortField.STRING, true));
-
- /**
- * Creates a new StorageQuery
- *
- * @param buffer -
- * the buffer instance to get the buffered inserts, updates from.
- * @param searcher -
- * the searcher instance to use to query the storage index.
- *
- *
- */
- protected StorageQuery(final StorageBuffer buffer, final Searcher searcher) {
-
- this.buffer = buffer;
- this.searcher = searcher;
-
- }
-
- private Hits storageQuery(List entryId) throws IOException {
- BooleanQuery query = new BooleanQuery();
- /*
- * query the index using a BooleanQuery
- */
- for (String id : entryId) {
- TermQuery termQuery = new TermQuery(new Term(
- StorageEntryWrapper.FIELD_ENTRY_ID, id));
- // use an OR query
- query.add(new BooleanClause(termQuery, Occur.SHOULD));
- }
-
- return this.searcher.search(query, new ModifiedEntryFilter(this.buffer
- .getExculdList()));
- }
-
- /*
- * query the storage index for a entire feed.
- */
- private Hits storageFeedQuery(final String feedId, final Sort sort)
- throws IOException {
- TermQuery query = new TermQuery(new Term(StorageEntryWrapper.FIELD_FEED_ID, feedId));
- return this.searcher.search(query, new ModifiedEntryFilter(this.buffer
- .getExculdList()), sort);
-
- }
-
- /*
- * get a single entry
- */
- private Hits storageQuery(String entryId) throws IOException {
- TermQuery termQuery = new TermQuery(new Term(
- StorageEntryWrapper.FIELD_ENTRY_ID, entryId));
- /*
- * Filter entries inside the buffer, buffered entries might contain
- * deleted entries. These entries must be found!!
- */
- return this.searcher.search(termQuery, new ModifiedEntryFilter(
- this.buffer.getExculdList()));
-
- }
-
- /**
- * This method fetches the latest feed entries from the storage. Feed
- * ususaly requested via a search query or as a simple query to the REST
- * interface.
- *
- * The REST interface requestes all the entries from a Storage. The Storage
- * retrieves the entries corresponding to the parameters specified. This
- * method first requests the latest entries or updated entries from the
- * {@link StorageBuffer}. If the buffer already contains enought entries
- * for the the specified result count the entires will be returned. If not,
- * the underlaying lucene index will be searcher for all documents of the
- * specified feed sorted by storing timestamp desc.
- *
- *
- * The entries will be searched in a feed context specified by the given
- * feed ID
- *
- *
- *
- * @param feedId -
- * the requested feed, this id will be used to retrieve the
- * entries.
- * @param resultCount -
- * how many entries are requested
- * @param startIndex -
- * the offset of the entriy to start from.
- * @param profil -
- * the extension profile used to create the entriy instances
- * @return - an ordered list of {@link BaseEntry} objects, or an empty list
- * if no entries could be found
- * @throws IOException -
- * if the index could not be queries or the entries could not be
- * build
- * @throws FeedNotFoundException -
- * if the requested feed is not registered
- * @throws ParseException -
- * if an entry could not be parsed while building it from the
- * Lucene Document.
- */
- // TODO check input parameter
- public List getLatestFeedQuery(final String feedId,
- final int resultCount, final int startIndex,
- final ExtensionProfile profil) throws IOException,
- FeedNotFoundException, ParseException {
- List returnList = new ArrayList(resultCount);
- List bufferedWrapperList = this.buffer
- .getSortedEntries(feedId);
- int alreadyAdded = 0;
- int offset = startIndex - 1;
- if (bufferedWrapperList != null
- && bufferedWrapperList.size() >= startIndex) {
-
- for (; alreadyAdded < resultCount; alreadyAdded++) {
- if ((bufferedWrapperList.size() - offset) > 0) {
- StorageEntryWrapper wrappedEntry = bufferedWrapperList
- .get(offset++);
- returnList.add(wrappedEntry.getEntry());
- } else
- break;
- }
- // reset offset
- offset = startIndex - 1;
- if (alreadyAdded == resultCount)
- return returnList;
- } else {
- /*
- * if the buffersize is less than the startindex the buffersize must
- * be considered. Sublists would not be a repeatable read part of
- * the whole list
- */
- if (bufferedWrapperList != null)
- offset = startIndex - 1 - bufferedWrapperList.size();
- }
-
- Hits hits = storageFeedQuery(feedId, this.timeStampSort);
- if (hits.length() > 0) {
-
- for (; (offset < hits.length()) && (alreadyAdded < resultCount); offset++, alreadyAdded++) {
- Document doc = hits.doc(offset);
- BaseEntry entry = buildEntryFromLuceneDocument(doc, profil);
- returnList.add(entry);
- }
-
- }
- return returnList;
- }
-
- /**
- * This method retrieves a single entry from the storage. If the
- * {@link StorageBuffer} does not contain the requested entry the
- * underlaying storage index will be searched.
- *
- * The Entry will be searched in a feed context specified by the given feed
- * ID
- *
- *
- * @param entryId -
- * the entry to fetch
- * @param feedId -
- * the feedid eg. feed context
- * @param profil -
- * the extension profile used to create the entriy instances
- * @return - the requested {@link BaseEntry} or null if the
- * entry can not be found
- * @throws IOException -
- * if the index could not be queries or the entries could not be
- * build
- * @throws FeedNotFoundException -
- * if the requested feed is not registered
- * @throws ParseException -
- * if an entry could not be parsed while building it from the
- * Lucene Document.
- */
- public BaseEntry singleEntryQuery(final String entryId,
- final String feedId, final ExtensionProfile profil)
- throws IOException, FeedNotFoundException, ParseException {
- StorageEntryWrapper wrapper = this.buffer.getEntry(entryId, feedId);
-
- if (wrapper == null) {
- Hits hits = storageQuery(entryId);
- if (hits.length() <= 0)
- return null;
- Document doc = hits.doc(0);
-
- return buildEntryFromLuceneDocument(doc, profil);
- }
- return wrapper.getEntry();
-
- }
-
- /**
- * Fetches the requested entries from the storage. The given list contains
- * entry ids to be looked up in the storage. First the {@link StorageBuffer}
- * will be queried for the entry ids. If not all of the entries remain in
- * the buffer the underlaying lucene index will be searched. The entries are
- * not guaranteed to be in the same order as they are in the given id list.
- * Entry ID's not found in the index or the buffer will be omitted.
- *
- * The entries will be searched in a feed context specified by the given
- * feed ID
- *
- *
- * @param entryIds -
- * the entriy ids to fetch.
- * @param feedId -
- * the feed id eg. feed context.
- * @param profil -
- * the extension profile used to create the entry instances.
- * @return - the list of entries corresponding to the given entry id list.
- * @throws IOException -
- * if the index could not be queries or the entries could not be
- * build
- * @throws FeedNotFoundException -
- * if the requested feed is not registered
- * @throws ParseException -
- * if an entry could not be parsed while building it from the
- * Lucene Document.
- */
- public List entryQuery(List entryIds,
- final String feedId, final ExtensionProfile profil)
- throws IOException, FeedNotFoundException, ParseException {
- List resultList = new ArrayList(entryIds.size());
- List searchList = new ArrayList(entryIds.size());
- for (String entry : entryIds) {
-
- StorageEntryWrapper bufferedEntry = this.buffer.getEntry(entry,
- feedId);
- if (bufferedEntry != null) {
- resultList.add(bufferedEntry.getEntry());
- } else
- searchList.add(entry);
- }
- if (searchList.isEmpty())
- return resultList;
-
- Hits hits = storageQuery(searchList);
- Iterator hitIterator = hits.iterator();
- while (hitIterator.hasNext()) {
- Hit hit = (Hit) hitIterator.next();
- Document doc = hit.getDocument();
- BaseEntry entry = buildEntryFromLuceneDocument(doc, profil);
- resultList.add(entry);
-
- }
-
- return resultList;
-
- }
-
- private BaseEntry buildEntryFromLuceneDocument(final Document doc,
- final ExtensionProfile profil) throws FeedNotFoundException,
- ParseException, IOException {
- StringReader reader = new StringReader(doc.getField(StorageEntryWrapper.FIELD_CONTENT)
- .stringValue());
- return GDataEntityBuilder.buildEntry(doc.getField(StorageEntryWrapper.FIELD_FEED_ID)
- .stringValue(), reader, profil);
-
- }
-
- /**
- * Closes all resources used in the {@link StorageQuery}. The instance can
- * not be reused after invoking this method.
- *
- * @throws IOException -
- * if the resouces can not be closed
- */
- public void close() throws IOException {
- this.searcher.close();
- this.buffer.close();
- }
-
-}
+ */
+
+package org.apache.lucene.gdata.storage.lucenestorage;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.lucene.document.Document;
+import org.apache.lucene.gdata.data.GDataAccount;
+import org.apache.lucene.gdata.server.GDataEntityBuilder;
+import org.apache.lucene.gdata.server.registry.ProvidedService;
+import org.apache.lucene.gdata.storage.StorageException;
+import org.apache.lucene.index.Term;
+import org.apache.lucene.search.BooleanClause;
+import org.apache.lucene.search.BooleanQuery;
+import org.apache.lucene.search.Hit;
+import org.apache.lucene.search.Hits;
+import org.apache.lucene.search.Searcher;
+import org.apache.lucene.search.Sort;
+import org.apache.lucene.search.SortField;
+import org.apache.lucene.search.TermQuery;
+import org.apache.lucene.search.BooleanClause.Occur;
+
+import com.google.gdata.data.BaseEntry;
+import com.google.gdata.data.BaseFeed;
+import com.google.gdata.data.DateTime;
+import com.google.gdata.util.ParseException;
+
+/**
+ * StorageQuery wrapps a Lucene {@link org.apache.lucene.search.IndexSearcher}
+ * and a {@link org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer} to
+ * perform all request on the lucene storage. The wrapped components are thread -
+ * safe.
+ *
+ * An instance of this class will serve all client requests. To obtain the
+ * current instance of the {@link StorageQuery} the method
+ * {@link org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController#getStorageQuery()}
+ * has to be invoked. This method will release the current StorageQuery.
+ *
+ *
+ * @see org.apache.lucene.search.IndexSearcher
+ * @see org.apache.lucene.gdata.storage.lucenestorage.StorageCoreController
+ * @see org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer
+ *
+ * @author Simon Willnauer
+ *
+ */
+public class StorageQuery {
+ private static final Log LOG = LogFactory.getLog(StorageQuery.class);
+ private final StorageBuffer buffer;
+
+ private final Searcher searcher;
+
+ /*
+ * Sort the result by timestamp desc
+ */
+ private final Sort timeStampSort = new Sort(new SortField(
+ StorageEntryWrapper.FIELD_TIMESTAMP, SortField.STRING, true));
+
+ /**
+ * Creates a new StorageQuery
+ *
+ * @param buffer -
+ * the buffer instance to get the buffered inserts, updates from.
+ * @param searcher -
+ * the searcher instance to use to query the storage index.
+ *
+ *
+ */
+ protected StorageQuery(final StorageBuffer buffer, final Searcher searcher) {
+
+ this.buffer = buffer;
+ this.searcher = searcher;
+
+ }
+
+ private Hits storageQuery(List entryId) throws IOException {
+ BooleanQuery query = new BooleanQuery();
+ /*
+ * query the index using a BooleanQuery
+ */
+ for (String id : entryId) {
+ TermQuery termQuery = new TermQuery(new Term(
+ StorageEntryWrapper.FIELD_ENTRY_ID, id));
+ // use an OR query
+ query.add(new BooleanClause(termQuery, Occur.SHOULD));
+ }
+
+ return this.searcher.search(query, new ModifiedEntryFilter(this.buffer
+ .getExculdList()));
+ }
+
+ /*
+ * query the storage index for a entire feed.
+ */
+ private Hits storageFeedQuery(final String feedId, final Sort sort)
+ throws IOException {
+ TermQuery query = new TermQuery(new Term(
+ StorageEntryWrapper.FIELD_FEED_REFERENCE, feedId));
+ return this.searcher.search(query, new ModifiedEntryFilter(this.buffer
+ .getExculdList()), sort);
+
+ }
+
+ /*
+ * get a single entry
+ */
+ private Hits storageQuery(String entryId) throws IOException {
+ TermQuery termQuery = new TermQuery(new Term(
+ StorageEntryWrapper.FIELD_ENTRY_ID, entryId));
+ /*
+ * Filter entries inside the buffer, buffered entries might contain
+ * deleted entries. These entries must be found!!
+ */
+ return this.searcher.search(termQuery, new ModifiedEntryFilter(
+ this.buffer.getExculdList()));
+
+ }
+
+ /**
+ * This method fetches the latest feed entries from the storage. Feed
+ * ususaly requested via a search query or as a simple query to the REST
+ * interface.
+ *
+ * The REST interface requestes all the entries from a Storage. The Storage
+ * retrieves the entries corresponding to the parameters specified. This
+ * method first requests the latest entries or updated entries from the
+ * {@link StorageBuffer}. If the buffer already contains enought entries
+ * for the the specified result count the entires will be returned. If not,
+ * the underlaying lucene index will be searcher for all documents of the
+ * specified feed sorted by storing timestamp desc.
+ *
+ *
+ * The entries will be searched in a feed context specified by the given
+ * feed ID
+ *
+ *
+ *
+ * @param feedId -
+ * the requested feed, this id will be used to retrieve the
+ * entries.
+ * @param resultCount -
+ * how many entries are requested
+ * @param startIndex -
+ * the offset of the entriy to start from.
+ * @param config -
+ * the FeedInstanceConfiguration contaning extension profile used
+ * to create the entriy instances
+ * @return - an ordered list of {@link BaseEntry} objects, or an empty list
+ * if no entries could be found
+ * @throws IOException -
+ * if the index could not be queries or the entries could not be
+ * build
+ * @throws ParseException -
+ * if an entry could not be parsed while building it from the
+ * Lucene Document.
+ */
+ // TODO check input parameter
+ @SuppressWarnings("unchecked")
+ public BaseFeed getLatestFeedQuery(final String feedId,
+ final int resultCount, final int startIndex,
+ final ProvidedService config) throws IOException,
+ ParseException {
+ DateTime updated = null;
+ Hits feedHits = storageFeedQuery(feedId);
+ if(feedHits.length() == 0)
+ return null;
+ BaseFeed retVal = buildFeedFromLuceneDocument(feedHits.doc(0),config);
+
+ List returnList = new ArrayList(resultCount);
+ List bufferedWrapperList = this.buffer
+ .getSortedEntries(feedId);
+ int alreadyAdded = 0;
+ int offset = startIndex - 1;
+
+ if (bufferedWrapperList != null
+ && bufferedWrapperList.size() >= startIndex) {
+ updated = bufferedWrapperList.get(0).getEntry().getUpdated();
+ for (; alreadyAdded < resultCount; alreadyAdded++) {
+ if ((bufferedWrapperList.size() - offset) > 0) {
+ StorageEntryWrapper wrappedEntry = bufferedWrapperList
+ .get(offset++);
+ returnList
+ .add(wrappedEntry.getEntry());
+ } else
+ break;
+ }
+ // reset offset
+ offset = startIndex - 1;
+ if (alreadyAdded == resultCount){
+ retVal.getEntries().addAll(returnList);
+ retVal.setUpdated(updated);
+ return retVal;
+ }
+ } else {
+ /*
+ * if the buffersize is less than the startindex the buffersize must
+ * be considered. Sublists would not be a repeatable read part of
+ * the whole list
+ */
+ if (bufferedWrapperList != null)
+ offset = startIndex - 1 - bufferedWrapperList.size();
+ }
+
+ Hits hits = storageFeedQuery(feedId, this.timeStampSort);
+ if (hits.length() > 0) {
+
+ for (; (offset < hits.length()) && (alreadyAdded < resultCount); offset++, alreadyAdded++) {
+ Document doc = hits.doc(offset);
+ BaseEntry entry = buildEntryFromLuceneDocument(doc, config);
+ returnList.add(entry);
+ }
+ if(updated == null){
+ try{
+ long updatedTimeStamp = Long.parseLong(hits.doc(0).get(StorageEntryWrapper.FIELD_TIMESTAMP));
+ updated = new DateTime(updatedTimeStamp);
+ }catch (Exception e) {
+ LOG.warn("could not create DateTime -- "+e.getMessage(),e);
+ updated = buildEntryFromLuceneDocument(hits.doc(0),config).getUpdated();
+ }
+ }
+ }
+ retVal.setUpdated(updated);
+ retVal.getEntries().addAll(returnList);
+ return retVal;
+ }
+
+ /**
+ * This method retrieves a single entry from the storage. If the
+ * {@link StorageBuffer} does not contain the requested entry the
+ * underlaying storage index will be searched.
+ *
+ * The Entry will be searched in a feed context specified by the given feed
+ * ID
+ *
+ *
+ * @param entryId -
+ * the entry to fetch
+ * @param feedId -
+ * the feedid eg. feed context
+ * @param config -
+ * the FeedInstanceConfiguration contaning extension profile used
+ * to create the entriy instances
+ * @return - the requested {@link BaseEntry} or null if the
+ * entry can not be found
+ * @throws IOException -
+ * if the index could not be queries or the entries could not be
+ * build
+ * @throws ParseException -
+ * if an entry could not be parsed while building it from the
+ * Lucene Document.
+ */
+ public BaseEntry singleEntryQuery(final String entryId,
+ final String feedId, final ProvidedService config)
+ throws IOException, ParseException {
+ StorageEntryWrapper wrapper = this.buffer.getEntry(entryId, feedId);
+
+ if (wrapper == null) {
+ Hits hits = storageQuery(entryId);
+ if (hits.length() <= 0)
+ return null;
+ Document doc = hits.doc(0);
+
+ return buildEntryFromLuceneDocument(doc, config);
+ }
+ /*
+ * ServerBaseEntry enables the dynamic element of the entry like the
+ * links to be dynamic. BufferedEntries will be reused until they are
+ * written.
+ */
+ return wrapper.getEntry();
+
+ }
+
+ /**
+ * Fetches the requested entries from the storage. The given list contains
+ * entry ids to be looked up in the storage. First the {@link StorageBuffer}
+ * will be queried for the entry ids. If not all of the entries remain in
+ * the buffer the underlaying lucene index will be searched. The entries are
+ * not guaranteed to be in the same order as they are in the given id list.
+ * Entry ID's not found in the index or the buffer will be omitted.
+ *
+ * The entries will be searched in a feed context specified by the given
+ * feed ID
+ *
+ *
+ * @param entryIds -
+ * the entriy ids to fetch.
+ * @param feedId -
+ * the feed id eg. feed context.
+ * @param config -
+ * the FeedInstanceConfiguration contaning extension profile used
+ * to create the entriy instances
+ *
+ * @return - the list of entries corresponding to the given entry id list.
+ * @throws IOException -
+ * if the index could not be queries or the entries could not be
+ * build
+ * @throws ParseException -
+ * if an entry could not be parsed while building it from the
+ * Lucene Document.
+ */
+ public List entryQuery(List entryIds,
+ final String feedId, final ProvidedService config)
+ throws IOException, ParseException {
+ List resultList = new ArrayList(entryIds.size());
+ List searchList = new ArrayList(entryIds.size());
+ for (String entry : entryIds) {
+
+ StorageEntryWrapper bufferedEntry = this.buffer.getEntry(entry,
+ feedId);
+ if (bufferedEntry != null) {
+ resultList.add(bufferedEntry.getEntry());
+ } else
+ searchList.add(entry);
+ }
+ if (searchList.isEmpty())
+ return resultList;
+
+ Hits hits = storageQuery(searchList);
+ Iterator hitIterator = hits.iterator();
+ while (hitIterator.hasNext()) {
+ Hit hit = (Hit) hitIterator.next();
+ Document doc = hit.getDocument();
+ BaseEntry entry = buildEntryFromLuceneDocument(doc, config);
+ resultList.add(entry);
+
+ }
+
+ return resultList;
+
+ }
+
+ private BaseEntry buildEntryFromLuceneDocument(final Document doc,
+ final ProvidedService config) throws ParseException,
+ IOException {
+ StringReader reader = new StringReader(doc.getField(
+ StorageEntryWrapper.FIELD_CONTENT).stringValue());
+ return GDataEntityBuilder.buildEntry( reader, config);
+
+ }
+
+ private BaseFeed buildFeedFromLuceneDocument(final Document doc,
+ final ProvidedService config) throws ParseException,
+ IOException {
+ StringReader reader = new StringReader(doc.getField(
+ StorageFeedWrapper.FIELD_CONTENT).stringValue());
+ return GDataEntityBuilder
+ .buildFeed(reader, config);
+
+ }
+
+ /**
+ * Queries the storage for an user instance
+ *
+ * @param username -
+ * the username (primary key)
+ * @return - the user instance if found or null if not exists
+ * @throws IOException -
+ * if the storage can not be accessed.
+ */
+ public GDataAccount getUser(final String username) throws IOException {
+ if (username == null)
+ return null;
+ TermQuery query = new TermQuery(new Term(
+ StorageAccountWrapper.FIELD_ACCOUNTNAME, username));
+ Hits h = this.searcher.search(query);
+ if (h.length() == 0)
+ return null;
+ return StorageAccountWrapper.buildEntity(h.doc(0));
+ }
+
+ /**
+ * Closes all resources used in the {@link StorageQuery}. The instance can
+ * not be reused after invoking this method.
+ *
+ * @throws IOException -
+ * if the resouces can not be closed
+ */
+ public void close() throws IOException {
+ this.searcher.close();
+ this.buffer.close();
+ }
+
+ /**
+ * Checks whether a feed for the given feedID is stored
+ * @param feedId - the feed ID
+ * @return true if and only if a feed is stored for the provided feed ID, false if no feed for the given id is stored
+ * @throws IOException
+ */
+ public boolean isFeedStored(String feedId)throws IOException{
+ Hits h = storageFeedQuery(feedId);
+ return (h.length() > 0);
+
+ }
+
+ /**
+ * Looks up the feedtype for the given feed ID
+ * @param feedID - the feed ID
+ * @return - the feed type
+ * @throws IOException - if the storage can not be accessed
+ */
+ public String getService(String feedID) throws IOException {
+ Hits hits = storageFeedQuery(feedID);
+ if (hits.length() <= 0)
+ return null;
+ Document doc = hits.doc(0);
+ String feedType = doc.get(StorageFeedWrapper.FIELD_SERVICE_ID);
+ return feedType;
+ }
+ private Hits storageFeedQuery(String feedId) throws IOException {
+ TermQuery query = new TermQuery(new Term(
+ StorageFeedWrapper.FIELD_FEED_ID, feedId));
+ return this.searcher.search(query);
+ }
+
+ /**
+ * Looks up the account reference for the given feed id
+ * @param feedId - id of the feed
+ * @return - the name of the account associated with the feed for the given feed id, or null if the feed is not stored
+ * @throws IOException - if the storage can not be accessed
+ */
+ public String getAccountNameForFeedId(String feedId) throws IOException {
+ Hits h = storageFeedQuery(feedId);
+ if(h.length() == 0)
+ return null;
+ Document doc = h.doc(0);
+ return doc.get(StorageFeedWrapper.FIELD_ACCOUNTREFERENCE);
+
+ }
+ protected long getEntryLastModified(final String entryId,final String feedId) throws IOException, StorageException{
+ StorageEntryWrapper wrapper = this.buffer.getEntry(entryId,feedId);
+ if(wrapper != null)
+ return wrapper.getTimestamp();
+
+ Hits h = storageQuery(entryId);
+ if(h.length() > 0)
+ try{
+ return Long.parseLong(h.doc(0).get(StorageEntryWrapper.FIELD_TIMESTAMP));
+ }catch (Exception e) {
+ LOG.warn("Can not parse timestamp from entry -- "+h.doc(0).get(StorageEntryWrapper.FIELD_TIMESTAMP));
+ }
+ else
+ throw new StorageException("Entry not found");
+ return 0;
+
+ }
+
+ protected long getFeedLastModified(final String feedId)throws IOException{
+ Long bufferedTime = this.buffer.getFeedLastModified(feedId);
+ if(bufferedTime != null)
+ return bufferedTime;
+ Hits entryHits = storageFeedQuery(feedId,this.timeStampSort);
+ if(entryHits.length() > 0){
+ try{
+ return Long.parseLong(entryHits.doc(0).getField(StorageEntryWrapper.FIELD_TIMESTAMP).stringValue());
+ }catch (Exception e) {
+ LOG.warn("Can not parse timestamp from entry -- "+entryHits.doc(0).get(StorageEntryWrapper.FIELD_TIMESTAMP));
+ }
+ }
+ return 0;
+
+ }
+ protected boolean isEntryStored(String entryId,String feedId) throws IOException{
+ if(this.buffer.getEntry(entryId,feedId)!=null)
+ return true;
+
+ Hits h = storageQuery(entryId);
+ if(h.length() > 0)
+ return true;
+ return false;
+ }
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageBuffer.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageBuffer.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageBuffer.java (working copy)
@@ -16,20 +16,27 @@
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 java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+import java.util.Map.Entry;
+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;
+
+import com.google.gdata.data.BaseEntry;
+import com.google.gdata.data.ExtensionProfile;
+import com.google.gdata.data.Link;
-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
@@ -55,7 +62,9 @@
public class StorageBuffer {
private static final Log LOG = LogFactory.getLog(StorageBuffer.class);
- private final Map> bufferMap;
+ private final Map> bufferMap;
+
+ private final Map modifiyMap;
private final List excludeList;
@@ -86,6 +95,9 @@
this.excludeList = new ArrayList(
expectedBufferCount < DEFAULT_BUFFER_COUNT ? DEFAULT_BUFFER_COUNT
: expectedBufferCount);
+ this.modifiyMap = new HashMap(
+ expectedBufferCount < DEFAULT_BUFFER_COUNT ? DEFAULT_BUFFER_COUNT
+ : expectedBufferCount);
}
/**
@@ -114,7 +126,9 @@
20);
newFeedMap.put(wrapper.getEntryId(), wrapper);
this.bufferMap.put(feedId, newFeedMap);
+
}
+ addLastModified(wrapper.getFeedId(),wrapper.getTimestamp());
} finally {
/*
* add all to exclude from searches doc will be available via the
@@ -124,6 +138,22 @@
this.writeLock.unlock();
}
}
+
+ private void addLastModified(final String feedId,Long timestamp){
+ if(this.modifiyMap.containsKey(feedId))
+ this.modifiyMap.remove(feedId);
+ this.modifiyMap.put(feedId,timestamp);
+
+ }
+
+ protected Long getFeedLastModified(final String feedId){
+ return this.modifiyMap.get(feedId);
+ }
+ protected Set> getLastModified(){
+ return this.modifiyMap.entrySet();
+ }
+
+
/**
* Returns all entries for the given feed id sorted by the update timestamp
@@ -173,6 +203,7 @@
if (tempMap == null)
return;
tempMap.remove(entryId);
+ this.addLastModified(feedId,new Long(System.currentTimeMillis()));
} finally {
this.writeLock.unlock();
@@ -230,6 +261,7 @@
private void clearBuffer() {
this.bufferMap.clear();
this.excludeList.clear();
+ this.modifiyMap.clear();
}
@@ -245,5 +277,36 @@
}
}
+
+
+ static class BufferableEntry extends BaseEntry{
+
+ /**
+ *
+ */
+ @SuppressWarnings("unchecked")
+ public BufferableEntry() {
+ super();
+ this.links = new LinkedList();
+ }
+
+ /**
+ * @param arg0
+ */
+ @SuppressWarnings("unchecked")
+ public BufferableEntry(BaseEntry arg0) {
+ super(arg0);
+ this.links = new LinkedList();
+ }
+
+ /**
+ * @see com.google.gdata.data.BaseEntry#declareExtensions(com.google.gdata.data.ExtensionProfile)
+ */
+ @Override
+ public void declareExtensions(ExtensionProfile arg0) {
+ //
+ }
+
+ }
}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/IDGenerator.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/IDGenerator.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/IDGenerator.java (working copy)
@@ -51,7 +51,9 @@
private static final int DEFAULT_CAPACITY = 10;
- protected static final Log LOGGER = LogFactory.getLog(IDGenerator.class);
+ protected static final Log LOGGER = LogFactory.getLog(IDGenerator.class);
+
+ private static final String RUNNER_THREAD_NAME = "GDATA-ID Generator";
/**
* Constructs a new ID generator. with a fixed capacity of prebuild ids. The
@@ -91,7 +93,9 @@
if (this.runner == null) {
UIDProducer producer = new UIDProducer(this.blockingQueue,
this.secureRandom, this.mdigest);
- this.runner = new Thread(producer);
+ this.runner = new Thread(producer);
+ this.runner.setDaemon(true);
+ this.runner.setName(RUNNER_THREAD_NAME);
this.runner.start();
}
}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/ResourceNotFoundException.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/ResourceNotFoundException.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/ResourceNotFoundException.java (revision 0)
@@ -0,0 +1,66 @@
+/**
+ * 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;
+
+/**
+ * This exception will be thrown if an requested resource of a resource to modify can not be found
+ * @author Simon Willnauer
+ *
+ */
+public class ResourceNotFoundException extends StorageException {
+
+
+ private static final long serialVersionUID = -8549987918130998249L;
+
+ /**
+ * Constructs an empty ResourceNotFoundException
+ */
+ public ResourceNotFoundException() {
+ super();
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * Constructs a new ResourceNotFoundException with an exception message
+ * @param message - the exception message
+ */
+ public ResourceNotFoundException(String message) {
+ super(message);
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * Constructs a new ResourceNotFoundException with an exception message and a root cause
+ * @param message - the exception message
+ * @param cause - the root cause of this exception
+ */
+ public ResourceNotFoundException(String message, Throwable cause) {
+ super(message, cause);
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * Constructs a new ResourceNotFoundException with a root cause
+ * @param cause - the root cause of this exception
+ *
+ */
+ public ResourceNotFoundException(Throwable cause) {
+ super(cause);
+ // TODO Auto-generated constructor stub
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/Storage.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/Storage.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/Storage.java (working copy)
@@ -12,89 +12,263 @@
* 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 getEntries(List entryIdList,
- String feedId) throws StorageException;
-
- /**
- * @param profile
- */
- public abstract void setExtensionProfile(final ExtensionProfile profile);
-
- /**
- * close this storage instance
- */
- public abstract void close();
-
-}
+ */
+package org.apache.lucene.gdata.storage;
+
+import org.apache.lucene.gdata.data.GDataAccount;
+import org.apache.lucene.gdata.data.ServerBaseEntry;
+import org.apache.lucene.gdata.data.ServerBaseFeed;
+
+import com.google.gdata.data.BaseEntry;
+import com.google.gdata.data.BaseFeed;
+
+/**
+ * A interface every storage implementation must provide to access the
+ * Storage. It describes all access methodes needed to store,
+ * retrieve and look up data stored in the Storage component. This
+ * interface acts as a Facade to hide the storage implementation from
+ * the user.
+ *
+ * This could also act as a proxy for a remote storage. It also removes any
+ * restrictions from custom storage implementations.
+ *
+ *
+ *
+ * @author Simon Willnauer
+ *
+ */
+/*
+ * not final yet
+ */
+public interface Storage {
+
+ /**
+ *
+ * Stores the given entry. The ServerBaseEntry must provide a feed id and
+ * the service type. configuration for the entry.
+ *
+ * @param entry -
+ * the entry to store
+ *
+ * @return - the stored Entry for the server response
+ * @throws StorageException -
+ * if the entry can not be stored or required field are not set.
+ */
+ public abstract BaseEntry storeEntry(ServerBaseEntry entry)
+ throws StorageException;
+
+ /**
+ * Deletes the given entry. The ServerBaseEntry just hase to provide the
+ * entry id to be deleted.
+ *
+ * @param entry -
+ * the entry to delete from the storage
+ * @throws StorageException -
+ * if the entry can not be deleted or the entry does not exist
+ * or required field are not set.
+ */
+ public abstract void deleteEntry(ServerBaseEntry entry)
+ throws StorageException;
+
+ /**
+ * Updates the given entry. The ServerBaseEntry must provide a feed id,
+ * service id and the
+ * {@link org.apache.lucene.gdata.server.registry.ProvidedService}
+ *
+ * @param entry -
+ * the entry to update
+ *
+ * @return - the updated entry for server response.
+ * @throws StorageException -
+ * if the entry can not be updated or does not exist or required
+ * field are not set.
+ */
+ public abstract BaseEntry updateEntry(ServerBaseEntry entry)
+ throws StorageException;
+
+ /**
+ * Retrieves the requested feed from the storage. The given ServerBaseFeed
+ * must provide information about the feed id, max-result count and the
+ * start index. To create feeds and entries also the service type must be
+ * provided.
+ *
+ * @param feed -
+ * the to retieve from the storage
+ * @return the requested feed
+ * @throws StorageException -
+ * the feed does not exist or can not be retrieved or required
+ * field are not set.
+ */
+ public abstract BaseFeed getFeed(ServerBaseFeed feed)
+ throws StorageException;
+
+ /**
+ * Retrieves the requested entry from the storage. The given entry must
+ * provide information about the entry id and service type.
+ *
+ * @param entry -
+ * the entry to retrieve
+ * @return - the requested entry
+ * @throws StorageException -
+ * if the entry does not exist or can not be created or required
+ * field are not set.
+ */
+ public abstract BaseEntry getEntry(ServerBaseEntry entry)
+ throws StorageException;
+
+ /**
+ * Saves a new account. Required attributes to set are password
+ * and accountname
+ *
+ * @param account -
+ * the account to save
+ * @throws StorageException -
+ * if the account can not be stored or the account already
+ * exists or required field are not set.
+ */
+ public abstract void storeAccount(final GDataAccount account)
+ throws StorageException;
+
+ /**
+ * Updates an existing account. Required attributes to set are
+ * password and accountname
+ *
+ * @param account -
+ * the account to update
+ * @throws StorageException -
+ * if the account does not exist or required field are not set.
+ */
+ public abstract void updateAccount(final GDataAccount account)
+ throws StorageException;
+
+ /**
+ * Deletes the account for the given account name. All feeds and entries
+ * referencing this account will be deleted as well!
+ *
+ * @param accountname -
+ * the name of the account to delete
+ * @throws StorageException -
+ * if the account does not exist
+ */
+ public abstract void deleteAccount(final String accountname)
+ throws StorageException;
+
+ /**
+ * Stores a new feed for a existing account. The Feed must provide
+ * information about the service type to store the feed for and the feed id
+ * used for accessing and retrieving the feed from the storage. Each feed is
+ * associated with a provided service. This method does check wheather a
+ * feed with the same feed id as the given feed does already exists.
+ *
+ * @see org.apache.lucene.gdata.server.registry.ProvidedService
+ * @param feed -
+ * the feed to create
+ * @param accountname -
+ * the account name belongs to the feed
+ * @throws StorageException -
+ * if the feed already exists or the feed can not be stored
+ */
+ public abstract void storeFeed(final ServerBaseFeed feed, String accountname)
+ throws StorageException;
+
+ /**
+ * Deletes the feed for the given feed id. All Entries referencing the given
+ * feed id will be deleted as well.
+ *
+ * @param feedId -
+ * the feed id for the feed to delete.
+ * @throws StorageException -
+ * if the feed for the feed id does not exist or the feed can
+ * not be deleted
+ */
+ public abstract void deleteFeed(final String feedId)
+ throws StorageException;
+
+ /**
+ * Updates a stored feed. The Feed must provide information about the
+ * service type to store the feed for and the feed id used for accessing and
+ * retrieving the feed from the storage.
+ *
+ * @param feed -
+ * the feed to update
+ * @param accountname -
+ * the account name belongs to the feed
+ * @throws StorageException -
+ * if the feed does not exist or the feed can not be updated
+ */
+ public abstract void updateFeed(final ServerBaseFeed feed,
+ String accountname) throws StorageException;
+
+ /**
+ * Retrieves the service name for a stored feed
+ *
+ * @param feedId -
+ * the feed id
+ * @return - the name of the service
+ * @throws StorageException -
+ * if no feed for the provided id is stored
+ */
+ public abstract String getServiceForFeed(String feedId)
+ throws StorageException;
+
+ /**
+ * @param accountName -
+ * the name of the requested account
+ * @return - a {@link GDataAccount} instance for the requested account name
+ * @throws StorageException -
+ * if no account for the account name is stored
+ *
+ */
+ public abstract GDataAccount getAccount(String accountName)
+ throws StorageException;
+
+ /**
+ * close this storage instance. This method will be called by clients after
+ * use.
+ */
+ public abstract void close();
+
+ /**
+ * Each feed belongs to one specific account. This method retrieves the
+ * account name for
+ *
+ * @param feedId -
+ * the id of the feed to retrieve the accountname
+ * @return - the name / id of the account associated with the feed for the
+ * given feed id
+ * @throws StorageException -
+ * if the feed is not stored or the storage can not be accessed
+ */
+ public String getAccountNameForFeedId(String feedId)
+ throws StorageException;
+
+ /**
+ * Retrieves the date of the last modification for the given id
+ *
+ * @param entryId -
+ * the entry Id
+ * @param feedId -
+ * the feed which contains the entry
+ * @return - The date of the last modifiaction in milliseconds or
+ * new Long(0) if the resource can not be found eg.
+ * the time can not be accessed
+ * @throws StorageException -
+ * if the storage can not be accessed
+ */
+ public Long getEntryLastModified(String entryId, String feedId)
+ throws StorageException;
+
+ /**
+ * Retrieves the date of the last modification for the given id
+ *
+ * @param feedId -
+ * the feed Id
+ * @return - The date of the last modifiaction in milliseconds or
+ * new Long(0) if the resource can not be found eg.
+ * the time can not be accessed
+ * @throws StorageException -
+ * if the storage can not be accessed
+ */
+ public Long getFeedLastModified(String feedId) throws StorageException;
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/StorageController.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/StorageController.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/StorageController.java (working copy)
@@ -1,27 +1,61 @@
-/**
- * Copyright 2004 The Apache Software Foundation
+/**
+ * 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 org.apache.lucene.gdata.server.registry.ServerComponent;
+
+/**
+ * An interface to define a central storage controller acting as a
+ * Stroage Factory. The StroageController manages the
+ * storage logic. Subclasses of {@link StorageController} can be registered as
+ * {@link org.apache.lucene.gdata.server.registry.Component} in the
+ * {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry}. A
+ * single instance of the contorller will be loaded and passed to clients via
+ * the lookup service.
+ *
+ * This instances, registered in the registry must be thread save as they are
+ * shared between several clients
+ *
+ *
+ * Each StroageController implementation must provide a super user
+ * {@link org.apache.lucene.gdata.data.GDataAccount} with all
+ * {@link org.apache.lucene.gdata.data.GDataAccount.AccountRole} set. This
+ * account must have the defined name administrator and a default
+ * password password. The password has to be updated by the server
+ * administrator before production use.
+ * To get the predefinded GDataAccount use {@link org.apache.lucene.gdata.data.GDataAccount#createAdminAccount()}
+ *
+ *
*
- * 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
+ * @author Simon Willnauer
*
- * 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();
-}
+ */
+public interface StorageController extends ServerComponent {
+ /**
+ * Destroys the controller - this method is called by the registry when the
+ * context will be destroyed
+ */
+ public abstract void destroy();
+
+ /**
+ * Creates Storage instances to access the underlaying storage component
+ *
+ * @return a storage instance
+ * @throws StorageException -
+ * if the storage instance can not be created
+ */
+ public abstract Storage getStorage() throws StorageException;
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/StorageFactory.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/StorageFactory.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/StorageFactory.java (working copy)
@@ -1,44 +0,0 @@
-/**
- * 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;
-
- }
- }
-}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/GDataResponse.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/GDataResponse.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/GDataResponse.java (working copy)
@@ -12,231 +12,279 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
-
-package org.apache.lucene.gdata.server;
-
-import java.io.IOException;
-import java.io.Writer;
-
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.lucene.gdata.server.GDataRequest.OutputFormat;
-
-import com.google.gdata.data.BaseEntry;
-import com.google.gdata.data.BaseFeed;
-import com.google.gdata.data.ExtensionProfile;
-import com.google.gdata.util.common.xml.XmlWriter;
-import com.google.gdata.util.common.xml.XmlWriter.Namespace;
-
-/**
- * The FeedRequest Class wraps the curren HttpServletResponse. Any action on the
- * HttpServletRequest will be executed via this class. This represents an
- * abstraction on the plain {@link HttpServletResponse}. Any action which has
- * to be performed on the underlaying {@link HttpServletResponse} will be
- * executed within this class.
- *
- * The GData basicly writes two different kinds ouf reponse to the output
- * stream.
- *
- *
update, delete or insert requests will respond with a statuscode and if
- * successful the feed entry modified or created
- *
get requests will respond with a statuscode and if successful the
- * requested feed
- *
- *
- * For this purpose the {@link GDataResponse} class provides the overloaded
- * method
- * {@link org.apache.lucene.gdata.server.GDataResponse#sendResponse(BaseEntry, ExtensionProfile)}
- * which sends the entry e.g feed to the output stream.
- *
- *
- *
- *
- *
- * @author Simon Willnauer
- *
- */
-public class GDataResponse {
- private int error;
-
- private boolean isError = false;
-
- private String encoding;
-
- private OutputFormat outputFormat;
-
- private final HttpServletResponse response;
-
- private static final String DEFAUL_NAMESPACE_URI = "http://www.w3.org/2005/Atom";
-
- private static final Namespace DEFAULT_NAMESPACE = new Namespace("",
- DEFAUL_NAMESPACE_URI);
-
- /**
- * Creates a new GDataResponse
- *
- * @param response -
- * The underlaying {@link HttpServletResponse}
- */
- public GDataResponse(HttpServletResponse response) {
- if (response == null)
- throw new IllegalArgumentException("response must not be null");
- this.response = response;
- this.response.setContentType("text/xml");
- }
-
- /**
- * Sets an error code to this FeedResponse.
- *
- * @param errorCode -
- * {@link HttpServletResponse} error code
- */
- public void setError(int errorCode) {
- this.isError = true;
- this.error = errorCode;
- }
- /**
- * Sets the status of the underlaying response
- * @see HttpServletResponse
- * @param responseCode - the status of the response
- */
- public void setResponseCode(int responseCode){
- this.response.setStatus(responseCode);
- }
- /**
- * This method sends the specified error to the user if set
- *
- * @throws IOException -
- * if an I/O Exception occures
- */
- public void sendError() throws IOException {
- if (this.isError)
- this.response.sendError(this.error);
- }
-
- /**
- * @return - the {@link HttpServletResponse} writer
- * @throws IOException -
- * If an I/O exception occures
- */
- public Writer getWriter() throws IOException {
- return this.response.getWriter();
- }
-
- /**
- * Sends a response for a get e.g. query request. This method must not
- * invoked in a case of an error performing the requeste action.
- *
- * @param feed -
- * the feed to respond to the client
- * @param profile -
- * the extension profil for the feed to write
- * @throws IOException -
- * if an I/O exception accures, often caused by an already
- * closed Writer or OutputStream
- *
- */
- public void sendResponse(BaseFeed feed, ExtensionProfile profile)
- throws IOException {
- if (feed == null)
- throw new IllegalArgumentException("feed must not be null");
- if(profile == null)
- throw new IllegalArgumentException("extension profil must not be null");
- XmlWriter writer = createWriter();
-
- if (this.outputFormat.equals(OutputFormat.ATOM))
- feed.generateAtom(writer, profile);
- else
- feed.generateRss(writer, profile);
-
- }
-
- /**
- *
- * Sends a response for an update, insert or delete request. This method
- * must not invoked in a case of an error performing the requeste action.
- * If the specified response format is ATOM the default namespace will be set to ATOM.
- * @param entry -
- * the modified / created entry to send
- * @param profile -
- * the entries extension profile
- * @throws IOException -
- * if an I/O exception accures, often caused by an already
- * closed Writer or OutputStream
- */
- public void sendResponse(BaseEntry entry, ExtensionProfile profile)
- throws IOException {
- if (entry == null)
- throw new IllegalArgumentException("entry must not be null");
- if(profile == null)
- throw new IllegalArgumentException("extension profil must not be null");
- XmlWriter writer = createWriter();
- if (this.outputFormat.equals(OutputFormat.ATOM))
- entry.generateAtom(writer, profile);
- else
- entry.generateRss(writer, profile);
- }
-
- private XmlWriter createWriter() throws IOException {
- XmlWriter writer = new XmlWriter(getWriter(), this.encoding);
- // set the default namespace to Atom if Atom is the response format
- if(this.outputFormat.equals(OutputFormat.ATOM))
- writer.setDefaultNamespace(DEFAULT_NAMESPACE);
- return writer;
- }
-
- /**
- * This encoding will be used to encode the xml representation of feed or
- * entry written to the {@link HttpServletResponse} output stream.
- *
- * @return - the entry / feed encoding
- */
- public String getEncoding() {
- return this.encoding;
- }
-
- /**
- * This encoding will be used to encode the xml representation of feed or
- * entry written to the {@link HttpServletResponse} output stream. UTF-8
- * ISO-8859-1
- *
- * @param encoding -
- * string represents the encoding
- */
- public void setEncoding(String encoding) {
- this.encoding = encoding;
- }
-
- /**
- * @return - the response
- * {@link org.apache.lucene.gdata.server.GDataRequest.OutputFormat}
- */
- public OutputFormat getOutputFormat() {
- return this.outputFormat;
- }
-
- /**
- * @param outputFormat -
- * the response
- * {@link org.apache.lucene.gdata.server.GDataRequest.OutputFormat}
- */
- public void setOutputFormat(OutputFormat outputFormat) {
- this.outputFormat = outputFormat;
- }
- /**
- * @see Object#toString()
- */
- @Override
- public String toString(){
- StringBuilder builder = new StringBuilder(" GDataResponse: ");
- builder.append("Error: ").append(this.error);
- builder.append(" outputFormat: ").append(getOutputFormat());
- builder.append(" encoding: ").append(this.encoding);
-
- return builder.toString();
-
-
- }
-
-}
+ */
+
+package org.apache.lucene.gdata.server;
+
+import java.io.IOException;
+import java.io.Writer;
+import java.util.Date;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.lucene.gdata.server.GDataRequest.OutputFormat;
+import org.apache.lucene.gdata.utils.DateFormater;
+
+import com.google.gdata.data.BaseEntry;
+import com.google.gdata.data.BaseFeed;
+import com.google.gdata.data.DateTime;
+import com.google.gdata.data.ExtensionProfile;
+import com.google.gdata.util.common.xml.XmlWriter;
+import com.google.gdata.util.common.xml.XmlWriter.Namespace;
+
+/**
+ * The FeedRequest Class wraps the curren HttpServletResponse. Any action on the
+ * HttpServletRequest will be executed via this class. This represents an
+ * abstraction on the plain {@link HttpServletResponse}. Any action which has
+ * to be performed on the underlaying {@link HttpServletResponse} will be
+ * executed within this class.
+ *
+ * The GData basicly writes two different kinds ouf reponse to the output
+ * stream.
+ *
+ *
update, delete or insert requests will respond with a statuscode and if
+ * successful the feed entry modified or created
+ *
get requests will respond with a statuscode and if successful the
+ * requested feed
+ *
+ *
+ * For this purpose the {@link GDataResponse} class provides the overloaded
+ * method
+ * {@link org.apache.lucene.gdata.server.GDataResponse#sendResponse(BaseEntry, ExtensionProfile)}
+ * which sends the entry e.g feed to the output stream.
+ *
+ *
+ * This class will set the HTTP Last-Modified Header to enable
+ * clients to send If-Modified-Since request header to avoid
+ * retrieving the content again if it hasn't changed. If the content hasn't
+ * changed since the If-Modified-Since time, then the GData service returns a
+ * 304 (Not Modified) HTTP response.
+ *
+ *
+ *
+ *
+ *
+ * @author Simon Willnauer
+ *
+ */
+public class GDataResponse {
+ private int error;
+
+ private boolean isError = false;
+
+ private String encoding;
+
+ private OutputFormat outputFormat;
+
+ private final HttpServletResponse response;
+
+ protected static final String XMLMIME_ATOM = "text/xml";
+
+ protected static final String XMLMIME_RSS = "text/xml";
+
+ private static final String DEFAUL_NAMESPACE_URI = "http://www.w3.org/2005/Atom";
+
+ private static final Namespace DEFAULT_NAMESPACE = new Namespace("",
+ DEFAUL_NAMESPACE_URI);
+
+ private static final String HEADER_LASTMODIFIED = "Last-Modified";
+
+ /**
+ * Creates a new GDataResponse
+ *
+ * @param response -
+ * The underlaying {@link HttpServletResponse}
+ */
+ public GDataResponse(HttpServletResponse response) {
+ if (response == null)
+ throw new IllegalArgumentException("response must not be null");
+ this.response = response;
+
+ }
+
+ /**
+ * Sets an error code to this FeedResponse.
+ *
+ * @param errorCode -
+ * {@link HttpServletResponse} error code
+ */
+ public void setError(int errorCode) {
+ this.isError = true;
+ this.error = errorCode;
+ }
+
+ /**
+ * Sets the status of the underlaying response
+ *
+ * @see HttpServletResponse
+ * @param responseCode -
+ * the status of the response
+ */
+ public void setResponseCode(int responseCode) {
+ this.response.setStatus(responseCode);
+ }
+
+ /**
+ * This method sends the specified error to the user if set
+ *
+ * @throws IOException -
+ * if an I/O Exception occures
+ */
+ public void sendError() throws IOException {
+ if (this.isError)
+ this.response.sendError(this.error);
+
+ }
+
+ /**
+ * @return - the {@link HttpServletResponse} writer
+ * @throws IOException -
+ * If an I/O exception occures
+ */
+ public Writer getWriter() throws IOException {
+ return this.response.getWriter();
+ }
+
+ /**
+ * Sends a response for a get e.g. query request. This method must not
+ * invoked in a case of an error performing the requeste action.
+ *
+ * @param feed -
+ * the feed to respond to the client
+ * @param profile -
+ * the extension profil for the feed to write
+ * @throws IOException -
+ * if an I/O exception accures, often caused by an already
+ * closed Writer or OutputStream
+ *
+ */
+ public void sendResponse(BaseFeed feed, ExtensionProfile profile)
+ throws IOException {
+ if (feed == null)
+ throw new IllegalArgumentException("feed must not be null");
+ if (profile == null)
+ throw new IllegalArgumentException(
+ "extension profil must not be null");
+ DateTime time = feed.getUpdated();
+ if (time != null)
+ setLastModifiedHeader(time.getValue());
+ XmlWriter writer = createWriter();
+
+ if (this.outputFormat.equals(OutputFormat.ATOM)) {
+ this.response.setContentType(XMLMIME_ATOM);
+ feed.generateAtom(writer, profile);
+ } else {
+ this.response.setContentType(XMLMIME_RSS);
+ feed.generateRss(writer, profile);
+ }
+
+ }
+
+ /**
+ *
+ * Sends a response for an update, insert or delete request. This method
+ * must not invoked in a case of an error performing the requeste action. If
+ * the specified response format is ATOM the default namespace will be set
+ * to ATOM.
+ *
+ * @param entry -
+ * the modified / created entry to send
+ * @param profile -
+ * the entries extension profile
+ * @throws IOException -
+ * if an I/O exception accures, often caused by an already
+ * closed Writer or OutputStream
+ */
+ public void sendResponse(BaseEntry entry, ExtensionProfile profile)
+ throws IOException {
+ if (entry == null)
+ throw new IllegalArgumentException("entry must not be null");
+ if (profile == null)
+ throw new IllegalArgumentException(
+ "extension profil must not be null");
+ DateTime time = entry.getUpdated();
+ if (time != null)
+ setLastModifiedHeader(time.getValue());
+ XmlWriter writer = createWriter();
+ if (this.outputFormat.equals(OutputFormat.ATOM))
+ entry.generateAtom(writer, profile);
+ else
+ entry.generateRss(writer, profile);
+ }
+
+ private XmlWriter createWriter() throws IOException {
+ XmlWriter writer = new XmlWriter(getWriter(), this.encoding);
+ // set the default namespace to Atom if Atom is the response format
+ if (this.outputFormat.equals(OutputFormat.ATOM))
+ writer.setDefaultNamespace(DEFAULT_NAMESPACE);
+ return writer;
+ }
+
+ /**
+ * This encoding will be used to encode the xml representation of feed or
+ * entry written to the {@link HttpServletResponse} output stream.
+ *
+ * @return - the entry / feed encoding
+ */
+ public String getEncoding() {
+ return this.encoding;
+ }
+
+ /**
+ * This encoding will be used to encode the xml representation of feed or
+ * entry written to the {@link HttpServletResponse} output stream. UTF-8
+ * ISO-8859-1
+ *
+ * @param encoding -
+ * string represents the encoding
+ */
+ public void setEncoding(String encoding) {
+ this.encoding = encoding;
+ }
+
+ /**
+ * @return - the response
+ * {@link org.apache.lucene.gdata.server.GDataRequest.OutputFormat}
+ */
+ public OutputFormat getOutputFormat() {
+ return this.outputFormat;
+ }
+
+ /**
+ * @param outputFormat -
+ * the response
+ * {@link org.apache.lucene.gdata.server.GDataRequest.OutputFormat}
+ */
+ public void setOutputFormat(OutputFormat outputFormat) {
+ this.outputFormat = outputFormat;
+ }
+
+ /**
+ * @see Object#toString()
+ */
+ @Override
+ public String toString() {
+ StringBuilder builder = new StringBuilder(" GDataResponse: ");
+ builder.append("Error: ").append(this.error);
+ builder.append(" outputFormat: ").append(getOutputFormat());
+ builder.append(" encoding: ").append(this.encoding);
+
+ return builder.toString();
+
+ }
+
+ protected void setLastModifiedHeader(long lastModified) {
+ String lastMod = DateFormater.formatDate(new Date(lastModified),
+ DateFormater.HTTP_HEADER_DATE_FORMAT);
+ this.response.setHeader(HEADER_LASTMODIFIED, lastMod);
+ }
+
+ /**
+ * @see HttpServletResponse#setStatus(int)
+ * @param status - the request status code
+ */
+ public void setStatus(int status){
+ this.response.setStatus(status);
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/ServiceException.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/ServiceException.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/ServiceException.java (working copy)
@@ -12,52 +12,59 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
-
-package org.apache.lucene.gdata.server;
-
-/**
- * @author Simon Willnauer
+ */
+
+package org.apache.lucene.gdata.server;
+
+/**
+ * The ServiceException is used to encapsulate all {@link java.lang.Exception}
+ * throw by underlaying layers of the
+ * {@link org.apache.lucene.gdata.server.Service} layer.
*
- */
-public class ServiceException extends Exception {
-
- /**
- *
- */
- private static final long serialVersionUID = -7099825107871876584L;
-
- /**
- *
- */
- public ServiceException() {
- super();
-
- }
-
- /**
- * @param arg0
- */
- public ServiceException(String arg0) {
- super(arg0);
-
- }
-
- /**
- * @param arg0
- * @param arg1
- */
- public ServiceException(String arg0, Throwable arg1) {
- super(arg0, arg1);
-
- }
-
- /**
- * @param arg0
- */
- public ServiceException(Throwable arg0) {
- super(arg0);
-
- }
-
-}
+ * @author Simon Willnauer
+ *
+ */
+public class ServiceException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -7099825107871876584L;
+
+ /**
+ * Constructs a new ServiceException
+ */
+ public ServiceException() {
+ super();
+
+ }
+
+ /**
+ * Constructs a new ServiceException
+ * @param arg0 - the exception message
+ */
+ public ServiceException(String arg0) {
+ super(arg0);
+
+ }
+
+ /**
+ * Constructs a new ServiceException
+ * @param arg0 - the exceptin message
+ * @param arg1 - the exception cause
+ */
+ public ServiceException(String arg0, Throwable arg1) {
+ super(arg0, arg1);
+
+ }
+
+ /**
+ * Constructs a new ServiceException
+ * @param arg0 - the exception cause
+ */
+ public ServiceException(Throwable arg0) {
+ super(arg0);
+
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/authentication/BlowfishAuthenticationController.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/authentication/BlowfishAuthenticationController.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/authentication/BlowfishAuthenticationController.java (revision 0)
@@ -0,0 +1,274 @@
+/**
+ * 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.authentication;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.Provider;
+import java.security.Security;
+import java.util.StringTokenizer;
+import java.util.concurrent.locks.ReentrantLock;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.Cipher;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.KeyGenerator;
+import javax.crypto.spec.SecretKeySpec;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.lucene.gdata.data.GDataAccount;
+import org.apache.lucene.gdata.data.GDataAccount.AccountRole;
+import org.apache.lucene.gdata.server.registry.Component;
+import org.apache.lucene.gdata.server.registry.ComponentType;
+
+import sun.misc.BASE64Decoder;
+import sun.misc.BASE64Encoder;
+
+/**
+ * A
+ * {@link org.apache.lucene.gdata.server.authentication.AuthenticationController}
+ * implmentation using a Blowfish algorithmn to en/decrpyt the
+ * authentification token. The Blowfish algorithmn enables a stateless
+ * authetication of the client. The token contains all information to
+ * authenticate the client on possible other hosts.
+ *
+ * The token contains the first 32 bit of the client ip (e.g. 192.168.0),
+ * account name, {@link org.apache.lucene.gdata.data.GDataAccount.AccountRole}
+ * and the cration time as a timestamp. The timestamp will be checked on every
+ * subsequent request. If the timestamp plus the configured timeout is less
+ * than the current time the client has to reauthenticate again.
+ *
+ *
+ * The auth token returned by the
+ * {@link BlowfishAuthenticationController#authenticatAccount(GDataAccount, String)}
+ * method is a BASE64 encoded string.
+ *
+ *
+ * @see javax.crypto.Cipher
+ * @see sun.misc.BASE64Encoder
+ * @see sun.misc.BASE64Decoder
+ * @author Simon Willnauer
+ *
+ */
+@Component(componentType = ComponentType.AUTHENTICATIONCONTROLLER)
+public class BlowfishAuthenticationController implements
+ AuthenticationController {
+ private static final Log LOG = LogFactory
+ .getLog(BlowfishAuthenticationController.class);
+
+ private static final String ALG = "Blowfish";
+
+ private static final String TOKEN_LIMITER = "#";
+
+ private static final String ENCODING = "UTF-8";
+
+ private Cipher deCrypt;
+
+ private Cipher enCrypt;
+
+ // TODO make this configurable
+ private int minuteOffset = 30;
+
+ private long milisecondOffset;
+
+ private BASE64Encoder encoder = new BASE64Encoder();
+
+ private BASE64Decoder decoder = new BASE64Decoder();
+
+ private ReentrantLock lock = new ReentrantLock();
+
+ // TODO make this configurable
+ private String key = "myTestKey";
+
+ /**
+ * @see org.apache.lucene.gdata.server.authentication.AuthenticationController#initialize()
+ */
+ public void initialize() {
+ if (this.key == null)
+ throw new IllegalArgumentException("Auth key must not be null");
+ if (this.key.length() < 5 || this.key.length() > 16)
+ throw new IllegalArgumentException(
+ "Auth key length must be greater than 4 and less than 17");
+
+ try {
+ Provider sunJce = new com.sun.crypto.provider.SunJCE();
+ Security.addProvider(sunJce);
+ KeyGenerator kgen = KeyGenerator.getInstance(ALG);
+ kgen.init(448); // 448 Bit^M
+ byte[] raw = this.key.getBytes();
+ SecretKeySpec skeySpec = new SecretKeySpec(raw, ALG);
+ this.deCrypt = Cipher.getInstance(ALG);
+ this.enCrypt = Cipher.getInstance(ALG);
+ this.deCrypt.init(Cipher.DECRYPT_MODE, skeySpec);
+ this.enCrypt.init(Cipher.ENCRYPT_MODE, skeySpec);
+ } catch (Exception e) {
+ throw new AuthenticatorException(
+ "Can't initialize BlowfishAuthenticationController -- "
+ + e.getMessage(), e);
+
+ }
+ calculateTimeOffset();
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.authentication.AuthenticationController#authenticatAccount(org.apache.lucene.gdata.data.GDataAccount,
+ * java.lang.String)
+ */
+ public String authenticatAccount(GDataAccount account, String requestIp) {
+ try {
+ String passIp = requestIp.substring(0, requestIp.lastIndexOf('.'));
+ String role = Integer.toString(account.getRolesAsInt());
+
+ return calculateAuthToken(passIp, role, account.getName());
+ } catch (Exception e) {
+ throw new AuthenticatorException("Can not authenticat account -- "
+ + e.getMessage(), e);
+
+ }
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.authentication.AuthenticationController#authenticateToken(java.lang.String,
+ * java.lang.String,
+ * org.apache.lucene.gdata.data.GDataAccount.AccountRole,
+ * java.lang.String)
+ */
+ public boolean authenticateToken(final String token,
+ final String requestIp, AccountRole role, String accountName) {
+ if (LOG.isInfoEnabled())
+ LOG.info("authenticate Token " + token + " for requestIp: "
+ + requestIp);
+ if (token == null || requestIp == null)
+ return false;
+ String passIp = requestIp.substring(0, requestIp.lastIndexOf('.'));
+ String authString = null;
+ try {
+ authString = deCryptAuthToken(token);
+ } catch (Exception e) {
+ throw new AuthenticatorException("Can not decrypt token -- "
+ + e.getMessage(), e);
+ }
+ if (authString == null)
+ return false;
+ try {
+ StringTokenizer tokenizer = new StringTokenizer(authString,
+ TOKEN_LIMITER);
+ if (!tokenizer.nextToken().equals(passIp))
+ return false;
+ String tempAccountName = tokenizer.nextToken();
+ int intRole = Integer.parseInt(tokenizer.nextToken());
+ /*
+ * Authentication goes either for a account role or a account. For
+ * entry manipulation the account name will be retrieved by the
+ * feedId otherwise it will be null If it is null the authentication
+ * goes against the account role
+ */
+ if (tempAccountName == null
+ || (!tempAccountName.equals(accountName) && !GDataAccount
+ .isInRole(intRole, role)))
+ return false;
+ long timeout = Long.parseLong(tokenizer.nextToken());
+
+ return (timeout + this.milisecondOffset) > System
+ .currentTimeMillis();
+ } catch (Exception e) {
+ LOG.error("Error occured while encrypting token " + e.getMessage(),
+ e);
+ return false;
+ }
+
+ }
+
+ private void calculateTimeOffset() {
+ this.milisecondOffset = this.minuteOffset * 60 * 1000;
+ }
+
+ protected String calculateAuthToken(final String ipAddress,
+ final String role, String accountName)
+ throws IllegalBlockSizeException, BadPaddingException,
+ UnsupportedEncodingException {
+ StringBuilder builder = new StringBuilder();
+ builder.append(ipAddress).append(TOKEN_LIMITER);
+ builder.append(accountName).append(TOKEN_LIMITER);
+ builder.append(role).append(TOKEN_LIMITER);
+ builder.append(System.currentTimeMillis());
+
+ this.lock.lock();
+ try {
+ byte[] toencode = builder.toString().getBytes(ENCODING);
+ byte[] result = this.enCrypt.doFinal(toencode);
+ return this.encoder.encode(result);
+ } finally {
+ this.lock.unlock();
+
+ }
+
+ }
+
+ protected String deCryptAuthToken(final String authToken)
+ throws IOException, IllegalBlockSizeException, BadPaddingException {
+ this.lock.lock();
+ try {
+ byte[] input = this.decoder.decodeBuffer(authToken);
+ byte[] result = this.deCrypt.doFinal(input);
+ return new String(result, ENCODING);
+ } finally {
+ this.lock.unlock();
+ }
+
+ }
+
+ /**
+ * @return Returns the minuteOffset.
+ */
+ public int getMinuteOffset() {
+ return this.minuteOffset;
+ }
+
+ /**
+ * @param minuteOffset
+ * The minuteOffset to set.
+ */
+ public void setMinuteOffset(int minuteOffset) {
+ this.minuteOffset = minuteOffset;
+ calculateTimeOffset();
+ }
+
+ /**
+ * @return Returns the key.
+ */
+ public String getKey() {
+ return this.key;
+ }
+
+ /**
+ * @param key
+ * The key to set.
+ */
+ public void setKey(String key) {
+ this.key = key;
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.registry.ServerComponent#destroy()
+ */
+ public void destroy() {
+ //
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/authentication/AuthenticationController.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/authentication/AuthenticationController.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/authentication/AuthenticationController.java (revision 0)
@@ -0,0 +1,122 @@
+/**
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.gdata.server.authentication;
+
+import org.apache.lucene.gdata.data.GDataAccount;
+import org.apache.lucene.gdata.data.GDataAccount.AccountRole;
+import org.apache.lucene.gdata.server.registry.ServerComponent;
+
+/**
+ * Implementations of the AuthenticationController interface contain all the
+ * logic for processing token based authentification. A token is an encoded
+ * unique String value passed back to the client if successfully
+ * authenticated. Clients provide account name, password, the requested service
+ * and the name of the application used for accessing the the gdata service.
+ *
+ * The algorithmn to create and reauthenticate the token can be choosen by the
+ * implementor. This interface extends
+ * {@link org.apache.lucene.gdata.server.registry.ServerComponent} e.g.
+ * implementing classes can be registered as a
+ * {@link org.apache.lucene.gdata.server.registry.Component} in the
+ * {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry} to be
+ * accessed via the provided lookup service
+ *
+ *
+ * @see org.apache.lucene.gdata.server.authentication.BlowfishAuthenticationController
+ * @author Simon Willnauer
+ *
+ */
+public interface AuthenticationController extends ServerComponent {
+
+ /**
+ * The header name containing the authentication token provided by the
+ * client
+ */
+ public static final String AUTHORIZATION_HEADER = "Authorization";
+
+ /**
+ * Authentication parameter for the account name. Provided by the client to
+ * recieve the auth token.
+ */
+ public static final String ACCOUNT_PARAMETER = "Email";
+
+ /**
+ * Authentication parameter for the account password. Provided by the client
+ * to recieve the auth token.
+ */
+ public static final String PASSWORD_PARAMETER = "Passwd";
+
+ /**
+ * Authentication parameter for the requested service. Provided by the
+ * client to recieve the auth token.
+ */
+ public static final String SERVICE_PARAMETER = "service";
+
+ /**
+ * Authentication parameter for the application name of the clients
+ * application. This is just used for loggin purposes
+ */
+ public static final String APPLICATION_PARAMETER = "source";
+
+ /**
+ * The key used for respond the auth token to the client. Either as a cookie
+ * (key as cookie name) or as plain response (TOKEN_KEY=TOKEN)
+ */
+ public final static String TOKEN_KEY = "Auth";
+
+ /**
+ * Creates a authentication token for the given account. The token will be
+ * calculated based on a part of the clients ip address, the account role
+ * and the account name and the time in millisecond at the point of
+ * creation.
+ *
+ * @param account -
+ * the account to create the token for
+ * @param requestIp -
+ * the clients request ip address
+ * @return - a BASE64 encoded authentification token
+ */
+ public abstract String authenticatAccount(GDataAccount account,
+ String requestIp);
+
+ /**
+ * Authenticates the given auth token and checks the given parameter for
+ * matching the information contained inside the token.
+ *
+ * if the given account name is null the authentication will
+ * ignore the account name and the decision whether the token is valid or
+ * not will be based on the given role compared to the role inside the token
+ *
+ *
+ * @param token -
+ * the token to authenticate
+ * @param requestIp -
+ * the client request IP address
+ * @param role -
+ * the required role
+ * @param accountName -
+ * the name of the account
+ * @return true if the given values match the values inside
+ * the token and if the timestamp plus the configured timeout is
+ * greater than the current time, if one of the values does not
+ * match or the token has timed out it will return
+ * false
+ */
+ public abstract boolean authenticateToken(final String token,
+ final String requestIp, AccountRole role, String accountName);
+
+}
\ No newline at end of file
Index: gdata-server/src/java/org/apache/lucene/gdata/server/authentication/AuthenticatorException.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/authentication/AuthenticatorException.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/authentication/AuthenticatorException.java (revision 0)
@@ -0,0 +1,71 @@
+/**
+ * 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.authentication;
+
+/**
+ * This exception will be thrown by
+ * {@link org.apache.lucene.gdata.server.authentication.AuthenticationController}
+ * implementations if an error while de/encrypting the token occures.
+ *
+ * @author Simon Willnauer
+ *
+ */
+public class AuthenticatorException extends RuntimeException {
+
+ private static final long serialVersionUID = -5690495392712564651L;
+
+ /**
+ * Constructs a new Authenticator Exception
+ */
+ public AuthenticatorException() {
+ super();
+
+ }
+
+ /**
+ * Constructs a new Authenticator Exception with the specified detail message.
+ * @param arg0 - detail message
+ */
+ public AuthenticatorException(String arg0) {
+ super(arg0);
+
+ }
+
+ /**
+ * Constructs a new Authenticator Exception with the specified detail message and
+ * nested exception.
+ *
+ * @param arg0 -
+ * detail message
+ * @param arg1 -
+ * nested exception
+ */
+ public AuthenticatorException(String arg0, Throwable arg1) {
+ super(arg0, arg1);
+
+ }
+
+ /**
+ * Constructs a new Authenticator Exception with a nested exception caused this exception.
+ * @param arg0 - nested exception
+ */
+ public AuthenticatorException(Throwable arg0) {
+ super(arg0);
+
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/authentication/GDataHttpAuthenticator.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/authentication/GDataHttpAuthenticator.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/authentication/GDataHttpAuthenticator.java (revision 0)
@@ -0,0 +1,59 @@
+/**
+ * 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.authentication;
+
+import javax.servlet.http.HttpServletRequest;
+
+import org.apache.lucene.gdata.data.GDataAccount.AccountRole;
+import org.apache.lucene.gdata.server.GDataRequest;
+
+/**
+ * The GData protocol is based on the widly know REST approach and therefor
+ * client authentication will mostly be provided via a REST interface.
+ *
+ * This interface describes internally used authentication methods to be
+ * implemented by http based authenticator implementations. The GData Server
+ * basically has 2 different REST interfaces need authentication. One is for
+ * altering feed entries and the other for administration actions.
+ *
+ *
The interface altering entries work with {@link com.google.gdata.client.Service.GDataRequest} object created by the handler and passed to the {@link org.apache.lucene.gdata.server.Service} instance.
+ * Administration interfaces use the plain {@link javax.servlet.http.HttpServletRequest} inside the handler.
+ * For each type of interface a authentication type a method has to be provided by implementing classes.
+ *
+ * @author Simon Willnauer
+ *
+ */
+public interface GDataHttpAuthenticator {
+
+ /**
+ * Authenticates the client request based on the given GdataRequst and required account role
+ * @param request - the gdata request
+ * @param role - the required role for passing the authentication
+ *
+ * @return true if the request successfully authenticates, otherwise false
+ */
+ public boolean authenticateAccount(final GDataRequest request,
+ AccountRole role);
+
+ /**
+ * Authenticates the client request based on the given requst and required account role
+ * @param request - the client request
+ * @param role - the required role for passing the authentication
+ * @return true if the request successfully authenticates, otherwise false
+ */
+ public boolean authenticateAccount(final HttpServletRequest request,
+ AccountRole role);
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/authentication/AuthenticationException.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/authentication/AuthenticationException.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/authentication/AuthenticationException.java (revision 0)
@@ -0,0 +1,70 @@
+/**
+ * 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.authentication;
+
+/**
+ *
+ * @author Simon Willnauer
+ *
+ */
+public class AuthenticationException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5467768078178612671L;
+
+ /**
+ * Constructs a new Authentication Exception
+ */
+ public AuthenticationException() {
+ super();
+
+ }
+
+ /**
+ * Constructs a new Authentication Exception with the specified detail message
+ * @param arg0 - detail message
+ */
+ public AuthenticationException(String arg0) {
+ super(arg0);
+
+ }
+
+ /**
+ * Constructs a new Authentication Exception with the specified detail message and
+ * nested exception caused this exception.
+ * @param arg0 -
+ * detail message
+ * @param arg1 -
+ * nested exception
+ */
+ public AuthenticationException(String arg0, Throwable arg1) {
+ super(arg0, arg1);
+
+ }
+
+ /**
+ * Constructs a new Authentication Exception with a nested exception caused this exception
+ * @param arg0 - nested exception
+ */
+ public AuthenticationException(Throwable arg0) {
+ super(arg0);
+
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/authentication/package.html
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/authentication/package.html (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/authentication/package.html (revision 0)
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+Classes and Exceptions used for client authentification.
+
+
\ No newline at end of file
Index: gdata-server/src/java/org/apache/lucene/gdata/server/Service.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/Service.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/Service.java (working copy)
@@ -16,6 +16,8 @@
package org.apache.lucene.gdata.server;
+import java.util.Date;
+
import com.google.gdata.data.BaseEntry;
import com.google.gdata.data.BaseFeed;
@@ -39,7 +41,7 @@
*
*
*/
-public abstract class Service {
+public interface Service {
/**
* Service method to create an entry in an already created and existing
@@ -133,6 +135,27 @@
public abstract BaseEntry getSingleEntry(final GDataRequest request, final GDataResponse response)
throws ServiceException;
+ /**
+ * will close the Service - service should not be used after this method has been called
+ */
+ public void close();
+
+ /**
+ * Retruns the date of the last modification for the given feed id
+ * @param feedId - the id of the feed
+ * @return - the last modified date or the current date if the date can not be retrieved
+ * @throws ServiceException - if the storage can not be accessed
+ */
+ public abstract Date getFeedLastModified(String feedId)throws ServiceException;
+
+ /**
+ * Retruns the date of the last modification for the given entry id
+ * @param entryId - the id of the entry
+ * @param feedId - the feed id this entry belongs to
+ * @return - the last modified date or the current date if the date can not be retrieved
+ * @throws ServiceException - if the storage can not be accessed
+ */
+ public abstract Date getEntryLastModified(String entryId, String feedId)throws ServiceException;
Index: gdata-server/src/java/org/apache/lucene/gdata/server/GDataService.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/GDataService.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/GDataService.java (working copy)
@@ -1,275 +1,398 @@
-/**
- * Copyright 2004 The Apache Software Foundation
+/**
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.gdata.server;
+
+import java.io.IOException;
+import java.util.Date;
+import java.util.List;
+
+import javax.servlet.http.HttpServletResponse;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.lucene.gdata.data.ServerBaseEntry;
+import org.apache.lucene.gdata.data.ServerBaseFeed;
+import org.apache.lucene.gdata.server.registry.ComponentType;
+import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
+import org.apache.lucene.gdata.storage.ResourceNotFoundException;
+import org.apache.lucene.gdata.storage.Storage;
+import org.apache.lucene.gdata.storage.StorageController;
+import org.apache.lucene.gdata.storage.StorageException;
+
+import com.google.gdata.data.BaseEntry;
+import com.google.gdata.data.BaseFeed;
+import com.google.gdata.data.DateTime;
+import com.google.gdata.data.Generator;
+import com.google.gdata.data.Link;
+import com.google.gdata.util.ParseException;
+
+/**
+ * default implementation of the {@link org.apache.lucene.gdata.server.Service}
+ * interface.
*
- * 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
+ * @author Simon Willnauer
*
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.gdata.server;
-
-import java.io.IOException;
-import java.util.List;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
-import org.apache.lucene.gdata.storage.Storage;
-import org.apache.lucene.gdata.storage.StorageException;
-import org.apache.lucene.gdata.storage.StorageFactory;
-
-import com.google.gdata.data.BaseEntry;
-import com.google.gdata.data.BaseFeed;
-import com.google.gdata.data.DateTime;
-import com.google.gdata.data.Generator;
-import com.google.gdata.data.Link;
-import com.google.gdata.util.ParseException;
-
-/**
- * @author Simon Willnauer
- *
- */
-public class GDataService extends Service {
- private static final Log LOGGER = LogFactory.getLog(GDataService.class);
-
- private Storage storage;
-
- private GDataServerRegistry registry = GDataServerRegistry.getRegistry();
-
- private static final Generator generator;
-
- private static final String generatorName = "Lucene GData-Server";
-
- private static final String generatorURI = "http://lucene.apache.org";
- static {
- generator = new Generator();
- generator.setName(generatorName);
- generator.setUri(generatorURI);
- generator.setVersion("0.1");
- }
-
- protected GDataService() throws ServiceException {
- try {
- this.storage = StorageFactory.getStorage();
-
- } catch (StorageException e) {
- LOGGER
- .fatal(
- "Can't get Storage Instance -- can't serve any requests",
- e);
- ServiceException ex = new ServiceException(
- "Can't get Storage instance" + e.getMessage(), e);
- ex.setStackTrace(e.getStackTrace());
- throw ex;
- }
- }
-
- /**
- * @see org.apache.lucene.gdata.server.Service#createEntry(org.apache.lucene.gdata.server.GDataRequest,
- * org.apache.lucene.gdata.server.GDataResponse)
- */
- @Override
- public BaseEntry createEntry(GDataRequest request, GDataResponse response)
- throws ServiceException {
-
- checkFeedIsRegisterd(request);
- if (LOGGER.isInfoEnabled())
- LOGGER.info("create Entry for feedId: " + request.getFeedId());
- BaseEntry entry = buildEntry(request);
- setUpdateTime(entry);
- try {
-
- this.storage.storeEntry(entry, request.getFeedId());
- } catch (Exception e) {
- ServiceException ex = new ServiceException("Could not store entry",
- e);
- ex.setStackTrace(e.getStackTrace());
- throw ex;
- }
- return entry;
- }
-
- /**
- * @see org.apache.lucene.gdata.server.Service#deleteEntry(org.apache.lucene.gdata.server.GDataRequest,
- * org.apache.lucene.gdata.server.GDataResponse)
- */
- @Override
- public BaseEntry deleteEntry(GDataRequest request, GDataResponse response)
- throws ServiceException {
- checkFeedIsRegisterd(request);
- String entryid = request.getEntryId();
- String feedid = request.getFeedId();
- try {
- this.storage.deleteEntry(entryid, feedid);
- } catch (Exception e) {
- ServiceException ex = new ServiceException(
- "Could not delete entry", e);
- ex.setStackTrace(e.getStackTrace());
- throw ex;
- }
- return null;
- }
-
- /**
- * @see org.apache.lucene.gdata.server.Service#updateEntry(org.apache.lucene.gdata.server.GDataRequest,
- * org.apache.lucene.gdata.server.GDataResponse)
- */
- @Override
- public BaseEntry updateEntry(GDataRequest request, GDataResponse response)
- throws ServiceException {
- checkFeedIsRegisterd(request);
-
- BaseEntry entry = buildEntry(request);
- String feedid = request.getFeedId();
- if (LOGGER.isInfoEnabled())
- LOGGER.info("update Entry" + entry.getId() + " for feedId: "
- + feedid);
- setUpdateTime(entry);
- try {
- this.storage.updateEntry(entry, feedid);
- } catch (StorageException e) {
- ServiceException ex = new ServiceException(
- "Could not update entry", e);
- ex.setStackTrace(e.getStackTrace());
- throw ex;
- }
- return entry;
- }
-
- /**
- * @see org.apache.lucene.gdata.server.Service#getFeed(org.apache.lucene.gdata.server.GDataRequest,
- * org.apache.lucene.gdata.server.GDataResponse)
- */
- @SuppressWarnings("unchecked")
- @Override
- public BaseFeed getFeed(GDataRequest request, GDataResponse response)
- throws ServiceException {
- checkFeedIsRegisterd(request);
-
- try {
- // TODO remove when storing feeds is implemented just for
- // development
- BaseFeed feed = this.storage.getFeed(request.getFeedId(), request
- .getStartIndex(), request.getItemsPerPage());
- buildDynamicFeedElements(request, feed);
- List list = feed.getEntries();
- addContextPath(list, request.getContextPath());
- return feed;
- } catch (StorageException e) {
- ServiceException ex = new ServiceException("Could not get feed", e);
- ex.setStackTrace(e.getStackTrace());
- throw ex;
- }
-
- }
-
- /*
- * build the dynamic elements like self link and next link
- */
- private void buildDynamicFeedElements(final GDataRequest request,
- final BaseFeed feed) {
- feed.setGenerator(generator);
- feed.setItemsPerPage(request.getItemsPerPage());
- feed.getLinks().add(
- buildLink(Link.Rel.SELF, Link.Type.ATOM, request.getSelfId()));
- // TODO add next link
- }
-
- private Link buildLink(String rel, String type, String href) {
- Link retVal = new Link();
- retVal.setHref(href);
- retVal.setRel(rel);
- retVal.setType(type);
- return retVal;
- }
-
- /*
- * every entry has an ID which has to have a prefix. The prefix is the
- * context path of the requested feed. This will be used to request the
- * entry directly
- */
- private void addContextPath(List list, final String contextPath) {
- for (BaseEntry entry : list) {
- addcontextPath(entry, contextPath);
- }
- }
-
- @SuppressWarnings("unchecked")
- private BaseEntry addcontextPath(final BaseEntry entry,
- final String contextPath) {
- String id = contextPath + entry.getId();
- entry.setId(id);
- Link self = new Link();
- self.setRel("self");
- self.setHref(id);
- self.setType("application/atom+xml");
- entry.getLinks().add(self);
- return entry;
- }
-
- private BaseEntry buildEntry(final GDataRequest request)
- throws ServiceException {
- try {
- return GDataEntityBuilder.buildEntry(request);
-
- } catch (ParseException e) {
- ServiceException ex = new ServiceException(
- "Could not parse entry from incoming request", e);
- ex.setStackTrace(e.getStackTrace());
- throw ex;
- } catch (IOException e) {
- ServiceException ex = new ServiceException(
- "Could not read or open input stream", e);
- ex.setStackTrace(e.getStackTrace());
- throw ex;
- }
- }
-
- /*
- * checks whether the reqeuested feed is registered
- */
- private void checkFeedIsRegisterd(final GDataRequest request)
- throws FeedNotFoundException {
- if (!this.registry.isFeedRegistered(request.getFeedId()))
- throw new FeedNotFoundException(
- "Feed could not be found - is not registed - Feed ID:"
- + request.getFeedId());
- this.storage.setExtensionProfile(request.getExtensionProfile());
- }
-
- private BaseEntry setUpdateTime(final BaseEntry entry) {
- entry.setUpdated(DateTime.now());
- return entry;
- }
-
- /**
- * @see org.apache.lucene.gdata.server.Service#getSingleEntry(org.apache.lucene.gdata.server.GDataRequest,
- * org.apache.lucene.gdata.server.GDataResponse)
- */
- @Override
- public BaseEntry getSingleEntry(GDataRequest request, GDataResponse response)
- throws ServiceException {
- checkFeedIsRegisterd(request);
-
- try {
- BaseEntry entry = this.storage.getEntry(request.getEntryId(),
- request.getFeedId());
- if(entry == null)
- return null;
- addcontextPath(entry, request.getContextPath());
- return entry;
- } catch (StorageException e) {
- ServiceException ex = new ServiceException("Could not get feed", e);
- ex.setStackTrace(e.getStackTrace());
- throw ex;
- }
- }
-
-}
+ */
+public class GDataService implements Service {
+ private static final Log LOGGER = LogFactory.getLog(GDataService.class);
+
+ protected Storage storage;
+
+ protected GDataServerRegistry registry = GDataServerRegistry.getRegistry();
+
+ private static final Generator generator;
+
+ private static final String generatorName = "Lucene GData-Server";
+
+ private static final String generatorURI = "http://lucene.apache.org";
+
+ private static final String XMLMIME = "application/atom+xml";
+ static {
+ generator = new Generator();
+ generator.setName(generatorName);
+ generator.setUri(generatorURI);
+ generator.setVersion("0.1");
+ }
+
+ protected GDataService() throws ServiceException {
+ try {
+ StorageController controller = GDataServerRegistry.getRegistry()
+ .lookup(StorageController.class,
+ ComponentType.STORAGECONTROLLER);
+ if (controller == null)
+ throw new StorageException(
+ "StorageController is not registered");
+ this.storage = controller.getStorage();
+
+ } catch (StorageException e) {
+ LOGGER
+ .fatal(
+ "Can't get Storage Instance -- can't serve any requests",
+ e);
+ ServiceException ex = new ServiceException(
+ "Can't get Storage instance" + e.getMessage(), e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+ }
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.Service#createEntry(org.apache.lucene.gdata.server.GDataRequest,
+ * org.apache.lucene.gdata.server.GDataResponse)
+ */
+
+ public BaseEntry createEntry(GDataRequest request, GDataResponse response)
+ throws ServiceException {
+
+ if (LOGGER.isInfoEnabled())
+ LOGGER.info("create Entry for feedId: " + request.getFeedId());
+
+ ServerBaseEntry entry = buildEntry(request, response);
+ entry.setFeedId(request.getFeedId());
+ entry.setServiceConfig(request.getConfigurator());
+ setTimeStamps(entry.getEntry());
+ BaseEntry retVal = null;
+ try {
+ retVal = this.storage.storeEntry(entry);
+ } catch (Exception e) {
+ response.setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ ServiceException ex = new ServiceException("Could not store entry",
+ e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+ }
+ return retVal;
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.Service#deleteEntry(org.apache.lucene.gdata.server.GDataRequest,
+ * org.apache.lucene.gdata.server.GDataResponse)
+ */
+
+ public BaseEntry deleteEntry(GDataRequest request, GDataResponse response)
+ throws ServiceException {
+
+ ServerBaseEntry entry = new ServerBaseEntry();
+ entry.setServiceConfig(request.getConfigurator());
+ entry.setFeedId(request.getFeedId());
+ entry.setId(request.getEntryId());
+ if (entry.getId() == null)
+ throw new ServiceException(
+ "entry id is null -- can not delete null entry");
+ try {
+ this.storage.deleteEntry(entry);
+ } catch (ResourceNotFoundException e) {
+ response.setError(HttpServletResponse.SC_BAD_REQUEST);
+ ServiceException ex = new ServiceException(
+ "Could not delete entry", e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+ } catch (Exception e) {
+ response.setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ ServiceException ex = new ServiceException(
+ "Could not delete entry", e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+ }
+ return null;
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.Service#updateEntry(org.apache.lucene.gdata.server.GDataRequest,
+ * org.apache.lucene.gdata.server.GDataResponse)
+ */
+
+ public BaseEntry updateEntry(GDataRequest request, GDataResponse response)
+ throws ServiceException {
+
+ ServerBaseEntry entry = buildEntry(request, response);
+ entry.setFeedId(request.getFeedId());
+
+ entry.setServiceConfig(request.getConfigurator());
+ if (LOGGER.isInfoEnabled())
+ LOGGER.info("update Entry" + entry.getId() + " for feedId: "
+ + request.getFeedId());
+ if (entry.getId() == null) {
+ response.setError(HttpServletResponse.SC_BAD_REQUEST);
+ throw new ServiceException("Entry id is null can not update entry");
+ }
+ if (!entry.getId().equals(request.getEntryId())) {
+ if (LOGGER.isInfoEnabled())
+ LOGGER
+ .info("Entry id in the entry xml does not match the requested resource -- XML-ID:"
+ + entry.getId()
+ + "; Requested resource: "
+ + request.getEntryId());
+ response.setError(HttpServletResponse.SC_BAD_REQUEST);
+ throw new ServiceException(
+ "Entry id in the entry xml does not match the requested resource");
+ }
+ setTimeStamps(entry.getEntry());
+ BaseEntry retVal = null;
+ try {
+ retVal = this.storage.updateEntry(entry);
+ } catch (ResourceNotFoundException e) {
+ response.setError(HttpServletResponse.SC_BAD_REQUEST);
+ ServiceException ex = new ServiceException(
+ "Could not update entry", e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+ } catch (StorageException e) {
+ response.setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ ServiceException ex = new ServiceException(
+ "Could not update entry", e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+ }
+ return retVal;
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.Service#getFeed(org.apache.lucene.gdata.server.GDataRequest,
+ * org.apache.lucene.gdata.server.GDataResponse)
+ */
+ @SuppressWarnings("unchecked")
+ public BaseFeed getFeed(GDataRequest request, GDataResponse response)
+ throws ServiceException {
+
+ ServerBaseFeed feed = new ServerBaseFeed();
+ feed.setId(request.getFeedId());
+ feed.setStartIndex(request.getStartIndex());
+ feed.setItemsPerPage(request.getItemsPerPage());
+ feed.setServiceConfig(request.getConfigurator());
+ try {
+ BaseFeed retVal = this.storage.getFeed(feed);
+ dynamicElementFeedStragey(retVal, request);
+
+ return retVal;
+ /*
+ * resouce not found will be detected in Gdata request.
+ * the request queries the storage for the feed to get the serivce for the feed
+ */
+ } catch (StorageException e) {
+ response.setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
+ ServiceException ex = new ServiceException("Could not get feed", e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+ }
+
+ }
+
+ private Link buildLink(String rel, String type, String href) {
+ Link retVal = new Link();
+ retVal.setHref(href);
+ retVal.setRel(rel);
+ retVal.setType(type);
+ return retVal;
+ }
+
+ private ServerBaseEntry buildEntry(final GDataRequest request,
+ final GDataResponse response) throws ServiceException {
+ try {
+ ServerBaseEntry entry = new ServerBaseEntry(GDataEntityBuilder
+ .buildEntry(request));
+ return entry;
+
+ } catch (ParseException e) {
+ response.setError(HttpServletResponse.SC_BAD_REQUEST);
+ ServiceException ex = new ServiceException(
+ "Could not parse entry from incoming request", e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+ } catch (IOException e) {
+ response.setError(HttpServletResponse.SC_BAD_REQUEST);
+ ServiceException ex = new ServiceException(
+ "Could not read or open input stream", e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+ }
+ }
+
+ private BaseEntry setTimeStamps(final BaseEntry entry) {
+ if (entry.getUpdated() == null)
+ entry.setUpdated(DateTime.now());
+ if (entry.getPublished() == null)
+ entry.setPublished(DateTime.now());
+ return entry;
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.Service#getSingleEntry(org.apache.lucene.gdata.server.GDataRequest,
+ * org.apache.lucene.gdata.server.GDataResponse)
+ */
+
+ public BaseEntry getSingleEntry(GDataRequest request, GDataResponse response)
+ throws ServiceException {
+
+ try {
+ ServerBaseEntry entry = new ServerBaseEntry();
+ entry.setServiceConfig(request.getConfigurator());
+ entry.setFeedId(request.getFeedId());
+ entry.setId(request.getEntryId());
+ if(entry.getId() == null){
+ response.setError(HttpServletResponse.SC_BAD_REQUEST);
+ throw new ServiceException("entry is null can't get entry");
+ }
+
+ BaseEntry retVal = null;
+ retVal = this.storage.getEntry(entry);
+ dynamicElementEntryStragey(retVal, request);
+ return retVal;
+ } catch (ResourceNotFoundException e) {
+ response.setError(HttpServletResponse.SC_BAD_REQUEST);
+ ServiceException ex = new ServiceException(
+ "Could not get entry", e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+ } catch (StorageException e) {
+ ServiceException ex = new ServiceException("Could not get feed", e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+ }
+ }
+
+ /*
+ * adds all dynamic element to the entry
+ */
+ private void dynamicElementEntryStragey(final BaseEntry entry,
+ final GDataRequest request) {
+ setSelfLink(entry, request.getContextPath());
+ }
+
+ /*
+ * adds all dynamic element to the feed entries
+ */
+ @SuppressWarnings("unchecked")
+ private void dynamicElementFeedStragey(final BaseFeed feed,
+ final GDataRequest request) {
+ buildDynamicFeedElements(request, feed);
+ List entryList = feed.getEntries();
+ for (BaseEntry entry : entryList) {
+ String id = request.getContextPath() + entry.getId();
+ setSelfLink(entry, id);
+ }
+
+ }
+
+ /*
+ * The selfLink is build from a prefix and the entry id. The prefix is the
+ * context path of the requested feed. This will be used to request the
+ * entry directly
+ */@SuppressWarnings("unchecked")
+ private BaseEntry setSelfLink(final BaseEntry entry, String id) {
+ Link self = buildLink(Link.Rel.SELF, XMLMIME, id);
+ entry.getLinks().add(self);
+ return entry;
+ }
+
+ /*
+ * build the dynamic elements like self link and next link
+ */
+ private void buildDynamicFeedElements(final GDataRequest request,
+ final BaseFeed feed) {
+ feed.setGenerator(generator);
+ feed.setItemsPerPage(request.getItemsPerPage());
+ feed.setStartIndex(request.getStartIndex());
+ feed.setId(request.getContextPath());
+ feed.getLinks().add(
+ buildLink(Link.Rel.SELF, Link.Type.ATOM, request.getSelfId()));
+ feed.getLinks().add(
+ buildLink(Link.Rel.NEXT, XMLMIME, request.getNextId()));
+
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.Service#close()
+ */
+ public void close() {
+ this.storage.close();
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.Service#getFeedLastModified(java.lang.String)
+ */
+ public Date getFeedLastModified(final String feedId) throws ServiceException {
+ try {
+ return new Date(this.storage.getFeedLastModified(feedId));
+
+ } catch (StorageException e) {
+ ServiceException ex = new ServiceException(
+ "Could not get Last update for feed -- "+feedId, e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+ }
+
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.Service#getEntryLastModified(java.lang.String, java.lang.String)
+ */
+ public Date getEntryLastModified(final String entryId,final String feedId) throws ServiceException {
+ try {
+ return new Date(this.storage.getEntryLastModified(entryId, feedId));
+
+
+
+ } catch (StorageException e) {
+ ServiceException ex = new ServiceException(
+ "Could not get Last update for entry -- "+entryId, e);
+ ex.setStackTrace(e.getStackTrace());
+ throw ex;
+ }
+
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/GDataEntityBuilder.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/GDataEntityBuilder.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/GDataEntityBuilder.java (working copy)
@@ -12,160 +12,160 @@
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
- */
-package org.apache.lucene.gdata.server;
-
-import java.io.IOException;
-import java.io.Reader;
-
-import org.apache.lucene.gdata.server.registry.DataBuilderException;
-import org.apache.lucene.gdata.server.registry.FeedInstanceConfigurator;
-import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
-
-import com.google.gdata.data.BaseEntry;
-import com.google.gdata.data.BaseFeed;
-import com.google.gdata.data.ExtensionProfile;
-import com.google.gdata.util.ParseException;
-
-/**
- * {@link com.google.gdata.data.BaseFeed},
- * {@link com.google.gdata.data.BaseEntry} instances have to be build from a
- * {@link java.io.Reader} instance as they come in from a client request or out
- * of a storage.
- *
- * To provide a generic builder class the {@link GDataEntityBuilder} requests
- * the type of the feed / entry and the corresponding
- * {@link com.google.gdata.data.ExtensionProfile} form the global
- * {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry} and builds the
- * instances from the provided reader.
- *
- *
- * @author Simon Willnauer
- *
- */
-public class GDataEntityBuilder {
- private static final GDataServerRegistry REGISTRY = GDataServerRegistry.getRegistry(); // TODO find another way for getting the registered feeds
-
- /**
- * Builds a {@link BaseFeed} instance from the {@link Reader} provided by
- * the {@link GDataRequest}
- *
- * @param request -
- * the request to build the instance from
- * @return - a BaseFeed instance
- * @throws FeedNotFoundException -
- * if the feed is not registered
- * @throws IOException -
- * if an I/O Exception occures on the provided reader
- * @throws ParseException -
- * if the feed could not be parsed
- */
- public static BaseFeed buildFeed(final GDataRequest request)
- throws FeedNotFoundException, IOException, ParseException {
- if (request == null)
- throw new IllegalArgumentException("request must not be null");
- return buildFeed(request.getFeedId(), request.getReader(),request.getExtensionProfile());
- }
-
- /**
- * Builds a {@link BaseFeed} from the provided {@link Reader}
- *
- * @param feedId -
- * the feed ID to request the feed type from the registry
- * @param reader -
- * the reader to build the feed from
- * @param profile - extension profile to parse the resource
- * @return - a BaseFeed instance
- * @throws FeedNotFoundException -
- * if the feed is not registered
- * @throws IOException -
- * if an I/O Exception occures on the provided reader
- * @throws ParseException -
- * if the feed could not be parsed
- */
- public static BaseFeed buildFeed(final String feedId, final Reader reader,final ExtensionProfile profile)
- throws FeedNotFoundException, ParseException, IOException {
-
- BaseFeed retVal = null;
- try {
- retVal = (BaseFeed) createEntityInstance(feedId);
- } catch (FeedNotFoundException e) {
- throw e;
- } catch (Exception e) {
- DataBuilderException ex = new DataBuilderException(
- "Could not build Feed for Feed class ", e);
- ex.setStackTrace(e.getStackTrace());
- throw ex;
- }
- retVal.parseAtom(profile, reader);
-
- return retVal;
- }
-
- /**
- * Builds a {@link BaseEntry} instance from the {@link Reader} provided by
- * the {@link GDataRequest}
- *
- * @param request -
- * the request to build the instance from
- * @return - a BaseEntry instance
- * @throws FeedNotFoundException -
- * if the feed, requested by the client is not registered
- * @throws IOException -
- * if an I/O Exception occures on the provided reader
- * @throws ParseException -
- * if the entry could not be parsed
- */
- public static BaseEntry buildEntry(final GDataRequest request)
- throws FeedNotFoundException, IOException, ParseException {
- if (request == null)
- throw new IllegalArgumentException("request must not be null");
- return buildEntry(request.getFeedId(), request.getReader(),request.getExtensionProfile());
- }
-
- /**
- * Builds a {@link BaseFeed} instance from the {@link Reader} provided by
- * the {@link GDataRequest}
- * @param feedId -
- * the feed ID to request the feed type from the registry
- * @param reader -
- * the reader to build the feed from
- * @param profile - extension profile to parse the resource
- * @return - a BaseFeed instance
- * @throws FeedNotFoundException -
- * if the feed is not registered
- * @throws IOException -
- * if an I/O Exception occures on the provided reader
- * @throws ParseException -
- * if the entry could not be parsed
- */
- public static BaseEntry buildEntry(final String feedId, final Reader reader,final ExtensionProfile profile)
- throws FeedNotFoundException, ParseException, IOException {
-
- BaseEntry retVal = null;
- try {
- retVal = ((BaseFeed) createEntityInstance(feedId)).createEntry();
- } catch (FeedNotFoundException e) {
- throw e;
- } catch (Exception e) {
- DataBuilderException ex = new DataBuilderException(
- "Could not build Entry for Entry class ", e);
- ex.setStackTrace(e.getStackTrace());
- throw ex;
- }
- retVal.parseAtom(new ExtensionProfile(), reader);
- return retVal;
- }
-
- private static Object createEntityInstance(String feedId)
- throws FeedNotFoundException, InstantiationException,
- IllegalAccessException {
- FeedInstanceConfigurator config = REGISTRY.getFeedConfigurator(feedId);
- if (config == null)
- throw new FeedNotFoundException(
- "No feed for requested feed ID found - " + feedId);
- Class feedClass = config.getFeedType();
- return feedClass.newInstance();
- }
-
-}
+ */
+package org.apache.lucene.gdata.server;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.lucene.gdata.server.registry.ProvidedService;
+
+import com.google.gdata.data.BaseEntry;
+import com.google.gdata.data.BaseFeed;
+import com.google.gdata.util.ParseException;
+
+/**
+ * {@link com.google.gdata.data.BaseFeed},
+ * {@link com.google.gdata.data.BaseEntry} instances have to be build from a
+ * {@link java.io.Reader} instance as they come in from a client request or out
+ * of a storage.
+ *
+ * To provide a generic builder class the {@link GDataEntityBuilder} requests
+ * the type of the feed / entry and the corresponding
+ * {@link com.google.gdata.data.ExtensionProfile} form the global
+ * {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry} and
+ * builds the instances from the provided reader.
+ *
+ *
+ * This build will not returne the abstract base classes.
+ *
+ *
+ * @author Simon Willnauer
+ *
+ */
+public class GDataEntityBuilder {
+
+ /**
+ * Builds a {@link BaseFeed} instance from the {@link Reader} provided by
+ * the {@link GDataRequest}
+ *
+ * @param request -
+ * the request to build the instance from
+ * @return - a BaseFeed instance
+ *
+ * @throws IOException -
+ * if an I/O Exception occures on the provided reader
+ * @throws ParseException -
+ * if the feed could not be parsed
+ */
+ public static BaseFeed buildFeed(final GDataRequest request)
+ throws IOException, ParseException {
+ if (request == null)
+ throw new IllegalArgumentException("request must not be null");
+ ProvidedService config = request.getConfigurator();
+ return buildFeed(request.getReader(), config);
+ }
+
+ /**
+ * Builds a {@link BaseFeed} from the provided {@link Reader}
+ *
+ *
+ * @param reader -
+ * the reader to build the feed from
+ * @param config -
+ * the feed instance config containing the extension profile to
+ * parse the resource
+ * @return - a BaseFeed instance
+ *
+ * @throws IOException -
+ * if an I/O Exception occures on the provided reader
+ * @throws ParseException -
+ * if the feed could not be parsed
+ */
+ public static BaseFeed buildFeed(final Reader reader,
+ final ProvidedService config) throws ParseException, IOException {
+
+ BaseFeed retVal = null;
+ retVal = createEntityInstance(config);
+ retVal.parseAtom(config.getExtensionProfile(), reader);
+
+ return retVal;
+ }
+
+ /**
+ * Builds a {@link BaseEntry} instance from the {@link Reader} provided by
+ * the {@link GDataRequest}
+ *
+ * @param request -
+ * the request to build the instance from
+ * @return - a BaseEntry instance
+ *
+ * @throws IOException -
+ * if an I/O Exception occures on the provided reader
+ * @throws ParseException -
+ * if the entry could not be parsed
+ */
+ public static BaseEntry buildEntry(final GDataRequest request)
+ throws IOException, ParseException {
+ if (request == null)
+ throw new IllegalArgumentException("request must not be null");
+ ProvidedService config = request.getConfigurator();
+ return buildEntry(request.getReader(), config);
+ }
+
+ /**
+ * Builds a {@link BaseFeed} instance from the {@link Reader} provided by
+ * the {@link GDataRequest}
+ *
+ * @param reader -
+ * the reader to build the feed from
+ * @param config -
+ * the instance config containing the extension profile to parse
+ * the resource
+ * @return - a BaseFeed instance
+ *
+ * @throws IOException -
+ * if an I/O Exception occures on the provided reader
+ * @throws ParseException -
+ * if the entry could not be parsed
+ */
+ public static BaseEntry buildEntry(final Reader reader,
+ final ProvidedService config) throws ParseException, IOException {
+
+ BaseEntry e = createEntityInstance(config).createEntry();
+ e.parseAtom(config.getExtensionProfile(), reader);
+ return e;
+ }
+
+ private static BaseFeed createEntityInstance(
+ final ProvidedService config) {
+ if(config.getFeedType() == null)
+ throw new IllegalArgumentException("feedtype is null in ProvidedService");
+
+ BaseFeed retVal = null;
+ try {
+ retVal = (BaseFeed) config.getFeedType().newInstance();
+ } catch (Exception e) {
+ throw new EntityBuilderException("Can't instanciate Feed for feedType "+config.getFeedType().getName(),e);
+ }
+ return retVal;
+ }
+ static class EntityBuilderException extends RuntimeException{
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 7224011324202237951L;
+
+ EntityBuilderException(String arg0) {
+ super(arg0);
+
+ }
+
+ EntityBuilderException(String arg0, Throwable arg1) {
+ super(arg0, arg1);
+
+ }
+
+ }
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/administration/AccountBuilder.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/administration/AccountBuilder.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/administration/AccountBuilder.java (revision 0)
@@ -0,0 +1,62 @@
+/**
+ * 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.administration;
+
+import java.io.IOException;
+import java.io.Reader;
+
+import org.apache.commons.digester.Digester;
+import org.apache.lucene.gdata.data.GDataAccount;
+import org.xml.sax.SAXException;
+
+/**
+ * Helperclass to create {@link org.apache.lucene.gdata.data.GDataAccount}
+ * instances from a xml stream provided via a {@link Reader} instance.
+ *
+ * @author Simon Willnauer
+ *
+ */
+public class AccountBuilder {
+
+ /**
+ * Reads the xml from the provided reader and binds the values to the
+ * @param reader - the reader to read the xml from
+ * @return - the GDataAccount
+ * @throws IOException - if an IOException occures
+ * @throws SAXException - if the xml can not be parsed by the sax reader
+ */
+ public static GDataAccount buildAccount(final Reader reader) throws IOException,
+ SAXException {
+ if (reader == null)
+ throw new IllegalArgumentException("Reader must not be null");
+ GDataAccount account = null;
+ Digester digester = new Digester();
+ digester.setValidating(false);
+ digester.addObjectCreate("account", GDataAccount.class);
+ digester.addBeanPropertySetter("account/account-name", "name");
+ digester.addBeanPropertySetter("account/password", "password");
+ digester.addBeanPropertySetter("account/account-role", "rolesAsInt");
+ digester.addBeanPropertySetter("account/account-owner/name",
+ "authorname");
+ digester.addBeanPropertySetter("account/account-owner/email-address",
+ "authorMail");
+ digester.addBeanPropertySetter("account/account-owner/url",
+ "authorLink");
+ account = (GDataAccount) digester.parse(reader);
+ return account;
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/administration/AdminService.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/administration/AdminService.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/administration/AdminService.java (revision 0)
@@ -0,0 +1,123 @@
+/**
+ * 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.administration;
+
+import org.apache.lucene.gdata.data.GDataAccount;
+import org.apache.lucene.gdata.data.ServerBaseFeed;
+import org.apache.lucene.gdata.server.Service;
+import org.apache.lucene.gdata.server.ServiceException;
+
+/**
+ * The AdminService interface extends the Service interface to serve common
+ * administrator requests. Common users can not create feed or user instances.
+ * This interface provides all actions for create, delete or update Users and
+ * Feeds. Each Feed has an associated Feed - Name which acts as an ID. Feed will
+ * be identified by the feed name e.g. {@link com.google.gdata.data.Source#getId()}
+ *
User accounts are supposed to have a unique username attribute as the username acts as a primary key for the storage
+ *
+ *
+ * @author Simon Willnauer
+ *
+ */
+public interface AdminService extends Service {
+
+ /**
+ * Creates a new feed instance.
+ *
+ * @param feed -
+ * the feed to create
+ * @param account - the account who own this feed
+ * @throws ServiceException -
+ * if the feed can not be created
+ */
+ public abstract void createFeed(final ServerBaseFeed feed,
+ final GDataAccount account) throws ServiceException;
+
+ /**
+ * Updates the given feed
+ *
+ * @param feed -
+ * the feed to update
+ * @param account - the account who own this feed
+ *
+ * @throws ServiceException -
+ * if the feed can not be updated or does not exist.
+ */
+ public abstract void updateFeed(final ServerBaseFeed feed,
+ final GDataAccount account) throws ServiceException;
+
+ /**
+ * Deletes the given feed and all containing entries from the storage. The feed will not be accessable
+ * anymore.
+ *
+ * @param feed -
+ * the feed to deltete
+ *
+ * @throws ServiceException -
+ * if the feed can not be deleted or does not exist
+ */
+ public abstract void deleteFeed(final ServerBaseFeed feed) throws ServiceException;
+
+ /**
+ * Creates a new account accout.
+ *
+ * @param account -
+ * the account to create
+ * @throws ServiceException -
+ * if the account can not be created or the account does already
+ * exist.
+ */
+ public abstract void createAccount(final GDataAccount account)
+ throws ServiceException;
+
+ /**
+ * Deletes the given account from the storage. it will also delete all
+ * accociated feeds.
+ *
+ * @param account
+ * the account to delete
+ * @throws ServiceException -
+ * if the account does not exist or the account can not be deleted
+ */
+ public abstract void deleteAccount(final GDataAccount account)
+ throws ServiceException;
+
+ /**
+ * Updates the given account if the account already exists.
+ *
+ * @param account - the account to update
+ * @throws ServiceException - if the account can not be updated or the account does not exist
+ */
+ public abstract void updateAccount(final GDataAccount account)
+ throws ServiceException;
+
+ /**
+ * Returns the account for the given account name or null if the account does not exist
+ *
+ * @param account - account name
+ * @return - the account for the given account name or null if the account does not exist
+ * @throws ServiceException - if the account can not be accessed
+ */
+ public abstract GDataAccount getAccount(String account) throws ServiceException;
+
+ /**
+ * Returns the account associated with the feed for the given feed id
+ * @param feedId - the feed id
+ * @return - the GdataAccount assoziated with the feed for the given feed Id or null if there is no feed for the given feed Id
+ * @throws ServiceException - if the storage can not be accessed
+ */
+ public abstract GDataAccount getFeedOwningAccount(String feedId) throws ServiceException;
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/administration/GDataAdminService.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/administration/GDataAdminService.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/administration/GDataAdminService.java (revision 0)
@@ -0,0 +1,195 @@
+/**
+ * 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.administration;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.lucene.gdata.data.GDataAccount;
+import org.apache.lucene.gdata.data.ServerBaseFeed;
+import org.apache.lucene.gdata.server.GDataService;
+import org.apache.lucene.gdata.server.ServiceException;
+import org.apache.lucene.gdata.storage.StorageException;
+
+
+
+/**
+ * default implementation of the {@link org.apache.lucene.gdata.server.administration.AdminService} interface.
+ * @author Simon Willnauer
+ *
+ */
+public class GDataAdminService extends GDataService implements AdminService {
+ private static final Log LOG = LogFactory.getLog(GDataAdminService.class);
+ /**
+ * @throws ServiceException
+ */
+ public GDataAdminService() throws ServiceException {
+ super();
+
+ }
+
+
+
+ /**
+ * @see org.apache.lucene.gdata.server.administration.AdminService#createFeed(org.apache.lucene.gdata.data.ServerBaseFeed, org.apache.lucene.gdata.data.GDataAccount)
+ */
+ public void createFeed(final ServerBaseFeed feed,final GDataAccount account) throws ServiceException {
+ if(feed == null)
+ throw new ServiceException("Can not create feed -- feed is null");
+ if(account == null)
+ throw new ServiceException("Can not create feed -- account is null");
+ if(feed.getId() == null)
+ throw new ServiceException("Feed ID is null can not create feed");
+ if(account.getName() == null)
+ throw new ServiceException("Account name is null -- can't create feed");
+ try {
+ feed.setAccount(account);
+ this.storage.storeFeed(feed,account.getName());
+ } catch (StorageException e) {
+ if(LOG.isInfoEnabled())
+ LOG.info("Can not save feed -- "+e.getMessage(),e);
+ throw new ServiceException("Can not save feed",e);
+ }
+
+ }
+
+
+
+ /**
+ * @see org.apache.lucene.gdata.server.administration.AdminService#updateFeed(org.apache.lucene.gdata.data.ServerBaseFeed, org.apache.lucene.gdata.data.GDataAccount)
+ */
+ public void updateFeed(ServerBaseFeed feed, GDataAccount account) throws ServiceException {
+ if(feed == null)
+ throw new ServiceException("Can not update null feed");
+ if(account == null)
+ throw new ServiceException("Can not update feed -- account is null");
+ if(feed.getId() == null)
+ throw new ServiceException("Feed ID is null can not update feed");
+ if(account.getName() == null)
+ throw new ServiceException("Account name is null -- can't update feed");
+ try {
+ feed.setAccount(account);
+ this.storage.updateFeed(feed,account.getName());
+ } catch (StorageException e) {
+ if(LOG.isInfoEnabled())
+ LOG.info("Can not update feed -- "+e.getMessage(),e);
+ throw new ServiceException("Can not update feed",e);
+ }
+
+ }
+
+
+
+ /**
+ * @see org.apache.lucene.gdata.server.administration.AdminService#deleteFeed(org.apache.lucene.gdata.data.ServerBaseFeed)
+ */
+ public void deleteFeed(ServerBaseFeed feed) throws ServiceException {
+ if(feed == null)
+ throw new ServiceException("Can not delete null feed");
+ if(feed.getId() == null)
+ throw new ServiceException("Feed ID is null can not delete feed");
+ try {
+ this.storage.deleteFeed(feed.getId());
+ } catch (StorageException e) {
+ if(LOG.isInfoEnabled())
+ LOG.info("Can not delete feed -- "+e.getMessage(),e);
+ throw new ServiceException("Can not delete feed",e);
+ }
+
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.administration.AdminService#createAccount(org.apache.lucene.gdata.data.GDataAccount)
+ */
+ public void createAccount(GDataAccount account) throws ServiceException {
+ if(account == null)
+ throw new ServiceException("Can not save null account");
+ try {
+ this.storage.storeAccount(account);
+ } catch (StorageException e) {
+ if(LOG.isInfoEnabled())
+ LOG.info("Can not save account -- "+e.getMessage(),e);
+ throw new ServiceException("Can not save account",e);
+ }
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.administration.AdminService#deleteAccount(org.apache.lucene.gdata.data.GDataAccount)
+ */
+ public void deleteAccount(GDataAccount account) throws ServiceException {
+ if(account == null)
+ throw new ServiceException("Can not delete null account");
+ try {
+ this.storage.deleteAccount(account.getName());
+ } catch (StorageException e) {
+ if(LOG.isInfoEnabled())
+ LOG.info("Can not save account -- "+e.getMessage(),e);
+ throw new ServiceException("Can not save account",e);
+ }
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.administration.AdminService#updateAccount(org.apache.lucene.gdata.data.GDataAccount)
+ */
+ public void updateAccount(GDataAccount account) throws ServiceException {
+ if(account == null)
+ throw new ServiceException("Can not update null account");
+ try {
+ this.storage.updateAccount(account);
+ } catch (StorageException e) {
+ if(LOG.isInfoEnabled())
+ LOG.info("Can not save account -- "+e.getMessage(),e);
+ throw new ServiceException("Can not save account",e);
+ }
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.administration.AdminService#getAccount(java.lang.String)
+ */
+ public GDataAccount getAccount(String accountName)throws ServiceException{
+ if(accountName == null)
+ throw new ServiceException("Can not get null account");
+ try {
+ return this.storage.getAccount(accountName);
+ } catch (StorageException e) {
+ if(LOG.isInfoEnabled())
+ LOG.info("Can not get account -- "+e.getMessage(),e);
+ throw new ServiceException("Can not get account",e);
+ }
+
+ }
+
+
+
+ /**
+ * @see org.apache.lucene.gdata.server.administration.AdminService#getFeedOwningAccount(java.lang.String)
+ */
+ public GDataAccount getFeedOwningAccount(String feedId) throws ServiceException {
+ if(feedId == null)
+ throw new ServiceException("Can not get account - feed id must not be null");
+ try {
+ String accountName = this.storage.getAccountNameForFeedId(feedId);
+ return this.storage.getAccount(accountName);
+
+ } catch (StorageException e) {
+ if(LOG.isInfoEnabled())
+ LOG.info("Can not get account for feed Id -- "+e.getMessage(),e);
+ throw new ServiceException("Can not get account for the given feed id",e);
+ }
+ }
+
+
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/administration/package.html
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/administration/package.html (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/administration/package.html (revision 0)
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+Classes and Services used for user and feed configuration
+
+
\ No newline at end of file
Index: gdata-server/src/java/org/apache/lucene/gdata/server/ServiceFactory.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/ServiceFactory.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/ServiceFactory.java (working copy)
@@ -1,57 +1,92 @@
-/**
- * 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;
-
-
-/**
- * The {@link ServiceFactory} creates {@link Service} implementations to access
- * the GData - Server components.
- *
- * @author Simon Willnauer
- *
- */
-public class ServiceFactory {
-
- private static ServiceFactory INSTANCE = null;
-
- /**
- * @return - a Singleton Instance of the factory
- */
- public static synchronized ServiceFactory getInstance() {
- if (INSTANCE == null)
- INSTANCE = new ServiceFactory();
- return INSTANCE;
-
- }
-
- private ServiceFactory() {
- // private constructor --> singleton
- }
-
- /**
- * Creates a {@link Service} implementation.
- *
- * @return a Service Implementation
- */
- public Service getService() {
- try{
- return new GDataService();
- }catch (Exception e) {
- //
- }
- return null;
- }
-}
+/**
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.gdata.server;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.lucene.gdata.server.administration.AdminService;
+import org.apache.lucene.gdata.server.administration.GDataAdminService;
+import org.apache.lucene.gdata.server.registry.Component;
+import org.apache.lucene.gdata.server.registry.ComponentType;
+import org.apache.lucene.gdata.server.registry.ServerComponent;
+
+
+/**
+ * The {@link ServiceFactory} creates {@link Service} implementations to access
+ * the GData - Server components.
+ * This class should not be access directy. The class will be registered in the {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry}.
+ * Use {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry#lookup(Class, ComponentType)}
+ *
+ * @author Simon Willnauer
+ *
+ */
+@Component(componentType=ComponentType.SERVICEFACTORY)
+public class ServiceFactory implements ServerComponent {
+
+ private static final Log LOG = LogFactory.getLog(ServiceFactory.class);
+
+
+
+ /**
+ * public constructor to enable loading via the registry
+ * @see org.apache.lucene.gdata.server.registry.Component
+ * @see org.apache.lucene.gdata.server.registry.GDataServerRegistry
+ */
+ public ServiceFactory() {
+ //
+ }
+
+ /**
+ * Creates a {@link Service} instance.
+ *
+ * @return a Service instance
+ */
+ public Service getService() {
+ try{
+ return new GDataService();
+ }catch (Exception e) {
+ //
+ }
+ return null;
+ }
+
+ /**
+ * Creates a {@link AdminService} instance
+ * @return a AdminService instance
+ */
+ public AdminService getAdminService(){
+ try {
+ return new GDataAdminService();
+ } catch (ServiceException e) {
+ LOG.warn("Factory method can not create GDataAdminService returning null-- "+e.getMessage(),e);
+ }
+ return null;
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.registry.ServerComponent#initialize()
+ */
+ public void initialize() {
+ //
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.registry.ServerComponent#destroy()
+ */
+ public void destroy() {
+ //
+ }
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/registry/DataBuilderException.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/registry/DataBuilderException.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/registry/DataBuilderException.java (working copy)
@@ -1,62 +0,0 @@
-/**
- * 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;
-
-/**
- * @author Simon Willnauer
- *
- */
-public class DataBuilderException extends RuntimeException {
-
- /**
- *
- */
- private static final long serialVersionUID = -3802958802500735198L;
-
- /**
- *
- */
- public DataBuilderException() {
- super();
- // TODO Auto-generated constructor stub
- }
-
- /**
- * @param message
- */
- public DataBuilderException(String message) {
- super(message);
- // TODO Auto-generated constructor stub
- }
-
- /**
- * @param message
- * @param cause
- */
- public DataBuilderException(String message, Throwable cause) {
- super(message, cause);
- // TODO Auto-generated constructor stub
- }
-
- /**
- * @param cause
- */
- public DataBuilderException(Throwable cause) {
- super(cause);
- // TODO Auto-generated constructor stub
- }
-
-}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryBuilder.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryBuilder.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryBuilder.java (working copy)
@@ -12,30 +12,59 @@
* 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 com.google.gdata.data.ExtensionProfile;
-import com.google.gdata.data.Feed;
-
-/**
- * @author Simon Willnauer
+ */
+package org.apache.lucene.gdata.server.registry;
+
+import java.io.IOException;
+
+import org.apache.commons.digester.Digester;
+import org.xml.sax.SAXException;
+
+/**
+ * Reads the configuration file and creates the
+ * {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry} singleton
+ * instance. All services and components will be instanciated and registered in
+ * the registry.
*
- */
-public class RegistryBuilder {
-
- /**
- *
- */
- public static void buildRegistry(){
- // TODO Implement this!! -- just for develping purposes
- GDataServerRegistry reg = GDataServerRegistry.getRegistry();
- FeedInstanceConfigurator configurator = new FeedInstanceConfigurator();
- configurator.setFeedType(Feed.class);
- configurator.setFeedId("weblog");
- configurator.setExtensionProfileClass(ExtensionProfile.class);
- reg.registerFeed(configurator);
-
- }
-
-}
+ * @author Simon Willnauer
+ *
+ */
+class RegistryBuilder {
+
+ /**
+ * builds the {@link GDataServerRegistry} accessible via the
+ * {@link GDataServerRegistry#getRegistry()} method
+ *
+ * @throws IOException -
+ * if an IOException occures while reading the config file
+ * @throws SAXException -
+ * if the config file can not be parsed
+ */
+ static void buildRegistry() throws IOException, SAXException {
+
+ buildFromConfiguration(new Digester(), GDataServerRegistry
+ .getRegistry());
+
+ }
+
+ private static void buildFromConfiguration(Digester digester,
+ GDataServerRegistry registry) throws IOException, SAXException {
+
+ digester.setValidating(false);
+ digester.push(registry);
+ digester.addCallMethod("gdata/server-components/component",
+ "registerComponent", 0, new Class[] { Class.class });
+ digester.addObjectCreate("gdata/service", ProvidedServiceConfig.class);
+ digester.addSetProperties("gdata/service");
+ digester.addSetNext("gdata/service", "registerService");
+ digester.addBeanPropertySetter("gdata/service/feed-class", "feedType");
+ digester.addBeanPropertySetter("gdata/service/entry-class", "entryType");
+ digester.addBeanPropertySetter("gdata/service/extension-profile",
+ "extensionProfileClass");
+ digester.parse(RegistryBuilder.class
+ .getResourceAsStream("/gdata-config.xml"));
+ }
+
+
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/registry/GDataServerRegistry.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/registry/GDataServerRegistry.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/registry/GDataServerRegistry.java (working copy)
@@ -1,154 +1,254 @@
-/**
- * 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 java.util.HashMap;
-import java.util.Map;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.lucene.gdata.storage.StorageController;
-
-import com.google.gdata.data.ExtensionProfile;
-
-/**
- *
- * The FeedRegistry represents the registry component of the GData Server. All
- * feed configurations will be registered here. Feed configurations contain
- * several informationsa about GData feed like:
- *
- *
the feed id - where the feed can be accessed via http methodes
- *
the feed type - feed types are implementations of the abstract
- * {@link com.google.gdata.data.BaseFeed}
- *
- * The registry will be set up at start up of the server application and can be
- * accessed from other components to get configurations according to incoming
- * requests.
- *
- * @author Simon Willnauer
- *
- */
-public class GDataServerRegistry {
- private static GDataServerRegistry INSTANCE;
-
- private StorageController storageInstance;
-
- private static final Log LOGGER = LogFactory
- .getLog(GDataServerRegistry.class);
-
- private final Map feedTypMap = new HashMap();
-
- private GDataServerRegistry() {
- // private - singleton
- }
-
- /**
- * @return a Sinleton registry instance
- */
- public static synchronized GDataServerRegistry getRegistry() {
- if (INSTANCE == null)
- INSTANCE = new GDataServerRegistry();
- return INSTANCE;
- }
-
- /**
- * Registers a {@link FeedInstanceConfigurator}
- *
- * @param configurator -
- * the configurator to register in the registry
- */
- public void registerFeed(FeedInstanceConfigurator configurator) {
- if (configurator == null) {
- LOGGER.warn("Feedconfigurator is null -- skip registration");
- return;
- }
- this.feedTypMap.put(configurator.getFeedId(), configurator);
- }
-
- /**
- * Looks up the {@link FeedInstanceConfigurator} by the given feed id.
- *
- * @param feedId
- * @return - the {@link FeedInstanceConfigurator} or null if
- * the no configuration for this feed has been registered
- */
- public FeedInstanceConfigurator getFeedConfigurator(String feedId) {
- if (feedId == null)
- throw new IllegalArgumentException(
- "Feed URL is null - must not be null to get registered feedtype");
- return this.feedTypMap.get(feedId);
- }
-
- protected void flushRegistry() {
- this.feedTypMap.clear();
- }
-
- /**
- * @param feedId -
- * the id of the feed as the feed is registered
- * @return - true if and only if the feed is registered,
- * otherwise false.
- */
- public boolean isFeedRegistered(String feedId) {
- return this.feedTypMap.containsKey(feedId);
-
- }
-
- /**
- * @param storage
- */
- public void registerStorage(StorageController storage) {
- if (this.storageInstance != null)
- throw new IllegalStateException(
- "Storage already registered -- Instance of "
- + this.storageInstance.getClass());
- this.storageInstance = storage;
- }
-
- /**
- * Destroys the registry and release all resources
- */
- public void destroy() {
- flushRegistry();
- this.storageInstance.destroy();
- this.storageInstance = null;
-
- }
-
- /**
- * Creates the {@link ExtensionProfile} for a registered feed
- * @param feedId - the feed id
- * @return - the extension profil for this feed of null if
- * the feed is not registered or the extension profile could not be
- * instanciated
- */
- public ExtensionProfile getExtensionProfile(final String feedId) {
- FeedInstanceConfigurator configurator = this.feedTypMap.get(feedId);
- if (configurator == null)
- return null;
- Class clazz = configurator.getExtensionProfilClass();
- try {
- return (ExtensionProfile) clazz.newInstance();
- } catch (Exception e) {
- LOGGER
- .error("Can not create instance of ExtensionProfil for class: "
- + clazz + " -- feedId: " + feedId);
-
- }
- return null;
- }
-
-}
+/**
+ * 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 java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+/**
+ *
+ * The GDataServerRegistry represents the registry component of the GData
+ * Server. All provided services and server components will be registered here.
+ * The Gdata Server serves RSS / ATOM feeds for defined services. Each service
+ * provides n feeds of a defined subclass of
+ * {@link com.google.gdata.data.BaseFeed}. Each feed contains m entries
+ * of a defined subclass of {@link com.google.gdata.data.BaseEntry}. To
+ * generate RSS / ATOM formates a class of the type
+ * {@link com.google.gdata.data.ExtensionProfile} is also defined for a service.
+ *
+ * The entry,feed and the ExtensionProfile classes are defined in the
+ * gdata-config.xml and will be loaded when the server starts up.
+ *
+ *
+ * The components defined in the gdata-config.xml will also be loaded and
+ * instanciated at startup. If a component can not be loaded or an Exception
+ * occures the server will not start up. To cause of the exception or error will
+ * be logged to the standart server output.
+ *
+ *
The GDataServerRegistry is a Singleton
+ *
+ *
+ * @author Simon Willnauer
+ *
+ */
+public class GDataServerRegistry {
+ private static GDataServerRegistry INSTANCE;
+
+ private static final Log LOGGER = LogFactory
+ .getLog(GDataServerRegistry.class);
+
+ private final Map serviceTypeMap = new HashMap();
+
+ private final Map componentMap = new HashMap(
+ 10);
+
+ private GDataServerRegistry() {
+ // private - singleton
+ }
+
+ /**
+ * @return a Sinleton registry instance
+ */
+ public static synchronized GDataServerRegistry getRegistry() {
+ if (INSTANCE == null)
+ INSTANCE = new GDataServerRegistry();
+ return INSTANCE;
+ }
+
+ /**
+ * Registers a {@link ProvidedService}
+ *
+ * @param configurator -
+ * the configurator to register in the registry
+ */
+ public void registerService(ProvidedService configurator) {
+ if (configurator == null) {
+ LOGGER.warn("Feedconfigurator is null -- skip registration");
+ return;
+ }
+ this.serviceTypeMap.put(configurator.getName(), configurator);
+ }
+
+ /**
+ * Looks up the {@link ProvidedServiceConfig} by the given service name.
+ *
+ * @param service
+ * @return - the {@link ProvidedServiceConfig} or null if the
+ * no configuration for this service has been registered
+ */
+ public ProvidedService getProvidedService(String service) {
+ if (service == null)
+ throw new IllegalArgumentException(
+ "Service is null - must not be null to get registered feedtype");
+ return this.serviceTypeMap.get(service);
+ }
+
+ protected void flushRegistry() {
+ this.serviceTypeMap.clear();
+ this.componentMap.clear();
+ }
+
+ /**
+ * @param service -
+ * the name of the service
+ * @return - true if and only if the service is registered,
+ * otherwise false.
+ */
+ public boolean isServiceRegistered(String service) {
+ return this.serviceTypeMap.containsKey(service);
+
+ }
+
+ /**
+ * Destroys the registry and release all resources
+ */
+ public void destroy() {
+ for (ComponentBean component : this.componentMap.values()) {
+ component.getObject().destroy();
+ }
+ flushRegistry();
+
+ }
+
+ /**
+ * This method is the main interface to the Component Lookup Service of the
+ * registry. Every GDATA - Server component like STORAGE or the INDEXER
+ * component will be accessible via this method. To get a Component from the
+ * lookup service specify the expected Class as an argument and the
+ * component type of the component to return. For a lookup of the
+ * STORAGECONTORLER the code looks like:
+ *
+ *
+ * @param
+ * the type of the expected return value
+ * @param clazz -
+ * Class object of the expected return value
+ * @param compType -
+ * The component type
+ * @return the registered component or null if the component
+ * can not looked up.
+ */
+ @SuppressWarnings("unchecked")
+ public R lookup(Class clazz, ComponentType compType) {
+ ComponentBean bean = this.componentMap.get(compType);
+ if (bean == null)
+ return null;
+ if (bean.getSuperType().equals(clazz))
+ return (R) bean.getObject();
+ return null;
+ }
+
+ /**
+ * @param
+ * @param componentClass
+ * @throws RegistryException
+ */
+ @SuppressWarnings("unchecked")
+ public void registerComponent(final Class componentClass)
+ throws RegistryException {
+
+ if (componentClass == null)
+ throw new IllegalArgumentException(
+ "component class must not be null");
+
+ if(!checkImplementsServerComponent(componentClass))
+ throw new RegistryException("can not register component. the given class does not implement ServerComponent interface -- "+componentClass.getName());
+ try {
+
+ Component annotation = componentClass.getAnnotation(Component.class);
+ if (annotation == null)
+ throw new RegistryException(
+ "can not register component. the given class is not a component -- "
+ + componentClass.getName());
+ ComponentType type = annotation.componentType();
+ if (this.componentMap.containsKey(type))
+ throw new RegistryException("component already registered -- "
+ + type.name());
+ Class superType = type.getClass().getField(type.name())
+ .getAnnotation(SuperType.class).superType();
+ if (!checkSuperType(componentClass, superType))
+ throw new RegistryException("Considered Supertype <"
+ + superType.getName() + "> is not a super type of <"
+ + componentClass + ">");
+ ServerComponent comp = componentClass.newInstance();
+ comp.initialize();
+ ComponentBean bean = new ComponentBean(comp, superType);
+
+ this.componentMap.put(type, bean);
+
+ } catch (Exception e) {
+ throw new RegistryException("Can not register component -- "
+ + e.getMessage(), e);
+ }
+
+ }
+
+ private static boolean checkImplementsServerComponent(Class type){
+ if(type == null)
+ return false;
+ if(type.equals(Object.class))
+ return false;
+ if(type.equals(ServerComponent.class))
+ return true;
+ Class[] compInterfaces = type.getInterfaces();
+ for (int i = 0; i < compInterfaces.length; i++) {
+ if(checkImplementsServerComponent(compInterfaces[i]))
+ return true;
+ }
+ return checkImplementsServerComponent(type.getSuperclass());
+
+ }
+
+ private static boolean checkSuperType(Class type, Class consideredSuperType) {
+
+ if (type.equals(Object.class))
+ return false;
+ if (type.equals(consideredSuperType))
+ return true;
+ Class[] interfaces = type.getInterfaces();
+ for (int i = 0; i < interfaces.length; i++) {
+ if (interfaces[i].equals(consideredSuperType))
+ return true;
+ }
+ return checkSuperType(type.getSuperclass(), consideredSuperType);
+ }
+
+ private class ComponentBean {
+ private final Class superType;
+
+ private final ServerComponent object;
+
+ ComponentBean(final ServerComponent object, final Class superType) {
+ this.superType = superType;
+ this.object = object;
+ }
+
+ ServerComponent getObject() {
+ return this.object;
+ }
+
+ Class getSuperType() {
+ return this.superType;
+ }
+
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/registry/SuperType.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/registry/SuperType.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/registry/SuperType.java (revision 0)
@@ -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.server.registry;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * This Annotation is use to annotate
+ * {@link org.apache.lucene.gdata.server.registry.ComponentType} elements to
+ * specify an interface e.g. super type of a defined component.
+ *
This annotation will be visible at runtime
+ * @see org.apache.lucene.gdata.server.registry.Component
+ * @see org.apache.lucene.gdata.server.registry.GDataServerRegistry
+ *
+ * @author Simon Willnauer
+ *
+ */
+@Target( { FIELD })
+@Retention(value = RUNTIME)
+public @interface SuperType {
+ /**
+ *
+ * @return the specified super type
+ */
+ Class superType();
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/registry/Component.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/registry/Component.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/registry/Component.java (revision 0)
@@ -0,0 +1,74 @@
+/**
+ * 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 static java.lang.annotation.ElementType.TYPE;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * The {@link Component} annotation is used to annotate a class as a
+ * server-component of the GDATA-Server. Annotated class can be configured via
+ * the gdata-config.xml file to be looked up by aribaty classes at runtime via
+ * the
+ * {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry#lookup(Class, ComponentType)}
+ * method.
+ *
+ * Classes annotated with the Component annotation need to provide a default
+ * constructor to be instanciated via reflection. Components of the GData-Server
+ * are definded in the
+ * {@link org.apache.lucene.gdata.server.registry.ComponentType} enumeration.
+ * Each of the enum types are annotated with a
+ * {@link org.apache.lucene.gdata.server.registry.SuperType} annotation. This
+ * annotation specifies the super class or interface of the component. A class
+ * annotated with the Component annotation must implement or extends this
+ * defined super-type. This enables developers to use custom implemetations of
+ * the component like a custom {@link org.apache.lucene.gdata.storage.Storage}.
+ *
+ *
+ * Each ComponentType can only registerd once as the
+ * {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry} does not
+ * provide multipe instances of a ComponentType.
+ *
+ *
+ * This annotation can only annotate types and can be accessed at runtime.
+ * {@link java.lang.annotation.Target} ==
+ * {@link java.lang.annotation.ElementType#TYPE} and
+ * {@link java.lang.annotation.Retention} ==
+ * {@link java.lang.annotation.RetentionPolicy#RUNTIME}.
+ *
+ * @see org.apache.lucene.gdata.server.registry.GDataServerRegistry
+ * @see org.apache.lucene.gdata.server.registry.ComponentType
+ * @see org.apache.lucene.gdata.server.registry.SuperType
+ *
+ *
+ * @author Simon Willnauer
+ *
+ */
+@Target( { TYPE })
+@Retention(value = RUNTIME)
+public @interface Component {
+
+ /**
+ * @see ComponentType
+ * @return - the component type
+ */
+ ComponentType componentType();
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/registry/ProvidedServiceConfig.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/registry/ProvidedServiceConfig.java (revision 413530)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/registry/ProvidedServiceConfig.java (working copy)
@@ -12,55 +12,120 @@
* 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;
-
-/**
- * @author Simon Willnauer
+ */
+package org.apache.lucene.gdata.server.registry;
+
+import com.google.gdata.data.ExtensionProfile;
+
+/**
+ * Standart implementation of
+ * {@link org.apache.lucene.gdata.server.registry.ProvidedService} to be used
+ * inside the
+ * {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry}
*
- */
-public class FeedInstanceConfigurator {
- private Class feedType;
- private String feedId;
- private Class extensionProfileClass;
- /**
- * @return Returns the feedType.
- */
- public Class getFeedType() {
- return this.feedType;
- }
- /**
- * @param feedType The feedType to set.
- */
- public void setFeedType(Class feedType) {
- this.feedType = feedType;
- }
- /**
- * @return Returns the feedURL.
- */
- public String getFeedId() {
- return this.feedId;
- }
- /**
- * @param feedURL The feedURL to set.
- */
- public void setFeedId(String feedURL) {
- this.feedId = feedURL;
- }
-
- /**
- * @return - the extension profile for this feed
- */
- public Class getExtensionProfilClass(){
- return this.extensionProfileClass;
- }
-
- /**
- * @param extensionProfilClass
- */
- public void setExtensionProfileClass(Class extensionProfilClass){
- this.extensionProfileClass = extensionProfilClass;
- }
-
-
-}
+ * @author Simon Willnauer
+ *
+ */
+public class ProvidedServiceConfig implements ProvidedService {
+ private String serviceName;
+
+ private Class entryType;
+
+ private Class feedType;
+
+ private ExtensionProfile extensionProfile;
+
+
+ ProvidedServiceConfig(ExtensionProfile profile, Class feedType,
+ Class entryType, String serviceName) {
+ this.extensionProfile = profile;
+ this.feedType = feedType;
+ this.entryType = entryType;
+ this.serviceName = serviceName;
+
+ }
+
+ /**
+ * Default constructor to instanciate via reflection
+ */
+ public ProvidedServiceConfig() {
+ //
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.registry.ProvidedService#getFeedType()
+ */
+ public Class getFeedType() {
+ return this.feedType;
+ }
+
+ /**
+ * @param feedType
+ * The feedType to set.
+ */
+ public void setFeedType(Class feedType) {
+ this.feedType = feedType;
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.registry.ProvidedService#getExtensionProfile()
+ */
+ public ExtensionProfile getExtensionProfile() {
+ return this.extensionProfile;
+ }
+
+ /**
+ * @param extensionProfil -
+ * the extensionprofile for this feed configuration
+ */
+ public void setExtensionProfile(ExtensionProfile extensionProfil) {
+ this.extensionProfile = extensionProfil;
+ }
+
+
+ /**
+ *TODO add comment
+ * @param
+ * @param extensionProfileClass
+ * @throws InstantiationException
+ * @throws IllegalAccessException
+ */
+ public void setExtensionProfileClass(
+ Class extensionProfileClass) throws InstantiationException,
+ IllegalAccessException {
+ if (extensionProfileClass == null)
+ throw new IllegalArgumentException(
+ "ExtensionProfile class must not be null");
+
+ this.extensionProfile = extensionProfileClass.newInstance();
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.registry.ProvidedService#getEntryType()
+ */
+ public Class getEntryType() {
+ return this.entryType;
+ }
+
+ /**
+ * @param entryType
+ */
+ public void setEntryType(Class entryType) {
+ this.entryType = entryType;
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.registry.ProvidedService#getName()
+ */
+ public String getName() {
+ return this.serviceName;
+ }
+
+ /**
+ * @param serviceName
+ */
+ public void setName(String serviceName) {
+ this.serviceName = serviceName;
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryContextListener.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryContextListener.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryContextListener.java (working copy)
@@ -1,65 +1,80 @@
-/**
- * Copyright 2004 The Apache Software Foundation
+/**
+ * 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.
+ *
+ * This ContextListener has to be configured in the web.xml
+ * deployment descriptor.
+ *
+ *
+ * When the
+ * {@link javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)}
+ * method is called the registry will be destroyed using
+ * {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry#destroy()}
+ * method.
*
- * 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
+ * @author Simon Willnauer
*
- * 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.
- *
- * This ContextListener has to be configured in the web.xml
- * deployment descriptor.
- *
- *
- * @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();
-
- }
-
-}
+ */
+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");
+
+ try {
+ RegistryBuilder.buildRegistry();
+ this.serverRegistry = GDataServerRegistry.getRegistry();
+ } catch (Exception e) {
+ this.serverRegistry.destroy();
+ LOG.error("can not register requiered components", e);
+ throw new RuntimeException("Can not register required components",
+ e);
+ }
+
+
+ }
+
+ /**
+ * @see javax.servlet.ServletContextListener#contextDestroyed(javax.servlet.ServletContextEvent)
+ */
+ public void contextDestroyed(ServletContextEvent arg0) {
+ LOG.info("Destroying context");
+ this.serverRegistry.destroy();
+
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/registry/ComponentType.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/registry/ComponentType.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/registry/ComponentType.java (revision 0)
@@ -0,0 +1,53 @@
+package org.apache.lucene.gdata.server.registry;
+
+import org.apache.lucene.gdata.server.ServiceFactory;
+import org.apache.lucene.gdata.server.authentication.AuthenticationController;
+import org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory;
+import org.apache.lucene.gdata.storage.StorageController;
+
+/**
+ * The enmueration {@link ComponentType} defines the GDATA-Server Components
+ * available via {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry#lookup(Class, ComponentType)}
+ * method.
+ * @see org.apache.lucene.gdata.server.registry.Component
+ * @see org.apache.lucene.gdata.server.registry.GDataServerRegistry
+ * @author Simon Willnauer
+ *
+ */
+public enum ComponentType {
+ /**
+ * StorageController Type
+ *
+ * @see StorageController
+ */
+ @SuperType(superType = StorageController.class)
+ STORAGECONTROLLER,
+ /**
+ * RequestHandlerFactory Type
+ *
+ * @see RequestHandlerFactory
+ */
+ @SuperType(superType = RequestHandlerFactory.class)
+ REQUESTHANDLERFACTORY,
+ /**
+ * INDEXER TYPE
+ *
+ */
+ // TODO not available yet
+ @SuperType(superType = Object.class)
+ INDEXER,
+ /**
+ * ServiceFactory Type
+ *
+ * @see ServiceFactory
+ */
+ @SuperType(superType = ServiceFactory.class)
+ SERVICEFACTORY,
+ /**
+ * Supertype for AuthenticationController implementations
+ * @see AuthenticationController
+ */
+ @SuperType(superType = AuthenticationController.class)
+ AUTHENTICATIONCONTROLLER
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryException.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryException.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryException.java (revision 0)
@@ -0,0 +1,51 @@
+package org.apache.lucene.gdata.server.registry;
+
+/**
+ * This exception is thrown by the
+ * {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry} if
+ * registering a service or a component fails.
+ *
+ * @author Simon Willnauer
+ *
+ */
+public class RegistryException extends Exception {
+
+
+ private static final long serialVersionUID = -3563720639871194466L;
+
+ /**
+ * Constructs a new Registry Exception.
+ */
+ public RegistryException() {
+ super();
+
+ }
+
+ /**
+ * Constructs a new Registry Exception with the specified detail message.
+ * @param arg0 - detail message
+ */
+ public RegistryException(String arg0) {
+ super(arg0);
+
+ }
+
+ /**
+ * Constructs a new Registry Exception with the specified detail message and nested exception.
+ * @param arg0 - detail message
+ * @param arg1 - nested exception
+ */
+ public RegistryException(String arg0, Throwable arg1) {
+ super(arg0, arg1);
+
+ }
+
+ /** Constructs a new Registry Exception with a nested exception.
+ * @param arg0 - nested exception
+ */
+ public RegistryException(Throwable arg0) {
+ super(arg0);
+
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/registry/ServerComponent.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/registry/ServerComponent.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/registry/ServerComponent.java (revision 0)
@@ -0,0 +1,42 @@
+/**
+ * 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;
+
+/**
+ * To Register a class as a component in the
+ * {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry} the class
+ * or a super class must implements this interface.
+ *
+ * ServerComponent defines a method initialize and
+ * destroy. initialize will be called when the component
+ * is registered and destroy when the registry is destroyed (usually
+ * at server shut down).
+ * @see org.apache.lucene.gdata.server.registry.GDataServerRegistry
+ * @author Simon Willnauer
+ *
+ */
+public interface ServerComponent {
+ /**
+ * will be call when the component is registered.
+ */
+ public abstract void initialize();
+
+ /**
+ * will be called when the registry is going down e.g. when the {@link GDataServerRegistry#destroy()} method is called.
+ */
+ public abstract void destroy();
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/registry/FeedInstanceConfigurator.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/registry/FeedInstanceConfigurator.java (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/registry/FeedInstanceConfigurator.java (working copy)
@@ -1,66 +0,0 @@
-/**
- * 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;
-
-/**
- * @author Simon Willnauer
- *
- */
-public class FeedInstanceConfigurator {
- private Class feedType;
- private String feedId;
- private Class extensionProfileClass;
- /**
- * @return Returns the feedType.
- */
- public Class getFeedType() {
- return this.feedType;
- }
- /**
- * @param feedType The feedType to set.
- */
- public void setFeedType(Class feedType) {
- this.feedType = feedType;
- }
- /**
- * @return Returns the feedURL.
- */
- public String getFeedId() {
- return this.feedId;
- }
- /**
- * @param feedURL The feedURL to set.
- */
- public void setFeedId(String feedURL) {
- this.feedId = feedURL;
- }
-
- /**
- * @return - the extension profile for this feed
- */
- public Class getExtensionProfilClass(){
- return this.extensionProfileClass;
- }
-
- /**
- * @param extensionProfilClass
- */
- public void setExtensionProfileClass(Class extensionProfilClass){
- this.extensionProfileClass = extensionProfilClass;
- }
-
-
-}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/registry/ProvidedService.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/registry/ProvidedService.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/registry/ProvidedService.java (revision 0)
@@ -0,0 +1,48 @@
+/**
+ * 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 com.google.gdata.data.ExtensionProfile;
+
+/**
+ * This interface describes a service provided by the GData-Server.
+ * @see org.apache.lucene.gdata.server.registry.GDataServerRegistry
+ * @author Simon Willnauer
+ *
+ */
+public interface ProvidedService {
+
+ /**
+ * @return Returns the feedType.
+ */
+ public abstract Class getFeedType();
+
+ /**
+ * @return - the extension profile for this feed
+ */
+ public abstract ExtensionProfile getExtensionProfile();
+
+ /**
+ * @return the entry Type configured for this Service
+ */
+ public abstract Class getEntryType();
+
+ /**
+ * @return - the servicename
+ */
+ public abstract String getName();
+
+}
\ No newline at end of file
Index: gdata-server/src/java/org/apache/lucene/gdata/server/registry/package.html
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/registry/package.html (revision 417093)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/registry/package.html (working copy)
@@ -5,6 +5,6 @@
-Internal registry - registering feeds and configurations
+Internal registry - registering services and server components