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/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/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/DefaultDeleteHandler.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultDeleteHandler.java (revision 415964)
+++ gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultDeleteHandler.java (working copy)
@@ -1,84 +1,84 @@
-/**
- * Copyright 2004 The Apache Software Foundation
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.apache.lucene.gdata.servlet.handler;
-
-import java.io.IOException;
-
-import javax.servlet.ServletException;
-import javax.servlet.http.HttpServletRequest;
-import javax.servlet.http.HttpServletResponse;
-
-import org.apache.commons.logging.Log;
-import org.apache.commons.logging.LogFactory;
-import org.apache.lucene.gdata.server.FeedNotFoundException;
-import org.apache.lucene.gdata.server.GDataRequestException;
-import org.apache.lucene.gdata.server.Service;
-import org.apache.lucene.gdata.server.ServiceException;
-import org.apache.lucene.gdata.server.GDataRequest.GDataRequestType;
-
-/**
- * Default Handler implementation. This handler processes the incoming
- * {@link org.apache.lucene.gdata.server.GDataRequest} and deletes the requested
- * feed entry from the storage and the search component.
- * - * The handler sends following response to the client: - *
- *+ * The handler sends following response to the client: + *
+ *+ * The handler sends following response to the client: + *
+ *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: - *
- *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); + setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + 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 415964) +++ 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/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/RequestHandlerFactory.java =================================================================== --- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/RequestHandlerFactory.java (revision 415964) +++ 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/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/DefaultGetHandler.java =================================================================== --- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultGetHandler.java (revision 415964) +++ gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultGetHandler.java (working copy) @@ -1,104 +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.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. + *
* - * 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 { + 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); + if(entry == null){ + this.feedResponse.setError(HttpServletResponse.SC_NOT_FOUND); + sendError(); + } + this.feedResponse.sendResponse(entry, this.feedRequest.getConfigurator().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(); + } + closeService(); + + + } + + + +} 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/DefaultRequestHandlerFactory.java =================================================================== --- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultRequestHandlerFactory.java (revision 415964) +++ 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/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 415964) +++ gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultUpdateHandler.java (working copy) @@ -1,94 +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.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: - *
- *+ * The handler sends following response to the client: + *
+ *+ * 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 ReferenceCounternull 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 {
+ 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 415964)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageModifier.java (working copy)
@@ -1,236 +1,442 @@
-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.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 Listtrue if the storage is supposed to keep the
- * recovering files.
- */
- public boolean isKeepRecoveredFiles() {
- return this.keepRecoveredFiles;
- }
-
- /**
- * @return true if the storage is supposed to use recovering.
- * @see org.apache.lucene.gdata.storage.lucenestorage.StorageModifier
- */
- public boolean isRecover() {
- return this.recover;
- }
-
- /**
- * @return - the configured storage buffer size
- * @see org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer
- */
- public int getStorageBufferSize() {
- return this.storageBufferSize;
- }
-
- /**
- * @return - the configured storage directory
- * @see org.apache.lucene.gdata.storage.lucenestorage.StorageModifier
- */
- public String getStorageDirectory() {
- return this.storageDirectory;
- }
-
- /**
- * @return - the persist factor
- * @see org.apache.lucene.gdata.storage.lucenestorage.StorageModifier
- */
- public int getStoragepersistFactor() {
- return this.storagepersistFactor;
- }
-
- protected class StorageConfigurationError extends Error {
-
- /**
- *
- */
- private static final long serialVersionUID = 5261674332036111464L;
-
- protected StorageConfigurationError(String arg0, Throwable arg1) {
- super(arg0, arg1);
-
- }
-
- }
-
- /**
- * @return - the optimize interval
- * @see org.apache.lucene.gdata.storage.lucenestorage.StorageModifier
- */
- public int getIndexOptimizeInterval() {
-
- return this.indexOptimizeInterval;
- }
-
-}
+ */
+public class StorageConfigurator {
+ private final int storageBufferSize;
+
+ private final int storagepersistFactor;
+
+ private final String storageDirectory;
+
+ private final boolean keepRecoveredFiles;
+
+ private final boolean recover;
+
+ private final boolean ramDirectory;
+
+ private static StorageConfigurator INSTANCE = null;
+
+ private final int indexOptimizeInterval;
+
+ private StorageConfigurator() {
+ InputStream stream = StorageConfigurator.class
+ .getResourceAsStream("/lucenestorage.properties.xml");
+ Properties properties = new Properties();
+ try {
+ properties.loadFromXML(stream);
+
+ } catch (Exception e) {
+ throw new StorageConfigurationError("Could not load properties", e);
+ }
+ this.storageBufferSize = Integer.parseInt(properties
+ .getProperty("gdata.server.storage.lucene.buffersize"));
+ this.storagepersistFactor = Integer.parseInt(properties
+ .getProperty("gdata.server.storage.lucene.persistFactor"));
+ this.recover = Boolean.parseBoolean(properties
+ .getProperty("gdata.server.storage.lucene.recover"));
+ this.ramDirectory = Boolean.parseBoolean(properties
+ .getProperty("gdata.server.storage.lucene.directory.ramDirectory"));
+ this.keepRecoveredFiles = Boolean.parseBoolean(properties
+ .getProperty("gdata.server.storage.lucene.recover.keepFiles"));
+ this.storageDirectory = properties
+ .getProperty("gdata.server.storage.lucene.directory");
+ this.indexOptimizeInterval = Integer.parseInt(properties
+ .getProperty("gdata.server.storage.lucene.optimizeInterval"));
+
+ }
+
+ /**
+ * @return - the storage configurator
+ */
+ public static synchronized StorageConfigurator getStorageConfigurator() {
+ if (INSTANCE == null)
+ INSTANCE = new StorageConfigurator();
+ return INSTANCE;
+ }
+
+ /**
+ * Keep recovering files. -- will use a lot of disk space
+ *
+ * @return true if the storage is supposed to keep the
+ * recovering files.
+ */
+ public boolean isKeepRecoveredFiles() {
+ return this.keepRecoveredFiles;
+ }
+
+ /**
+ * @return true if the storage is supposed to use recovering.
+ * @see org.apache.lucene.gdata.storage.lucenestorage.StorageModifier
+ */
+ public boolean isRecover() {
+ return this.recover;
+ }
+
+ /**
+ * @return - the configured storage buffer size
+ * @see org.apache.lucene.gdata.storage.lucenestorage.StorageBuffer
+ */
+ public int getStorageBufferSize() {
+ return this.storageBufferSize;
+ }
+
+ /**
+ * @return - the configured storage directory
+ * @see org.apache.lucene.gdata.storage.lucenestorage.StorageModifier
+ */
+ public String getStorageDirectory() {
+ return this.storageDirectory;
+ }
+
+ /**
+ * @return - the persist factor
+ * @see org.apache.lucene.gdata.storage.lucenestorage.StorageModifier
+ */
+ public int getStoragepersistFactor() {
+ return this.storagepersistFactor;
+ }
+
+ protected class StorageConfigurationError extends Error {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = 5261674332036111464L;
+
+ protected StorageConfigurationError(String arg0, Throwable arg1) {
+ super(arg0, arg1);
+
+ }
+
+ }
+
+ /**
+ * @return - the optimize interval
+ * @see org.apache.lucene.gdata.storage.lucenestorage.StorageModifier
+ */
+ public int getIndexOptimizeInterval() {
+
+ return this.indexOptimizeInterval;
+ }
+
+ /**
+ * @return true if the used directory is a ramdirectory, otherwise false
+ */
+ 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,99 @@
+/**
+ * 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 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 415964)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageImplementation.java (working copy)
@@ -1,259 +1,468 @@
-/**
- * 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.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.
- */
+ * @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();
+ modifier.deleteEntry(entry.getId(),entry.getFeedId());
+ }
+
+
-package org.apache.lucene.gdata.storage.lucenestorage;
+ /**
+ * @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 (LOG.isInfoEnabled())
+ LOG.info("update entry " + entry.getId() + " -- feed: " + entry.getFeedId());
+ StorageModifier modifier = this.controller.getStorageModifier();
+
+ try {
+ StorageEntryWrapper wrapper = new StorageEntryWrapper(entry,
+ StorageOperation.UPDATE);
+ modifier.updateEntry(wrapper);
+ } 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- * 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- * 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- * 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} ornull 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+ * 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+ * 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 { + Hits feedHits = storageFeedQuery(feedId); + if(feedHits.length() == 0) + return null; + BaseFeed retVal = buildFeedFromLuceneDocument(feedHits.doc(0),config); + + List+ * 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} ornull 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 Listnull 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);
+
+ }
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/util/ReferenceCounter.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/util/ReferenceCounter.java (revision 415964)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/util/ReferenceCounter.java (working copy)
@@ -72,6 +72,8 @@
*/
public final Type get() {
return this.resource;
- }
+ }
+
+
}
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 415964)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageBuffer.java (working copy)
@@ -20,6 +20,7 @@
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.concurrent.locks.Lock;
@@ -29,6 +30,10 @@
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;
/**
* The StorageBuffer is used to buffer incoming updates, deletes and inserts to
@@ -245,5 +250,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 415964)
+++ 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/Storage.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/Storage.java (revision 415964)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/Storage.java (working copy)
@@ -12,89 +12,228 @@
* 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+ * 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; + +} Index: gdata-server/src/java/org/apache/lucene/gdata/storage/StorageController.java =================================================================== --- gdata-server/src/java/org/apache/lucene/gdata/storage/StorageController.java (revision 415964) +++ 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 415964) +++ 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 415964) +++ gdata-server/src/java/org/apache/lucene/gdata/server/GDataResponse.java (working copy) @@ -67,7 +67,8 @@ 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("", @@ -83,7 +84,7 @@ if (response == null) throw new IllegalArgumentException("response must not be null"); this.response = response; - this.response.setContentType("text/xml"); + } /** @@ -145,10 +146,13 @@ throw new IllegalArgumentException("extension profil must not be null"); XmlWriter writer = createWriter(); - if (this.outputFormat.equals(OutputFormat.ATOM)) + if (this.outputFormat.equals(OutputFormat.ATOM)){ + this.response.setContentType(XMLMIME_ATOM); feed.generateAtom(writer, profile); - else - feed.generateRss(writer, profile); + }else{ + this.response.setContentType(XMLMIME_RSS); + feed.generateRss(writer, profile); + } } Index: gdata-server/src/java/org/apache/lucene/gdata/server/ServiceException.java =================================================================== --- gdata-server/src/java/org/apache/lucene/gdata/server/ServiceException.java (revision 415964) +++ 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
+ *
+ * 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
+ *
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 + * + * @returntrue 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 415964)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/Service.java (working copy)
@@ -39,7 +39,7 @@
*
*
*/
-public abstract class Service {
+public interface Service {
/**
* Service method to create an entry in an already created and existing
@@ -133,6 +133,10 @@
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();
Index: gdata-server/src/java/org/apache/lucene/gdata/server/GDataService.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/GDataService.java (revision 415964)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/GDataService.java (working copy)
@@ -1,275 +1,317 @@
-/**
- * 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.List;
+
+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.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.
+ * @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.server;
+ */
+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);
+ entry.setFeedId(request.getFeedId());
+ entry.setServiceConfig(request.getConfigurator());
+ setTimeStamps(entry.getEntry());
+ BaseEntry retVal = null;
+ try {
+
+ retVal = this.storage.storeEntry(entry);
+ } catch (Exception e) {
+ 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());
+
+ try {
+ this.storage.deleteEntry(entry);
+ } 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)
+ */
+
+ public BaseEntry updateEntry(GDataRequest request, GDataResponse response)
+ throws ServiceException {
+
+
+ ServerBaseEntry entry = buildEntry(request);
+ entry.setFeedId(request.getFeedId());
+ entry.setServiceConfig(request.getConfigurator());
+ if (LOGGER.isInfoEnabled())
+ LOGGER.info("update Entry" + entry.getId() + " for feedId: "
+ + request.getFeedId());
+ setTimeStamps(entry.getEntry());
+ BaseEntry retVal = null;
+ try {
+ retVal = this.storage.updateEntry(entry);
+ } catch (StorageException e) {
+ 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")
-import java.io.IOException;
-import java.util.List;
+ 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;
+ } catch (StorageException e) {
+ 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)
+ throws ServiceException {
+ try {
+ ServerBaseEntry entry = new ServerBaseEntry(GDataEntityBuilder.buildEntry(request));
+ return entry;
+
+ } 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;
+ }
+ }
+
+
+
+ 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)
+ */
-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- * 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 ornull 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,191 @@
+/**
+ * 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 null feed");
+ 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(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 415964)
+++ 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 415964)
+++ 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 415964)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryBuilder.java (working copy)
@@ -12,30 +12,66 @@
* 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.apache.lucene.gdata.data.ServerBaseFeed;
+import org.apache.lucene.gdata.storage.Storage;
+import org.apache.lucene.gdata.storage.StorageController;
+import org.xml.sax.SAXException;
+
+import com.google.gdata.data.DateTime;
+import com.google.gdata.data.Person;
+import com.google.gdata.data.PlainTextConstruct;
+
+/**
+ * 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 415964)
+++ 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:
- * 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 Mapnull 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:
+ *
+ * registryInstance.lookup(StorageController.class,ComponentType.STORAGECONTROLLER);
+ *
null if the component
+ * can not looked up.
+ */
+ @SuppressWarnings("unchecked")
+ public 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,113 @@
* 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;
+ }
+
+
+ public
+ * This ContextListener has to be configured in the
+ * 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
+ * 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).web.xml
+ * deployment descriptor.
+ * web.xml
- * deployment descriptor.