+ * As the creation of SimpleDateFormat objects is quiet expensive and + * formating dates is used quiet fequently the objects will be cached and reused + * in subsequent calls. + *
+ *+ * This implementation is thread safe as it uses {@link java.util.Stack} as a + * cache + *
+ * + * @author Simon Willnauer + * + */ +public class DateFormater { + private final Stack+ * For request handler handling common requests like entry insert or update the + * authentication will be based on the account name verified as the owner of the + * feed to alter. If the accountname in the token does not match the name of the + * account which belongs to the feed the given role will be used for + * autentication. Authentication using the + * {@link RequestAuthenticator#authenticateAccount(HttpServletRequest, AccountRole)} + * method, the account name will be ignored, authentication will be based on the + * given AccountRole + *
+ * + * @author Simon Willnauer + * + */ +public class RequestAuthenticator implements GDataHttpAuthenticator { + private static final Log LOG = LogFactory + .getLog(RequestAuthenticator.class); + + /** + * @see org.apache.lucene.gdata.server.authentication.GDataHttpAuthenticator#authenticateAccount(org.apache.lucene.gdata.server.GDataRequest, + * org.apache.lucene.gdata.data.GDataAccount.AccountRole) + */ + public boolean authenticateAccount(GDataRequest request, AccountRole role) { + String clientIp = request.getRemoteAddress(); + if (LOG.isDebugEnabled()) + LOG + .debug("Authenticating Account for GDataRequest -- modifying entries -- Role: " + + role + "; ClientIp: " + clientIp); + + AuthenticationController controller = GDataServerRegistry.getRegistry() + .lookup(AuthenticationController.class, + ComponentType.AUTHENTICATIONCONTROLLER); + ServiceFactory factory = GDataServerRegistry.getRegistry().lookup( + ServiceFactory.class, ComponentType.SERVICEFACTORY); + AdminService adminService = factory.getAdminService(); + GDataAccount account; + try { + account = adminService.getFeedOwningAccount(request.getFeedId()); + String token = getTokenFromRequest(request.getHttpServletRequest()); + if (LOG.isDebugEnabled()) + LOG.debug("Got Token: " + token + "; for requesting account: " + + account); + if (account != null && token != null) + return controller.authenticateToken(token, clientIp, + AccountRole.ENTRYAMINISTRATOR, account.getName()); + + } catch (ServiceException e) { + LOG.error("can get GDataAccount for feedID -- " + + request.getFeedId(), e); + throw new AuthenticatorException(" Service exception occured", e); + + } + + return false; + } + + /** + * @see org.apache.lucene.gdata.server.authentication.GDataHttpAuthenticator#authenticateAccount(javax.servlet.http.HttpServletRequest, + * org.apache.lucene.gdata.data.GDataAccount.AccountRole) + */ + public boolean authenticateAccount(HttpServletRequest request, + AccountRole role) { + String clientIp = request.getRemoteAddr(); + if (LOG.isDebugEnabled()) + LOG + .debug("Authenticating Account for GDataRequest -- modifying entries -- Role: " + + role + "; ClientIp: " + clientIp); + AuthenticationController controller = GDataServerRegistry.getRegistry() + .lookup(AuthenticationController.class, + ComponentType.AUTHENTICATIONCONTROLLER); + String token = getTokenFromRequest(request); + if (LOG.isDebugEnabled()) + LOG.debug("Got Token: " + token + ";"); + if (token == null) + return false; + return controller.authenticateToken(token, clientIp, role, null); + + } + + protected String getTokenFromRequest(HttpServletRequest request) { + String token = request + .getHeader(AuthenticationController.AUTHORIZATION_HEADER); + if (token == null || !token.startsWith("GoogleLogin")) { + Cookie[] cookies = request.getCookies(); + if (cookies == null) { + return null; + } + for (int i = 0; i < cookies.length; i++) { + if (cookies[i].getName().equals( + AuthenticationController.TOKEN_KEY)) { + token = cookies[i].getValue(); + break; + } + + } + } + if (token != null) + token = token.substring(token.indexOf("=") + 1); + return token; + } + +} Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DeleteFeedHandler.java =================================================================== --- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DeleteFeedHandler.java (revision 0) +++ gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DeleteFeedHandler.java (revision 0) @@ -0,0 +1,81 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.servlet.handler; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.gdata.data.ServerBaseFeed; +import org.apache.lucene.gdata.server.ServiceFactory; +import org.apache.lucene.gdata.server.registry.ComponentType; +import org.apache.lucene.gdata.server.registry.GDataServerRegistry; + +/** + * @author Simon Willnauer + * + */ +public class DeleteFeedHandler extends AbstractFeedHandler{ + private static final Log LOG = LogFactory.getLog(DeleteFeedHandler.class); + + /** + * @throws IOException + * @see org.apache.lucene.gdata.servlet.handler.GDataRequestHandler#processRequest(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) + */ + @Override + public void processRequest(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { + super.processRequest(request,response); + if(this.authenticated){ + try { + ServerBaseFeed feed = createDeleteFeed(request); + + GDataServerRegistry registry = GDataServerRegistry.getRegistry(); + ServiceFactory serviceFactory = registry.lookup(ServiceFactory.class,ComponentType.SERVICEFACTORY); + if(serviceFactory == null){ + setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,"required component is not available"); + throw new FeedHandlerException("Can't save feed - ServiceFactory is null"); + } + serviceFactory.getAdminService().deleteFeed(feed); + } catch (FeedHandlerException e) { + LOG.error("Can not delete feed -- "+e.getMessage(),e); + }catch (Exception e) { + LOG.error("Can not delete feed -- "+e.getMessage(),e); + setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR,"can not create feed"); + } + } + sendResponse(response); + + + + } + + private ServerBaseFeed createDeleteFeed(final HttpServletRequest request) throws FeedHandlerException { + String feedId = request.getParameter("feedid"); + if(feedId == null){ + setError(HttpServletResponse.SC_BAD_REQUEST,"No feed id specified"); + throw new FeedHandlerException("no feed Id specified"); + } + ServerBaseFeed retVal = new ServerBaseFeed(); + retVal.setId(feedId); + return retVal; + } + +} Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractFeedHandler.java =================================================================== --- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractFeedHandler.java (revision 0) +++ gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractFeedHandler.java (revision 0) @@ -0,0 +1,173 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.servlet.handler; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.gdata.data.GDataAccount; +import org.apache.lucene.gdata.data.ServerBaseFeed; +import org.apache.lucene.gdata.data.GDataAccount.AccountRole; +import org.apache.lucene.gdata.server.GDataEntityBuilder; +import org.apache.lucene.gdata.server.ServiceException; +import org.apache.lucene.gdata.server.ServiceFactory; +import org.apache.lucene.gdata.server.administration.AdminService; +import org.apache.lucene.gdata.server.registry.ComponentType; +import org.apache.lucene.gdata.server.registry.GDataServerRegistry; +import org.apache.lucene.gdata.server.registry.ProvidedService; + +import com.google.gdata.util.ParseException; + +/** + * + * @author Simon Willnauer + * + */ +public abstract class AbstractFeedHandler extends RequestAuthenticator implements GDataRequestHandler { + private static final Log LOG = LogFactory.getLog(AbstractFeedHandler.class); + + protected static final String PARAMETER_ACCOUNT = "account"; + + protected static final String PARAMETER_SERVICE = "service"; + private int error; + protected boolean authenticated = false; + + private String errorMessage = ""; + private boolean isError = false; + + /** + * @see org.apache.lucene.gdata.servlet.handler.GDataRequestHandler#processRequest(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse) + */ + @SuppressWarnings("unused") + public void processRequest(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + this.authenticated = authenticateAccount(request,AccountRole.FEEDAMINISTRATOR); + if(!this.authenticated) + setError(HttpServletResponse.SC_UNAUTHORIZED,"Authorization failed"); + + } + + protected ServerBaseFeed createFeedFromRequest(HttpServletRequest request) throws ParseException, IOException, FeedHandlerException{ + GDataServerRegistry registry = GDataServerRegistry.getRegistry(); + String providedService = request.getParameter(PARAMETER_SERVICE); + if(!registry.isServiceRegistered(providedService)){ + setError(HttpServletResponse.SC_NOT_FOUND,"no such service"); + throw new FeedHandlerException("ProvicdedService is not registered -- Name: "+providedService); + } + ProvidedService provServiceInstance = registry.getProvidedService(providedService); + if(providedService == null){ + setError(HttpServletResponse.SC_BAD_REQUEST,"no such service"); + throw new FeedHandlerException("no such service registered -- "+providedService); + } + try{ + ServerBaseFeed retVal = new ServerBaseFeed(GDataEntityBuilder.buildFeed(request.getReader(),provServiceInstance)); + retVal.setServiceConfig(provServiceInstance); + return retVal; + }catch (IOException e) { + if(LOG.isInfoEnabled()) + LOG.info("Can not read from input stream - ",e); + setError(HttpServletResponse.SC_BAD_REQUEST,"Can not read from input stream"); + throw e; + }catch (ParseException e) { + if(LOG.isInfoEnabled()) + LOG.info("feed can not be parsed - ",e); + setError(HttpServletResponse.SC_BAD_REQUEST,"incoming feed can not be parsed"); + throw e; + } + + } + + + protected GDataAccount createRequestedAccount(HttpServletRequest request) throws FeedHandlerException{ + GDataServerRegistry registry = GDataServerRegistry.getRegistry(); + ServiceFactory serviceFactory = registry.lookup(ServiceFactory.class,ComponentType.SERVICEFACTORY); + + if(serviceFactory == null){ + setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, "Required server component not available"); + throw new FeedHandlerException("Required server component not available -- "+ServiceFactory.class.getName()); + } + AdminService service = serviceFactory.getAdminService(); + String account = request.getParameter(PARAMETER_ACCOUNT); + try{ + return service.getAccount(account); + }catch (ServiceException e) { + if(LOG.isInfoEnabled()) + LOG.info("no account for requested account - "+account,e); + setError(HttpServletResponse.SC_BAD_REQUEST,"no such account"); + throw new FeedHandlerException(e.getMessage(),e); + } + } + + protected void sendResponse(HttpServletResponse response){ + + if(!this.isError) + return; + try{ + response.sendError(this.error,this.errorMessage); + }catch (IOException e) { + LOG.warn("can send error in RequestHandler ",e); + } + } + + protected void setError(int error, String message){ + this.error = error; + this.errorMessage = message; + this.isError = true; + } + protected int getErrorCode(){ + return this.error; + } + + protected String getErrorMessage(){ + return this.errorMessage; + } + + class FeedHandlerException extends Exception{ + + /** + * + */ + private static final long serialVersionUID = 1L; + + /** + * Creates a new FeedHandlerException with a exception message and the exception cause this ex. + * @param arg0 - the message + * @param arg1 - the cause + */ + public FeedHandlerException(String arg0, Throwable arg1) { + super(arg0, arg1); + + } + + /** + * Creates a new FeedHandlerException with a exception message. + * @param arg0 - message + */ + public FeedHandlerException(String arg0) { + super(arg0 ); + + } + + } + + +} Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/InsertFeedHandler.java =================================================================== --- gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/InsertFeedHandler.java (revision 0) +++ gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/InsertFeedHandler.java (revision 0) @@ -0,0 +1,78 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.servlet.handler; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.gdata.data.GDataAccount; +import org.apache.lucene.gdata.data.ServerBaseFeed; +import org.apache.lucene.gdata.server.ServiceException; +import org.apache.lucene.gdata.server.ServiceFactory; +import org.apache.lucene.gdata.server.registry.ComponentType; +import org.apache.lucene.gdata.server.registry.GDataServerRegistry; + +/** + * @author Simon Willnauer + * + */ +public class InsertFeedHandler extends AbstractFeedHandler { + private static final Log LOG = LogFactory.getLog(InsertFeedHandler.class); + + /** + * @see org.apache.lucene.gdata.servlet.handler.GDataRequestHandler#processRequest(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + @SuppressWarnings("unused") + public void processRequest(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException { + super.processRequest(request, response); + if (this.authenticated) { + try { + ServerBaseFeed feed = createFeedFromRequest(request); + GDataAccount account = createRequestedAccount(request); + + GDataServerRegistry registry = GDataServerRegistry + .getRegistry(); + ServiceFactory serviceFactory = registry.lookup( + ServiceFactory.class, ComponentType.SERVICEFACTORY); + if (serviceFactory == null) { + setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, + "required component is not available"); + throw new FeedHandlerException( + "Can't save feed - ServiceFactory is null"); + } + serviceFactory.getAdminService().createFeed(feed, account); + } catch (ServiceException e) { + setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, + "can not create feed"); + LOG.error("Can not create feed -- " + e.getMessage(), e); + } catch (Exception e) { + LOG.error("Can not create feed -- " + e.getMessage(), e); + + } + + } + sendResponse(response); + } + +} Index: gdata-server/src/java/org/apache/lucene/gdata/servlet/FeedAdministrationServlet.java =================================================================== --- gdata-server/src/java/org/apache/lucene/gdata/servlet/FeedAdministrationServlet.java (revision 0) +++ gdata-server/src/java/org/apache/lucene/gdata/servlet/FeedAdministrationServlet.java (revision 0) @@ -0,0 +1,71 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.servlet; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.gdata.servlet.handler.GDataRequestHandler; + +/** + * This Servlet provides an REST interface to create / update and delete Feed instances. + * + * @author Simon Willnauer + * + */ +public class FeedAdministrationServlet extends AbstractGdataServlet { + private static final Log LOGGER = LogFactory.getLog(FeedAdministrationServlet.class); + /** + * + */ + private static final long serialVersionUID = -905586350743277032L; + + @Override + protected void doDelete(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException { + GDataRequestHandler handler = HANDLER_FACTORY.getDeleteFeedHandler(); + if(LOGGER.isInfoEnabled()) + LOGGER.info("Process delete feed request"); + handler.processRequest(arg0,arg1); + + } + + @Override + protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException { + GDataRequestHandler handler = HANDLER_FACTORY.getInsertFeedHandler(); + if(LOGGER.isInfoEnabled()) + LOGGER.info("Process insert feed request"); + handler.processRequest(arg0,arg1); + + } + + @Override + protected void doPut(HttpServletRequest arg0, HttpServletResponse arg1) throws ServletException, IOException { + GDataRequestHandler handler = HANDLER_FACTORY.getUpdateFeedHandler(); + if(LOGGER.isInfoEnabled()) + LOGGER.info("Process update feed request"); + handler.processRequest(arg0,arg1); + + } + + + +} Index: gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageAccountWrapper.java =================================================================== --- gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageAccountWrapper.java (revision 0) +++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageAccountWrapper.java (revision 0) @@ -0,0 +1,111 @@ +package org.apache.lucene.gdata.storage.lucenestorage; + +import java.net.MalformedURLException; +import java.net.URL; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.document.Document; +import org.apache.lucene.document.Field; +import org.apache.lucene.gdata.data.GDataAccount; + +/** + * Wrapps a User Object. + * The wrapper provides also a Lucene repesentation of the user; + * User Objects will not be Buffered in the lucene storage component. Each User will be written imidialtely. + * @author Simon Willnauer + * + */ +public class StorageAccountWrapper implements StorageWrapper{ + private static final Log LOG = LogFactory.getLog(StorageAccountWrapper.class); + + /** + * Lucene field for the username + */ + public static final String FIELD_ACCOUNTNAME = "accountName"; + /** + * Lucene field for the password + */ + public static final String FIELD_PASSWORD = "passwd"; + /** + * Lucene field for the author name + */ + public static final String FIELD_AUTHORNAME = "author"; + /** + * Lucene field for the author mail address + */ + public static final String FIELD_AUTHORMAIL = "authorMail"; + /** + * Lucene field for the author link + */ + public static final String FIELD_AUTHORHREF = "authorHref"; + /** + * Lucene field fot the userroles + */ + public static final String FIELD_ROLES = "userroles"; + private final GDataAccount user; + /** + * @param user - the user to be wrapped + */ + public StorageAccountWrapper(final GDataAccount user) { + if(user == null) + throw new IllegalArgumentException("user must not be null"); + this.user = user; + } + + /** + * @see org.apache.lucene.gdata.storage.lucenestorage.StorageWrapper#getLuceneDocument() + */ + public Document getLuceneDocument() { + Document doc = new Document(); + + doc.add(new Field(FIELD_ACCOUNTNAME,this.user.getName(),Field.Store.YES,Field.Index.UN_TOKENIZED)); + doc.add(new Field(FIELD_PASSWORD,this.user.getPassword()==null?"":this.user.getPassword(),Field.Store.YES,Field.Index.NO)); + doc.add(new Field(FIELD_AUTHORNAME,this.user.getAuthorname()==null?"":this.user.getAuthorname(),Field.Store.YES,Field.Index.NO)); + doc.add(new Field(FIELD_AUTHORMAIL,this.user.getAuthorMail()==null?"":this.user.getAuthorMail(),Field.Store.YES,Field.Index.NO)); + doc.add(new Field(FIELD_AUTHORHREF,this.user.getAuthorLink()==null?"":this.user.getAuthorLink().toString(),Field.Store.YES,Field.Index.NO)); + doc.add(new Field(FIELD_ROLES, Integer.toString(this.user.getRolesAsInt()),Field.Store.YES,Field.Index.NO)); + + return doc; + } + + + + + /** + * @param doc - a lucene document representation of an user + * @return - the user to build from the document. ornull if the document is null
+ */
+ public static GDataAccount buildEntity(final Document doc){
+ if(doc == null)
+ return null;
+
+ GDataAccount user = new GDataAccount();
+ user.setName(doc.get(FIELD_ACCOUNTNAME));
+ user.setPassword(doc.get(FIELD_PASSWORD));
+ user.setAuthorname(doc.get(FIELD_AUTHORNAME));
+ user.setAuthorMail(doc.get(FIELD_AUTHORMAIL));
+ try{
+ user.setRolesAsInt(Integer.parseInt(doc.get(FIELD_ROLES)));
+ }catch (NumberFormatException e) {
+ LOG.info("Can't parse userroles: "+user.getName()+" throws NumberFormatException. -- skipping --",e);
+ }
+ try {
+ if(doc.get(FIELD_AUTHORHREF)!= null)
+ user.setAuthorLink(new URL(doc.get(FIELD_AUTHORHREF)));
+ } catch (MalformedURLException e) {
+ LOG.info("SPECIFIED URL for user: "+user.getName()+" throws MalformedURLException. -- skipping --",e);
+ }
+ return user;
+ }
+
+
+
+ /**
+ * @return - the wrapped user
+ */
+ public GDataAccount getUser() {
+ return this.user;
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageWrapper.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageWrapper.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/StorageWrapper.java (revision 0)
@@ -0,0 +1,38 @@
+/**
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.gdata.storage.lucenestorage;
+
+import org.apache.lucene.document.Document;
+
+/**
+ * A interface to be implemented by StorageWrapper sub classes to
+ * provide a lucene document for each entity wrapped.
+ *
+ * @see org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper
+ * @see org.apache.lucene.gdata.storage.lucenestorage.StorageAccountWrapper
+ * @see org.apache.lucene.gdata.storage.lucenestorage.StorageFeedWrapper
+ * @author Simon Willnauer
+ *
+ */
+public interface StorageWrapper {
+ /**
+ * Returns a Lucene document representing the Wrapped Entry
+ *
+ * @return a Lucene Document
+ */
+ public abstract Document getLuceneDocument();
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/RecoverWriter.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/RecoverWriter.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/RecoverWriter.java (revision 0)
@@ -0,0 +1,104 @@
+/**
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.gdata.storage.lucenestorage.recover;
+
+import java.io.IOException;
+import java.io.Writer;
+
+import org.apache.lucene.gdata.server.registry.ProvidedService;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation;
+
+import com.google.gdata.data.BaseEntry;
+import com.google.gdata.util.common.xml.XmlWriter;
+
+/**
+ * Writes the recover objects to the hard disc.
+ * @author Simon Willnauer
+ *
+ */
+public class RecoverWriter {
+ protected static final String META_DATA_SEPARATOR = ";";
+ protected static final String META_DATA_ENTRY_SEPARATOR = System.getProperty("line.separator");
+ protected static final String STORAGE_OPERATION_SEPARATOR = "###########";
+ protected static final String OPERATION_DELETE = "D";
+ protected static final String OPERATION_UPDATE = "U";
+ protected static final String OPERATION_INSERT = "I";
+ protected static final String FILE_PREFIX = ".strg";
+
+
+
+ /**
+ * @param wrapper
+ * @throws IOException
+ *
+ *
+ *
+ */
+ public void writeEntry(StorageEntryWrapper wrapper,Writer writer)throws IOException{
+
+ writeOperation(wrapper.getOperation(),writer);
+ writeFeedID(wrapper.getFeedId(),writer);
+ writeEntryID(wrapper.getEntryId(),writer);
+ writeTimeStamp(wrapper.getTimestamp().toString(),writer);
+ if(!wrapper.getOperation().equals(StorageOperation.DELETE)){
+ writeService(wrapper,writer);
+ writer.write(META_DATA_ENTRY_SEPARATOR);
+ BaseEntry entry = wrapper.getEntry();
+ XmlWriter xmlWriter = new XmlWriter(writer);
+ entry.generateAtom(xmlWriter,wrapper.getConfigurator().getExtensionProfile());
+ }
+ writer.write(META_DATA_ENTRY_SEPARATOR);
+ writer.write(STORAGE_OPERATION_SEPARATOR);
+ writer.write(META_DATA_ENTRY_SEPARATOR);
+ }
+
+
+
+ private void writeTimeStamp(String timestamp, Writer writer) throws IOException{
+ writer.write(timestamp);
+ writer.write(META_DATA_SEPARATOR);
+ }
+ private void writeFeedID(String feedId,Writer writer) throws IOException{
+ writer.write(feedId);
+ writer.write(META_DATA_SEPARATOR);
+ }
+ private void writeEntryID(String entryId,Writer writer) throws IOException{
+ writer.write(entryId);
+ writer.write(META_DATA_SEPARATOR);
+ }
+
+ private void writeService(StorageEntryWrapper wrapper, Writer writer) throws IOException{
+ ProvidedService config = wrapper.getConfigurator();
+ writer.write(config.getName());
+ writer.write(META_DATA_SEPARATOR);
+ }
+
+ private void writeOperation(StorageOperation operation, Writer writer) throws IOException{
+ if(operation.equals(StorageOperation.INSERT))
+ writer.write(OPERATION_INSERT);
+ else if (operation.equals(StorageOperation.UPDATE))
+ writer.write(OPERATION_UPDATE);
+ else if (operation.equals(StorageOperation.DELETE))
+ writer.write(OPERATION_DELETE);
+ writer.write(META_DATA_SEPARATOR);
+ }
+
+
+
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/RecoverException.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/RecoverException.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/RecoverException.java (revision 0)
@@ -0,0 +1,63 @@
+/**
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.gdata.storage.lucenestorage.recover;
+
+/**
+ * @author Simon Willnauer
+ *
+ */
+public class RecoverException extends Exception {
+
+ /**
+ *
+ */
+ private static final long serialVersionUID = -1862309520257024464L;
+
+ /**
+ *
+ */
+ public RecoverException() {
+ super();
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * @param arg0
+ */
+ public RecoverException(String arg0) {
+ super(arg0);
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * @param arg0
+ * @param arg1
+ */
+ public RecoverException(String arg0, Throwable arg1) {
+ super(arg0, arg1);
+ // TODO Auto-generated constructor stub
+ }
+
+ /**
+ * @param arg0
+ */
+ public RecoverException(Throwable arg0) {
+ super(arg0);
+ // TODO Auto-generated constructor stub
+ }
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/RecoverReader.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/RecoverReader.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/storage/lucenestorage/recover/RecoverReader.java (revision 0)
@@ -0,0 +1,174 @@
+/**
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.gdata.storage.lucenestorage.recover;
+
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.StringReader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.lucene.gdata.data.ServerBaseEntry;
+import org.apache.lucene.gdata.server.GDataEntityBuilder;
+import org.apache.lucene.gdata.server.registry.GDataServerRegistry;
+import org.apache.lucene.gdata.server.registry.ProvidedService;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper;
+import org.apache.lucene.gdata.storage.lucenestorage.StorageEntryWrapper.StorageOperation;
+
+import com.google.gdata.data.BaseEntry;
+import com.google.gdata.util.ParseException;
+
+/**
+ * Recovers the written object from the harddisc
+ * @author Simon Willnauer
+ *
+ */
+public class RecoverReader {
+
+ private static final Log LOG = LogFactory.getLog(RecoverReader.class);
+ private RecoverStrategy strategy;
+ protected RecoverReader(){
+ this.strategy = new RecoverStrategy();
+ }
+ /**
+ * @param reader
+ * @return
+ * @throws IOException
+ */
+ public List+ * 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/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,195 @@
+/**
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.gdata.server.administration;
+
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.apache.lucene.gdata.data.GDataAccount;
+import org.apache.lucene.gdata.data.ServerBaseFeed;
+import org.apache.lucene.gdata.server.GDataService;
+import org.apache.lucene.gdata.server.ServiceException;
+import org.apache.lucene.gdata.storage.StorageException;
+
+
+
+/**
+ * default implementation of the {@link org.apache.lucene.gdata.server.administration.AdminService} interface.
+ * @author Simon Willnauer
+ *
+ */
+public class GDataAdminService extends GDataService implements AdminService {
+ private static final Log LOG = LogFactory.getLog(GDataAdminService.class);
+ /**
+ * @throws ServiceException
+ */
+ public GDataAdminService() throws ServiceException {
+ super();
+
+ }
+
+
+
+ /**
+ * @see org.apache.lucene.gdata.server.administration.AdminService#createFeed(org.apache.lucene.gdata.data.ServerBaseFeed, org.apache.lucene.gdata.data.GDataAccount)
+ */
+ public void createFeed(final ServerBaseFeed feed,final GDataAccount account) throws ServiceException {
+ if(feed == null)
+ throw new ServiceException("Can not create feed -- feed is null");
+ if(account == null)
+ throw new ServiceException("Can not create feed -- account is null");
+ if(feed.getId() == null)
+ throw new ServiceException("Feed ID is null can not create feed");
+ if(account.getName() == null)
+ throw new ServiceException("Account name is null -- can't create feed");
+ try {
+ feed.setAccount(account);
+ this.storage.storeFeed(feed,account.getName());
+ } catch (StorageException e) {
+ if(LOG.isInfoEnabled())
+ LOG.info("Can not save feed -- "+e.getMessage(),e);
+ throw new ServiceException("Can not save feed",e);
+ }
+
+ }
+
+
+
+ /**
+ * @see org.apache.lucene.gdata.server.administration.AdminService#updateFeed(org.apache.lucene.gdata.data.ServerBaseFeed, org.apache.lucene.gdata.data.GDataAccount)
+ */
+ public void updateFeed(ServerBaseFeed feed, GDataAccount account) throws ServiceException {
+ if(feed == null)
+ throw new ServiceException("Can not update null feed");
+ if(account == null)
+ throw new ServiceException("Can not update feed -- account is null");
+ if(feed.getId() == null)
+ throw new ServiceException("Feed ID is null can not update feed");
+ if(account.getName() == null)
+ throw new ServiceException("Account name is null -- can't update feed");
+ try {
+ feed.setAccount(account);
+ this.storage.updateFeed(feed,account.getName());
+ } catch (StorageException e) {
+ if(LOG.isInfoEnabled())
+ LOG.info("Can not update feed -- "+e.getMessage(),e);
+ throw new ServiceException("Can not update feed",e);
+ }
+
+ }
+
+
+
+ /**
+ * @see org.apache.lucene.gdata.server.administration.AdminService#deleteFeed(org.apache.lucene.gdata.data.ServerBaseFeed)
+ */
+ public void deleteFeed(ServerBaseFeed feed) throws ServiceException {
+ if(feed == null)
+ throw new ServiceException("Can not delete null feed");
+ if(feed.getId() == null)
+ throw new ServiceException("Feed ID is null can not delete feed");
+ try {
+ this.storage.deleteFeed(feed.getId());
+ } catch (StorageException e) {
+ if(LOG.isInfoEnabled())
+ LOG.info("Can not delete feed -- "+e.getMessage(),e);
+ throw new ServiceException("Can not delete feed",e);
+ }
+
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.administration.AdminService#createAccount(org.apache.lucene.gdata.data.GDataAccount)
+ */
+ public void createAccount(GDataAccount account) throws ServiceException {
+ if(account == null)
+ throw new ServiceException("Can not save null account");
+ try {
+ this.storage.storeAccount(account);
+ } catch (StorageException e) {
+ if(LOG.isInfoEnabled())
+ LOG.info("Can not save account -- "+e.getMessage(),e);
+ throw new ServiceException("Can not save account",e);
+ }
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.administration.AdminService#deleteAccount(org.apache.lucene.gdata.data.GDataAccount)
+ */
+ public void deleteAccount(GDataAccount account) throws ServiceException {
+ if(account == null)
+ throw new ServiceException("Can not delete null account");
+ try {
+ this.storage.deleteAccount(account.getName());
+ } catch (StorageException e) {
+ if(LOG.isInfoEnabled())
+ LOG.info("Can not save account -- "+e.getMessage(),e);
+ throw new ServiceException("Can not save account",e);
+ }
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.administration.AdminService#updateAccount(org.apache.lucene.gdata.data.GDataAccount)
+ */
+ public void updateAccount(GDataAccount account) throws ServiceException {
+ if(account == null)
+ throw new ServiceException("Can not update null account");
+ try {
+ this.storage.updateAccount(account);
+ } catch (StorageException e) {
+ if(LOG.isInfoEnabled())
+ LOG.info("Can not save account -- "+e.getMessage(),e);
+ throw new ServiceException("Can not save account",e);
+ }
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.administration.AdminService#getAccount(java.lang.String)
+ */
+ public GDataAccount getAccount(String accountName)throws ServiceException{
+ if(accountName == null)
+ throw new ServiceException("Can not get null account");
+ try {
+ return this.storage.getAccount(accountName);
+ } catch (StorageException e) {
+ if(LOG.isInfoEnabled())
+ LOG.info("Can not get account -- "+e.getMessage(),e);
+ throw new ServiceException("Can not get account",e);
+ }
+
+ }
+
+
+
+ /**
+ * @see org.apache.lucene.gdata.server.administration.AdminService#getFeedOwningAccount(java.lang.String)
+ */
+ public GDataAccount getFeedOwningAccount(String feedId) throws ServiceException {
+ if(feedId == null)
+ throw new ServiceException("Can not get account - feed id must not be null");
+ try {
+ String accountName = this.storage.getAccountNameForFeedId(feedId);
+ return this.storage.getAccount(accountName);
+
+ } catch (StorageException e) {
+ if(LOG.isInfoEnabled())
+ LOG.info("Can not get account for feed Id -- "+e.getMessage(),e);
+ throw new ServiceException("Can not get account for the given feed id",e);
+ }
+ }
+
+
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/administration/package.html
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/administration/package.html (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/administration/package.html (revision 0)
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+Classes and Services used for user and feed configuration
+
+
\ No newline at end of file
Index: gdata-server/src/java/org/apache/lucene/gdata/server/registry/SuperType.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/registry/SuperType.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/registry/SuperType.java (revision 0)
@@ -0,0 +1,44 @@
+/**
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.lucene.gdata.server.registry;
+
+import static java.lang.annotation.ElementType.FIELD;
+import static java.lang.annotation.RetentionPolicy.RUNTIME;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.Target;
+
+/**
+ * This Annotation is use to annotate
+ * {@link org.apache.lucene.gdata.server.registry.ComponentType} elements to
+ * specify an interface e.g. super type of a defined component.
+ * This annotation will be visible at runtime
+ * @see org.apache.lucene.gdata.server.registry.Component + * @see org.apache.lucene.gdata.server.registry.GDataServerRegistry + * + * @author Simon Willnauer + * + */ +@Target( { FIELD }) +@Retention(value = RUNTIME) +public @interface SuperType { + /** + * + * @return the specified super type + */ + Class superType(); +} Index: gdata-server/src/java/org/apache/lucene/gdata/server/registry/Component.java =================================================================== --- gdata-server/src/java/org/apache/lucene/gdata/server/registry/Component.java (revision 0) +++ gdata-server/src/java/org/apache/lucene/gdata/server/registry/Component.java (revision 0) @@ -0,0 +1,74 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.server.registry; + +import static java.lang.annotation.ElementType.TYPE; +import static java.lang.annotation.RetentionPolicy.RUNTIME; + +import java.lang.annotation.Retention; +import java.lang.annotation.Target; + +/** + * The {@link Component} annotation is used to annotate a class as a + * server-component of the GDATA-Server. Annotated class can be configured via + * the gdata-config.xml file to be looked up by aribaty classes at runtime via + * the + * {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry#lookup(Class, ComponentType)} + * method. + *+ * Classes annotated with the Component annotation need to provide a default + * constructor to be instanciated via reflection. Components of the GData-Server + * are definded in the + * {@link org.apache.lucene.gdata.server.registry.ComponentType} enumeration. + * Each of the enum types are annotated with a + * {@link org.apache.lucene.gdata.server.registry.SuperType} annotation. This + * annotation specifies the super class or interface of the component. A class + * annotated with the Component annotation must implement or extends this + * defined super-type. This enables developers to use custom implemetations of + * the component like a custom {@link org.apache.lucene.gdata.storage.Storage}. + *
+ *+ * Each ComponentType can only registerd once as the + * {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry} does not + * provide multipe instances of a ComponentType. + *
+ *
+ * This annotation can only annotate types and can be accessed at runtime.
+ * {@link java.lang.annotation.Target} ==
+ * {@link java.lang.annotation.ElementType#TYPE} and
+ * {@link java.lang.annotation.Retention} ==
+ * {@link java.lang.annotation.RetentionPolicy#RUNTIME}.
+ *
+ * @see org.apache.lucene.gdata.server.registry.GDataServerRegistry
+ * @see org.apache.lucene.gdata.server.registry.ComponentType
+ * @see org.apache.lucene.gdata.server.registry.SuperType
+ *
+ *
+ * @author Simon Willnauer
+ *
+ */
+@Target( { TYPE })
+@Retention(value = RUNTIME)
+public @interface Component {
+
+ /**
+ * @see ComponentType
+ * @return - the component type
+ */
+ ComponentType componentType();
+
+}
Index: gdata-server/src/java/org/apache/lucene/gdata/server/registry/ProvidedServiceConfig.java
===================================================================
--- gdata-server/src/java/org/apache/lucene/gdata/server/registry/ProvidedServiceConfig.java (revision 0)
+++ gdata-server/src/java/org/apache/lucene/gdata/server/registry/ProvidedServiceConfig.java (revision 0)
@@ -0,0 +1,131 @@
+/**
+ * Copyright 2004 The Apache Software Foundation
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.apache.lucene.gdata.server.registry;
+
+import com.google.gdata.data.ExtensionProfile;
+
+/**
+ * Standart implementation of
+ * {@link org.apache.lucene.gdata.server.registry.ProvidedService} to be used
+ * inside the
+ * {@link org.apache.lucene.gdata.server.registry.GDataServerRegistry}
+ *
+ * @author Simon Willnauer
+ *
+ */
+public class ProvidedServiceConfig implements ProvidedService {
+ private String serviceName;
+
+ private Class entryType;
+
+ private Class feedType;
+
+ private ExtensionProfile extensionProfile;
+
+
+ ProvidedServiceConfig(ExtensionProfile profile, Class feedType,
+ Class entryType, String serviceName) {
+ this.extensionProfile = profile;
+ this.feedType = feedType;
+ this.entryType = entryType;
+ this.serviceName = serviceName;
+
+ }
+
+ /**
+ * Default constructor to instanciate via reflection
+ */
+ public ProvidedServiceConfig() {
+ //
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.registry.ProvidedService#getFeedType()
+ */
+ public Class getFeedType() {
+ return this.feedType;
+ }
+
+ /**
+ * @param feedType
+ * The feedType to set.
+ */
+ public void setFeedType(Class feedType) {
+ this.feedType = feedType;
+ }
+
+ /**
+ * @see org.apache.lucene.gdata.server.registry.ProvidedService#getExtensionProfile()
+ */
+ public ExtensionProfile getExtensionProfile() {
+ return this.extensionProfile;
+ }
+
+ /**
+ * @param extensionProfil -
+ * the extensionprofile for this feed configuration
+ */
+ public void setExtensionProfile(ExtensionProfile extensionProfil) {
+ this.extensionProfile = extensionProfil;
+ }
+
+
+ /**
+ *TODO add comment
+ * @param
+ * 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). For a general overview of the generic BaseFeed class see the gdata-client API documentation
+ * Additionally an account can be in role to modify other feeds, create accounts
+ * or feeds. See {@link AccountRole} for detailed infomation about roles. One
+ * account can also have more than one role. All roles in {@link AccountRole}
+ * can be combined
+ *
+ * For each account values for author name, author email and author link can be
+ * set at creation time or during an update. These values will be used as the
+ * corresponding values for the feed
+ * {@link org.apache.lucene.gdata.data.ServerBaseFeed#addAuthor(Person)} if no
+ * value for the feed has be specified.
+ *
Some components of the server also need
+ * additional infomation like the service type
+ * {@link org.apache.lucene.gdata.server.registry.ProvidedService} of the entry
+ * and the feedid a entry belongs to. All these information are
+ * encapsulated in the ServerBaseEntry decorating a concrete sub class of BaseEntry. The actual
+ * {@link com.google.gdata.data.BaseEntry} will be passed to the ServerBaseEntry
+ * at creation time via the constructor. To use the ServerBaseFeed for generation a provided format like
+ * RSS/ATOM the corresponding {@link com.google.gdata.data.ExtensionProfile} has
+ * to be provided to the generation method.
+ *
Some components of the server also need
+ * additional infomation like the service type
+ * {@link org.apache.lucene.gdata.server.registry.ProvidedService} of the feed.
+ * All these information are
+ * encapsulated in the ServerBaseFeed decoration a concrete subl class of BaseFeed. The type of the
+ * {@link com.google.gdata.data.BaseEntry} contained it this feed will be passed to the ServerBaseFeed
+ * at creation time via the constructor. To retrieve the original entry call
+ * {@link ServerBaseFeed#getFeed()} returns a
+ * {@link com.google.gdata.data.BaseFeed} instance which can be casted into the
+ * actual type. To use the ServerBaseEntry for generation a provided format like
+ * RSS/ATOM the corresponding {@link com.google.gdata.data.ExtensionProfile} has
+ * to be provided to the generation method.
+ *
+ * @author Simon Willnauer
+ *
+ */
+public class ServerBaseFeed {
+
+ private String serviceType;
+
+ private ProvidedService serviceConfig;
+
+ private GDataAccount account;
+
+ private BaseFeed feed;
+ /**
+ * @return Returns the account.
+ */
+ public GDataAccount getAccount() {
+ return this.account;
+ }
+
+ /**
+ * @param account The account to set.
+ */
+ public void setAccount(GDataAccount account) {
+ this.account = account;
+ }
+
+ /**
+ * Creates a new ServerBaseFeed and decorates a basic instance of {@link Feed}
+ */
+ @SuppressWarnings("unchecked")
+ public ServerBaseFeed() {
+ this.feed = new Feed();
+
+ }
+ /**
+ * @param feed - the feed to decorate
+ *
+ */
+ @SuppressWarnings("unchecked")
+ public ServerBaseFeed(BaseFeed feed) {
+ this.feed = feed;
+
+ }
+
+ /**
+ * @return Returns the feed.
+ */
+ public BaseFeed getFeed() {
+ return this.feed;
+ }
+
+ /**
+ * @param feed The feed to set.
+ */
+ public void setFeed(BaseFeed feed) {
+ this.feed = feed;
+ }
+
+ /**
+ * @see com.google.gdata.data.BaseFeed#declareExtensions(com.google.gdata.data.ExtensionProfile)
+ */
+ public void declareExtensions(ExtensionProfile extProfile) {
+
+ this.feed.declareExtensions(extProfile);
+ }
+
+ /**
+ * @param link -
+ * a link added to the link list of the feed
+ */
+ @SuppressWarnings("unchecked")
+ public void addLink(final Link link) {
+ this.feed.getLinks().add(link);
+ }
+
+ /**
+ * @param collection -
+ * a collection of Link instance to be added to
+ * the feeds link list
+ */
+ public void addLinks(final Collection collection) {
+ this.feed.getLinks().addAll(collection);
+ }
+
+ /**
+ * @return - the name of the service related of the feed represented by this
+ * ServerBaseFeed
+ */
+ public String getServiceType() {
+ return this.serviceType;
+ }
+
+ /**
+ * @param serviceType -
+ * the name of the service related of the feed represented by
+ * this ServerBaseFeed
+ */
+ public void setServiceType(String serviceType) {
+ this.serviceType = serviceType;
+ }
+
+ /**
+ * @return - the provided service
+ */
+ public ProvidedService getServiceConfig() {
+ return this.serviceConfig;
+ }
+
+ /**
+ * @param serviceConfig - -
+ * the provided service
+ */
+ public void setServiceConfig(ProvidedService serviceConfig) {
+ this.serviceConfig = serviceConfig;
+ if (serviceConfig != null)
+ this.serviceType = this.serviceConfig.getName();
+
+ }
+
+ /**
+ * @param person -
+ * adds an author to the feed
+ */
+ public void addAuthor(final Person person) {
+ this.feed.getAuthors().add(person);
+ }
+
+ /**
+ * @see com.google.gdata.data.BaseFeed#createEntry()
+ */
+
+ public BaseEntry createEntry() {
+
+ return this.feed.createEntry();
+ }
+
+ /**
+ * @see com.google.gdata.data.BaseFeed#generateAtom(com.google.gdata.util.common.xml.XmlWriter, com.google.gdata.data.ExtensionProfile)
+ */
+
+ public void generateAtom(XmlWriter arg0, ExtensionProfile arg1) throws IOException {
+
+ this.feed.generateAtom(arg0, arg1);
+ }
+
+ /**
+ * @see com.google.gdata.data.BaseFeed#generateAtomColl(com.google.gdata.util.common.xml.XmlWriter)
+ */
+
+ public void generateAtomColl(XmlWriter arg0) throws IOException {
+
+ this.feed.generateAtomColl(arg0);
+ }
+
+ /**
+ * @see com.google.gdata.data.BaseFeed#generateRss(com.google.gdata.util.common.xml.XmlWriter, com.google.gdata.data.ExtensionProfile)
+ */
+
+ public void generateRss(XmlWriter arg0, ExtensionProfile arg1) throws IOException {
+
+ this.feed.generateRss(arg0, arg1);
+ }
+
+ /**
+ * @see com.google.gdata.data.BaseFeed#getCanPost()
+ */
+
+ public boolean getCanPost() {
+
+ return this.feed.getCanPost();
+ }
+
+ /**
+ * @see com.google.gdata.data.BaseFeed#getEntries()
+ */
+
+ public List getEntries() {
+
+ return this.feed.getEntries();
+ }
+
+ /**
+ * @see com.google.gdata.data.BaseFeed#getEntryPostLink()
+ */
+
+ public Link getEntryPostLink() {
+
+ return this.feed.getEntryPostLink();
+ }
+
+ /**
+ * @see com.google.gdata.data.BaseFeed#getItemsPerPage()
+ */
+
+ public int getItemsPerPage() {
+
+ return this.feed.getItemsPerPage();
+ }
+
+ /**
+ * @see com.google.gdata.data.BaseFeed#getSelf()
+ */
+
+ public BaseFeed getSelf() throws IOException, ServiceException {
+
+ return this.feed.getSelf();
+ }
+
+ /**
+ * @see com.google.gdata.data.BaseFeed#getSelfLink()
+ */
+
+ public Link getSelfLink() {
+
+ return this.feed.getSelfLink();
+ }
+
+ /**
+ * @see com.google.gdata.data.BaseFeed#getService()
+ */
+
+ public Service getService() {
+
+ return this.feed.getService();
+ }
+
+ /**
+ * @see com.google.gdata.data.BaseFeed#getStartIndex()
+ */
+
+ public int getStartIndex() {
+
+ return this.feed.getStartIndex();
+ }
+
+ /**
+ * @see com.google.gdata.data.BaseFeed#getTotalResults()
+ */
+
+ public int getTotalResults() {
+
+ return this.feed.getTotalResults();
+ }
+
+ /**
+ * @see com.google.gdata.data.BaseFeed#insert(E)
+ */
+
+ public BaseEntry insert(BaseEntry arg0) throws ServiceException, IOException {
+
+ return this.feed.insert(arg0);
+ }
+
+ /**
+ * @see com.google.gdata.data.BaseFeed#parseAtom(com.google.gdata.data.ExtensionProfile, java.io.InputStream)
+ */
+
+ public void parseAtom(ExtensionProfile arg0, InputStream arg1) throws IOException, ParseException {
+
+ this.feed.parseAtom(arg0, arg1);
+ }
+
+ /**
+ * @see com.google.gdata.data.BaseFeed#parseAtom(com.google.gdata.data.ExtensionProfile, java.io.Reader)
+ */
+
+ public void parseAtom(ExtensionProfile arg0, Reader arg1) throws IOException, ParseException {
+
+ this.feed.parseAtom(arg0, arg1);
+ }
+
+ /**
+ * @see com.google.gdata.data.BaseFeed#setCanPost(boolean)
+ */
+
+ public void setCanPost(boolean arg0) {
+
+ this.feed.setCanPost(arg0);
+ }
+
+ /**
+ * @see com.google.gdata.data.BaseFeed#setItemsPerPage(int)
+ */
+
+ public void setItemsPerPage(int arg0) {
+
+ this.feed.setItemsPerPage(arg0);
+ }
+
+ /**
+ * @see com.google.gdata.data.BaseFeed#setService(com.google.gdata.client.Service)
+ */
+
+ public void setService(Service arg0) {
+
+ this.feed.setService(arg0);
+ }
+
+ /**
+ * @see com.google.gdata.data.BaseFeed#setStartIndex(int)
+ */
+
+ public void setStartIndex(int arg0) {
+
+ this.feed.setStartIndex(arg0);
+ }
+
+ /**
+ * @see com.google.gdata.data.BaseFeed#setTotalResults(int)
+ */
+
+ public void setTotalResults(int arg0) {
+
+ this.feed.setTotalResults(arg0);
+ }
+
+ /**
+ * @see com.google.gdata.data.Source#addHtmlLink(java.lang.String, java.lang.String, java.lang.String)
+ */
+
+ public void addHtmlLink(String arg0, String arg1, String arg2) {
+
+ this.feed.addHtmlLink(arg0, arg1, arg2);
+ }
+
+ /**
+ * @see com.google.gdata.data.Source#getAuthors()
+ */
+
+ public Listtrue if the role list contains the given role
+ */
+ public boolean isUserInRole(AccountRole role) {
+ if (role == null)
+ return false;
+ return this.roles.contains(role);
+ }
+
+ /**
+ * @see GDataAccount#setRolesAsInt(int)
+ * @return - the integer representation for the user roles
+ */
+ public int getRolesAsInt() {
+ // 1 as the Userrole is always set
+ int bits = 1;
+ for (AccountRole role : this.roles) {
+ if (role == AccountRole.ENTRYAMINISTRATOR)
+ bits ^= 2;
+ else if (role == AccountRole.FEEDAMINISTRATOR)
+ bits ^= 4;
+ else if (role == AccountRole.USERADMINISTRATOR)
+ bits ^= 8;
+
+ }
+ return bits;
+
+ }
+
+ /**
+ * Sets the roles from a int representation.
+ *
+ *
+ * This method will only set roles, will not remove roles! A combination of
+ * roles is also possible e.g. the int value 6 combines
+ * {@link AccountRole#ENTRYAMINISTRATOR} and
+ * {@link AccountRole#FEEDAMINISTRATOR}.
+ *
+ * @param i -
+ * the integer used to set the roles
+ */
+ public void setRolesAsInt(int i) {
+
+ if ((i & 2) > 0)
+ this.roles.add(AccountRole.ENTRYAMINISTRATOR);
+ if ((i & 4) > 0)
+ this.roles.add(AccountRole.FEEDAMINISTRATOR);
+ if ((i & 8) > 0)
+ this.roles.add(AccountRole.USERADMINISTRATOR);
+
+ }
+
+ /**
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ public boolean equals(Object o) {
+ if (this == o)
+ return true;
+ if (!(o instanceof GDataAccount) || o == null)
+ return false;
+ GDataAccount toCompare = (GDataAccount) o;
+ if (this.name.equals(toCompare.name))
+ return true;
+ return false;
+
+ }
+
+ /**
+ * @see java.lang.Object#hashCode()
+ */
+ public int hashCode() {
+ int ret = 37;
+ ret = 9 * ret + this.name.hashCode();
+ return ret;
+ }
+
+ /**
+ * Checks the requiered values for creating an account are set. Required
+ * values are name and password the minimum length of
+ * these values is 6.
+ *
+ * @return
true if an only if password and name are not null and the length is > 5
+ */
+ public boolean requiredValuesSet() {
+ return (this.name != null && this.password != null
+ && this.name.length() > 5 && this.password.length() > 5);
+ }
+
+ /**
+ * @see java.lang.Object#toString()
+ */
+ public String toString(){
+ StringBuilder builder = new StringBuilder("GdataAccount: ");
+ builder.append("name: ").append(this.name);
+ builder.append(" password: ").append((this.password!= null?" length: "+this.password.length():null));
+ builder.append(" author: ").append(this.authorname);
+ builder.append(" author email: ").append(this.authorMail);
+ builder.append(" author link: ").append(this.authorLink);
+ return builder.toString();
+ }
+
+ /**
+ * checks whether the given integer matches the account role.
+ * @param intRole - integer representation of a role
+ * @param role - the accountrole to match
+ * @return true if and only if the given roles match, otherwise false
+ */
+ public static boolean isInRole(int intRole, AccountRole role){
+ if(role == AccountRole.USER)
+ return (intRole&1)>0;
+ if (role == AccountRole.ENTRYAMINISTRATOR)
+ return (intRole&2) >0 ;
+ else if (role == AccountRole.FEEDAMINISTRATOR)
+ return (intRole&4) >0 ;
+ else if (role == AccountRole.USERADMINISTRATOR)
+ return (intRole&8) >0 ;
+ return false;
+ }
+
+ /**
+ * @return - a new Administartor accoutn
+ */
+ public static final GDataAccount createAdminAccount(){
+ GDataAccount retVal = new GDataAccount();
+ retVal.setName("administrator");
+ retVal.setPassword("password");
+ retVal.setRole(AccountRole.USERADMINISTRATOR);
+ retVal.setRole(AccountRole.FEEDAMINISTRATOR);
+ retVal.setRole(AccountRole.ENTRYAMINISTRATOR);
+ return retVal;
+ }
+
+ /**
+ * This enum respesents all account roles an account can have.
+ *
+ * @author Simon Willnauer
+ *
+ */
+ public enum AccountRole {
+
+ /**
+ * Can create / alter user
+ */
+ USERADMINISTRATOR,
+
+ /**
+ * Can create / alter feeds
+ */
+ FEEDAMINISTRATOR,
+ /**
+ * Can create / alter entries
+ */
+ ENTRYAMINISTRATOR,
+ /**
+ * can create / alter his own feed entries
+ */
+ USER
+ }
+
+}