Index: build.xml =================================================================== --- build.xml (revision 410675) +++ build.xml (working copy) @@ -379,6 +379,7 @@ + @@ -386,7 +387,7 @@ - + Index: contrib/gdata-server/build.xml =================================================================== --- contrib/gdata-server/build.xml (revision 0) +++ contrib/gdata-server/build.xml (revision 0) @@ -0,0 +1,46 @@ + + + + + + Serverside Google Data API implementation + + + + + + + + + + + + + + + + + + + + + + Prepare dist directory + + + + + Distributing GData War + + + + + + + + + + + + \ No newline at end of file Index: contrib/gdata-server/build.xml =================================================================== --- contrib/gdata-server/build.xml (revision 0) +++ contrib/gdata-server/build.xml (revision 0) @@ -0,0 +1,46 @@ + + + + + + Serverside Google Data API implementation + + + + + + + + + + + + + + + + + + + + + + Prepare dist directory + + + + + Distributing GData War + + + + + + + + + + + + \ No newline at end of file Index: contrib/gdata-server/lib/gdata-client-1.0.jar =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: contrib\gdata-server\lib\gdata-client-1.0.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Index: contrib/gdata-server/lib/easymock.jar =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: contrib\gdata-server\lib\easymock.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Index: contrib/gdata-server/lib/servlet-api.jar =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: contrib\gdata-server\lib\servlet-api.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Index: contrib/gdata-server/lib/commons-logging-1.1.jar =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: contrib\gdata-server\lib\commons-logging-1.1.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Index: contrib/gdata-server/lib/log4j-1.2.13.jar =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: contrib\gdata-server\lib\log4j-1.2.13.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Index: contrib/gdata-server/lib/commons-logging-1.1.jar =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: contrib\gdata-server\lib\commons-logging-1.1.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Index: contrib/gdata-server/lib/easymock.jar =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: contrib\gdata-server\lib\easymock.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Index: contrib/gdata-server/lib/gdata-client-1.0.jar =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: contrib\gdata-server\lib\gdata-client-1.0.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Index: contrib/gdata-server/lib/log4j-1.2.13.jar =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: contrib\gdata-server\lib\log4j-1.2.13.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Index: contrib/gdata-server/lib/servlet-api.jar =================================================================== Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream Property changes on: contrib\gdata-server\lib\servlet-api.jar ___________________________________________________________________ Name: svn:mime-type + application/octet-stream Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/package.html =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/package.html (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/package.html (revision 0) @@ -0,0 +1 @@ +Top-level package. \ No newline at end of file Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/data/package.html =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/data/package.html (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/data/package.html (revision 0) @@ -0,0 +1,10 @@ + + + + + + + +Contains classes for the internal representation of GData feeds and entries. + + \ No newline at end of file Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/data/package.html =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/data/package.html (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/data/package.html (revision 0) @@ -0,0 +1,10 @@ + + + + + + + +Contains classes for the internal representation of GData feeds and entries. + + \ No newline at end of file Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/package.html =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/package.html (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/package.html (revision 0) @@ -0,0 +1 @@ +Top-level package. \ No newline at end of file Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/FeedNotFoundException.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/FeedNotFoundException.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/FeedNotFoundException.java (revision 0) @@ -0,0 +1,52 @@ +package org.apache.lucene.gdata.server; + + +/** + * Will be thrown if a requested feed could not be found or is not + * registerd. + * + * @author Simon Willnauer + * + */ +public class FeedNotFoundException extends ServiceException { + + private static final long serialVersionUID = 1L; + + /** + * Constructs a FeedNotFoundException + */ + public FeedNotFoundException() { + super(); + + } + + /** + * @param arg0 - + * message + * @param arg1 - + * cause + */ + public FeedNotFoundException(String arg0, Throwable arg1) { + super(arg0, arg1); + + } + + /** + * @param arg0 - + * message + */ + public FeedNotFoundException(String arg0) { + super(arg0); + + } + + /** + * @param arg0 - + * cause + */ + public FeedNotFoundException(Throwable arg0) { + super(arg0); + + } + +} \ No newline at end of file Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataResponse.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataResponse.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataResponse.java (revision 0) @@ -0,0 +1,241 @@ +/** + * 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.io.Writer; + +import javax.servlet.http.HttpServletResponse; + +import org.apache.lucene.gdata.server.GDataRequest.OutputFormat; + +import com.google.gdata.data.BaseEntry; +import com.google.gdata.data.BaseFeed; +import com.google.gdata.data.ExtensionProfile; +import com.google.gdata.util.common.xml.XmlWriter; +import com.google.gdata.util.common.xml.XmlWriter.Namespace; + +/** + * The FeedRequest Class wraps the curren HttpServletResponse. Any action on the + * HttpServletRequest will be executed via this class. This represents an + * abstraction on the plain {@link HttpServletResponse}. Any action which has + * to be performed on the underlaying {@link HttpServletResponse} will be + * executed within this class. + *

+ * The GData basicly writes two different kinds ouf reponse to the output + * stream. + *

    + *
  1. update, delete or insert requests will respond with a statuscode and if + * successful the feed entry modified or created
  2. + *
  3. get requests will respond with a statuscode and if successful the + * requested feed
  4. + *
+ * + * For this purpose the {@link GDataResponse} class provides the overloaded + * method + * {@link org.apache.lucene.gdata.server.GDataResponse#sendResponse(BaseEntry, ExtensionProfile)} + * which sends the entry e.g feed to the output stream. + *

+ * + * + * + * + * @author Simon Willnauer + * + */ +public class GDataResponse { + private int error; + + private boolean isError = false; + + private String encoding; + + private OutputFormat outputFormat; + + private final HttpServletResponse response; + + private static final String DEFAUL_NAMESPACE_URI = "http://www.w3.org/2005/Atom"; + + private static final Namespace DEFAULT_NAMESPACE = new Namespace("", + DEFAUL_NAMESPACE_URI); + + /** + * Creates a new GDataResponse + * + * @param response - + * The underlaying {@link HttpServletResponse} + */ + public GDataResponse(HttpServletResponse response) { + if (response == null) + throw new IllegalArgumentException("response must not be null"); + this.response = response; + } + + /** + * Sets an error code to this FeedResponse. + * + * @param errorCode - + * {@link HttpServletResponse} error code + */ + public void setError(int errorCode) { + this.isError = true; + this.error = errorCode; + } + /** + * Sets the status of the underlaying response + * @see HttpServletResponse + * @param responseCode - the status of the response + */ + public void setResponseCode(int responseCode){ + this.response.setStatus(responseCode); + } + /** + * This method sends the specified error to the user if set + * + * @throws IOException - + * if an I/O Exception occures + */ + public void sendError() throws IOException { + if (this.isError) + this.response.sendError(this.error); + } + + /** + * @return - the {@link HttpServletResponse} writer + * @throws IOException - + * If an I/O exception occures + */ + public Writer getWriter() throws IOException { + return this.response.getWriter(); + } + + /** + * Sends a response for a get e.g. query request. This method must not + * invoked in a case of an error performing the requeste action. + * + * @param feed - + * the feed to respond to the client + * @param profile - + * the extension profil for the feed to write + * @throws IOException - + * if an I/O exception accures, often caused by an already + * closed Writer or OutputStream + * + */ + public void sendResponse(BaseFeed feed, ExtensionProfile profile) + throws IOException { + if (feed == null) + throw new IllegalArgumentException("feed must not be null"); + if(profile == null) + throw new IllegalArgumentException("extension profil must not be null"); + XmlWriter writer = createWriter(); + + if (this.outputFormat.equals(OutputFormat.ATOM)) + feed.generateAtom(writer, profile); + else + feed.generateRss(writer, profile); + + } + + /** + * + * Sends a response for an update, insert or delete request. This method + * must not invoked in a case of an error performing the requeste action. + * If the specified response format is ATOM the default namespace will be set to ATOM. + * @param entry - + * the modified / created entry to send + * @param profile - + * the entries extension profile + * @throws IOException - + * if an I/O exception accures, often caused by an already + * closed Writer or OutputStream + */ + public void sendResponse(BaseEntry entry, ExtensionProfile profile) + throws IOException { + if (entry == null) + throw new IllegalArgumentException("entry must not be null"); + if(profile == null) + throw new IllegalArgumentException("extension profil must not be null"); + XmlWriter writer = createWriter(); + if (this.outputFormat.equals(OutputFormat.ATOM)) + entry.generateAtom(writer, profile); + else + entry.generateRss(writer, profile); + } + + private XmlWriter createWriter() throws IOException { + XmlWriter writer = new XmlWriter(getWriter(), this.encoding); + // set the default namespace to Atom if Atom is the response format + if(this.outputFormat.equals(OutputFormat.ATOM)) + writer.setDefaultNamespace(DEFAULT_NAMESPACE); + return writer; + } + + /** + * This encoding will be used to encode the xml representation of feed or + * entry written to the {@link HttpServletResponse} output stream. + * + * @return - the entry / feed encoding + */ + public String getEncoding() { + return this.encoding; + } + + /** + * This encoding will be used to encode the xml representation of feed or + * entry written to the {@link HttpServletResponse} output stream. UTF-8 + * ISO-8859-1 + * + * @param encoding - + * string represents the encoding + */ + public void setEncoding(String encoding) { + this.encoding = encoding; + } + + /** + * @return - the response + * {@link org.apache.lucene.gdata.server.GDataRequest.OutputFormat} + */ + public OutputFormat getOutputFormat() { + return this.outputFormat; + } + + /** + * @param outputFormat - + * the response + * {@link org.apache.lucene.gdata.server.GDataRequest.OutputFormat} + */ + public void setOutputFormat(OutputFormat outputFormat) { + this.outputFormat = outputFormat; + } + /** + * @see Object#toString() + */ + @Override + public String toString(){ + StringBuilder builder = new StringBuilder(" GDataResponse: "); + builder.append("Error: ").append(this.error); + builder.append(" outputFormat: ").append(getOutputFormat()); + builder.append(" encoding: ").append(this.encoding); + + return builder.toString(); + + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/ServiceException.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/ServiceException.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/ServiceException.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.server; + +/** + * @author Simon Willnauer + * + */ +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); + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/Service.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/Service.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/Service.java (revision 0) @@ -0,0 +1,119 @@ +/** + * 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 com.google.gdata.data.BaseEntry; +import com.google.gdata.data.BaseFeed; + + +/** + * The Service class represents an interface to access the GData service + * componentes of the GData-Server. It encapsulates all interactions with the + * GData client. + *

+ * This class provides the base level common functionality required to access + * the GData components. It is also designed to act as a base class that can be + * extended for specific types of underlaying server components as different + * indexing or storage components. + *

+ *

+ * It could also encapsulate caching mechanismn build on top of the storage to + * reduce load on the storage component + *

+ * + * @author Simon Willnauer + * + * + */ +public abstract class Service { + + /** + * Service method to create an entry in an already created and existing + * feed. This method will create the entry and passes the entry to the + * indexing component to make the new entry accessable via get-queries. + * The response and the corresponding http status code will be added to the + * given FeedResponse. + * + * @param request - + * the current FeedRequest + * @param response - + * the current FeedResponse + * @return - the entry which has been created + * @throws ServiceException - + * if the corresponding feed does not exist or the storage can + * not be accessed + */ + public abstract BaseEntry createEntry(final GDataRequest request, + final GDataResponse response) throws ServiceException; + + /** + * Service Method to delete an entry specified in the given FeedRequest. + * This method will remove the entry permanently. There will be no + * possiblity to restore the entry. The response and the corresponding http + * status code will be added to the given FeedResponse. + * + * @param request - + * the current FeedRequest + * @param response - + * the current FeedResponse + * @return - the entry wich has been deleted + * @throws ServiceException - + * if the entry does not exist or the storage can not be + * accessed + */ + public abstract BaseEntry deleteEntry(GDataRequest request, final GDataResponse response) + throws ServiceException; + + /** + * Service method to update an existing entry in a existing feed context. + * The entry version will be checked and a ServiceException + * will be thrown if the version to update is outdated. The new entry will + * be passed to the indexing component to make the version accessable via + * get-queries. + * + * @param request - + * the current FeedRequest + * @param response - + * the current FeedResponse + * @return - the entry wich has been updated + * @throws ServiceException - + * if the corresponding feed does not exist, the storage can not + * be accessed or the version to update is out of date. + */ + public abstract BaseEntry updateEntry(final GDataRequest request, + final GDataResponse response) throws ServiceException; + + /** + * Service method to retrieve a requested Feed. The feed will be added to + * the given FeedResponse instance and can also be accessed + * via the FeedResponse object. + * + * @param request - + * the current FeedRequest + * @param response - + * the current FeedResponse + * @return - the requested feed + * + * @throws ServiceException - + * If the storage can not be accessed or the requested feed does + * not exist. + */ + public abstract BaseFeed getFeed(final GDataRequest request, final GDataResponse response) + throws ServiceException; + + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataService.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataService.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataService.java (revision 0) @@ -0,0 +1,139 @@ +/** + * 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 org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.gdata.server.registry.FeedRegistry; +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.util.ParseException; + +/** + * @author Simon Willnauer + * + */ +public class GDataService extends Service { + private static final Log LOGGER = LogFactory.getLog(GDataService.class); + private Storage storage = StorageFactory.getStorage(); + private FeedRegistry registry = FeedRegistry.getRegistry(); + /** + * @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); + + 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(); + try { + this.storage.deleteEntry(entryid); + } 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); + // TODO Auto-generated method stub + return null; + } + + /** + * @see org.apache.lucene.gdata.server.Service#getFeed(org.apache.lucene.gdata.server.GDataRequest, org.apache.lucene.gdata.server.GDataResponse) + */ + @Override + public BaseFeed getFeed(GDataRequest request, GDataResponse response) + throws ServiceException { + checkFeedIsRegisterd(request); + try { + // just for development + return this.storage.getFeed(request.getFeedId()); + } catch (StorageException e) { + ServiceException ex = new ServiceException("Could not get feed", + e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + } + + } + + + private BaseEntry buildEntry(final GDataRequest request) + throws ServiceException { + try { + return GDataEntityBuilder.buildEntry(request); + + } catch (ParseException e) { + ServiceException ex = new ServiceException( + "Could not parse entry from incoming request", e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + } catch (IOException e) { + ServiceException ex = new ServiceException( + "Could not read or open input stream", e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + } + } + /* + * checks whether the reqeuested feed is registered + */ + private void checkFeedIsRegisterd(GDataRequest request) throws FeedNotFoundException{ + if(this.registry.isFeedRegistered(request.getFeedId())) + throw new FeedNotFoundException("Feed could not be found - is not registed - Feed ID:"+request.getFeedId()); + } +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataEntityBuilder.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataEntityBuilder.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataEntityBuilder.java (revision 0) @@ -0,0 +1,169 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.gdata.server; + +import java.io.IOException; +import java.io.Reader; + +import org.apache.lucene.gdata.server.registry.DataBuilderException; +import org.apache.lucene.gdata.server.registry.FeedInstanceConfigurator; +import org.apache.lucene.gdata.server.registry.FeedRegistry; + +import com.google.gdata.data.BaseEntry; +import com.google.gdata.data.BaseFeed; +import com.google.gdata.data.ExtensionProfile; +import com.google.gdata.util.ParseException; + +/** + * {@link com.google.gdata.data.BaseFeed}, + * {@link com.google.gdata.data.BaseEntry} instances have to be build from a + * {@link java.io.Reader} instance as they come in from a client request or out + * of a storage. + *

+ * To provide a generic builder class the {@link GDataEntityBuilder} requests + * the type of the feed / entry and the corresponding + * {@link com.google.gdata.data.ExtensionProfile} form the global + * {@link org.apache.lucene.gdata.server.registry.FeedRegistry} and builds the + * instances from the provided reader. + *

+ * + * @author Simon Willnauer + * + */ +public class GDataEntityBuilder { + private static final FeedRegistry REGISTRY = FeedRegistry.getRegistry(); + + /** + * 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()); + } + + /** + * 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 + * @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) + 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(new ExtensionProfile(), 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()); + } + + /** + * 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 + * @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) + 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(); + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataRequestException.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataRequestException.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataRequestException.java (revision 0) @@ -0,0 +1,67 @@ +/** + * 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; + +/** + * This exception wraps all exceptions occure inside the {@link org.apache.lucene.gdata.server.GDataRequest} + * @author Simon Willnauer + * + */ +public class GDataRequestException extends Exception { + + /** + * Serial version ID. -> Implements Serializable + */ + private static final long serialVersionUID = -4440777051466950723L; + + /** + * Constructs a new GDataException + */ + public GDataRequestException() { + super(); + + } + + /** + * Constructs a new GDataException with a given message string + * @param arg0 - the excpetion message + */ + public GDataRequestException(String arg0) { + super(arg0); + + } + + /** + * Constructs a new GDataException with a given message string and cause + * @param arg0 - the exception message + * @param arg1 - the exception who caused this exception + */ + public GDataRequestException(String arg0, Throwable arg1) { + super(arg0, arg1); + + } + + /** + * Constructs a new GDataException with a given cause + * @param arg0 - exception cause + */ + public GDataRequestException(Throwable arg0) { + super(arg0); + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/ServiceFactory.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/ServiceFactory.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/ServiceFactory.java (revision 0) @@ -0,0 +1,56 @@ +/** + * 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 com.google.gdata.data.BaseFeed; +import com.google.gdata.data.extensions.EventFeed; + +/** + * 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() { + BaseFeed feed = new EventFeed(); + feed.getClass(); + return new GDataService(); + } +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataRequest.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataRequest.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataRequest.java (revision 0) @@ -0,0 +1,200 @@ +/** + * 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.io.Reader; +import java.util.Enumeration; +import java.util.Map; +import java.util.StringTokenizer; + +import javax.servlet.http.HttpServletRequest; + +/** + * The GDataRequest Class wraps the incoming HttpServletRequest. Needed + * information coming with the HttpServletRequest can be accessed directly. It + * represents an abstraction on the plain HttpServletRequest. Every GData + * specific data coming from the client will be availiable and can be accessed + * via the GDataRequest. + *

+ * GDataRequest instances will be passed to any action requested by the client. + * This class also holds the logic to retrieve important information like + * response format, the reqeusted feed instance and query parameters. + * + *

+ * + * @author Simon Willnauer + * + */ +/* this class might be extracted as an interface in later development */ +public class GDataRequest { + + + private static final String RESPONSE_FORMAT_PARAMETER = "alt"; + + private static final String RESPONSE_FORMAT_PARAMETER_RSS = "rss"; + + @SuppressWarnings("unused") + private static final String RESPONSE_FORMAT_PARAMETER_ATOM = "atom"; + + // Atom is the default resopnse format + private OutputFormat responseFormat = OutputFormat.ATOM; + + private final HttpServletRequest request; + + private String feedId = null; + + private String entryId = null; + + private String entryVersion = null; + + /** + * Creates a new FeedRequest + * + * @param requst - + * the incoming HttpServletReqeust + */ + public GDataRequest(final HttpServletRequest requst) { + if (requst == null) + throw new IllegalArgumentException("request must not be null "); + this.request = requst; + } + + /** + * Initialize the GDataRequest. This will initialize all needed values / + * attributes in this request. + * + * @throws GDataRequestException + */ + public void initializeRequest() throws GDataRequestException { + generateIdentificationProperties(); + setOutputFormat(); + } + + /** + * @return - the id of the requested feed + */ + public String getFeedId() { + + return this.feedId; + } + + /** + * @return - the entry id of the requested Entry if specified, otherwise + * null + */ + public String getEntryId() { + + return this.entryId; + } + + /** + * @return the version Id of the requested Entry if specified, otherwise + * null + */ + public String getEntryVersion() { + return this.entryVersion; + } + + /** + * A Reader instance to read form the client input stream + * + * @return - the HttpServletRequest {@link Reader} + * @throws IOException - + * if an I/O Exception occures + */ + public Reader getReader() throws IOException { + return this.request.getReader(); + } + + /** + * Returns the {@link HttpServletRequest} parameter map containig all GET + * request parameters. + * + * @return the parameter map + */ + @SuppressWarnings("unchecked") + public Map getQueryParameter() { + return this.request.getParameterMap(); + } + + /** + * The {@link HttpServletRequest} request parameter names + * + * @return parameter names enumeration + */ + @SuppressWarnings("unchecked") + public Enumeration getQueryParameterNames() { + return this.request.getParameterNames(); + } + + /** + * Either Atom or RSS + * + * @return - The output format requested by the client + */ + public OutputFormat getRequestedResponseFormat() { + + return this.responseFormat; + } + + private void generateIdentificationProperties() + throws GDataRequestException { + /* generate all needed data to identify the requested feed/entry */ + String pathInfo = this.request.getPathInfo(); + /* + * TODO this has to be changed to support the category queries. Category + * queries could also be rewrited in the Servlet. + */ + if (pathInfo.length() <= 1) + throw new GDataRequestException( + "No feed or entry specified for this request"); + StringTokenizer tokenizer = new StringTokenizer(pathInfo, "/"); + this.feedId = tokenizer.nextToken(); + this.entryId = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : ""; + this.entryVersion = tokenizer.hasMoreTokens() ? tokenizer.nextToken() + : ""; + + } + + private void setOutputFormat() { + String formatParameter = this.request + .getParameter(RESPONSE_FORMAT_PARAMETER); + if (formatParameter == null) + return; + if (formatParameter.equalsIgnoreCase(RESPONSE_FORMAT_PARAMETER_RSS)) + this.responseFormat = OutputFormat.RSS; + + } + + /** + * This enum represents the OutputFormat of the GDATA Server + * + * @author Simon Willnauer + * + */ + public static enum OutputFormat { + /** + * Output format ATOM. ATOM is the default response format. + */ + ATOM, + /** + * Output format RSS + */ + RSS + } +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/package.html =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/package.html (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/package.html (revision 0) @@ -0,0 +1,10 @@ + + + + + + + +GData-Server classes encapsulation all protocol-level interactions and underlaying GData components. + + \ No newline at end of file Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/FeedNotFoundException.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/FeedNotFoundException.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/FeedNotFoundException.java (revision 0) @@ -0,0 +1,52 @@ +package org.apache.lucene.gdata.server; + + +/** + * Will be thrown if a requested feed could not be found or is not + * registerd. + * + * @author Simon Willnauer + * + */ +public class FeedNotFoundException extends ServiceException { + + private static final long serialVersionUID = 1L; + + /** + * Constructs a FeedNotFoundException + */ + public FeedNotFoundException() { + super(); + + } + + /** + * @param arg0 - + * message + * @param arg1 - + * cause + */ + public FeedNotFoundException(String arg0, Throwable arg1) { + super(arg0, arg1); + + } + + /** + * @param arg0 - + * message + */ + public FeedNotFoundException(String arg0) { + super(arg0); + + } + + /** + * @param arg0 - + * cause + */ + public FeedNotFoundException(Throwable arg0) { + super(arg0); + + } + +} \ No newline at end of file Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataEntityBuilder.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataEntityBuilder.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataEntityBuilder.java (revision 0) @@ -0,0 +1,169 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.gdata.server; + +import java.io.IOException; +import java.io.Reader; + +import org.apache.lucene.gdata.server.registry.DataBuilderException; +import org.apache.lucene.gdata.server.registry.FeedInstanceConfigurator; +import org.apache.lucene.gdata.server.registry.FeedRegistry; + +import com.google.gdata.data.BaseEntry; +import com.google.gdata.data.BaseFeed; +import com.google.gdata.data.ExtensionProfile; +import com.google.gdata.util.ParseException; + +/** + * {@link com.google.gdata.data.BaseFeed}, + * {@link com.google.gdata.data.BaseEntry} instances have to be build from a + * {@link java.io.Reader} instance as they come in from a client request or out + * of a storage. + *

+ * To provide a generic builder class the {@link GDataEntityBuilder} requests + * the type of the feed / entry and the corresponding + * {@link com.google.gdata.data.ExtensionProfile} form the global + * {@link org.apache.lucene.gdata.server.registry.FeedRegistry} and builds the + * instances from the provided reader. + *

+ * + * @author Simon Willnauer + * + */ +public class GDataEntityBuilder { + private static final FeedRegistry REGISTRY = FeedRegistry.getRegistry(); + + /** + * 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()); + } + + /** + * 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 + * @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) + 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(new ExtensionProfile(), 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()); + } + + /** + * 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 + * @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) + 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(); + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataRequest.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataRequest.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataRequest.java (revision 0) @@ -0,0 +1,200 @@ +/** + * 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.io.Reader; +import java.util.Enumeration; +import java.util.Map; +import java.util.StringTokenizer; + +import javax.servlet.http.HttpServletRequest; + +/** + * The GDataRequest Class wraps the incoming HttpServletRequest. Needed + * information coming with the HttpServletRequest can be accessed directly. It + * represents an abstraction on the plain HttpServletRequest. Every GData + * specific data coming from the client will be availiable and can be accessed + * via the GDataRequest. + *

+ * GDataRequest instances will be passed to any action requested by the client. + * This class also holds the logic to retrieve important information like + * response format, the reqeusted feed instance and query parameters. + * + *

+ * + * @author Simon Willnauer + * + */ +/* this class might be extracted as an interface in later development */ +public class GDataRequest { + + + private static final String RESPONSE_FORMAT_PARAMETER = "alt"; + + private static final String RESPONSE_FORMAT_PARAMETER_RSS = "rss"; + + @SuppressWarnings("unused") + private static final String RESPONSE_FORMAT_PARAMETER_ATOM = "atom"; + + // Atom is the default resopnse format + private OutputFormat responseFormat = OutputFormat.ATOM; + + private final HttpServletRequest request; + + private String feedId = null; + + private String entryId = null; + + private String entryVersion = null; + + /** + * Creates a new FeedRequest + * + * @param requst - + * the incoming HttpServletReqeust + */ + public GDataRequest(final HttpServletRequest requst) { + if (requst == null) + throw new IllegalArgumentException("request must not be null "); + this.request = requst; + } + + /** + * Initialize the GDataRequest. This will initialize all needed values / + * attributes in this request. + * + * @throws GDataRequestException + */ + public void initializeRequest() throws GDataRequestException { + generateIdentificationProperties(); + setOutputFormat(); + } + + /** + * @return - the id of the requested feed + */ + public String getFeedId() { + + return this.feedId; + } + + /** + * @return - the entry id of the requested Entry if specified, otherwise + * null + */ + public String getEntryId() { + + return this.entryId; + } + + /** + * @return the version Id of the requested Entry if specified, otherwise + * null + */ + public String getEntryVersion() { + return this.entryVersion; + } + + /** + * A Reader instance to read form the client input stream + * + * @return - the HttpServletRequest {@link Reader} + * @throws IOException - + * if an I/O Exception occures + */ + public Reader getReader() throws IOException { + return this.request.getReader(); + } + + /** + * Returns the {@link HttpServletRequest} parameter map containig all GET + * request parameters. + * + * @return the parameter map + */ + @SuppressWarnings("unchecked") + public Map getQueryParameter() { + return this.request.getParameterMap(); + } + + /** + * The {@link HttpServletRequest} request parameter names + * + * @return parameter names enumeration + */ + @SuppressWarnings("unchecked") + public Enumeration getQueryParameterNames() { + return this.request.getParameterNames(); + } + + /** + * Either Atom or RSS + * + * @return - The output format requested by the client + */ + public OutputFormat getRequestedResponseFormat() { + + return this.responseFormat; + } + + private void generateIdentificationProperties() + throws GDataRequestException { + /* generate all needed data to identify the requested feed/entry */ + String pathInfo = this.request.getPathInfo(); + /* + * TODO this has to be changed to support the category queries. Category + * queries could also be rewrited in the Servlet. + */ + if (pathInfo.length() <= 1) + throw new GDataRequestException( + "No feed or entry specified for this request"); + StringTokenizer tokenizer = new StringTokenizer(pathInfo, "/"); + this.feedId = tokenizer.nextToken(); + this.entryId = tokenizer.hasMoreTokens() ? tokenizer.nextToken() : ""; + this.entryVersion = tokenizer.hasMoreTokens() ? tokenizer.nextToken() + : ""; + + } + + private void setOutputFormat() { + String formatParameter = this.request + .getParameter(RESPONSE_FORMAT_PARAMETER); + if (formatParameter == null) + return; + if (formatParameter.equalsIgnoreCase(RESPONSE_FORMAT_PARAMETER_RSS)) + this.responseFormat = OutputFormat.RSS; + + } + + /** + * This enum represents the OutputFormat of the GDATA Server + * + * @author Simon Willnauer + * + */ + public static enum OutputFormat { + /** + * Output format ATOM. ATOM is the default response format. + */ + ATOM, + /** + * Output format RSS + */ + RSS + } +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataRequestException.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataRequestException.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataRequestException.java (revision 0) @@ -0,0 +1,67 @@ +/** + * 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; + +/** + * This exception wraps all exceptions occure inside the {@link org.apache.lucene.gdata.server.GDataRequest} + * @author Simon Willnauer + * + */ +public class GDataRequestException extends Exception { + + /** + * Serial version ID. -> Implements Serializable + */ + private static final long serialVersionUID = -4440777051466950723L; + + /** + * Constructs a new GDataException + */ + public GDataRequestException() { + super(); + + } + + /** + * Constructs a new GDataException with a given message string + * @param arg0 - the excpetion message + */ + public GDataRequestException(String arg0) { + super(arg0); + + } + + /** + * Constructs a new GDataException with a given message string and cause + * @param arg0 - the exception message + * @param arg1 - the exception who caused this exception + */ + public GDataRequestException(String arg0, Throwable arg1) { + super(arg0, arg1); + + } + + /** + * Constructs a new GDataException with a given cause + * @param arg0 - exception cause + */ + public GDataRequestException(Throwable arg0) { + super(arg0); + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataResponse.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataResponse.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataResponse.java (revision 0) @@ -0,0 +1,241 @@ +/** + * 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.io.Writer; + +import javax.servlet.http.HttpServletResponse; + +import org.apache.lucene.gdata.server.GDataRequest.OutputFormat; + +import com.google.gdata.data.BaseEntry; +import com.google.gdata.data.BaseFeed; +import com.google.gdata.data.ExtensionProfile; +import com.google.gdata.util.common.xml.XmlWriter; +import com.google.gdata.util.common.xml.XmlWriter.Namespace; + +/** + * The FeedRequest Class wraps the curren HttpServletResponse. Any action on the + * HttpServletRequest will be executed via this class. This represents an + * abstraction on the plain {@link HttpServletResponse}. Any action which has + * to be performed on the underlaying {@link HttpServletResponse} will be + * executed within this class. + *

+ * The GData basicly writes two different kinds ouf reponse to the output + * stream. + *

    + *
  1. update, delete or insert requests will respond with a statuscode and if + * successful the feed entry modified or created
  2. + *
  3. get requests will respond with a statuscode and if successful the + * requested feed
  4. + *
+ * + * For this purpose the {@link GDataResponse} class provides the overloaded + * method + * {@link org.apache.lucene.gdata.server.GDataResponse#sendResponse(BaseEntry, ExtensionProfile)} + * which sends the entry e.g feed to the output stream. + *

+ * + * + * + * + * @author Simon Willnauer + * + */ +public class GDataResponse { + private int error; + + private boolean isError = false; + + private String encoding; + + private OutputFormat outputFormat; + + private final HttpServletResponse response; + + private static final String DEFAUL_NAMESPACE_URI = "http://www.w3.org/2005/Atom"; + + private static final Namespace DEFAULT_NAMESPACE = new Namespace("", + DEFAUL_NAMESPACE_URI); + + /** + * Creates a new GDataResponse + * + * @param response - + * The underlaying {@link HttpServletResponse} + */ + public GDataResponse(HttpServletResponse response) { + if (response == null) + throw new IllegalArgumentException("response must not be null"); + this.response = response; + } + + /** + * Sets an error code to this FeedResponse. + * + * @param errorCode - + * {@link HttpServletResponse} error code + */ + public void setError(int errorCode) { + this.isError = true; + this.error = errorCode; + } + /** + * Sets the status of the underlaying response + * @see HttpServletResponse + * @param responseCode - the status of the response + */ + public void setResponseCode(int responseCode){ + this.response.setStatus(responseCode); + } + /** + * This method sends the specified error to the user if set + * + * @throws IOException - + * if an I/O Exception occures + */ + public void sendError() throws IOException { + if (this.isError) + this.response.sendError(this.error); + } + + /** + * @return - the {@link HttpServletResponse} writer + * @throws IOException - + * If an I/O exception occures + */ + public Writer getWriter() throws IOException { + return this.response.getWriter(); + } + + /** + * Sends a response for a get e.g. query request. This method must not + * invoked in a case of an error performing the requeste action. + * + * @param feed - + * the feed to respond to the client + * @param profile - + * the extension profil for the feed to write + * @throws IOException - + * if an I/O exception accures, often caused by an already + * closed Writer or OutputStream + * + */ + public void sendResponse(BaseFeed feed, ExtensionProfile profile) + throws IOException { + if (feed == null) + throw new IllegalArgumentException("feed must not be null"); + if(profile == null) + throw new IllegalArgumentException("extension profil must not be null"); + XmlWriter writer = createWriter(); + + if (this.outputFormat.equals(OutputFormat.ATOM)) + feed.generateAtom(writer, profile); + else + feed.generateRss(writer, profile); + + } + + /** + * + * Sends a response for an update, insert or delete request. This method + * must not invoked in a case of an error performing the requeste action. + * If the specified response format is ATOM the default namespace will be set to ATOM. + * @param entry - + * the modified / created entry to send + * @param profile - + * the entries extension profile + * @throws IOException - + * if an I/O exception accures, often caused by an already + * closed Writer or OutputStream + */ + public void sendResponse(BaseEntry entry, ExtensionProfile profile) + throws IOException { + if (entry == null) + throw new IllegalArgumentException("entry must not be null"); + if(profile == null) + throw new IllegalArgumentException("extension profil must not be null"); + XmlWriter writer = createWriter(); + if (this.outputFormat.equals(OutputFormat.ATOM)) + entry.generateAtom(writer, profile); + else + entry.generateRss(writer, profile); + } + + private XmlWriter createWriter() throws IOException { + XmlWriter writer = new XmlWriter(getWriter(), this.encoding); + // set the default namespace to Atom if Atom is the response format + if(this.outputFormat.equals(OutputFormat.ATOM)) + writer.setDefaultNamespace(DEFAULT_NAMESPACE); + return writer; + } + + /** + * This encoding will be used to encode the xml representation of feed or + * entry written to the {@link HttpServletResponse} output stream. + * + * @return - the entry / feed encoding + */ + public String getEncoding() { + return this.encoding; + } + + /** + * This encoding will be used to encode the xml representation of feed or + * entry written to the {@link HttpServletResponse} output stream. UTF-8 + * ISO-8859-1 + * + * @param encoding - + * string represents the encoding + */ + public void setEncoding(String encoding) { + this.encoding = encoding; + } + + /** + * @return - the response + * {@link org.apache.lucene.gdata.server.GDataRequest.OutputFormat} + */ + public OutputFormat getOutputFormat() { + return this.outputFormat; + } + + /** + * @param outputFormat - + * the response + * {@link org.apache.lucene.gdata.server.GDataRequest.OutputFormat} + */ + public void setOutputFormat(OutputFormat outputFormat) { + this.outputFormat = outputFormat; + } + /** + * @see Object#toString() + */ + @Override + public String toString(){ + StringBuilder builder = new StringBuilder(" GDataResponse: "); + builder.append("Error: ").append(this.error); + builder.append(" outputFormat: ").append(getOutputFormat()); + builder.append(" encoding: ").append(this.encoding); + + return builder.toString(); + + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataService.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataService.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/GDataService.java (revision 0) @@ -0,0 +1,139 @@ +/** + * 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 org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.gdata.server.registry.FeedRegistry; +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.util.ParseException; + +/** + * @author Simon Willnauer + * + */ +public class GDataService extends Service { + private static final Log LOGGER = LogFactory.getLog(GDataService.class); + private Storage storage = StorageFactory.getStorage(); + private FeedRegistry registry = FeedRegistry.getRegistry(); + /** + * @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); + + 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(); + try { + this.storage.deleteEntry(entryid); + } 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); + // TODO Auto-generated method stub + return null; + } + + /** + * @see org.apache.lucene.gdata.server.Service#getFeed(org.apache.lucene.gdata.server.GDataRequest, org.apache.lucene.gdata.server.GDataResponse) + */ + @Override + public BaseFeed getFeed(GDataRequest request, GDataResponse response) + throws ServiceException { + checkFeedIsRegisterd(request); + try { + // just for development + return this.storage.getFeed(request.getFeedId()); + } catch (StorageException e) { + ServiceException ex = new ServiceException("Could not get feed", + e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + } + + } + + + private BaseEntry buildEntry(final GDataRequest request) + throws ServiceException { + try { + return GDataEntityBuilder.buildEntry(request); + + } catch (ParseException e) { + ServiceException ex = new ServiceException( + "Could not parse entry from incoming request", e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + } catch (IOException e) { + ServiceException ex = new ServiceException( + "Could not read or open input stream", e); + ex.setStackTrace(e.getStackTrace()); + throw ex; + } + } + /* + * checks whether the reqeuested feed is registered + */ + private void checkFeedIsRegisterd(GDataRequest request) throws FeedNotFoundException{ + if(this.registry.isFeedRegistered(request.getFeedId())) + throw new FeedNotFoundException("Feed could not be found - is not registed - Feed ID:"+request.getFeedId()); + } +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/package.html =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/package.html (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/package.html (revision 0) @@ -0,0 +1,10 @@ + + + + + + + +GData-Server classes encapsulation all protocol-level interactions and underlaying GData components. + + \ No newline at end of file Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/DataBuilderException.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/DataBuilderException.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/DataBuilderException.java (revision 0) @@ -0,0 +1,50 @@ +/** + * + */ +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: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryBuilder.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryBuilder.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryBuilder.java (revision 0) @@ -0,0 +1,26 @@ +/** + * + */ +package org.apache.lucene.gdata.server.registry; + +import com.google.gdata.data.Feed; + +/** + * @author Simon Willnauer + * + */ +public class RegistryBuilder { + + /** + * + */ + public static void buildRegistry(){ + // TODO Implement this!! -- just for develping purposes + FeedRegistry reg = FeedRegistry.getRegistry(); + FeedInstanceConfigurator configurator = new FeedInstanceConfigurator(); + configurator.setFeedType(Feed.class); + configurator.setFeedId("myFeed"); + reg.registerFeed(configurator); + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/FeedInstanceConfigurator.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/FeedInstanceConfigurator.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/FeedInstanceConfigurator.java (revision 0) @@ -0,0 +1,51 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.gdata.server.registry; + +/** + * @author Simon Willnauer + * + */ +public class FeedInstanceConfigurator { + private Class feedType; + private String feedId; + /** + * @return Returns the feedType. + */ + public Class getFeedType() { + return this.feedType; + } + /** + * @param feedType The feedType to set. + */ + protected void setFeedType(Class feedType) { + this.feedType = feedType; + } + /** + * @return Returns the feedURL. + */ + public String getFeedId() { + return this.feedId; + } + /** + * @param feedURL The feedURL to set. + */ + protected void setFeedId(String feedURL) { + this.feedId = feedURL; + } + + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/FeedRegistry.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/FeedRegistry.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/FeedRegistry.java (revision 0) @@ -0,0 +1,97 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.gdata.server.registry; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * + * 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: + *
    + *
  1. the feed id - where the feed can be accessed via http methodes
  2. + *
  3. the feed type - feed types are implementations of the abstract + * {@link com.google.gdata.data.BaseFeed}
  4. + *
+ * The registry will be set up at start up of the server application and can be + * accessed from other components to get configurations according to incoming + * requests. + * + * @author Simon Willnauer + * + */ +public class FeedRegistry { + private static FeedRegistry INSTANCE; + + private static final Log LOGGER = LogFactory.getLog(FeedRegistry.class); + + private final Map feedTypMap = new HashMap(); + + private FeedRegistry() { + // private - singleton + } + + /** + * @return a Sinleton registry instance + */ + public static synchronized FeedRegistry getRegistry() { + if (INSTANCE == null) + INSTANCE = new FeedRegistry(); + return INSTANCE; + } + /** + * Registers a {@link FeedInstanceConfigurator} + * @param configurator - the configurator to register in the registry + */ + protected void registerFeed(FeedInstanceConfigurator configurator) { + if (configurator == null) { + LOGGER.warn("Feedconfigurator is null -- skip registration"); + return; + } + this.feedTypMap.put(configurator.getFeedId(), configurator); + } + + /** + * Looks up the {@link FeedInstanceConfigurator} by the given feed id. + * @param feedId + * @return - the {@link FeedInstanceConfigurator} or null if the no configuration for this feed has been registered + */ + public FeedInstanceConfigurator getFeedConfigurator(String feedId) { + if (feedId == null) + throw new IllegalArgumentException( + "Feed URL is null - must not be null to get registered feedtype"); + return this.feedTypMap.get(feedId); + } + + protected void flushRegistry() { + this.feedTypMap.clear(); + } + + /** + * @param feedId - the id of the feed as the feed is registered + * @return - true if and only if the feed is registered, otherwise false. + */ + public boolean isFeedRegistered(String feedId) { + return this.feedTypMap.containsKey(feedId); + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/package.html =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/package.html (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/package.html (revision 0) @@ -0,0 +1,10 @@ + + + + + + + +Internal registry - registering feeds and configurations + + \ No newline at end of file Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/DataBuilderException.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/DataBuilderException.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/DataBuilderException.java (revision 0) @@ -0,0 +1,50 @@ +/** + * + */ +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: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/FeedInstanceConfigurator.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/FeedInstanceConfigurator.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/FeedInstanceConfigurator.java (revision 0) @@ -0,0 +1,51 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.gdata.server.registry; + +/** + * @author Simon Willnauer + * + */ +public class FeedInstanceConfigurator { + private Class feedType; + private String feedId; + /** + * @return Returns the feedType. + */ + public Class getFeedType() { + return this.feedType; + } + /** + * @param feedType The feedType to set. + */ + protected void setFeedType(Class feedType) { + this.feedType = feedType; + } + /** + * @return Returns the feedURL. + */ + public String getFeedId() { + return this.feedId; + } + /** + * @param feedURL The feedURL to set. + */ + protected void setFeedId(String feedURL) { + this.feedId = feedURL; + } + + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/FeedRegistry.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/FeedRegistry.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/FeedRegistry.java (revision 0) @@ -0,0 +1,97 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.gdata.server.registry; + +import java.util.HashMap; +import java.util.Map; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * + * 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: + *
    + *
  1. the feed id - where the feed can be accessed via http methodes
  2. + *
  3. the feed type - feed types are implementations of the abstract + * {@link com.google.gdata.data.BaseFeed}
  4. + *
+ * The registry will be set up at start up of the server application and can be + * accessed from other components to get configurations according to incoming + * requests. + * + * @author Simon Willnauer + * + */ +public class FeedRegistry { + private static FeedRegistry INSTANCE; + + private static final Log LOGGER = LogFactory.getLog(FeedRegistry.class); + + private final Map feedTypMap = new HashMap(); + + private FeedRegistry() { + // private - singleton + } + + /** + * @return a Sinleton registry instance + */ + public static synchronized FeedRegistry getRegistry() { + if (INSTANCE == null) + INSTANCE = new FeedRegistry(); + return INSTANCE; + } + /** + * Registers a {@link FeedInstanceConfigurator} + * @param configurator - the configurator to register in the registry + */ + protected void registerFeed(FeedInstanceConfigurator configurator) { + if (configurator == null) { + LOGGER.warn("Feedconfigurator is null -- skip registration"); + return; + } + this.feedTypMap.put(configurator.getFeedId(), configurator); + } + + /** + * Looks up the {@link FeedInstanceConfigurator} by the given feed id. + * @param feedId + * @return - the {@link FeedInstanceConfigurator} or null if the no configuration for this feed has been registered + */ + public FeedInstanceConfigurator getFeedConfigurator(String feedId) { + if (feedId == null) + throw new IllegalArgumentException( + "Feed URL is null - must not be null to get registered feedtype"); + return this.feedTypMap.get(feedId); + } + + protected void flushRegistry() { + this.feedTypMap.clear(); + } + + /** + * @param feedId - the id of the feed as the feed is registered + * @return - true if and only if the feed is registered, otherwise false. + */ + public boolean isFeedRegistered(String feedId) { + return this.feedTypMap.containsKey(feedId); + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/package.html =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/package.html (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/package.html (revision 0) @@ -0,0 +1,10 @@ + + + + + + + +Internal registry - registering feeds and configurations + + \ No newline at end of file Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryBuilder.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryBuilder.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/registry/RegistryBuilder.java (revision 0) @@ -0,0 +1,26 @@ +/** + * + */ +package org.apache.lucene.gdata.server.registry; + +import com.google.gdata.data.Feed; + +/** + * @author Simon Willnauer + * + */ +public class RegistryBuilder { + + /** + * + */ + public static void buildRegistry(){ + // TODO Implement this!! -- just for develping purposes + FeedRegistry reg = FeedRegistry.getRegistry(); + FeedInstanceConfigurator configurator = new FeedInstanceConfigurator(); + configurator.setFeedType(Feed.class); + configurator.setFeedId("myFeed"); + reg.registerFeed(configurator); + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/Service.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/Service.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/Service.java (revision 0) @@ -0,0 +1,119 @@ +/** + * 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 com.google.gdata.data.BaseEntry; +import com.google.gdata.data.BaseFeed; + + +/** + * The Service class represents an interface to access the GData service + * componentes of the GData-Server. It encapsulates all interactions with the + * GData client. + *

+ * This class provides the base level common functionality required to access + * the GData components. It is also designed to act as a base class that can be + * extended for specific types of underlaying server components as different + * indexing or storage components. + *

+ *

+ * It could also encapsulate caching mechanismn build on top of the storage to + * reduce load on the storage component + *

+ * + * @author Simon Willnauer + * + * + */ +public abstract class Service { + + /** + * Service method to create an entry in an already created and existing + * feed. This method will create the entry and passes the entry to the + * indexing component to make the new entry accessable via get-queries. + * The response and the corresponding http status code will be added to the + * given FeedResponse. + * + * @param request - + * the current FeedRequest + * @param response - + * the current FeedResponse + * @return - the entry which has been created + * @throws ServiceException - + * if the corresponding feed does not exist or the storage can + * not be accessed + */ + public abstract BaseEntry createEntry(final GDataRequest request, + final GDataResponse response) throws ServiceException; + + /** + * Service Method to delete an entry specified in the given FeedRequest. + * This method will remove the entry permanently. There will be no + * possiblity to restore the entry. The response and the corresponding http + * status code will be added to the given FeedResponse. + * + * @param request - + * the current FeedRequest + * @param response - + * the current FeedResponse + * @return - the entry wich has been deleted + * @throws ServiceException - + * if the entry does not exist or the storage can not be + * accessed + */ + public abstract BaseEntry deleteEntry(GDataRequest request, final GDataResponse response) + throws ServiceException; + + /** + * Service method to update an existing entry in a existing feed context. + * The entry version will be checked and a ServiceException + * will be thrown if the version to update is outdated. The new entry will + * be passed to the indexing component to make the version accessable via + * get-queries. + * + * @param request - + * the current FeedRequest + * @param response - + * the current FeedResponse + * @return - the entry wich has been updated + * @throws ServiceException - + * if the corresponding feed does not exist, the storage can not + * be accessed or the version to update is out of date. + */ + public abstract BaseEntry updateEntry(final GDataRequest request, + final GDataResponse response) throws ServiceException; + + /** + * Service method to retrieve a requested Feed. The feed will be added to + * the given FeedResponse instance and can also be accessed + * via the FeedResponse object. + * + * @param request - + * the current FeedRequest + * @param response - + * the current FeedResponse + * @return - the requested feed + * + * @throws ServiceException - + * If the storage can not be accessed or the requested feed does + * not exist. + */ + public abstract BaseFeed getFeed(final GDataRequest request, final GDataResponse response) + throws ServiceException; + + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/ServiceException.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/ServiceException.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/ServiceException.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.server; + +/** + * @author Simon Willnauer + * + */ +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); + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/server/ServiceFactory.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/server/ServiceFactory.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/server/ServiceFactory.java (revision 0) @@ -0,0 +1,56 @@ +/** + * 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 com.google.gdata.data.BaseFeed; +import com.google.gdata.data.extensions.EventFeed; + +/** + * 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() { + BaseFeed feed = new EventFeed(); + feed.getClass(); + return new GDataService(); + } +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/RequestControllerServlet.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/RequestControllerServlet.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/RequestControllerServlet.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; + +import java.io.IOException; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.gdata.server.registry.RegistryBuilder; +import org.apache.lucene.gdata.servlet.handler.DefaultRequestHandlerFactory; +import org.apache.lucene.gdata.servlet.handler.GDataRequestHandler; +import org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory; + +/** + * Provides a clean basic interface for GDATA Client API and requests to the + * GDATA Server. This Servlet dispatches the incoming requests to defined GDATA + * request handlers. Each of the handler processes the incoming request and + * responds according to the requested action. + * + * @author Simon Willnauer + * + */ +public class RequestControllerServlet extends AbstractGdataServlet { + private static RequestHandlerFactory HANDLER_FACTORY = null; + private static final Log LOGGER = LogFactory.getLog(RequestControllerServlet.class); + + /** + * Version ID since this class implements + * + * @see java.io.Serializable + */ + private static final long serialVersionUID = 7540810742476175576L; + + /** + * @see javax.servlet.http.HttpServlet#doDelete(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + @Override + protected void doDelete(HttpServletRequest arg0, HttpServletResponse arg1) + throws ServletException, IOException { + GDataRequestHandler hanlder = HANDLER_FACTORY.getDeleteHandler(); + if(LOGGER.isInfoEnabled()) + LOGGER.info("Process DELETE request"); + + hanlder.processRequest(arg0, arg1); + } + + /** + * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + @Override + protected void doGet(HttpServletRequest arg0, HttpServletResponse arg1) + throws ServletException, IOException { + GDataRequestHandler hanlder = HANDLER_FACTORY.getQueryHandler(); + if(LOGGER.isInfoEnabled()) + LOGGER.info("Process GET request"); + + hanlder.processRequest(arg0, arg1); + } + + /** + * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + @Override + protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1) + throws ServletException, IOException { + GDataRequestHandler hanlder = HANDLER_FACTORY.getInsertHandler(); + if(LOGGER.isInfoEnabled()) + LOGGER.info("Process POST request"); + hanlder.processRequest(arg0, arg1); + } + + /** + * @see javax.servlet.http.HttpServlet#doPut(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + @Override + protected void doPut(HttpServletRequest arg0, HttpServletResponse arg1) + throws ServletException, IOException { + GDataRequestHandler hanlder = HANDLER_FACTORY.getUpdateHandler(); + if(LOGGER.isInfoEnabled()) + LOGGER.info("Process PUT request"); + hanlder.processRequest(arg0, arg1); + } + + /** + * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig) + */ + @Override + public void init(ServletConfig arg0) { + /* + * The Factory implementation could be configured as an initial + * parameter or by an external config file. + * + */ + HANDLER_FACTORY = RequestHandlerFactory + .getInstance(DefaultRequestHandlerFactory.class); + RegistryBuilder.buildRegistry(); + + } + + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/AbstractGdataServlet.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/AbstractGdataServlet.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/AbstractGdataServlet.java (revision 0) @@ -0,0 +1,97 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.servlet; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * Provides an abstract class to be subclassed to create an GDATA servlet + * suitable for a GDATA serverside implementation. + * + * @see javax.servlet.http.HttpServlet + * + * @author Simon Willnauer + * + */ +public abstract class AbstractGdataServlet extends HttpServlet { + private static final String METHOD_HEADER_NAME = "x-http-method-override"; + + private static final String METHOD_DELETE = "DELETE"; + + private static final String METHOD_GET = "GET"; + + private static final String METHOD_POST = "POST"; + + private static final String METHOD_PUT = "PUT"; + + /** + * This overwrites the protected service method to dispatch + * the request to the correponding do method. There is + * ususaly no need for overwriting this method. The GData protool and the + * Google GData API uses the x-http-method-override header to + * get through firewalls. The http method will be overritten by the + * x-http-method-override and dispatched to the + * doXxx methods defined in this class. This method + * is an GDATA-specific version of the {@link javax.servlet.Servlet#service} + * method. + * + * @see HttpServlet#service(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + @Override + protected void service(HttpServletRequest arg0, HttpServletResponse arg1) + throws ServletException, IOException { + if (arg0.getHeader(METHOD_HEADER_NAME) == null) { + super.service(arg0, arg1); + return; + } + overrideMethod(arg0, arg1); + + } + + private void overrideMethod(HttpServletRequest arg0, + HttpServletResponse arg1) throws ServletException, IOException { + final String method = arg0.getMethod(); + final String overrideHeaderMethod = arg0.getHeader(METHOD_HEADER_NAME); + if (overrideHeaderMethod.equals(method)) { + super.service(arg0, arg1); + return; + } + // These methodes are use by GDATA Client APIs + if (overrideHeaderMethod.equals(METHOD_DELETE)) { + doDelete(arg0, arg1); + } else if (overrideHeaderMethod.equals(METHOD_GET)) { + doGet(arg0, arg1); + } else if (overrideHeaderMethod.equals(METHOD_POST)) { + doPost(arg0, arg1); + } else if (overrideHeaderMethod.equals(METHOD_PUT)) { + doPut(arg0, arg1); + } else { + // if another method has been overwritten follow the HttpServlet + // implementation + super.service(arg0, arg1); + } + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/package.html =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/package.html (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/package.html (revision 0) @@ -0,0 +1,10 @@ + + + + + + + +Servlets acting as basic interfaces for gdata requests. + + Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/AbstractGdataServlet.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/AbstractGdataServlet.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/AbstractGdataServlet.java (revision 0) @@ -0,0 +1,97 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.servlet; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServlet; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * Provides an abstract class to be subclassed to create an GDATA servlet + * suitable for a GDATA serverside implementation. + * + * @see javax.servlet.http.HttpServlet + * + * @author Simon Willnauer + * + */ +public abstract class AbstractGdataServlet extends HttpServlet { + private static final String METHOD_HEADER_NAME = "x-http-method-override"; + + private static final String METHOD_DELETE = "DELETE"; + + private static final String METHOD_GET = "GET"; + + private static final String METHOD_POST = "POST"; + + private static final String METHOD_PUT = "PUT"; + + /** + * This overwrites the protected service method to dispatch + * the request to the correponding do method. There is + * ususaly no need for overwriting this method. The GData protool and the + * Google GData API uses the x-http-method-override header to + * get through firewalls. The http method will be overritten by the + * x-http-method-override and dispatched to the + * doXxx methods defined in this class. This method + * is an GDATA-specific version of the {@link javax.servlet.Servlet#service} + * method. + * + * @see HttpServlet#service(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + @Override + protected void service(HttpServletRequest arg0, HttpServletResponse arg1) + throws ServletException, IOException { + if (arg0.getHeader(METHOD_HEADER_NAME) == null) { + super.service(arg0, arg1); + return; + } + overrideMethod(arg0, arg1); + + } + + private void overrideMethod(HttpServletRequest arg0, + HttpServletResponse arg1) throws ServletException, IOException { + final String method = arg0.getMethod(); + final String overrideHeaderMethod = arg0.getHeader(METHOD_HEADER_NAME); + if (overrideHeaderMethod.equals(method)) { + super.service(arg0, arg1); + return; + } + // These methodes are use by GDATA Client APIs + if (overrideHeaderMethod.equals(METHOD_DELETE)) { + doDelete(arg0, arg1); + } else if (overrideHeaderMethod.equals(METHOD_GET)) { + doGet(arg0, arg1); + } else if (overrideHeaderMethod.equals(METHOD_POST)) { + doPost(arg0, arg1); + } else if (overrideHeaderMethod.equals(METHOD_PUT)) { + doPut(arg0, arg1); + } else { + // if another method has been overwritten follow the HttpServlet + // implementation + super.service(arg0, arg1); + } + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultGetHandler.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultGetHandler.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultGetHandler.java (revision 0) @@ -0,0 +1,88 @@ +/** + * 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.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.ServiceFactory; + +import com.google.gdata.data.BaseFeed; +import com.google.gdata.data.ExtensionProfile; + +/** + * 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 { + try { + initializeRequestHandler(request, response); + } catch (GDataRequestException e) { + sendError(); + return; + } + ServiceFactory serviceFactory = ServiceFactory.getInstance(); + Service service = serviceFactory.getService(); + try { + BaseFeed feed = service + .getFeed(this.feedRequest, this.feedResponse); + if (LOG.isInfoEnabled()) + LOG.info("Requested output formate: " + + this.feedRequest.getRequestedResponseFormat()); + this.feedResponse.setOutputFormat(this.feedRequest + .getRequestedResponseFormat()); + this.feedResponse.sendResponse(feed, new ExtensionProfile()); + } 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(); + } + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultRequestHandlerFactory.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultRequestHandlerFactory.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultRequestHandlerFactory.java (revision 0) @@ -0,0 +1,69 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.servlet.handler; + +/** + * Default implementation for RequestHandlerFactory Builds the + * {@link org.apache.lucene.gdata.servlet.handler.GDataRequestHandler} + * instances. + * + * @author Simon Willnauer + * + */ +public class DefaultRequestHandlerFactory extends RequestHandlerFactory { + + DefaultRequestHandlerFactory() { + // + } + + /** + * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getUpdateHandler() + */ + @Override + public GDataRequestHandler getUpdateHandler() { + + return new DefaultUpdateHandler(); + } + + /** + * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getDeleteHandler() + */ + @Override + public GDataRequestHandler getDeleteHandler() { + + return new DefaultDeleteHandler(); + } + + /** + * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getQueryHandler() + */ + @Override + public GDataRequestHandler getQueryHandler() { + + return new DefaultGetHandler(); + } + + /** + * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getInsertHandler() + */ + @Override + public GDataRequestHandler getInsertHandler() { + + return new DefaultInsertHandler(); + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultDeleteHandler.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultDeleteHandler.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultDeleteHandler.java (revision 0) @@ -0,0 +1,82 @@ +/** + * 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.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.ServiceFactory; + +/** + * 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: + *

+ *
    + *
  1. if the entry could be deleted - HTTP status code 200 OK
  2. + *
  3. if an error occures - HTTP status code 500 INTERNAL SERVER ERROR
  4. + *
  5. if the resource could not found - HTTP status code 404 NOT FOUND
  6. + *
+ * + * @author Simon Willnauer + * + */ +public class DefaultDeleteHandler extends AbstractGdataRequestHandler { + private static final Log LOG = LogFactory + .getLog(DefaultDeleteHandler.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 { + try { + initializeRequestHandler(request, response); + } catch (GDataRequestException e) { + sendError(); + return; + } + ServiceFactory serviceFactory = ServiceFactory.getInstance(); + Service service = serviceFactory.getService(); + try { + service.deleteEntry(this.feedRequest, this.feedResponse); + } catch (FeedNotFoundException e) { + LOG.error("Could not process DeleteFeed request Feed Not Found- " + + e.getMessage(), e); + setError(HttpServletResponse.SC_NOT_FOUND); + sendError(); + } catch (ServiceException e) { + LOG.error("Could not process DeleteFeed request - " + + e.getMessage(), e); + setError(HttpServletResponse.SC_BAD_REQUEST); + sendError(); + } + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultUpdateHandler.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultUpdateHandler.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultUpdateHandler.java (revision 0) @@ -0,0 +1,93 @@ +/** + * 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.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.ServiceFactory; + +import com.google.gdata.data.BaseEntry; +import com.google.gdata.data.ExtensionProfile; + +/** + * 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: + *

+ *
    + *
  1. if the entry was successfully updated - HTTP status code 200 OK
  2. + *
  3. if an error occures - HTTP status code 500 INTERNAL SERVER ERROR
  4. + *
  5. if the resource could not found - HTTP status code 404 NOT FOUND
  6. + *
+ * + * @author Simon Willnauer + * + */ +public class DefaultUpdateHandler extends AbstractGdataRequestHandler { + private static final Log LOG = LogFactory + .getLog(DefaultUpdateHandler.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 { + try { + initializeRequestHandler(request, response); + } catch (GDataRequestException e) { + sendError(); + return; + } + ServiceFactory serviceFactory = ServiceFactory.getInstance(); + Service service = serviceFactory.getService(); + try { + BaseEntry entry = service.updateEntry(this.feedRequest, + this.feedResponse); + setFeedResponseFormat(); + setFeedResponseStatus(HttpServletResponse.SC_OK); + this.feedResponse.sendResponse(entry, new ExtensionProfile()); + }catch (FeedNotFoundException e) { + LOG.error("Could not process UpdateFeed request - " + + e.getMessage(), e); + setError(HttpServletResponse.SC_NOT_FOUND); + + sendError(); + } + catch (ServiceException e) { + + LOG.error("Could not process UpdateFeed request - " + + e.getMessage(), e); + setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + + sendError(); + } + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandlerException.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandlerException.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandlerException.java (revision 0) @@ -0,0 +1,64 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.servlet.handler; + +/** + * @author Simon Willnauer + * + */ +public class GDataRequestHandlerException extends RuntimeException { + + /** + * + */ + private static final long serialVersionUID = -418225239671624153L; + + + /** + * + */ + public GDataRequestHandlerException() { + super(); + + } + + /** + * @param arg0 + */ + public GDataRequestHandlerException(String arg0) { + super(arg0); + + } + + /** + * @param arg0 + * @param arg1 + */ + public GDataRequestHandlerException(String arg0, Throwable arg1) { + super(arg0, arg1); + + } + + /** + * @param arg0 + */ + public GDataRequestHandlerException(Throwable arg0) { + super(arg0); + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultInsertHandler.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultInsertHandler.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultInsertHandler.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.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.ServiceFactory; + +import com.google.gdata.data.BaseEntry; +import com.google.gdata.data.ExtensionProfile; + +/** + * 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: + *

+ *
    + *
  1. if the entry was added - HTTP status code 200 OK
  2. + *
  3. if an error occures - HTTP status code 500 INTERNAL SERVER ERROR
  4. + *
  5. if the resource could not found - HTTP status code 404 NOT FOUND
  6. + *
+ *

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); + /** + * @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 { + try { + initializeRequestHandler(request,response); + } catch (GDataRequestException e) { + sendError(); + return; + } + Service service = ServiceFactory.getInstance().getService(); + try{ + BaseEntry entry = service.createEntry(this.feedRequest,this.feedResponse); + setFeedResponseFormat(); + setFeedResponseStatus(HttpServletResponse.SC_CREATED); + this.feedResponse.sendResponse(entry, new ExtensionProfile()); + + }catch (ServiceException e) { + LOG.error("Could not process GetFeed request - "+e.getMessage(),e); + setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + this.feedResponse.sendError(); + } + + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandler.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandler.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandler.java (revision 0) @@ -0,0 +1,55 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.gdata.servlet.handler; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * Based on the Command pattern [GoF], the Command and Controller Strategy + * suggests providing a generic interface to the handler components to which the + * controller may delegate responsibility, minimizing the coupling among these + * components. + * + * Adding to or changing the work that needs to be completed by these handlers + * does not require any changes to the interface between the controller and the + * handlers, but rather to the type and/or content of the commands. This provides + * a flexible and easily extensible mechanism for developers to add request + * handling behaviors. + * + * The controller invokes the processRequest method from the corresponding servlet doXXX + * method to delegate the request to the handler. + * + * + * @author Simon Willnauer + * + */ +public interface GDataRequestHandler { + /** + * Processes the GDATA Client request + * + * @param request - the client request to be processed + * @param response - the response to the client request + * @throws ServletException - if a servlet exception is thrown by the request or response + * @throws IOException - if an input/output error occurs due to accessing an IO steam + */ + public abstract void processRequest(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException; +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractGdataRequestHandler.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractGdataRequestHandler.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractGdataRequestHandler.java (revision 0) @@ -0,0 +1,85 @@ +/** + * 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; + +/** + * @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) + throws GDataRequestException { + this.feedRequest = new GDataRequest(request); + 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); + } + + + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/package.html =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/package.html (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/package.html (revision 0) @@ -0,0 +1,10 @@ + + + + + + + +GData Request Handler. + + Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/RequestHandlerFactory.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/RequestHandlerFactory.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/RequestHandlerFactory.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.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); + + } + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractGdataRequestHandler.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractGdataRequestHandler.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/AbstractGdataRequestHandler.java (revision 0) @@ -0,0 +1,85 @@ +/** + * 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; + +/** + * @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) + throws GDataRequestException { + this.feedRequest = new GDataRequest(request); + 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); + } + + + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultDeleteHandler.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultDeleteHandler.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultDeleteHandler.java (revision 0) @@ -0,0 +1,82 @@ +/** + * 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.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.ServiceFactory; + +/** + * 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: + *

+ *
    + *
  1. if the entry could be deleted - HTTP status code 200 OK
  2. + *
  3. if an error occures - HTTP status code 500 INTERNAL SERVER ERROR
  4. + *
  5. if the resource could not found - HTTP status code 404 NOT FOUND
  6. + *
+ * + * @author Simon Willnauer + * + */ +public class DefaultDeleteHandler extends AbstractGdataRequestHandler { + private static final Log LOG = LogFactory + .getLog(DefaultDeleteHandler.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 { + try { + initializeRequestHandler(request, response); + } catch (GDataRequestException e) { + sendError(); + return; + } + ServiceFactory serviceFactory = ServiceFactory.getInstance(); + Service service = serviceFactory.getService(); + try { + service.deleteEntry(this.feedRequest, this.feedResponse); + } catch (FeedNotFoundException e) { + LOG.error("Could not process DeleteFeed request Feed Not Found- " + + e.getMessage(), e); + setError(HttpServletResponse.SC_NOT_FOUND); + sendError(); + } catch (ServiceException e) { + LOG.error("Could not process DeleteFeed request - " + + e.getMessage(), e); + setError(HttpServletResponse.SC_BAD_REQUEST); + sendError(); + } + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultGetHandler.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultGetHandler.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultGetHandler.java (revision 0) @@ -0,0 +1,88 @@ +/** + * 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.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.ServiceFactory; + +import com.google.gdata.data.BaseFeed; +import com.google.gdata.data.ExtensionProfile; + +/** + * 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 { + try { + initializeRequestHandler(request, response); + } catch (GDataRequestException e) { + sendError(); + return; + } + ServiceFactory serviceFactory = ServiceFactory.getInstance(); + Service service = serviceFactory.getService(); + try { + BaseFeed feed = service + .getFeed(this.feedRequest, this.feedResponse); + if (LOG.isInfoEnabled()) + LOG.info("Requested output formate: " + + this.feedRequest.getRequestedResponseFormat()); + this.feedResponse.setOutputFormat(this.feedRequest + .getRequestedResponseFormat()); + this.feedResponse.sendResponse(feed, new ExtensionProfile()); + } 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(); + } + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultInsertHandler.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultInsertHandler.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultInsertHandler.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.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.ServiceFactory; + +import com.google.gdata.data.BaseEntry; +import com.google.gdata.data.ExtensionProfile; + +/** + * 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: + *

+ *
    + *
  1. if the entry was added - HTTP status code 200 OK
  2. + *
  3. if an error occures - HTTP status code 500 INTERNAL SERVER ERROR
  4. + *
  5. if the resource could not found - HTTP status code 404 NOT FOUND
  6. + *
+ *

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); + /** + * @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 { + try { + initializeRequestHandler(request,response); + } catch (GDataRequestException e) { + sendError(); + return; + } + Service service = ServiceFactory.getInstance().getService(); + try{ + BaseEntry entry = service.createEntry(this.feedRequest,this.feedResponse); + setFeedResponseFormat(); + setFeedResponseStatus(HttpServletResponse.SC_CREATED); + this.feedResponse.sendResponse(entry, new ExtensionProfile()); + + }catch (ServiceException e) { + LOG.error("Could not process GetFeed request - "+e.getMessage(),e); + setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + this.feedResponse.sendError(); + } + + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultRequestHandlerFactory.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultRequestHandlerFactory.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultRequestHandlerFactory.java (revision 0) @@ -0,0 +1,69 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.servlet.handler; + +/** + * Default implementation for RequestHandlerFactory Builds the + * {@link org.apache.lucene.gdata.servlet.handler.GDataRequestHandler} + * instances. + * + * @author Simon Willnauer + * + */ +public class DefaultRequestHandlerFactory extends RequestHandlerFactory { + + DefaultRequestHandlerFactory() { + // + } + + /** + * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getUpdateHandler() + */ + @Override + public GDataRequestHandler getUpdateHandler() { + + return new DefaultUpdateHandler(); + } + + /** + * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getDeleteHandler() + */ + @Override + public GDataRequestHandler getDeleteHandler() { + + return new DefaultDeleteHandler(); + } + + /** + * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getQueryHandler() + */ + @Override + public GDataRequestHandler getQueryHandler() { + + return new DefaultGetHandler(); + } + + /** + * @see org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory#getInsertHandler() + */ + @Override + public GDataRequestHandler getInsertHandler() { + + return new DefaultInsertHandler(); + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultUpdateHandler.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultUpdateHandler.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/DefaultUpdateHandler.java (revision 0) @@ -0,0 +1,93 @@ +/** + * 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.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.ServiceFactory; + +import com.google.gdata.data.BaseEntry; +import com.google.gdata.data.ExtensionProfile; + +/** + * 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: + *

+ *
    + *
  1. if the entry was successfully updated - HTTP status code 200 OK
  2. + *
  3. if an error occures - HTTP status code 500 INTERNAL SERVER ERROR
  4. + *
  5. if the resource could not found - HTTP status code 404 NOT FOUND
  6. + *
+ * + * @author Simon Willnauer + * + */ +public class DefaultUpdateHandler extends AbstractGdataRequestHandler { + private static final Log LOG = LogFactory + .getLog(DefaultUpdateHandler.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 { + try { + initializeRequestHandler(request, response); + } catch (GDataRequestException e) { + sendError(); + return; + } + ServiceFactory serviceFactory = ServiceFactory.getInstance(); + Service service = serviceFactory.getService(); + try { + BaseEntry entry = service.updateEntry(this.feedRequest, + this.feedResponse); + setFeedResponseFormat(); + setFeedResponseStatus(HttpServletResponse.SC_OK); + this.feedResponse.sendResponse(entry, new ExtensionProfile()); + }catch (FeedNotFoundException e) { + LOG.error("Could not process UpdateFeed request - " + + e.getMessage(), e); + setError(HttpServletResponse.SC_NOT_FOUND); + + sendError(); + } + catch (ServiceException e) { + + LOG.error("Could not process UpdateFeed request - " + + e.getMessage(), e); + setError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR); + + sendError(); + } + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandler.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandler.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandler.java (revision 0) @@ -0,0 +1,55 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.gdata.servlet.handler; + +import java.io.IOException; + +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +/** + * + * Based on the Command pattern [GoF], the Command and Controller Strategy + * suggests providing a generic interface to the handler components to which the + * controller may delegate responsibility, minimizing the coupling among these + * components. + * + * Adding to or changing the work that needs to be completed by these handlers + * does not require any changes to the interface between the controller and the + * handlers, but rather to the type and/or content of the commands. This provides + * a flexible and easily extensible mechanism for developers to add request + * handling behaviors. + * + * The controller invokes the processRequest method from the corresponding servlet doXXX + * method to delegate the request to the handler. + * + * + * @author Simon Willnauer + * + */ +public interface GDataRequestHandler { + /** + * Processes the GDATA Client request + * + * @param request - the client request to be processed + * @param response - the response to the client request + * @throws ServletException - if a servlet exception is thrown by the request or response + * @throws IOException - if an input/output error occurs due to accessing an IO steam + */ + public abstract void processRequest(HttpServletRequest request, + HttpServletResponse response) throws ServletException, IOException; +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandlerException.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandlerException.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/GDataRequestHandlerException.java (revision 0) @@ -0,0 +1,64 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.servlet.handler; + +/** + * @author Simon Willnauer + * + */ +public class GDataRequestHandlerException extends RuntimeException { + + /** + * + */ + private static final long serialVersionUID = -418225239671624153L; + + + /** + * + */ + public GDataRequestHandlerException() { + super(); + + } + + /** + * @param arg0 + */ + public GDataRequestHandlerException(String arg0) { + super(arg0); + + } + + /** + * @param arg0 + * @param arg1 + */ + public GDataRequestHandlerException(String arg0, Throwable arg1) { + super(arg0, arg1); + + } + + /** + * @param arg0 + */ + public GDataRequestHandlerException(Throwable arg0) { + super(arg0); + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/package.html =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/package.html (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/package.html (revision 0) @@ -0,0 +1,10 @@ + + + + + + + +GData Request Handler. + + Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/RequestHandlerFactory.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/RequestHandlerFactory.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/handler/RequestHandlerFactory.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.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); + + } + + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/package.html =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/package.html (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/package.html (revision 0) @@ -0,0 +1,10 @@ + + + + + + + +Servlets acting as basic interfaces for gdata requests. + + Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/RequestControllerServlet.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/RequestControllerServlet.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/servlet/RequestControllerServlet.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; + +import java.io.IOException; + +import javax.servlet.ServletConfig; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.lucene.gdata.server.registry.RegistryBuilder; +import org.apache.lucene.gdata.servlet.handler.DefaultRequestHandlerFactory; +import org.apache.lucene.gdata.servlet.handler.GDataRequestHandler; +import org.apache.lucene.gdata.servlet.handler.RequestHandlerFactory; + +/** + * Provides a clean basic interface for GDATA Client API and requests to the + * GDATA Server. This Servlet dispatches the incoming requests to defined GDATA + * request handlers. Each of the handler processes the incoming request and + * responds according to the requested action. + * + * @author Simon Willnauer + * + */ +public class RequestControllerServlet extends AbstractGdataServlet { + private static RequestHandlerFactory HANDLER_FACTORY = null; + private static final Log LOGGER = LogFactory.getLog(RequestControllerServlet.class); + + /** + * Version ID since this class implements + * + * @see java.io.Serializable + */ + private static final long serialVersionUID = 7540810742476175576L; + + /** + * @see javax.servlet.http.HttpServlet#doDelete(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + @Override + protected void doDelete(HttpServletRequest arg0, HttpServletResponse arg1) + throws ServletException, IOException { + GDataRequestHandler hanlder = HANDLER_FACTORY.getDeleteHandler(); + if(LOGGER.isInfoEnabled()) + LOGGER.info("Process DELETE request"); + + hanlder.processRequest(arg0, arg1); + } + + /** + * @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + @Override + protected void doGet(HttpServletRequest arg0, HttpServletResponse arg1) + throws ServletException, IOException { + GDataRequestHandler hanlder = HANDLER_FACTORY.getQueryHandler(); + if(LOGGER.isInfoEnabled()) + LOGGER.info("Process GET request"); + + hanlder.processRequest(arg0, arg1); + } + + /** + * @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + @Override + protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1) + throws ServletException, IOException { + GDataRequestHandler hanlder = HANDLER_FACTORY.getInsertHandler(); + if(LOGGER.isInfoEnabled()) + LOGGER.info("Process POST request"); + hanlder.processRequest(arg0, arg1); + } + + /** + * @see javax.servlet.http.HttpServlet#doPut(javax.servlet.http.HttpServletRequest, + * javax.servlet.http.HttpServletResponse) + */ + @Override + protected void doPut(HttpServletRequest arg0, HttpServletResponse arg1) + throws ServletException, IOException { + GDataRequestHandler hanlder = HANDLER_FACTORY.getUpdateHandler(); + if(LOGGER.isInfoEnabled()) + LOGGER.info("Process PUT request"); + hanlder.processRequest(arg0, arg1); + } + + /** + * @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig) + */ + @Override + public void init(ServletConfig arg0) { + /* + * The Factory implementation could be configured as an initial + * parameter or by an external config file. + * + */ + HANDLER_FACTORY = RequestHandlerFactory + .getInstance(DefaultRequestHandlerFactory.class); + RegistryBuilder.buildRegistry(); + + } + + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/IDGenerator.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/IDGenerator.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/IDGenerator.java (revision 0) @@ -0,0 +1,171 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.storage; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * This is the main entry ID generator to generate unique ids for each entry. + * The Generator uses {@link java.security.SecureRandom} Numbers and the + * {@link java.lang.System#currentTimeMillis()} to create a semi-unique sting; + * The string will be digested by a {@link java.security.MessageDigest} which + * returns a byte array. The generator encodes the byte array as a hex string. + *

+ * The generated Id's will cached in a + * {@link java.util.concurrent.BlockingQueue} and reproduced if an id has been + * removed. + *

+ * + * @author Simon Willnauer + * + */ +public class IDGenerator { + private final SecureRandom secureRandom; + + private final MessageDigest mdigest; + + private final BlockingQueue blockingQueue; + + private Thread runner; + + private static final int DEFAULT_CAPACITY = 10; + + protected static final Log LOGGER = LogFactory.getLog(IDGenerator.class); + + /** + * Constructs a new ID generator. with a fixed capacity of prebuild ids. The + * default capacity is 10. Every given parameter less than 10 will be + * ignored. + * + * @param capacity - + * capacity of the prebuild id queue + * @throws NoSuchAlgorithmException - + * if the algorithm does not exist + */ + public IDGenerator(int capacity) throws NoSuchAlgorithmException { + + this.secureRandom = SecureRandom.getInstance("SHA1PRNG"); + this.mdigest = MessageDigest.getInstance("SHA-1"); + this.blockingQueue = new ArrayBlockingQueue( + (capacity < DEFAULT_CAPACITY ? DEFAULT_CAPACITY : capacity), + false); + startIDProducer(); + + } + + /** + * This method takes a gnerated id from the IDProducer queue and retruns it. + * If no ID is available this method will wait until an ID is produced. This + * implementation is thread-safe. + * + * @return a UID + * @throws InterruptedException - + * if interrupted while waiting + */ + public String getUID() throws InterruptedException { + return this.blockingQueue.take(); + } + + private void startIDProducer() { + if (this.runner == null) { + UIDProducer producer = new UIDProducer(this.blockingQueue, + this.secureRandom, this.mdigest); + this.runner = new Thread(producer); + this.runner.start(); + } + } + + /** + * @return the current size of the queue + */ + public int getQueueSize() { + return this.blockingQueue.size(); + } + + /** + * Stops the id-producer + */ + public void stopIDGenerator() { + this.runner.interrupt(); + } + + private class UIDProducer implements Runnable { + SecureRandom random; + + BlockingQueue queue; + + MessageDigest digest; + + UIDProducer(BlockingQueue queue, SecureRandom random, + MessageDigest digest) { + this.queue = queue; + this.random = random; + this.digest = digest; + + } + + /** + * @see java.lang.Runnable#run() + */ + public void run() { + + while (true) { + try { + this.queue.put(produce()); + } catch (InterruptedException e) { + LOGGER + .warn("UIDProducer has been interrupted -- runner is going down"); + return; + } + } + + } + + private String produce() { + String randomNumber = new Integer(this.random.nextInt()).toString(); + byte[] byteResult = this.digest.digest(randomNumber.getBytes()); + return hexEncode(byteResult); + } + + } + + /** + * Encodes a given byte array into a hex string. + * + * @param input - + * the byte array to encode + * @return hex string representation of the given byte array + */ + static String hexEncode(byte[] input) { + StringBuffer result = new StringBuffer(); + char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f' }; + for (int idx = 0; idx < input.length; ++idx) { + byte b = input[idx]; + result.append(digits[(b & 0xf0) >> 4]); + result.append(digits[b & 0x0f]); + } + return result.toString(); + } +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageException.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageException.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageException.java (revision 0) @@ -0,0 +1,45 @@ +/** + * + */ +package org.apache.lucene.gdata.storage; + +/** + * @author Simon Willnauer + * + */ +public class StorageException extends Exception { + + /** + * + */ + public StorageException() { + super(); + // TODO Auto-generated constructor stub + } + + /** + * @param message + */ + public StorageException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + */ + public StorageException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + /** + * @param cause + */ + public StorageException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/Storage.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/Storage.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/Storage.java (revision 0) @@ -0,0 +1,23 @@ +/** + * + */ +package org.apache.lucene.gdata.storage; + +import java.util.List; + +import com.google.gdata.data.BaseEntry; +import com.google.gdata.data.BaseFeed; + +/** + * @author Simon Willnauer + * + */ +public interface Storage { + + public abstract BaseEntry storeEntry(BaseEntry entry, String feedId)throws StorageException; + public abstract void deleteEntry(String entryId)throws StorageException; + public abstract BaseEntry updateEntry(BaseEntry entry)throws StorageException; + public abstract BaseFeed getFeed(String feedId)throws StorageException; + public abstract BaseEntry getEntry(String entryId, String feedId)throws StorageException; + public abstract List getEntries(List entryIdList, String feedId)throws StorageException; +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageFactory.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageFactory.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageFactory.java (revision 0) @@ -0,0 +1,31 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.gdata.storage; + +/** + * + * @author Simon Willnauer + * + */ +public class StorageFactory { + /** + * Creates a {@link Storage} instance + * @return - a storage instance + */ + public static Storage getStorage(){ + return null; + } +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/package.html =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/package.html (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/package.html (revision 0) @@ -0,0 +1,10 @@ + + + + + + + +Feed / Enty storage + + Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/IDGenerator.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/IDGenerator.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/IDGenerator.java (revision 0) @@ -0,0 +1,171 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.lucene.gdata.storage; + +import java.security.MessageDigest; +import java.security.NoSuchAlgorithmException; +import java.security.SecureRandom; +import java.util.concurrent.ArrayBlockingQueue; +import java.util.concurrent.BlockingQueue; + +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; + +/** + * This is the main entry ID generator to generate unique ids for each entry. + * The Generator uses {@link java.security.SecureRandom} Numbers and the + * {@link java.lang.System#currentTimeMillis()} to create a semi-unique sting; + * The string will be digested by a {@link java.security.MessageDigest} which + * returns a byte array. The generator encodes the byte array as a hex string. + *

+ * The generated Id's will cached in a + * {@link java.util.concurrent.BlockingQueue} and reproduced if an id has been + * removed. + *

+ * + * @author Simon Willnauer + * + */ +public class IDGenerator { + private final SecureRandom secureRandom; + + private final MessageDigest mdigest; + + private final BlockingQueue blockingQueue; + + private Thread runner; + + private static final int DEFAULT_CAPACITY = 10; + + protected static final Log LOGGER = LogFactory.getLog(IDGenerator.class); + + /** + * Constructs a new ID generator. with a fixed capacity of prebuild ids. The + * default capacity is 10. Every given parameter less than 10 will be + * ignored. + * + * @param capacity - + * capacity of the prebuild id queue + * @throws NoSuchAlgorithmException - + * if the algorithm does not exist + */ + public IDGenerator(int capacity) throws NoSuchAlgorithmException { + + this.secureRandom = SecureRandom.getInstance("SHA1PRNG"); + this.mdigest = MessageDigest.getInstance("SHA-1"); + this.blockingQueue = new ArrayBlockingQueue( + (capacity < DEFAULT_CAPACITY ? DEFAULT_CAPACITY : capacity), + false); + startIDProducer(); + + } + + /** + * This method takes a gnerated id from the IDProducer queue and retruns it. + * If no ID is available this method will wait until an ID is produced. This + * implementation is thread-safe. + * + * @return a UID + * @throws InterruptedException - + * if interrupted while waiting + */ + public String getUID() throws InterruptedException { + return this.blockingQueue.take(); + } + + private void startIDProducer() { + if (this.runner == null) { + UIDProducer producer = new UIDProducer(this.blockingQueue, + this.secureRandom, this.mdigest); + this.runner = new Thread(producer); + this.runner.start(); + } + } + + /** + * @return the current size of the queue + */ + public int getQueueSize() { + return this.blockingQueue.size(); + } + + /** + * Stops the id-producer + */ + public void stopIDGenerator() { + this.runner.interrupt(); + } + + private class UIDProducer implements Runnable { + SecureRandom random; + + BlockingQueue queue; + + MessageDigest digest; + + UIDProducer(BlockingQueue queue, SecureRandom random, + MessageDigest digest) { + this.queue = queue; + this.random = random; + this.digest = digest; + + } + + /** + * @see java.lang.Runnable#run() + */ + public void run() { + + while (true) { + try { + this.queue.put(produce()); + } catch (InterruptedException e) { + LOGGER + .warn("UIDProducer has been interrupted -- runner is going down"); + return; + } + } + + } + + private String produce() { + String randomNumber = new Integer(this.random.nextInt()).toString(); + byte[] byteResult = this.digest.digest(randomNumber.getBytes()); + return hexEncode(byteResult); + } + + } + + /** + * Encodes a given byte array into a hex string. + * + * @param input - + * the byte array to encode + * @return hex string representation of the given byte array + */ + static String hexEncode(byte[] input) { + StringBuffer result = new StringBuffer(); + char[] digits = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', + 'a', 'b', 'c', 'd', 'e', 'f' }; + for (int idx = 0; idx < input.length; ++idx) { + byte b = input[idx]; + result.append(digits[(b & 0xf0) >> 4]); + result.append(digits[b & 0x0f]); + } + return result.toString(); + } +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/package.html =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/package.html (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/package.html (revision 0) @@ -0,0 +1,10 @@ + + + + + + + +Feed / Enty storage + + Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/Storage.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/Storage.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/Storage.java (revision 0) @@ -0,0 +1,23 @@ +/** + * + */ +package org.apache.lucene.gdata.storage; + +import java.util.List; + +import com.google.gdata.data.BaseEntry; +import com.google.gdata.data.BaseFeed; + +/** + * @author Simon Willnauer + * + */ +public interface Storage { + + public abstract BaseEntry storeEntry(BaseEntry entry, String feedId)throws StorageException; + public abstract void deleteEntry(String entryId)throws StorageException; + public abstract BaseEntry updateEntry(BaseEntry entry)throws StorageException; + public abstract BaseFeed getFeed(String feedId)throws StorageException; + public abstract BaseEntry getEntry(String entryId, String feedId)throws StorageException; + public abstract List getEntries(List entryIdList, String feedId)throws StorageException; +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageException.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageException.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageException.java (revision 0) @@ -0,0 +1,45 @@ +/** + * + */ +package org.apache.lucene.gdata.storage; + +/** + * @author Simon Willnauer + * + */ +public class StorageException extends Exception { + + /** + * + */ + public StorageException() { + super(); + // TODO Auto-generated constructor stub + } + + /** + * @param message + */ + public StorageException(String message) { + super(message); + // TODO Auto-generated constructor stub + } + + /** + * @param message + * @param cause + */ + public StorageException(String message, Throwable cause) { + super(message, cause); + // TODO Auto-generated constructor stub + } + + /** + * @param cause + */ + public StorageException(Throwable cause) { + super(cause); + // TODO Auto-generated constructor stub + } + +} Index: contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageFactory.java =================================================================== --- contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageFactory.java (revision 0) +++ contrib/gdata-server/src/java/org/apache/lucene/gdata/storage/StorageFactory.java (revision 0) @@ -0,0 +1,31 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.gdata.storage; + +/** + * + * @author Simon Willnauer + * + */ +public class StorageFactory { + /** + * Creates a {@link Storage} instance + * @return - a storage instance + */ + public static Storage getStorage(){ + return null; + } +} Index: contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataResponse.java =================================================================== --- contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataResponse.java (revision 0) +++ contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataResponse.java (revision 0) @@ -0,0 +1,161 @@ +package org.apache.lucene.gdata.server; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; + +import javax.servlet.http.HttpServletResponse; + +import junit.framework.TestCase; + +import org.apache.lucene.gdata.server.GDataRequest.OutputFormat; +import org.easymock.MockControl; + +import com.google.gdata.data.Entry; +import com.google.gdata.data.ExtensionProfile; +import com.google.gdata.data.Feed; +import com.google.gdata.data.PlainTextConstruct; +/** + * + * @author Simon Willnauer + * + */ +public class TestGDataResponse extends TestCase { + private GDataResponse response; + private HttpServletResponse httpResponse; + private MockControl control; + private static String generatedFeedAtom = "Test"; + private static String generatedEntryAtom = "Test"; + private static String generatedFeedRSS = "Test"; + private static String generatedEntryRSS = "Test"; + protected void setUp() throws Exception { + this.control = MockControl.createControl(HttpServletResponse.class); + this.httpResponse = (HttpServletResponse)this.control.getMock(); + this.response = new GDataResponse(this.httpResponse); + + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + + public void testConstructor(){ + try{ + new GDataResponse(null); + fail("IllegalArgumentExceptin expected"); + }catch (IllegalArgumentException e) { + // TODO: handle exception + } + } + /* + * Test method for 'org.apache.lucene.gdata.server.GDataResponse.sendResponse(BaseFeed, ExtensionProfile)' + */ + public void testSendResponseBaseFeedExtensionProfile() throws IOException { + try{ + Feed f = null; + this.response.sendResponse(f,new ExtensionProfile()); + fail("Exception expected"); + }catch (IllegalArgumentException e) { + // + } + + try{ + Feed f = createFeed(); + this.response.sendResponse(f,null); + fail("Exception expected"); + }catch (IllegalArgumentException e) { + // + } + StringWriter stringWriter = new StringWriter(); + PrintWriter writer = new PrintWriter(stringWriter); + + this.control.expectAndReturn(this.httpResponse.getWriter(),writer); + this.response.setOutputFormat(OutputFormat.ATOM); + this.control.replay(); + + this.response.sendResponse(createFeed(),new ExtensionProfile + ()); + assertEquals("Simple XML representation",stringWriter.toString(),generatedFeedAtom); + this.control.reset(); + + stringWriter = new StringWriter(); + writer = new PrintWriter(stringWriter); + + this.control.expectAndReturn(this.httpResponse.getWriter(),writer); + this.response.setOutputFormat(OutputFormat.RSS); + this.control.replay(); + + this.response.sendResponse(createFeed(),new ExtensionProfile + ()); + assertEquals("Simple XML representation",stringWriter.toString(),generatedFeedRSS); + + + + + } + + /* + * Test method for 'org.apache.lucene.gdata.server.GDataResponse.sendResponse(BaseEntry, ExtensionProfile)' + */ + public void testSendResponseBaseEntryExtensionProfile() throws IOException { + try{ + Entry e = null; + this.response.sendResponse(e,new ExtensionProfile()); + fail("Exception expected"); + }catch (IllegalArgumentException e) { + // + } + try{ + Entry e = createEntry(); + this.response.sendResponse(e,null); + fail("Exception expected"); + }catch (IllegalArgumentException e) { + // + } +// // test Atom output + StringWriter stringWriter = new StringWriter(); + PrintWriter writer = new PrintWriter(stringWriter); + + this.control.expectAndReturn(this.httpResponse.getWriter(),writer); + this.response.setOutputFormat(OutputFormat.ATOM); + this.control.replay(); + + this.response.sendResponse(createEntry(),new ExtensionProfile + ()); + assertEquals("Simple XML representation ATOM",stringWriter.toString(),generatedEntryAtom); + + // test rss output + this.control.reset(); + stringWriter = new StringWriter(); + writer = new PrintWriter(stringWriter); + + this.control.expectAndReturn(this.httpResponse.getWriter(),writer); + this.response.setOutputFormat(OutputFormat.RSS); + this.control.replay(); + + this.response.sendResponse(createEntry(),new ExtensionProfile + ()); + + assertEquals("Simple XML representation RSS",stringWriter.toString(),generatedEntryRSS); + + + + } + + /* create a simple feed */ + private Feed createFeed(){ + Feed feed = new Feed(); + + feed.getEntries().add(createEntry()); + + return feed; + } + /* create a simple entry */ + private Entry createEntry(){ + Entry e = new Entry(); + e.setTitle(new PlainTextConstruct("Test")); + return e; + } + +} Index: contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataRequest.java =================================================================== --- contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataRequest.java (revision 0) +++ contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataRequest.java (revision 0) @@ -0,0 +1,149 @@ +/** + * 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 javax.servlet.http.HttpServletRequest; + +import junit.framework.TestCase; + +import org.apache.lucene.gdata.server.GDataRequest.OutputFormat; +import org.easymock.MockControl; + +/** + * + * @author Simon Willnauer + * + */ +public class TestGDataRequest extends TestCase { + private HttpServletRequest request; + + private MockControl control; + + private GDataRequest feedRequest; + + @Override + protected void setUp() throws Exception { + this.control = MockControl.createControl(HttpServletRequest.class); + this.request = (HttpServletRequest) this.control.getMock(); + this.feedRequest = new GDataRequest(this.request); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + public void testConstructor(){ + try{ + new GDataRequest(null); + fail("IllegalArgumentException expected"); + }catch (IllegalArgumentException e) { + // + } + } + + public void testGetFeedId() throws GDataRequestException { + + this.control.expectAndDefaultReturn(this.request.getPathInfo(), + "/feed/1/1"); + this.control.expectAndDefaultReturn(this.request.getParameter("alt"),null); + this.control.replay(); + this.feedRequest.initializeRequest(); + assertEquals("feedID", this.feedRequest.getFeedId(), "feed"); + this.control.reset(); + + } + + public void testEmptyPathInfo() { + this.control.expectAndDefaultReturn(this.request.getPathInfo(), "/"); + this.control.expectAndDefaultReturn(this.request.getParameter("alt"),null); + this.control.replay(); + try { + this.feedRequest.initializeRequest(); + + fail("FeedRequestException expected"); + } catch (GDataRequestException e) { + // expected + } catch (Exception e) { + fail("FeedRequestException expected"); + } + + } + + public void testGetFeedIdWithoutEntry() throws GDataRequestException { + this.control.expectAndDefaultReturn(this.request.getPathInfo(), "/feed"); + this.control.expectAndDefaultReturn(this.request.getParameter("alt"),null); + this.control.replay(); + this.feedRequest.initializeRequest(); + assertEquals("feedID", this.feedRequest.getFeedId(), "feed"); + } + + public void testGetEntyId() throws GDataRequestException { + + this.control.expectAndDefaultReturn(this.request.getPathInfo(), + "/feed/1/15"); + this.control.expectAndDefaultReturn(this.request.getParameter("alt"),null); + this.control.replay(); + this.feedRequest.initializeRequest(); + assertEquals("entryid", this.feedRequest.getEntryId(), "1"); + assertEquals("feedId", this.feedRequest.getFeedId(), "feed"); + assertEquals("entryid", this.feedRequest.getEntryVersion(), "15"); + this.control.reset(); + + } + + public void testSetResponseFormatAtom() throws GDataRequestException { + this.control.expectAndDefaultReturn(this.request.getParameter("alt"), + "atom"); + this.control.expectAndDefaultReturn(this.request.getPathInfo(), "/feed"); + this.control.replay(); + this.feedRequest.initializeRequest(); + assertEquals("ResponseFromat Atom", this.feedRequest + .getRequestedResponseFormat(), OutputFormat.ATOM); + this.control.reset(); + } + + public void testSetResponseFormatRSS() throws GDataRequestException { + this.control.expectAndDefaultReturn(this.request.getParameter("alt"), + "rss"); + this.control.expectAndDefaultReturn(this.request.getPathInfo(), "/feed"); + this.control.replay(); + this.feedRequest.initializeRequest(); + assertEquals("ResponseFromat RSS", this.feedRequest + .getRequestedResponseFormat(), OutputFormat.RSS); + this.control.reset(); + } + + public void testSetResponseFormatKeepAtom() throws GDataRequestException { + this.control.expectAndDefaultReturn(this.request.getParameter("alt"), + "fooBar"); + this.control.expectAndDefaultReturn(this.request.getPathInfo(), "/feed"); + this.control.replay(); + this.feedRequest.initializeRequest(); + assertEquals("ResponseFromat Atom", this.feedRequest + .getRequestedResponseFormat(), OutputFormat.ATOM); + this.control.reset(); + } + public void testSetResponseFormatNull() throws GDataRequestException { + this.control.expectAndDefaultReturn(this.request.getParameter("alt"), + null); + this.control.expectAndDefaultReturn(this.request.getPathInfo(), "/feed"); + this.control.replay(); + this.feedRequest.initializeRequest(); + assertEquals("ResponseFromat Atom", this.feedRequest + .getRequestedResponseFormat(), OutputFormat.ATOM); + this.control.reset(); + } +} Index: contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestIDGenerator.java =================================================================== --- contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestIDGenerator.java (revision 0) +++ contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestIDGenerator.java (revision 0) @@ -0,0 +1,52 @@ +package org.apache.lucene.gdata.server.registry; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.apache.lucene.gdata.storage.IDGenerator; + +/** + * @author Simon Willnauer + * + */ +public class TestIDGenerator extends TestCase { + private IDGenerator idgen; + + private int initialCap = 100; + + @Override + protected void setUp() throws Exception { + this.idgen = new IDGenerator(this.initialCap); + + + } + + @Override + protected void tearDown() throws Exception { + this.idgen.stopIDGenerator(); + } + + /** + * Test method for 'org.apache.lucene.gdata.storage.IDGenerator.getUID()' + * @throws InterruptedException + */ + public void testGetUID() throws InterruptedException { + + List idlist = new ArrayList(); + //TODO think about a better way to test this + for (int i = 0; i < 1000; i++) { + String id = this.idgen.getUID(); + assertNotNull(id); + assertFalse(idlist.contains(id)); + idlist.add(id); + System.out.println(id); + + + } + + } + + +} Index: contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestGDataEntityBuilder.java =================================================================== --- contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestGDataEntityBuilder.java (revision 0) +++ contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestGDataEntityBuilder.java (revision 0) @@ -0,0 +1,95 @@ +/** + * 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.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; + +import junit.framework.TestCase; + +import org.apache.lucene.gdata.server.FeedNotFoundException; +import org.apache.lucene.gdata.server.GDataEntityBuilder; + +import com.google.gdata.data.BaseEntry; +import com.google.gdata.data.BaseFeed; +import com.google.gdata.data.Entry; +import com.google.gdata.data.Feed; +import com.google.gdata.util.ParseException; + +/** + * @author Simon Willnauer + * + */ +public class TestGDataEntityBuilder extends TestCase { + private static File incomingFeed = new File("src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingFeed.xml"); + private static File incomingEntry = new File("src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingEntry.xml"); + private static String feedTitleFromXML = "Simon Willnauer"; + private static String entrySummaryFromXML = "When: 2006-12-23 to 2006-12-31 America/Los_Angeles"; + private static FeedRegistry reg = FeedRegistry.getRegistry(); + private Reader reader; + private static String feedID = "myFeed"; + private static Class feedType = Feed.class; + + + /** + * @see junit.framework.TestCase#setUp() + */ + @Override + protected void setUp() throws Exception { + FeedInstanceConfigurator config = new FeedInstanceConfigurator(); + config.setFeedId(feedID); + config.setFeedType(feedType); + reg.registerFeed(config); + } + + /** + * @see junit.framework.TestCase#tearDown() + */ + @Override + protected void tearDown() throws Exception { + reg.flushRegistry(); + this.reader = null; + } + + /** + * Test method for 'org.apache.lucene.gdata.data.GDataEntityBuilder.buildFeed(String, Reader)' + */ + public void testBuildFeedStringReader() throws FeedNotFoundException, ParseException, IOException { + this.reader = new FileReader(incomingFeed); + BaseFeed feed = GDataEntityBuilder.buildFeed(feedID,this.reader); + assertNotNull(feed); + assertEquals("feed title",feed.getTitle().getPlainText(), feedTitleFromXML); + assertTrue( feed instanceof Feed); + + } + + /* + * Test method for 'org.apache.lucene.gdata.data.GDataEntityBuilder.buildEntry(String, Reader)' + */ + public void testBuildEntryStringReader() throws FeedNotFoundException, ParseException, IOException { + this.reader = new FileReader(incomingEntry); + BaseEntry entry = GDataEntityBuilder.buildEntry(feedID,this.reader); + assertNotNull(entry); + assertEquals("entry summary",entry.getSummary().getPlainText(),entrySummaryFromXML); + assertTrue(entry instanceof Entry); + + } + + + +} Index: contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingEntry.xml =================================================================== --- contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingEntry.xml (revision 0) +++ contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingEntry.xml (revision 0) @@ -0,0 +1,21 @@ + + + + http://www.google.com/calendar/feeds/simon.willnauer%40googlemail.com/public/basic/af4b5ca305c80f96f42c9af66c5b04a8473c949c + + 2006-12-23T00:00:00.000Z + 2006-05-23T16:42:48.000Z + + + + When: 2006-12-23 to 2006-12-31 America/Los_Angeles<br> + + + + + + \ No newline at end of file Index: contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingFeed.xml =================================================================== --- contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingFeed.xml (revision 0) +++ contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingFeed.xml (revision 0) @@ -0,0 +1,90 @@ + + + + http://www.google.com/calendar/feeds/simon.willnauer%40googlemail.com/public/basic + + 2006-05-27T11:47:55.000Z + Simon Willnauer + Simon Willnauer + + + + + + + + Simon Willnauer + simon.willnauer@googlemail.com + + + Google Calendar + + 25 + + + http://www.google.com/calendar/feeds/simon.willnauer%40googlemail.com/public/basic/af4b5ca305c80f96f42c9af66c5b04a8473c949c + + 2006-12-23T00:00:00.000Z + 2006-05-23T16:42:48.000Z + + + + When: 2006-12-23 to 2006-12-31 America/Los_Angeles<br> + + + + + + + + + http://www.google.com/calendar/feeds/simon.willnauer%40googlemail.com/public/basic/d5402951792ce690f6a45e51143deb78f4fffac4 + + 2006-05-26T00:00:00.000Z + 2006-05-20T22:17:44.000Z + + + + When: 2006-05-26 to 2006-05-27 America/Los_Angeles<br> + + + + + + + + + http://www.google.com/calendar/feeds/simon.willnauer%40googlemail.com/public/basic/21630e853795ea81d5e792d0ab082ad1c44256e4 + + 2006-06-19T14:00:00.000Z + 2006-05-17T16:10:57.000Z + + + + When: 2006-06-19 07:00:00 to 08:00:00 + America/Los_Angeles<br> + + + + + + + \ No newline at end of file Index: contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestFeedRegistry.java =================================================================== --- contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestFeedRegistry.java (revision 0) +++ contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestFeedRegistry.java (revision 0) @@ -0,0 +1,98 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.gdata.server.registry; + +import com.google.gdata.data.Feed; + +import junit.framework.TestCase; + +/** + * @author Simon Willnauer + * + */ +public class TestFeedRegistry extends TestCase { + private FeedRegistry reg; + private FeedInstanceConfigurator configurator; + @Override + protected void setUp(){ + this.reg = FeedRegistry.getRegistry(); + this.configurator = new FeedInstanceConfigurator(); + } + /** + * @see junit.framework.TestCase#tearDown() + */ + @Override + protected void tearDown() throws Exception { + this.reg.flushRegistry(); + } + /** + * Test method for 'org.apache.lucene.gdata.server.registry.FeedRegistry.getRegistry()' + */ + public void testGetRegistry() { + + FeedRegistry reg1 = FeedRegistry.getRegistry(); + assertEquals("test singleton",this.reg,reg1); + } + + /** + * Test method for 'org.apache.lucene.gdata.server.registry.FeedRegistry.registerFeed(FeedInstanceConfigurator)' + */ + public void testRegisterFeed() { + String feedURL = "myFeed"; + registerFeed(feedURL); + assertEquals("Registered Configurator",this.configurator,this.reg.getFeedConfigurator(feedURL)); + assertNull("not registered Configurator",this.reg.getFeedConfigurator("somethingElse")); + try{ + this.reg.getFeedConfigurator(null); + fail("Exception expected"); + }catch (IllegalArgumentException e) { + // + } + } + + /** + * Test method for 'org.apache.lucene.gdata.server.registry.FeedRegistry.getFeedConfigurator(String)' + */ + public void testFlushRegistry() { + String feedURL = "testFeed"; + registerFeed(feedURL); + assertEquals("Registered Configurator",this.configurator,this.reg.getFeedConfigurator(feedURL)); + this.reg.flushRegistry(); + assertNull("Registry flushed",this.reg.getFeedConfigurator(feedURL)); + + + } + + /** + * + */ + public void testIsFeedRegistered(){ + String myFeed = "myFeed"; + registerFeed(myFeed); + assertTrue("Feed is registerd",this.reg.isFeedRegistered(myFeed)); + assertFalse("null Feed is not registerd",this.reg.isFeedRegistered(null)); + assertFalse("Feed is not registerd",this.reg.isFeedRegistered("someOtherFeed")); + + } + + private void registerFeed(String feedURL){ + + this.configurator.setFeedType(Feed.class); + this.configurator.setFeedId(feedURL); + this.reg.registerFeed(this.configurator); + } + +} Index: contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingEntry.xml =================================================================== --- contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingEntry.xml (revision 0) +++ contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingEntry.xml (revision 0) @@ -0,0 +1,21 @@ + + + + http://www.google.com/calendar/feeds/simon.willnauer%40googlemail.com/public/basic/af4b5ca305c80f96f42c9af66c5b04a8473c949c + + 2006-12-23T00:00:00.000Z + 2006-05-23T16:42:48.000Z + + + + When: 2006-12-23 to 2006-12-31 America/Los_Angeles<br> + + + + + + \ No newline at end of file Index: contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingFeed.xml =================================================================== --- contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingFeed.xml (revision 0) +++ contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingFeed.xml (revision 0) @@ -0,0 +1,90 @@ + + + + http://www.google.com/calendar/feeds/simon.willnauer%40googlemail.com/public/basic + + 2006-05-27T11:47:55.000Z + Simon Willnauer + Simon Willnauer + + + + + + + + Simon Willnauer + simon.willnauer@googlemail.com + + + Google Calendar + + 25 + + + http://www.google.com/calendar/feeds/simon.willnauer%40googlemail.com/public/basic/af4b5ca305c80f96f42c9af66c5b04a8473c949c + + 2006-12-23T00:00:00.000Z + 2006-05-23T16:42:48.000Z + + + + When: 2006-12-23 to 2006-12-31 America/Los_Angeles<br> + + + + + + + + + http://www.google.com/calendar/feeds/simon.willnauer%40googlemail.com/public/basic/d5402951792ce690f6a45e51143deb78f4fffac4 + + 2006-05-26T00:00:00.000Z + 2006-05-20T22:17:44.000Z + + + + When: 2006-05-26 to 2006-05-27 America/Los_Angeles<br> + + + + + + + + + http://www.google.com/calendar/feeds/simon.willnauer%40googlemail.com/public/basic/21630e853795ea81d5e792d0ab082ad1c44256e4 + + 2006-06-19T14:00:00.000Z + 2006-05-17T16:10:57.000Z + + + + When: 2006-06-19 07:00:00 to 08:00:00 + America/Los_Angeles<br> + + + + + + + \ No newline at end of file Index: contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestFeedRegistry.java =================================================================== --- contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestFeedRegistry.java (revision 0) +++ contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestFeedRegistry.java (revision 0) @@ -0,0 +1,98 @@ +/** + * Copyright 2004 The Apache Software Foundation + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.lucene.gdata.server.registry; + +import com.google.gdata.data.Feed; + +import junit.framework.TestCase; + +/** + * @author Simon Willnauer + * + */ +public class TestFeedRegistry extends TestCase { + private FeedRegistry reg; + private FeedInstanceConfigurator configurator; + @Override + protected void setUp(){ + this.reg = FeedRegistry.getRegistry(); + this.configurator = new FeedInstanceConfigurator(); + } + /** + * @see junit.framework.TestCase#tearDown() + */ + @Override + protected void tearDown() throws Exception { + this.reg.flushRegistry(); + } + /** + * Test method for 'org.apache.lucene.gdata.server.registry.FeedRegistry.getRegistry()' + */ + public void testGetRegistry() { + + FeedRegistry reg1 = FeedRegistry.getRegistry(); + assertEquals("test singleton",this.reg,reg1); + } + + /** + * Test method for 'org.apache.lucene.gdata.server.registry.FeedRegistry.registerFeed(FeedInstanceConfigurator)' + */ + public void testRegisterFeed() { + String feedURL = "myFeed"; + registerFeed(feedURL); + assertEquals("Registered Configurator",this.configurator,this.reg.getFeedConfigurator(feedURL)); + assertNull("not registered Configurator",this.reg.getFeedConfigurator("somethingElse")); + try{ + this.reg.getFeedConfigurator(null); + fail("Exception expected"); + }catch (IllegalArgumentException e) { + // + } + } + + /** + * Test method for 'org.apache.lucene.gdata.server.registry.FeedRegistry.getFeedConfigurator(String)' + */ + public void testFlushRegistry() { + String feedURL = "testFeed"; + registerFeed(feedURL); + assertEquals("Registered Configurator",this.configurator,this.reg.getFeedConfigurator(feedURL)); + this.reg.flushRegistry(); + assertNull("Registry flushed",this.reg.getFeedConfigurator(feedURL)); + + + } + + /** + * + */ + public void testIsFeedRegistered(){ + String myFeed = "myFeed"; + registerFeed(myFeed); + assertTrue("Feed is registerd",this.reg.isFeedRegistered(myFeed)); + assertFalse("null Feed is not registerd",this.reg.isFeedRegistered(null)); + assertFalse("Feed is not registerd",this.reg.isFeedRegistered("someOtherFeed")); + + } + + private void registerFeed(String feedURL){ + + this.configurator.setFeedType(Feed.class); + this.configurator.setFeedId(feedURL); + this.reg.registerFeed(this.configurator); + } + +} Index: contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestGDataEntityBuilder.java =================================================================== --- contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestGDataEntityBuilder.java (revision 0) +++ contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestGDataEntityBuilder.java (revision 0) @@ -0,0 +1,95 @@ +/** + * 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.io.File; +import java.io.FileReader; +import java.io.IOException; +import java.io.Reader; + +import junit.framework.TestCase; + +import org.apache.lucene.gdata.server.FeedNotFoundException; +import org.apache.lucene.gdata.server.GDataEntityBuilder; + +import com.google.gdata.data.BaseEntry; +import com.google.gdata.data.BaseFeed; +import com.google.gdata.data.Entry; +import com.google.gdata.data.Feed; +import com.google.gdata.util.ParseException; + +/** + * @author Simon Willnauer + * + */ +public class TestGDataEntityBuilder extends TestCase { + private static File incomingFeed = new File("src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingFeed.xml"); + private static File incomingEntry = new File("src/test/org/apache/lucene/gdata/server/registry/TestEntityBuilderIncomingEntry.xml"); + private static String feedTitleFromXML = "Simon Willnauer"; + private static String entrySummaryFromXML = "When: 2006-12-23 to 2006-12-31 America/Los_Angeles"; + private static FeedRegistry reg = FeedRegistry.getRegistry(); + private Reader reader; + private static String feedID = "myFeed"; + private static Class feedType = Feed.class; + + + /** + * @see junit.framework.TestCase#setUp() + */ + @Override + protected void setUp() throws Exception { + FeedInstanceConfigurator config = new FeedInstanceConfigurator(); + config.setFeedId(feedID); + config.setFeedType(feedType); + reg.registerFeed(config); + } + + /** + * @see junit.framework.TestCase#tearDown() + */ + @Override + protected void tearDown() throws Exception { + reg.flushRegistry(); + this.reader = null; + } + + /** + * Test method for 'org.apache.lucene.gdata.data.GDataEntityBuilder.buildFeed(String, Reader)' + */ + public void testBuildFeedStringReader() throws FeedNotFoundException, ParseException, IOException { + this.reader = new FileReader(incomingFeed); + BaseFeed feed = GDataEntityBuilder.buildFeed(feedID,this.reader); + assertNotNull(feed); + assertEquals("feed title",feed.getTitle().getPlainText(), feedTitleFromXML); + assertTrue( feed instanceof Feed); + + } + + /* + * Test method for 'org.apache.lucene.gdata.data.GDataEntityBuilder.buildEntry(String, Reader)' + */ + public void testBuildEntryStringReader() throws FeedNotFoundException, ParseException, IOException { + this.reader = new FileReader(incomingEntry); + BaseEntry entry = GDataEntityBuilder.buildEntry(feedID,this.reader); + assertNotNull(entry); + assertEquals("entry summary",entry.getSummary().getPlainText(),entrySummaryFromXML); + assertTrue(entry instanceof Entry); + + } + + + +} Index: contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestIDGenerator.java =================================================================== --- contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestIDGenerator.java (revision 0) +++ contrib/gdata-server/src/test/org/apache/lucene/gdata/server/registry/TestIDGenerator.java (revision 0) @@ -0,0 +1,52 @@ +package org.apache.lucene.gdata.server.registry; + +import java.util.ArrayList; +import java.util.List; + +import junit.framework.TestCase; + +import org.apache.lucene.gdata.storage.IDGenerator; + +/** + * @author Simon Willnauer + * + */ +public class TestIDGenerator extends TestCase { + private IDGenerator idgen; + + private int initialCap = 100; + + @Override + protected void setUp() throws Exception { + this.idgen = new IDGenerator(this.initialCap); + + + } + + @Override + protected void tearDown() throws Exception { + this.idgen.stopIDGenerator(); + } + + /** + * Test method for 'org.apache.lucene.gdata.storage.IDGenerator.getUID()' + * @throws InterruptedException + */ + public void testGetUID() throws InterruptedException { + + List idlist = new ArrayList(); + //TODO think about a better way to test this + for (int i = 0; i < 1000; i++) { + String id = this.idgen.getUID(); + assertNotNull(id); + assertFalse(idlist.contains(id)); + idlist.add(id); + System.out.println(id); + + + } + + } + + +} Index: contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataRequest.java =================================================================== --- contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataRequest.java (revision 0) +++ contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataRequest.java (revision 0) @@ -0,0 +1,149 @@ +/** + * 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 javax.servlet.http.HttpServletRequest; + +import junit.framework.TestCase; + +import org.apache.lucene.gdata.server.GDataRequest.OutputFormat; +import org.easymock.MockControl; + +/** + * + * @author Simon Willnauer + * + */ +public class TestGDataRequest extends TestCase { + private HttpServletRequest request; + + private MockControl control; + + private GDataRequest feedRequest; + + @Override + protected void setUp() throws Exception { + this.control = MockControl.createControl(HttpServletRequest.class); + this.request = (HttpServletRequest) this.control.getMock(); + this.feedRequest = new GDataRequest(this.request); + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + public void testConstructor(){ + try{ + new GDataRequest(null); + fail("IllegalArgumentException expected"); + }catch (IllegalArgumentException e) { + // + } + } + + public void testGetFeedId() throws GDataRequestException { + + this.control.expectAndDefaultReturn(this.request.getPathInfo(), + "/feed/1/1"); + this.control.expectAndDefaultReturn(this.request.getParameter("alt"),null); + this.control.replay(); + this.feedRequest.initializeRequest(); + assertEquals("feedID", this.feedRequest.getFeedId(), "feed"); + this.control.reset(); + + } + + public void testEmptyPathInfo() { + this.control.expectAndDefaultReturn(this.request.getPathInfo(), "/"); + this.control.expectAndDefaultReturn(this.request.getParameter("alt"),null); + this.control.replay(); + try { + this.feedRequest.initializeRequest(); + + fail("FeedRequestException expected"); + } catch (GDataRequestException e) { + // expected + } catch (Exception e) { + fail("FeedRequestException expected"); + } + + } + + public void testGetFeedIdWithoutEntry() throws GDataRequestException { + this.control.expectAndDefaultReturn(this.request.getPathInfo(), "/feed"); + this.control.expectAndDefaultReturn(this.request.getParameter("alt"),null); + this.control.replay(); + this.feedRequest.initializeRequest(); + assertEquals("feedID", this.feedRequest.getFeedId(), "feed"); + } + + public void testGetEntyId() throws GDataRequestException { + + this.control.expectAndDefaultReturn(this.request.getPathInfo(), + "/feed/1/15"); + this.control.expectAndDefaultReturn(this.request.getParameter("alt"),null); + this.control.replay(); + this.feedRequest.initializeRequest(); + assertEquals("entryid", this.feedRequest.getEntryId(), "1"); + assertEquals("feedId", this.feedRequest.getFeedId(), "feed"); + assertEquals("entryid", this.feedRequest.getEntryVersion(), "15"); + this.control.reset(); + + } + + public void testSetResponseFormatAtom() throws GDataRequestException { + this.control.expectAndDefaultReturn(this.request.getParameter("alt"), + "atom"); + this.control.expectAndDefaultReturn(this.request.getPathInfo(), "/feed"); + this.control.replay(); + this.feedRequest.initializeRequest(); + assertEquals("ResponseFromat Atom", this.feedRequest + .getRequestedResponseFormat(), OutputFormat.ATOM); + this.control.reset(); + } + + public void testSetResponseFormatRSS() throws GDataRequestException { + this.control.expectAndDefaultReturn(this.request.getParameter("alt"), + "rss"); + this.control.expectAndDefaultReturn(this.request.getPathInfo(), "/feed"); + this.control.replay(); + this.feedRequest.initializeRequest(); + assertEquals("ResponseFromat RSS", this.feedRequest + .getRequestedResponseFormat(), OutputFormat.RSS); + this.control.reset(); + } + + public void testSetResponseFormatKeepAtom() throws GDataRequestException { + this.control.expectAndDefaultReturn(this.request.getParameter("alt"), + "fooBar"); + this.control.expectAndDefaultReturn(this.request.getPathInfo(), "/feed"); + this.control.replay(); + this.feedRequest.initializeRequest(); + assertEquals("ResponseFromat Atom", this.feedRequest + .getRequestedResponseFormat(), OutputFormat.ATOM); + this.control.reset(); + } + public void testSetResponseFormatNull() throws GDataRequestException { + this.control.expectAndDefaultReturn(this.request.getParameter("alt"), + null); + this.control.expectAndDefaultReturn(this.request.getPathInfo(), "/feed"); + this.control.replay(); + this.feedRequest.initializeRequest(); + assertEquals("ResponseFromat Atom", this.feedRequest + .getRequestedResponseFormat(), OutputFormat.ATOM); + this.control.reset(); + } +} Index: contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataResponse.java =================================================================== --- contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataResponse.java (revision 0) +++ contrib/gdata-server/src/test/org/apache/lucene/gdata/server/TestGDataResponse.java (revision 0) @@ -0,0 +1,161 @@ +package org.apache.lucene.gdata.server; + +import java.io.IOException; +import java.io.PrintWriter; +import java.io.StringWriter; + +import javax.servlet.http.HttpServletResponse; + +import junit.framework.TestCase; + +import org.apache.lucene.gdata.server.GDataRequest.OutputFormat; +import org.easymock.MockControl; + +import com.google.gdata.data.Entry; +import com.google.gdata.data.ExtensionProfile; +import com.google.gdata.data.Feed; +import com.google.gdata.data.PlainTextConstruct; +/** + * + * @author Simon Willnauer + * + */ +public class TestGDataResponse extends TestCase { + private GDataResponse response; + private HttpServletResponse httpResponse; + private MockControl control; + private static String generatedFeedAtom = "Test"; + private static String generatedEntryAtom = "Test"; + private static String generatedFeedRSS = "Test"; + private static String generatedEntryRSS = "Test"; + protected void setUp() throws Exception { + this.control = MockControl.createControl(HttpServletResponse.class); + this.httpResponse = (HttpServletResponse)this.control.getMock(); + this.response = new GDataResponse(this.httpResponse); + + } + + protected void tearDown() throws Exception { + super.tearDown(); + } + + + public void testConstructor(){ + try{ + new GDataResponse(null); + fail("IllegalArgumentExceptin expected"); + }catch (IllegalArgumentException e) { + // TODO: handle exception + } + } + /* + * Test method for 'org.apache.lucene.gdata.server.GDataResponse.sendResponse(BaseFeed, ExtensionProfile)' + */ + public void testSendResponseBaseFeedExtensionProfile() throws IOException { + try{ + Feed f = null; + this.response.sendResponse(f,new ExtensionProfile()); + fail("Exception expected"); + }catch (IllegalArgumentException e) { + // + } + + try{ + Feed f = createFeed(); + this.response.sendResponse(f,null); + fail("Exception expected"); + }catch (IllegalArgumentException e) { + // + } + StringWriter stringWriter = new StringWriter(); + PrintWriter writer = new PrintWriter(stringWriter); + + this.control.expectAndReturn(this.httpResponse.getWriter(),writer); + this.response.setOutputFormat(OutputFormat.ATOM); + this.control.replay(); + + this.response.sendResponse(createFeed(),new ExtensionProfile + ()); + assertEquals("Simple XML representation",stringWriter.toString(),generatedFeedAtom); + this.control.reset(); + + stringWriter = new StringWriter(); + writer = new PrintWriter(stringWriter); + + this.control.expectAndReturn(this.httpResponse.getWriter(),writer); + this.response.setOutputFormat(OutputFormat.RSS); + this.control.replay(); + + this.response.sendResponse(createFeed(),new ExtensionProfile + ()); + assertEquals("Simple XML representation",stringWriter.toString(),generatedFeedRSS); + + + + + } + + /* + * Test method for 'org.apache.lucene.gdata.server.GDataResponse.sendResponse(BaseEntry, ExtensionProfile)' + */ + public void testSendResponseBaseEntryExtensionProfile() throws IOException { + try{ + Entry e = null; + this.response.sendResponse(e,new ExtensionProfile()); + fail("Exception expected"); + }catch (IllegalArgumentException e) { + // + } + try{ + Entry e = createEntry(); + this.response.sendResponse(e,null); + fail("Exception expected"); + }catch (IllegalArgumentException e) { + // + } +// // test Atom output + StringWriter stringWriter = new StringWriter(); + PrintWriter writer = new PrintWriter(stringWriter); + + this.control.expectAndReturn(this.httpResponse.getWriter(),writer); + this.response.setOutputFormat(OutputFormat.ATOM); + this.control.replay(); + + this.response.sendResponse(createEntry(),new ExtensionProfile + ()); + assertEquals("Simple XML representation ATOM",stringWriter.toString(),generatedEntryAtom); + + // test rss output + this.control.reset(); + stringWriter = new StringWriter(); + writer = new PrintWriter(stringWriter); + + this.control.expectAndReturn(this.httpResponse.getWriter(),writer); + this.response.setOutputFormat(OutputFormat.RSS); + this.control.replay(); + + this.response.sendResponse(createEntry(),new ExtensionProfile + ()); + + assertEquals("Simple XML representation RSS",stringWriter.toString(),generatedEntryRSS); + + + + } + + /* create a simple feed */ + private Feed createFeed(){ + Feed feed = new Feed(); + + feed.getEntries().add(createEntry()); + + return feed; + } + /* create a simple entry */ + private Entry createEntry(){ + Entry e = new Entry(); + e.setTitle(new PlainTextConstruct("Test")); + return e; + } + +} Index: contrib/gdata-server/src/test/org/apache/lucene/gdata/servlet/TestAbstractGdataServlet.java =================================================================== --- contrib/gdata-server/src/test/org/apache/lucene/gdata/servlet/TestAbstractGdataServlet.java (revision 0) +++ contrib/gdata-server/src/test/org/apache/lucene/gdata/servlet/TestAbstractGdataServlet.java (revision 0) @@ -0,0 +1,282 @@ +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.easymock.MockControl; + +import junit.framework.TestCase; + +/** + * @author Simon Willnauer + * + */ +public class TestAbstractGdataServlet extends TestCase { + private static final String METHOD_DELETE = "DELETE"; + + private static final String METHOD_GET = "GET"; + + private static final String METHOD_POST = "POST"; + + private static final String METHOD_PUT = "PUT"; + + private static final String METHOD_HEADER_NAME = "x-http-method-override"; + + private HttpServletRequest mockRequest = null; + + private HttpServletResponse mockResponse = null; + + private AbstractGdataServlet servletInstance = null; + + private MockControl requestMockControl; + + private MockControl responseMockControl; + + protected void setUp() throws Exception { + this.requestMockControl = MockControl + .createControl(HttpServletRequest.class); + this.responseMockControl = MockControl + .createControl(HttpServletResponse.class); + this.mockRequest = (HttpServletRequest) this.requestMockControl + .getMock(); + this.mockResponse = (HttpServletResponse) this.responseMockControl + .getMock(); + this.servletInstance = new StubGDataServlet(); + } + + /** + * Test method for + * 'org.apache.lucene.gdata.servlet.AbstractGdataServlet.service(HttpServletRequest, + * HttpServletResponse)' + */ + public void testServiceHttpServletRequestHttpServletResponseDelete() { + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_DELETE); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_DELETE); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + this.requestMockControl.reset(); + + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_POST); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_DELETE); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + } + + /** + * + */ + public void testServiceNullOverrideHeader() { + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_POST); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), null); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + this.requestMockControl.reset(); + } + + /** + * Test method for + * 'org.apache.lucene.gdata.servlet.AbstractGdataServlet.service(HttpServletRequest, + * HttpServletResponse)' + */ + public void testServiceHttpServletRequestHttpServletResponsePOST() { + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_POST); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_POST); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + this.requestMockControl.reset(); + + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_PUT); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_POST); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + } + + /** + * Test method for + * 'org.apache.lucene.gdata.servlet.AbstractGdataServlet.service(HttpServletRequest, + * HttpServletResponse)' + */ + public void testServiceHttpServletRequestHttpServletResponsePUT() { + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_PUT); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_PUT); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + this.requestMockControl.reset(); + + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_POST); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_PUT); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + } + + /** + * Test method for + * 'org.apache.lucene.gdata.servlet.AbstractGdataServlet.service(HttpServletRequest, + * HttpServletResponse)' + */ + public void testServiceHttpServletRequestHttpServletResponseGET() { + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_GET); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_GET); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + this.requestMockControl.reset(); + + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_POST); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_GET); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + + } + /** + * Stub Implementation for AbstractGdataServlet + * @author Simon Willnauer + * + */ + static class StubGDataServlet extends AbstractGdataServlet { + + private static final long serialVersionUID = -6271464588547620925L; + + protected void doDelete(HttpServletRequest arg0, + HttpServletResponse arg1) { + if (arg0.getHeader(METHOD_HEADER_NAME) == null) + assertEquals("Http-Method --DELETE--", METHOD_DELETE, arg0 + .getMethod()); + else + assertEquals("Http-Method override --DELETE--", METHOD_DELETE, + arg0.getHeader(METHOD_HEADER_NAME)); + + } + + protected void doGet(HttpServletRequest arg0, HttpServletResponse arg1) { + if (arg0.getHeader(METHOD_HEADER_NAME) == null) + assertEquals("Http-Method --GET--", arg0.getMethod(), + METHOD_GET); + else + assertEquals("Http-Method override --GET--", arg0 + .getHeader(METHOD_HEADER_NAME), METHOD_GET); + } + + protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1) { + if (arg0.getHeader(METHOD_HEADER_NAME) == null) + assertEquals("Http-Method --POST--", arg0.getMethod(), + METHOD_POST); + else + assertEquals("Http-Method override --POST--", METHOD_POST, arg0 + .getHeader(METHOD_HEADER_NAME)); + + } + + protected void doPut(HttpServletRequest arg0, HttpServletResponse arg1) { + if (arg0.getHeader(METHOD_HEADER_NAME) == null) + assertEquals("Http-Method --PUT--", arg0.getMethod(), + METHOD_PUT); + else + assertEquals("Http-Method override --PUT--", arg0 + .getHeader(METHOD_HEADER_NAME), METHOD_PUT); + } + + } + +} Index: contrib/gdata-server/src/test/org/apache/lucene/gdata/servlet/TestAbstractGdataServlet.java =================================================================== --- contrib/gdata-server/src/test/org/apache/lucene/gdata/servlet/TestAbstractGdataServlet.java (revision 0) +++ contrib/gdata-server/src/test/org/apache/lucene/gdata/servlet/TestAbstractGdataServlet.java (revision 0) @@ -0,0 +1,282 @@ +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.easymock.MockControl; + +import junit.framework.TestCase; + +/** + * @author Simon Willnauer + * + */ +public class TestAbstractGdataServlet extends TestCase { + private static final String METHOD_DELETE = "DELETE"; + + private static final String METHOD_GET = "GET"; + + private static final String METHOD_POST = "POST"; + + private static final String METHOD_PUT = "PUT"; + + private static final String METHOD_HEADER_NAME = "x-http-method-override"; + + private HttpServletRequest mockRequest = null; + + private HttpServletResponse mockResponse = null; + + private AbstractGdataServlet servletInstance = null; + + private MockControl requestMockControl; + + private MockControl responseMockControl; + + protected void setUp() throws Exception { + this.requestMockControl = MockControl + .createControl(HttpServletRequest.class); + this.responseMockControl = MockControl + .createControl(HttpServletResponse.class); + this.mockRequest = (HttpServletRequest) this.requestMockControl + .getMock(); + this.mockResponse = (HttpServletResponse) this.responseMockControl + .getMock(); + this.servletInstance = new StubGDataServlet(); + } + + /** + * Test method for + * 'org.apache.lucene.gdata.servlet.AbstractGdataServlet.service(HttpServletRequest, + * HttpServletResponse)' + */ + public void testServiceHttpServletRequestHttpServletResponseDelete() { + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_DELETE); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_DELETE); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + this.requestMockControl.reset(); + + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_POST); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_DELETE); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + } + + /** + * + */ + public void testServiceNullOverrideHeader() { + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_POST); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), null); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + this.requestMockControl.reset(); + } + + /** + * Test method for + * 'org.apache.lucene.gdata.servlet.AbstractGdataServlet.service(HttpServletRequest, + * HttpServletResponse)' + */ + public void testServiceHttpServletRequestHttpServletResponsePOST() { + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_POST); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_POST); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + this.requestMockControl.reset(); + + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_PUT); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_POST); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + } + + /** + * Test method for + * 'org.apache.lucene.gdata.servlet.AbstractGdataServlet.service(HttpServletRequest, + * HttpServletResponse)' + */ + public void testServiceHttpServletRequestHttpServletResponsePUT() { + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_PUT); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_PUT); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + this.requestMockControl.reset(); + + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_POST); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_PUT); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + } + + /** + * Test method for + * 'org.apache.lucene.gdata.servlet.AbstractGdataServlet.service(HttpServletRequest, + * HttpServletResponse)' + */ + public void testServiceHttpServletRequestHttpServletResponseGET() { + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_GET); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_GET); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + this.requestMockControl.reset(); + + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getMethod(), METHOD_POST); + this.requestMockControl.expectAndDefaultReturn(this.mockRequest + .getHeader(METHOD_HEADER_NAME), METHOD_GET); + this.requestMockControl.replay(); + + try { + this.servletInstance.service(this.mockRequest, this.mockResponse); + } catch (ServletException e) { + fail("ServeltExpception not expected"); + } catch (IOException e) { + fail("IOExpception not expected"); + } + + this.requestMockControl.verify(); + + } + /** + * Stub Implementation for AbstractGdataServlet + * @author Simon Willnauer + * + */ + static class StubGDataServlet extends AbstractGdataServlet { + + private static final long serialVersionUID = -6271464588547620925L; + + protected void doDelete(HttpServletRequest arg0, + HttpServletResponse arg1) { + if (arg0.getHeader(METHOD_HEADER_NAME) == null) + assertEquals("Http-Method --DELETE--", METHOD_DELETE, arg0 + .getMethod()); + else + assertEquals("Http-Method override --DELETE--", METHOD_DELETE, + arg0.getHeader(METHOD_HEADER_NAME)); + + } + + protected void doGet(HttpServletRequest arg0, HttpServletResponse arg1) { + if (arg0.getHeader(METHOD_HEADER_NAME) == null) + assertEquals("Http-Method --GET--", arg0.getMethod(), + METHOD_GET); + else + assertEquals("Http-Method override --GET--", arg0 + .getHeader(METHOD_HEADER_NAME), METHOD_GET); + } + + protected void doPost(HttpServletRequest arg0, HttpServletResponse arg1) { + if (arg0.getHeader(METHOD_HEADER_NAME) == null) + assertEquals("Http-Method --POST--", arg0.getMethod(), + METHOD_POST); + else + assertEquals("Http-Method override --POST--", METHOD_POST, arg0 + .getHeader(METHOD_HEADER_NAME)); + + } + + protected void doPut(HttpServletRequest arg0, HttpServletResponse arg1) { + if (arg0.getHeader(METHOD_HEADER_NAME) == null) + assertEquals("Http-Method --PUT--", arg0.getMethod(), + METHOD_PUT); + else + assertEquals("Http-Method override --PUT--", arg0 + .getHeader(METHOD_HEADER_NAME), METHOD_PUT); + } + + } + +} Index: contrib/gdata-server/webroot/WEB-INF/web.xml =================================================================== --- contrib/gdata-server/webroot/WEB-INF/web.xml (revision 0) +++ contrib/gdata-server/webroot/WEB-INF/web.xml (revision 0) @@ -0,0 +1,18 @@ + + + Lucene GData - Server + + Server-side implementation of the GData protocol based on Apache + - Lucene + + ControllerServlet + org.apache.lucene.gdata.servlet.RequestControllerServlet + + + ControllerServlet + /* + + \ No newline at end of file Index: contrib/gdata-server/webroot/WEB-INF/web.xml =================================================================== --- contrib/gdata-server/webroot/WEB-INF/web.xml (revision 0) +++ contrib/gdata-server/webroot/WEB-INF/web.xml (revision 0) @@ -0,0 +1,18 @@ + + + Lucene GData - Server + + Server-side implementation of the GData protocol based on Apache + - Lucene + + ControllerServlet + org.apache.lucene.gdata.servlet.RequestControllerServlet + + + ControllerServlet + /* + + \ No newline at end of file