You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@abdera.apache.org by jm...@apache.org on 2012/02/01 18:55:02 UTC
svn commit: r1239237 [7/12] - in /abdera/abdera2-server: ./ .settings/ etc/
examples/ examples/src/ examples/src/main/ examples/src/main/java/
examples/src/main/java/org/ examples/src/main/java/org/apache/
examples/src/main/java/org/apache/abdera2/ exa...
Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/context/EntityProviderResponseContext.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/context/EntityProviderResponseContext.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/context/EntityProviderResponseContext.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/context/EntityProviderResponseContext.java Wed Feb 1 17:54:54 2012
@@ -0,0 +1,72 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. The ASF licenses this file to You
+ * 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.protocol.server.context;
+
+import java.io.IOException;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.protocol.EntityProvider;
+import org.apache.abdera2.writer.StreamWriter;
+
+/**
+ * StreamWriterResponseContext implementation based on the EntityProvider interface
+ */
+public class EntityProviderResponseContext
+ extends StreamWriterResponseContext {
+
+ private final EntityProvider provider;
+
+ public EntityProviderResponseContext(
+ EntityProvider provider,
+ Abdera abdera,
+ String encoding,
+ String sw) {
+ super(abdera, encoding, sw);
+ this.provider = provider;
+ init();
+ }
+
+ public EntityProviderResponseContext(
+ EntityProvider provider,
+ Abdera abdera,
+ String encoding) {
+ super(abdera, encoding);
+ this.provider = provider;
+ init();
+ }
+
+ public EntityProviderResponseContext(
+ EntityProvider provider,
+ Abdera abdera) {
+ super(abdera);
+ this.provider = provider;
+ init();
+ }
+
+ private void init() {
+ setContentType(provider.getContentType());
+ setEntityTag(provider.getEntityTag());
+ setLastModified(provider.getLastModified());
+ }
+
+ @Override
+ protected void writeTo(StreamWriter sw) throws IOException {
+ provider.writeTo(sw);
+ }
+
+}
Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/context/EntityProviderResponseContext.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/context/FOMResponseContext.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/context/FOMResponseContext.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/context/FOMResponseContext.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/context/FOMResponseContext.java Wed Feb 1 17:54:54 2012
@@ -0,0 +1,145 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. The ASF licenses this file to You
+ * 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.protocol.server.context;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import javax.activation.MimeType;
+
+import org.apache.abdera2.model.Base;
+import org.apache.abdera2.model.Document;
+import org.apache.abdera2.model.Element;
+import org.apache.abdera2.model.Element.Helper;
+import org.apache.abdera2.protocol.server.AtompubResponseContext;
+import org.apache.abdera2.common.mediatype.MimeTypeHelper;
+import org.apache.abdera2.common.protocol.AbstractResponseContext;
+import org.apache.abdera2.writer.Writer;
+
+public class FOMResponseContext<T extends Base>
+ extends AbstractResponseContext
+ implements AtompubResponseContext {
+
+ private final T base;
+ private final boolean chunked;
+
+ protected Writer writer;
+
+ public FOMResponseContext(T base) {
+ this(base, true);
+ }
+
+ public FOMResponseContext(T base, boolean chunked) {
+ this.base = base;
+ setStatus(200);
+ setStatusText("OK");
+ this.chunked = chunked;
+ try {
+ MimeType type = getContentType();
+ String charset =
+ type.getParameter("charset");
+ if (charset == null)
+ charset = getCharsetFromBase(base);
+ if (charset == null)
+ charset = "UTF-8";
+ type.setParameter("charset", charset);
+ setContentType(type.toString());
+ } catch (Exception e) {
+ }
+ }
+
+ private String getCharsetFromBase(Base base) {
+ return base == null ?
+ null :
+ base instanceof Document ?
+ ((Document<?>)base).getCharset() :
+ base instanceof Element ?
+ getCharsetFromBase(((Element)base).getDocument()) :
+ null;
+ }
+
+ public T getBase() {
+ return base;
+ }
+
+ public boolean hasEntity() {
+ return (base != null);
+ }
+
+ public void writeTo(java.io.Writer javaWriter) throws IOException {
+ if (hasEntity())
+ if (writer == null)
+ base.writeTo(javaWriter);
+ else
+ writeTo(javaWriter, writer);
+ }
+
+ public void writeTo(OutputStream out) throws IOException {
+ if (hasEntity())
+ if (writer == null)
+ base.writeTo(out);
+ else
+ writeTo(out, writer);
+ }
+
+ @Override
+ public MimeType getContentType() {
+ MimeType t = super.getContentType();
+ if (t == null) {
+ String type = Helper.getMimeType(base);
+ if (type != null)
+ t = MimeTypeHelper.create(type);
+ }
+ return t;
+ }
+
+ @Override
+ public long getContentLength() {
+ long len = super.getContentLength();
+ if (hasEntity() && len == -1 && !chunked) {
+ try {
+ ByteArrayOutputStream out =
+ new ByteArrayOutputStream();
+ base.writeTo(out);
+ len = out.size();
+ super.setContentLength(len);
+ } catch (Exception e) {}
+ }
+ return len;
+ }
+
+ public void writeTo(
+ OutputStream out,
+ Writer writer)
+ throws IOException {
+ writer.writeTo(base, out);
+ }
+
+ public void writeTo(
+ java.io.Writer javaWriter,
+ Writer abderaWriter)
+ throws IOException {
+ abderaWriter.writeTo(base, javaWriter);
+ }
+
+ public AtompubResponseContext setWriter(Writer writer) {
+ this.writer = writer;
+ return this;
+ }
+}
Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/context/FOMResponseContext.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/context/ResponseContextWrapper.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/context/ResponseContextWrapper.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/context/ResponseContextWrapper.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/context/ResponseContextWrapper.java Wed Feb 1 17:54:54 2012
@@ -0,0 +1,60 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. The ASF licenses this file to You
+ * 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.protocol.server.context;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import org.apache.abdera2.common.protocol.BaseResponseContextWrapper;
+import org.apache.abdera2.protocol.server.AtompubResponseContext;
+import org.apache.abdera2.writer.Writer;
+
+public class ResponseContextWrapper
+ extends BaseResponseContextWrapper
+ implements AtompubResponseContext {
+
+ public ResponseContextWrapper(
+ AtompubResponseContext response) {
+ super(response);
+ }
+
+ private AtompubResponseContext getResponse() {
+ return (AtompubResponseContext)response;
+ }
+
+ public AtompubResponseContext setWriter(
+ Writer writer) {
+ getResponse().setWriter(writer);
+ return this;
+ }
+
+ public void writeTo(
+ OutputStream out,
+ Writer writer)
+ throws IOException {
+ getResponse().writeTo(out, writer);
+ }
+
+ public void writeTo(
+ java.io.Writer javaWriter,
+ Writer abderaWriter)
+ throws IOException {
+ getResponse().writeTo(
+ javaWriter,
+ abderaWriter);
+ }
+}
Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/context/ResponseContextWrapper.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/context/StreamWriterResponseContext.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/context/StreamWriterResponseContext.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/context/StreamWriterResponseContext.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/context/StreamWriterResponseContext.java Wed Feb 1 17:54:54 2012
@@ -0,0 +1,129 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. The ASF licenses this file to You
+ * 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.protocol.server.context;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.Writer;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.common.protocol.SimpleResponseContext;
+import org.apache.abdera2.protocol.server.AtompubResponseContext;
+import org.apache.abdera2.writer.StreamWriter;
+
+/**
+ * Abstract base class for creating ResponseContext implementations that use the StreamWriter interface. Using the
+ * StreamWriter to write out documents is significantly faster than using the object model but requires developers to
+ * know more about proper Atom syntax.
+ */
+public abstract class StreamWriterResponseContext
+ extends SimpleResponseContext
+ implements AtompubResponseContext {
+
+ private final Abdera abdera;
+ private final String sw;
+ private boolean autoindent;
+
+ /**
+ * Create a new StreamWriterResponseContext
+ *
+ * @param abdera The Abdera instance
+ */
+ protected StreamWriterResponseContext(Abdera abdera) {
+ this(abdera, null, null);
+ }
+
+ /**
+ * Create a new StreamWriterResponseContext
+ *
+ * @param abdera The Abdera instance
+ * @param encoding The charset encoding
+ */
+ protected StreamWriterResponseContext(Abdera abdera, String encoding) {
+ this(abdera, encoding, null);
+ }
+
+ /**
+ * Create a new StreamWriterResponseContext
+ *
+ * @param abdera The Abdera instance
+ * @param encoding The charset encoding
+ * @param sw The name of the Named StreamWriter to use
+ */
+ protected StreamWriterResponseContext(Abdera abdera, String encoding, String sw) {
+ super(encoding);
+ this.abdera = abdera!=null?abdera:Abdera.getInstance();
+ this.sw = sw;
+ }
+
+ /**
+ * Get the Abdera instance
+ */
+ protected final Abdera getAbdera() {
+ return abdera;
+ }
+
+ /**
+ * Create a new StreamWriter instance. If the sw property was set, the specified Named StreamWriter will be returned
+ */
+ protected StreamWriter newStreamWriter() {
+ return sw == null ? abdera.create(StreamWriter.class) :
+ abdera.getWriterFactory().newStreamWriter(sw);
+ }
+
+ protected void writeEntity(Writer writer) throws IOException {
+ writeTo(newStreamWriter().setWriter(writer).setAutoIndent(autoindent));
+ }
+
+ /**
+ * Write to the specified StreamWriter. Subclasses of this class must implement this method.
+ */
+ protected abstract void writeTo(StreamWriter sw) throws IOException;
+
+ /**
+ * True to enable automatic indenting on the StreamWriter
+ */
+ public StreamWriterResponseContext setAutoIndent(boolean autoindent) {
+ this.autoindent = autoindent;
+ return this;
+ }
+
+ /**
+ * True if automatic indenting is enabled on the StreamWriter
+ */
+ public boolean getAutoIndent() {
+ return this.autoindent;
+ }
+
+ public boolean hasEntity() {
+ return true;
+ }
+
+ public AtompubResponseContext setWriter(
+ org.apache.abdera2.writer.Writer writer) {
+ throw new UnsupportedOperationException();
+ }
+
+ public void writeTo(OutputStream out, org.apache.abdera2.writer.Writer writer) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+
+ public void writeTo(Writer javaWriter, org.apache.abdera2.writer.Writer abderaWriter) throws IOException {
+ throw new UnsupportedOperationException();
+ }
+}
Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/context/StreamWriterResponseContext.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/AbstractAtompubCollectionAdapter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/AbstractAtompubCollectionAdapter.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/AbstractAtompubCollectionAdapter.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/AbstractAtompubCollectionAdapter.java Wed Feb 1 17:54:54 2012
@@ -0,0 +1,152 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. The ASF licenses this file to You
+ * 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.protocol.server.impl;
+
+import java.util.Arrays;
+import java.util.Collections;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.factory.Factory;
+import org.apache.abdera2.common.protocol.AbstractCollectionAdapter;
+import org.apache.abdera2.common.protocol.ProviderHelper;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.ResponseContext;
+import org.apache.abdera2.common.protocol.ResponseContextException;
+import org.apache.abdera2.model.Collection;
+import org.apache.abdera2.model.Document;
+import org.apache.abdera2.model.Entry;
+import org.apache.abdera2.model.Feed;
+import org.apache.abdera2.parser.ParseException;
+import org.apache.abdera2.parser.Parser;
+import org.apache.abdera2.protocol.server.context.FOMResponseContext;
+import org.apache.abdera2.protocol.server.model.AtompubCategoriesInfo;
+import org.apache.abdera2.protocol.server.model.AtompubCollectionInfo;
+
+import com.google.common.base.Predicate;
+import com.google.common.base.Predicates;
+
+/**
+ * Base CollectionAdapter implementation that provides a number of helper utility methods for adapter implementations.
+ */
+public abstract class AbstractAtompubCollectionAdapter
+ extends AbstractCollectionAdapter
+ implements AtompubCollectionInfo {
+
+ public AbstractAtompubCollectionAdapter(String href) {
+ super(href);
+ }
+
+ public Iterable<String> getAccepts(RequestContext request) {
+ return Arrays.<String>asList("application/atom+xml;type=entry");
+ }
+
+ public Iterable<AtompubCategoriesInfo> getCategoriesInfo(RequestContext request) {
+ return Collections.<AtompubCategoriesInfo>emptySet();
+ }
+
+ /**
+ * Creates the ResponseContext for a newly created entry. By default, a BaseResponseContext is returned. The
+ * Location, Content-Location, Etag and status are set appropriately.
+ */
+ protected ResponseContext buildCreateEntryResponse(String link, Entry entry) {
+ return new FOMResponseContext<Entry>(entry)
+ .setLocation(link)
+ .setContentLocation(link)
+ .setEntityTag(AbstractAtompubProvider.calculateEntityTag(entry))
+ .setStatus(201);
+ }
+
+ /**
+ * Creates the ResponseContext for a newly created entry. By default, a BaseResponseContext is returned. The
+ * Location, Content-Location, Etag and status are set appropriately.
+ */
+ protected ResponseContext buildPostMediaEntryResponse(String link, Entry entry) {
+ return buildCreateEntryResponse(link, entry);
+ }
+
+ /**
+ * Creates the ResponseContext for a GET entry request. By default, a BaseResponseContext is returned. The Entry
+ * will contain an appropriate atom:source element and the Etag header will be set.
+ */
+ protected ResponseContext buildGetEntryResponse(RequestContext request, Entry entry)
+ throws ResponseContextException {
+ Feed feed = createFeedBase(request);
+ entry.setSource(feed.getAsSource());
+ Document<Entry> entry_doc = entry.getDocument();
+ return new FOMResponseContext<Document<Entry>>(entry_doc)
+ .setEntityTag(AbstractAtompubProvider.calculateEntityTag(entry));
+ }
+
+ /**
+ * Creates the ResponseContext for a GET feed request. By default, a BaseResponseContext is returned. The Etag
+ * header will be set.
+ */
+ protected ResponseContext buildGetFeedResponse(Feed feed) {
+ Document<Feed> document = feed.getDocument();
+ return new FOMResponseContext<Document<Feed>>(document)
+ .setEntityTag(AbstractAtompubProvider.calculateEntityTag(document.getRoot()));
+ }
+
+ /**
+ * Create the base feed for the requested collection.
+ */
+ protected Feed createFeedBase(RequestContext request) throws ResponseContextException {
+ Factory factory = AbstractAtompubProvider.getAbdera(request).getFactory();
+ Feed feed = factory.newFeed();
+ feed.setId(getId(request));
+ feed.setTitle(getTitle(request));
+ feed.addLink("");
+ feed.addLink("", "self");
+ feed.addAuthor(getAuthor(request));
+ feed.setUpdatedNow();
+ return feed;
+ }
+
+ /**
+ * Retrieves the FOM Entry object from the request payload.
+ */
+ protected Entry getEntryFromRequest(RequestContext request) throws ResponseContextException {
+ Abdera abdera = AbstractAtompubProvider.getAbdera(request);
+ Parser parser = abdera.getParser();
+
+ Document<Entry> entry_doc;
+ try {
+ entry_doc = AbstractAtompubProvider.getDocument(parser,request);
+ } catch (ParseException e) {
+ throw new ResponseContextException(400, e);
+ } catch (Throwable t) {
+ throw new ResponseContextException(500, t);
+ }
+ return entry_doc == null ? null : entry_doc.getRoot();
+ }
+
+ public Collection asCollectionElement(RequestContext request) {
+ Collection collection = AbstractAtompubProvider.getAbdera(request).getFactory().newCollection();
+ collection.setHref(getHref(request));
+ collection.setTitle(getTitle(request));
+ collection.setAccept(getAccepts(request));
+ for (AtompubCategoriesInfo catsinfo : getCategoriesInfo(request)) {
+ collection.addCategories(catsinfo.asCategoriesElement(request));
+ }
+ return collection;
+ }
+
+ public Predicate<RequestContext> acceptable() {
+ return Predicates.or(super.acceptable(),ProviderHelper.isAtom());
+ }
+}
Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/AbstractAtompubCollectionAdapter.java
------------------------------------------------------------------------------
svn:executable = *
Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/AbstractAtompubCollectionAdapter.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/AbstractAtompubProvider.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/AbstractAtompubProvider.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/AbstractAtompubProvider.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/AbstractAtompubProvider.java Wed Feb 1 17:54:54 2012
@@ -0,0 +1,316 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. The ASF licenses this file to You
+ * 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.protocol.server.impl;
+
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+
+import javax.activation.MimeType;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.common.Constants;
+import org.apache.abdera2.common.Localizer;
+import org.apache.abdera2.common.date.DateTimes;
+import org.apache.abdera2.common.http.EntityTag;
+import org.apache.abdera2.common.http.QualityHelper;
+import org.apache.abdera2.common.http.QualityHelper.QToken;
+import org.apache.abdera2.common.mediatype.MimeTypeHelper;
+import org.apache.abdera2.common.misc.ExceptionHelper;
+import org.apache.abdera2.common.protocol.AbstractProvider;
+import org.apache.abdera2.common.protocol.CollectionRequestProcessor;
+import org.apache.abdera2.common.protocol.EntryRequestProcessor;
+import org.apache.abdera2.common.protocol.MediaRequestProcessor;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.RequestContext.Scope;
+import org.apache.abdera2.common.protocol.ResponseContext;
+import org.apache.abdera2.common.protocol.Provider;
+import org.apache.abdera2.common.protocol.ProviderHelper;
+import org.apache.abdera2.common.protocol.TargetType;
+import org.apache.abdera2.common.protocol.WorkspaceInfo;
+import org.apache.abdera2.common.protocol.WorkspaceManager;
+import org.apache.abdera2.model.Base;
+import org.apache.abdera2.model.Document;
+import org.apache.abdera2.model.Element;
+import org.apache.abdera2.model.Entry;
+import org.apache.abdera2.model.Feed;
+import org.apache.abdera2.model.Link;
+import org.apache.abdera2.model.Service;
+import org.apache.abdera2.parser.ParseException;
+import org.apache.abdera2.parser.Parser;
+import org.apache.abdera2.parser.ParserOptions;
+import org.apache.abdera2.protocol.error.Error;
+import org.apache.abdera2.protocol.server.AtompubProvider;
+import org.apache.abdera2.protocol.server.AtompubResponseContext;
+import org.apache.abdera2.protocol.server.context.FOMResponseContext;
+import org.apache.abdera2.protocol.server.context.StreamWriterResponseContext;
+import org.apache.abdera2.protocol.server.model.AtompubWorkspaceInfo;
+import org.apache.abdera2.protocol.server.processors.CategoriesRequestProcessor;
+import org.apache.abdera2.protocol.server.processors.ServiceRequestProcessor;
+import org.apache.abdera2.writer.StreamWriter;
+import org.apache.abdera2.writer.Writer;
+import org.apache.abdera2.writer.WriterFactory;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.joda.time.DateTime;
+
+import com.google.common.base.Predicate;
+
+/**
+ * Base Provider implementation that provides the core implementation details for all Providers. This class provides the
+ * basic request routing logic.
+ */
+public abstract class AbstractAtompubProvider
+ extends AbstractProvider
+ implements AtompubProvider {
+
+ private final static Log log = LogFactory.getLog(AbstractAtompubProvider.class);
+ protected Abdera abdera;
+ protected WorkspaceManager workspaceManager;
+ public static final Predicate<RequestContext> IS_ATOM =
+ new Predicate<RequestContext>() {
+ public boolean apply(RequestContext input) {
+ MimeType ct = input.getContentType();
+ if (ct == null) return false;
+ return MimeTypeHelper.isAtom(ct.toString());
+ }
+ };
+
+ protected AbstractAtompubProvider(
+ WorkspaceManager workspaceManager) {
+ this.workspaceManager = workspaceManager;
+ addRequestProcessor(
+ TargetType.TYPE_SERVICE,
+ ServiceRequestProcessor.class,
+ workspaceManager);
+ addRequestProcessor(
+ TargetType.TYPE_CATEGORIES,
+ CategoriesRequestProcessor.class,
+ workspaceManager);
+ addRequestProcessor(
+ TargetType.TYPE_COLLECTION,
+ CollectionRequestProcessor.class,
+ ProviderHelper.isAtom(),
+ workspaceManager);
+ addRequestProcessor(
+ TargetType.TYPE_ENTRY,
+ EntryRequestProcessor.class,
+ workspaceManager);
+ addRequestProcessor(
+ TargetType.TYPE_MEDIA,
+ MediaRequestProcessor.class,
+ workspaceManager);
+ }
+
+ public void init(Map<String, Object> properties) {
+ this.abdera =
+ properties != null &&
+ properties.containsKey("abdera") ?
+ (Abdera)properties.get("abdera") :
+ Abdera.getInstance();
+ super.init(properties);
+ }
+
+ public Abdera getAbdera() {
+ return abdera;
+ }
+
+ protected Service getServiceElement(RequestContext request) {
+ Service service = abdera.newService();
+ for (WorkspaceInfo wi : getWorkspaceManager().getWorkspaces(request)) {
+ if (wi instanceof AtompubWorkspaceInfo) {
+ AtompubWorkspaceInfo awi = (AtompubWorkspaceInfo) wi;
+ service.addWorkspace(awi.asWorkspaceElement(request));
+ }
+ }
+ return service;
+ }
+
+ public WorkspaceManager getWorkspaceManager() {
+ return workspaceManager;
+ }
+
+ public ResponseContext createErrorResponse(int code, String message, Throwable t) {
+ return createErrorResponse(abdera,code,message,t);
+ }
+
+ public static Abdera getAbdera(RequestContext context) {
+ Provider provider = context.getProvider();
+ return provider instanceof AtompubProvider ?
+ ((AtompubProvider)provider).getAbdera() :
+ Abdera.getInstance();
+ }
+
+ public static ResponseContext createErrorResponse(
+ Abdera abdera,
+ final int code,
+ final String message,
+ final Throwable t) {
+ return
+ new StreamWriterResponseContext(abdera) {
+ protected void writeTo(StreamWriter sw) throws IOException {
+ Error.create(sw, code, message, t);
+ }
+ }
+ .setStatus(code)
+ .setStatusText(message);
+ }
+
+ /**
+ * Returns an appropriate NamedWriter instance given an appropriately formatted HTTP Accept header. The header will
+ * be parsed and sorted according to it's q parameter values. The first named writer capable of supporting the
+ * specified type, in order of q-value preference, will be returned. The results on this are not always predictable.
+ * For instance, if the Accept header says "application/*" it could end up with either the JSON writer or the
+ * PrettyXML writer, or any other writer that supports any writer that supports a specific form of "application/*".
+ * It's always best to be very specific in the Accept headers.
+ */
+ public static Writer getAcceptableNamedWriter(Abdera abdera, String accept_header) {
+ QToken[] sorted_accepts = QualityHelper.orderByQ(accept_header);
+ WriterFactory factory = abdera.getWriterFactory();
+ if (factory == null)
+ return null;
+ for (QToken accept : sorted_accepts) {
+ Writer writer = factory.getWriterByMediaType(accept.token());
+ if (writer != null)
+ return writer;
+ }
+ return null;
+ }
+
+ public static Writer getNamedWriter(Abdera abdera, String mediatype) {
+ WriterFactory factory = abdera.getWriterFactory();
+ if (factory == null)
+ return null;
+ Writer writer = factory.getWriterByMediaType(mediatype);
+ return writer;
+ }
+
+ public static EntityTag calculateEntityTag(Base base) {
+ String id = null;
+ String modified = null;
+ if (base instanceof Entry) {
+ Entry entry = (Entry)base;
+ id = entry.getId().toString();
+ modified =
+ DateTimes.format(
+ entry.getEdited() != null ?
+ entry.getEdited() :
+ entry.getUpdated());
+ } else if (base instanceof Feed) {
+ Feed feed = (Feed)base;
+ id = feed.getId().toString();
+ modified = DateTimes.format(feed.getUpdated());
+ } else if (base instanceof Document) {
+ return calculateEntityTag(((Document<?>)base).getRoot());
+ }
+ return EntityTag.generate(id, modified);
+ }
+
+ public static String getEditUriFromEntry(Entry entry) {
+ String editUri = null;
+ List<Link> editLinks = entry.getLinks("edit");
+ if (editLinks != null) {
+ for (Link link : editLinks) {
+ // if there is more than one edit link, we should not automatically
+ // assume that it's always going to point to an Atom document
+ // representation.
+ if (link.getMimeType() != null) {
+ if (MimeTypeHelper.isMatch(link.getMimeType().toString(), Constants.ATOM_MEDIA_TYPE)) {
+ editUri = link.getResolvedHref().toString();
+ break;
+ }
+ } else {
+ // edit link with no type attribute is the right one to use
+ editUri = link.getResolvedHref().toString();
+ break;
+ }
+ }
+ }
+ return editUri;
+ }
+
+ /**
+ * Return a document
+ */
+ public static AtompubResponseContext returnBase(Base base, int status, DateTime lastModified) {
+ log.debug(Localizer.get("RETURNING.DOCUMENT"));
+ FOMResponseContext<Base> response = new FOMResponseContext<Base>(base);
+ response.setStatus(status);
+ if (lastModified != null)
+ response.setLastModified(lastModified);
+ // response.setContentType(MimeTypeHelper.getMimeType(base));
+ Document<?> doc = base instanceof Document ? (Document<?>)base : ((Element)base).getDocument();
+ if (doc.getEntityTag() != null) {
+ response.setEntityTag(doc.getEntityTag());
+ } else if (doc.getLastModified() != null) {
+ response.setLastModified(doc.getLastModified());
+ }
+ return response;
+ }
+
+ public static <T extends Element>Document<T> getDocument(
+ RequestContext context)
+ throws ParseException, IOException {
+ return getDocument(null, null, context);
+ }
+
+ public static <T extends Element> Document<T> getDocument(
+ Parser parser, RequestContext context)
+ throws ParseException, IOException {
+ return getDocument(parser,null,context);
+ }
+
+ public static <T extends Element> Document<T> getDocument(
+ ParserOptions options,
+ RequestContext context) throws ParseException,
+ IOException {
+ return getDocument(null,options,context);
+ }
+
+ public static <T extends Element> Document<T> getDocument(
+ Parser parser,
+ ParserOptions options,
+ RequestContext context)
+ throws ParseException, IOException {
+
+ Document<T> doc = context.getAttribute(Scope.REQUEST, Document.class.getName());
+ if (doc == null) {
+ try {
+ AtompubProvider provider = context.<AtompubProvider>getProvider();
+ Abdera abdera = provider.getAbdera();
+ log.debug(Localizer.get("PARSING.REQUEST.DOCUMENT"));
+ if (parser == null)
+ parser = abdera.getParser();
+ if (parser == null)
+ throw new IllegalArgumentException(
+ "No Parser implementation was provided");
+ if (options == null)
+ options = parser.getDefaultParserOptions();
+ doc = parser.parse(
+ context.getInputStream(),
+ context.getResolvedUri().toString(),
+ options);
+ context.setAttribute(Document.class.getName(), doc);
+ } catch (Throwable t) {
+ throw ExceptionHelper.propogate(t);
+ }
+ }
+ return doc;
+ }
+
+}
Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/AbstractAtompubProvider.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/AbstractAtompubWorkspaceProvider.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/AbstractAtompubWorkspaceProvider.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/AbstractAtompubWorkspaceProvider.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/AbstractAtompubWorkspaceProvider.java Wed Feb 1 17:54:54 2012
@@ -0,0 +1,83 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. The ASF licenses this file to You
+ * 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.protocol.server.impl;
+
+import java.util.Map;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.common.protocol.AbstractWorkspaceProvider;
+import org.apache.abdera2.common.protocol.CollectionRequestProcessor;
+import org.apache.abdera2.common.protocol.EntryRequestProcessor;
+import org.apache.abdera2.common.protocol.MediaRequestProcessor;
+import org.apache.abdera2.common.protocol.ProviderHelper;
+import org.apache.abdera2.common.protocol.ResponseContext;
+import org.apache.abdera2.common.protocol.TargetType;
+import org.apache.abdera2.common.protocol.WorkspaceManager;
+import org.apache.abdera2.protocol.server.AtompubProvider;
+import org.apache.abdera2.protocol.server.processors.CategoriesRequestProcessor;
+import org.apache.abdera2.protocol.server.processors.ServiceRequestProcessor;
+
+public abstract class AbstractAtompubWorkspaceProvider
+ extends AbstractWorkspaceProvider
+ implements AtompubProvider,
+ WorkspaceManager {
+
+ protected Abdera abdera;
+
+ protected AbstractAtompubWorkspaceProvider() {
+ addRequestProcessor(
+ TargetType.TYPE_SERVICE,
+ ServiceRequestProcessor.class,
+ this);
+ addRequestProcessor(
+ TargetType.TYPE_CATEGORIES,
+ CategoriesRequestProcessor.class,
+ this);
+ addRequestProcessor(
+ TargetType.TYPE_COLLECTION,
+ CollectionRequestProcessor.class,
+ ProviderHelper.isAtom(),
+ this);
+ addRequestProcessor(
+ TargetType.TYPE_ENTRY,
+ EntryRequestProcessor.class,
+ this);
+ addRequestProcessor(
+ TargetType.TYPE_MEDIA,
+ MediaRequestProcessor.class,
+ this);
+ }
+
+ public void init(Map<String, Object> properties) {
+ this.abdera =
+ properties != null &&
+ properties.containsKey("abdera") ?
+ (Abdera)properties.get("abdera") :
+ Abdera.getInstance();
+ super.init(properties);
+ }
+
+ public Abdera getAbdera() {
+ return abdera;
+ }
+
+ public ResponseContext createErrorResponse(int code, String message, Throwable t) {
+ return AbstractAtompubProvider.createErrorResponse(abdera,code,message,t);
+ }
+
+}
\ No newline at end of file
Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/AbstractAtompubWorkspaceProvider.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/AbstractEntityCollectionAdapter.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/AbstractEntityCollectionAdapter.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/AbstractEntityCollectionAdapter.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/AbstractEntityCollectionAdapter.java Wed Feb 1 17:54:54 2012
@@ -0,0 +1,723 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. The ASF licenses this file to You
+ * 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.protocol.server.impl;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import javax.activation.MimeType;
+
+import org.apache.abdera2.Abdera;
+import org.apache.abdera2.factory.Factory;
+import org.apache.abdera2.common.iri.IRI;
+import org.apache.abdera2.common.text.UrlEncoding;
+import org.apache.abdera2.common.text.CharUtils.Profile;
+import org.apache.abdera2.common.date.DateTimes;
+import org.apache.abdera2.model.Content;
+import org.apache.abdera2.model.Entry;
+import org.apache.abdera2.model.Feed;
+import org.apache.abdera2.model.Person;
+import org.apache.abdera2.model.Text;
+import org.apache.abdera2.parser.ParseException;
+import org.apache.abdera2.util.MorePredicates;
+import org.apache.abdera2.common.http.EntityTag;
+import org.apache.abdera2.common.mediatype.MimeTypeHelper;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.ResponseContext;
+import org.apache.abdera2.common.protocol.EmptyResponseContext;
+import org.apache.abdera2.common.protocol.MediaResponseContext;
+import org.apache.abdera2.common.protocol.ProviderHelper;
+import org.apache.abdera2.common.protocol.ResponseContextException;
+import org.apache.abdera2.common.protocol.TargetType;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+import org.joda.time.DateTime;
+
+import com.google.common.base.Function;
+
+/**
+ * By extending this class it becomes easy to build Collections which are backed by a set of entities - such as a
+ * database row, domain objects, or files.
+ *
+ * @param <T> The entity that this is backed by.
+ */
+public abstract class AbstractEntityCollectionAdapter<T>
+ extends AbstractAtompubCollectionAdapter {
+
+ private final static Log log = LogFactory.getLog(AbstractEntityCollectionAdapter.class);
+
+ public AbstractEntityCollectionAdapter(String href) {
+ super(href);
+ putHandler(TargetType.TYPE_COLLECTION,"POST",handlePost());
+ putHandler(TargetType.TYPE_COLLECTION,"GET",getItemList());
+ putHandler(TargetType.TYPE_COLLECTION,"HEAD",getItemList());
+ putHandler(TargetType.TYPE_MEDIA,"PUT",putMedia());
+ putHandler(TargetType.TYPE_MEDIA,"DELETE",deleteMedia());
+ putHandler(TargetType.TYPE_MEDIA, "HEAD", headMedia());
+ putHandler(TargetType.TYPE_MEDIA, "GET", getMedia());
+ putHandler(TargetType.TYPE_ENTRY,"DELETE",deleteItem());
+ putHandler(TargetType.TYPE_ENTRY,"GET",getItem());
+ putHandler(TargetType.TYPE_ENTRY,"HEAD",headItem());
+ putHandler(TargetType.TYPE_ENTRY,"PUT",putItem());
+ }
+
+ /**
+ * Create a new entry
+ *
+ * @param title The title of the entry (assumes that type="text")
+ * @param id The value of the atom:id element
+ * @param summary The summary of the entry
+ * @param updated The value of the atom:updated element
+ * @param authors Listing of atom:author elements
+ * @param context The content of the entry
+ * @param request The request context
+ */
+ public abstract T postEntry(String title,
+ IRI id,
+ String summary,
+ DateTime updated,
+ List<Person> authors,
+ Content content,
+ RequestContext request) throws ResponseContextException;
+
+ Function<RequestContext,ResponseContext> postMedia() {
+ return new Function<RequestContext,ResponseContext>() {
+ public ResponseContext apply(RequestContext input) {
+ return createMediaEntry(input);
+ }
+ };
+ }
+
+ private Function<RequestContext,ResponseContext> putMedia() {
+ return new Function<RequestContext,ResponseContext>() {
+ public ResponseContext apply(RequestContext input) {
+ try {
+ String id = getResourceName(input);
+ T entryObj = getEntry(id, input);
+ putMedia(entryObj, input.getContentType(), input.getSlug(), input.getInputStream(), input);
+ return new EmptyResponseContext(200);
+ } catch (IOException e) {
+ return new EmptyResponseContext(500);
+ } catch (ResponseContextException e) {
+ return createErrorResponse(e);
+ }
+ }
+ };
+ }
+
+ /**
+ * Update a media resource. By default this method is not allowed. Implementations must override this method to
+ * support media resource updates
+ *
+ * @param entryObj
+ * @param contentType The mime-type of the media resource
+ * @param slug The value of the Slug request header
+ * @param inputStream An input stream providing access to the request payload
+ * @param request The request context
+ */
+ public void putMedia(T entryObj, MimeType contentType, String slug, InputStream inputStream, RequestContext request)
+ throws ResponseContextException {
+ throw new ResponseContextException(ProviderHelper.notallowed(request));
+ }
+
+ Function<RequestContext,ResponseContext> postItem() {
+ return new Function<RequestContext,ResponseContext>() {
+ public ResponseContext apply(RequestContext input) {
+ return createNonMediaEntry(input);
+ }
+ };
+ }
+
+ private Function<RequestContext,ResponseContext> handlePost() {
+ return new Function<RequestContext,ResponseContext>() {
+ public ResponseContext apply(RequestContext input) {
+ return AbstractAtompubProvider.IS_ATOM.apply(input) ?
+ postItem().apply(input) :
+ postMedia().apply(input);
+ }
+ };
+ }
+
+ protected String getLink(T entryObj, IRI feedIri, RequestContext request) throws ResponseContextException {
+ return getLink(entryObj, feedIri, request, false);
+ }
+
+ protected String getLink(T entryObj, IRI feedIri, RequestContext request, boolean absolute)
+ throws ResponseContextException {
+ return getLink(getName(entryObj), entryObj, feedIri, request, absolute);
+ }
+
+ protected String getLink(String name, T entryObj, IRI feedIri, RequestContext request) {
+ return getLink(name, entryObj, feedIri, request, false);
+ }
+
+ protected String getLink(String name, T entryObj, IRI feedIri, RequestContext request, boolean absolute) {
+ feedIri = feedIri.trailingSlash();
+ IRI entryIri = feedIri.resolve(UrlEncoding.encode(name, Profile.PATH));
+
+ if (absolute) {
+ entryIri = request.getResolvedUri().resolve(entryIri);
+ }
+
+ String link = entryIri.toString();
+
+ String qp = getQueryParameters(entryObj, request);
+ if (qp != null && !"".equals(qp)) {
+ StringBuilder sb = new StringBuilder();
+ sb.append(link).append("?").append(qp);
+ link = sb.toString();
+ }
+
+ return link;
+ }
+
+ protected String getQueryParameters(T entryObj, RequestContext request) {
+ return null;
+ }
+
+ /**
+ * Post a new media resource to the collection. By default, this method is not supported. Implementations must
+ * override this method to support posting media resources
+ *
+ * @param mimeType The mime-type of the resource
+ * @param slug The value of the Slug header
+ * @param inputStream An InputStream providing access to the request payload
+ * @param request The request context
+ */
+ public T postMedia(MimeType mimeType, String slug, InputStream inputStream, RequestContext request)
+ throws ResponseContextException {
+ throw new UnsupportedOperationException();
+ }
+
+ private Function<RequestContext,ResponseContext> deleteItem() {
+ return new Function<RequestContext,ResponseContext>() {
+ public ResponseContext apply(RequestContext input) {
+ String id = getResourceName(input);
+ if (id != null) {
+ try {
+ deleteEntry(id, input);
+ } catch (ResponseContextException e) {
+ return createErrorResponse(e);
+ }
+ return new EmptyResponseContext(204);
+ } else {
+ return new EmptyResponseContext(404);
+ }
+ }
+ };
+ }
+
+ /**
+ * Delete an entry
+ *
+ * @param resourceName The entry to delete
+ * @param request The request context
+ */
+ public abstract void deleteEntry(String resourceName, RequestContext request) throws ResponseContextException;
+
+ private Function<RequestContext,ResponseContext> deleteMedia() {
+ return new Function<RequestContext,ResponseContext>() {
+ public ResponseContext apply(RequestContext input) {
+ String resourceName = getResourceName(input);
+ if (resourceName != null) {
+ try {
+ deleteMedia(resourceName, input);
+ } catch (ResponseContextException e) {
+ return createErrorResponse(e);
+ }
+ return new EmptyResponseContext(204);
+ } else {
+ return new EmptyResponseContext(404);
+ }
+ }
+ };
+ }
+
+ /**
+ * Delete a media resource. By default this method is not supported. Implementations must override this method to
+ * support deleting media resources
+ */
+ public void deleteMedia(String resourceName, RequestContext request) throws ResponseContextException {
+ throw new ResponseContextException(ProviderHelper.notsupported(request));
+ }
+
+ /**
+ * Get the authors for an entry. By default this returns null. Implementations must override in order to providing a
+ * listing of authors for an entry
+ */
+ public List<Person> getAuthors(T entry, RequestContext request) throws ResponseContextException {
+ return null;
+ }
+
+ /**
+ * Get the content for the entry.
+ */
+ public abstract Object getContent(T entry, RequestContext request) throws ResponseContextException;
+
+ // GET, POST, PUT, DELETE
+
+ /**
+ * Get the content-type for the entry. By default this operation is not supported.
+ */
+ public String getContentType(T entry) {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Get the listing of entries requested
+ */
+ public abstract Iterable<T> getEntries(RequestContext request) throws ResponseContextException;
+
+ private Function<RequestContext,ResponseContext> getItem() {
+ return new Function<RequestContext,ResponseContext>() {
+ public ResponseContext apply(RequestContext input) {
+ try {
+ Entry entry = getEntryFromCollectionProvider(input);
+ if (entry != null) {
+ return buildGetEntryResponse(input, entry);
+ } else {
+ return new EmptyResponseContext(404);
+ }
+ } catch (ResponseContextException e) {
+ return createErrorResponse(e);
+ }
+ }
+ };
+ }
+
+ /**
+ * Get a specific entry
+ *
+ * @param resourceName The entry to get
+ * @param request The request context
+ */
+ public abstract T getEntry(String resourceName, RequestContext request) throws ResponseContextException;
+
+ private Function<RequestContext,ResponseContext> headItem() {
+ return new Function<RequestContext,ResponseContext>() {
+ public ResponseContext apply(RequestContext input) {
+ try {
+ String resourceName = getResourceName(input);
+ T entryObj = getEntry(resourceName, input);
+ if (entryObj != null) {
+ return buildHeadEntryResponse(input, resourceName, getUpdated(entryObj));
+ } else {
+ return new EmptyResponseContext(404);
+ }
+ } catch (ResponseContextException e) {
+ return createErrorResponse(e);
+ }
+ }
+ };
+ }
+
+ private Function<RequestContext,ResponseContext> headMedia() {
+ return new Function<RequestContext,ResponseContext>() {
+ public ResponseContext apply(RequestContext input) {
+ try {
+ String resourceName = getResourceName(input);
+ T entryObj = getEntry(resourceName, input);
+
+ if (entryObj != null) {
+ return buildHeadEntryResponse(input, resourceName, getUpdated(entryObj));
+ } else {
+ return new EmptyResponseContext(404);
+ }
+ } catch (ResponseContextException e) {
+ return createErrorResponse(e);
+ }
+ }
+ };
+ }
+
+ public Function<RequestContext,ResponseContext> getItemList() {
+ return new Function<RequestContext,ResponseContext>() {
+ public ResponseContext apply(RequestContext input) {
+ try {
+ Feed feed = createFeedBase(input);
+ addFeedDetails(feed, input);
+ return buildGetFeedResponse(feed);
+ } catch (ResponseContextException e) {
+ return createErrorResponse(e);
+ }
+ }
+ };
+ }
+
+
+ /**
+ * Adds the selected entries to the Feed document. By default, this will set the feed's atom:updated element to the
+ * current date and time
+ */
+ protected void addFeedDetails(Feed feed, RequestContext request) throws ResponseContextException {
+ feed.setUpdated(DateTime.now());
+
+ Iterable<T> entries = getEntries(request);
+ if (entries != null) {
+ for (T entryObj : entries) {
+ Entry e = feed.addEntry();
+
+ IRI feedIri = new IRI(getFeedIriForEntry(entryObj, request));
+ addEntryDetails(request, e, feedIri, entryObj);
+
+ if (isMediaEntry(entryObj)) {
+ addMediaContent(feedIri, e, entryObj, request);
+ } else {
+ addContent(e, entryObj, request);
+ }
+ }
+ }
+ }
+
+ private IRI getFeedIRI(T entryObj, RequestContext request) {
+ String feedIri = getFeedIriForEntry(entryObj, request);
+ return new IRI(feedIri).trailingSlash();
+ }
+
+ /**
+ * Gets the UUID for the specified entry.
+ *
+ * @param entry
+ * @return
+ */
+ public abstract String getId(T entry) throws ResponseContextException;
+
+ private Function<RequestContext,ResponseContext> getMedia() {
+ return new Function<RequestContext,ResponseContext>() {
+ public ResponseContext apply(RequestContext input) {
+ try {
+ String resource = getResourceName(input);
+ T entryObj = getEntry(resource, input);
+ if (entryObj == null) {
+ return new EmptyResponseContext(404);
+ }
+ return buildGetMediaResponse(resource, entryObj);
+ } catch (ParseException pe) {
+ return new EmptyResponseContext(415);
+ } catch (ClassCastException cce) {
+ return new EmptyResponseContext(415);
+ } catch (ResponseContextException e) {
+ return e.getResponseContext();
+ } catch (Exception e) {
+ log.warn(e.getMessage(), e);
+ return new EmptyResponseContext(400);
+ }
+ }
+ };
+ }
+
+ /**
+ * Creates a ResponseContext for a GET media request. By default, this returns a MediaResponseContext containing the
+ * media resource. The last-modified header will be set.
+ */
+ protected ResponseContext buildGetMediaResponse(String id, T entryObj) throws ResponseContextException {
+ DateTime updated = getUpdated(entryObj);
+ return new MediaResponseContext(getMediaStream(entryObj), updated, 200)
+ .setContentType(getContentType(entryObj))
+ .setEntityTag(EntityTag.generate(id, DateTimes.format(updated)));
+ }
+
+ /**
+ * Get the name of the media resource. By default this method is unsupported. Implementations must override.
+ */
+ public String getMediaName(T entry) throws ResponseContextException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Get an input stream for the media resource. By default this method is unsupported. Implementations must override.
+ */
+ public InputStream getMediaStream(T entry) throws ResponseContextException {
+ throw new UnsupportedOperationException();
+ }
+
+ /**
+ * Get the name of the entry resource (used to construct links)
+ */
+ public abstract String getName(T entry) throws ResponseContextException;
+
+ /**
+ * Get the title fo the entry
+ */
+ public abstract String getTitle(T entry) throws ResponseContextException;
+
+ /**
+ * Get the value to use in the atom:updated element
+ */
+ public abstract DateTime getUpdated(T entry) throws ResponseContextException;
+
+ /**
+ * True if this entry is a media-link entry. By default this always returns false. Implementations must override to
+ * support media link entries
+ */
+ public boolean isMediaEntry(T entry) throws ResponseContextException {
+ return false;
+ }
+
+ private Function<RequestContext,ResponseContext> putItem() {
+ return new Function<RequestContext,ResponseContext>() {
+ public ResponseContext apply(RequestContext input) {
+ try {
+ String id = getResourceName(input);
+ T entryObj = getEntry(id, input);
+
+ if (entryObj == null) {
+ return new EmptyResponseContext(404);
+ }
+
+ Entry orig_entry =
+ getEntryFromCollectionProvider(entryObj, new IRI(getFeedIriForEntry(entryObj, input)), input);
+ if (orig_entry != null) {
+
+ MimeType contentType = input.getContentType();
+ if (contentType != null && !MimeTypeHelper.isAtom(contentType.toString()))
+ return new EmptyResponseContext(415);
+
+ Entry entry = getEntryFromRequest(input);
+ if (entry != null) {
+ if (!entry.getId().equals(orig_entry.getId()))
+ return new EmptyResponseContext(409);
+
+ if (!MorePredicates.VALID_ENTRY.apply(entry))
+ return new EmptyResponseContext(400);
+
+ putEntry(entryObj, entry.getTitle(), DateTime.now(), entry.getAuthors(), entry.getSummary(), entry
+ .getContentElement(), input);
+ return new EmptyResponseContext(204);
+ } else {
+ return new EmptyResponseContext(400);
+ }
+ } else {
+ return new EmptyResponseContext(404);
+ }
+ } catch (ResponseContextException e) {
+ return createErrorResponse(e);
+ } catch (ParseException pe) {
+ return new EmptyResponseContext(415);
+ } catch (ClassCastException cce) {
+ return new EmptyResponseContext(415);
+ } catch (Exception e) {
+ log.warn(e.getMessage(), e);
+ return new EmptyResponseContext(400);
+ }
+ }
+ };
+ }
+
+ /**
+ * Get the Feed IRI
+ */
+ protected String getFeedIriForEntry(T entryObj, RequestContext request) {
+ return getHref(request);
+ }
+
+ /**
+ * Update an entry.
+ *
+ * @param entry The entry to update
+ * @param title The new title of the entry
+ * @param updated The new value of atom:updated
+ * @param authors To new listing of authors
+ * @param summary The new summary
+ * @param content The new content
+ * @param request The request context
+ */
+ public abstract void putEntry(T entry,
+ String title,
+ DateTime updated,
+ List<Person> authors,
+ String summary,
+ Content content,
+ RequestContext request) throws ResponseContextException;
+
+ /**
+ * Adds the atom:content element to an entry
+ */
+ protected void addContent(Entry e, T doc, RequestContext request) throws ResponseContextException {
+ Object content = getContent(doc, request);
+
+ if (content instanceof Content) {
+ e.setContentElement((Content)content);
+ } else if (content instanceof String) {
+ e.setContent((String)content);
+ }
+ }
+
+ /**
+ * Add the details to an entry
+ *
+ * @param request The request context
+ * @param e The entry
+ * @param feedIri The feed IRI
+ * @param entryObj
+ */
+ protected String addEntryDetails(RequestContext request, Entry e, IRI feedIri, T entryObj)
+ throws ResponseContextException {
+ String link = getLink(entryObj, feedIri, request);
+
+ e.addLink(link, "edit");
+ e.setId(getId(entryObj));
+ e.setTitle(getTitle(entryObj));
+ e.setUpdated(getUpdated(entryObj));
+
+ List<Person> authors = getAuthors(entryObj, request);
+ if (authors != null) {
+ for (Person a : authors) {
+ e.addAuthor(a);
+ }
+ }
+
+ Text t = getSummary(entryObj, request);
+ if (t != null) {
+ e.setSummaryElement(t);
+ }
+ return link;
+ }
+
+ /**
+ * Get the summary of the entry. By default this returns null.
+ */
+ public Text getSummary(T entry, RequestContext request) throws ResponseContextException {
+ return null;
+ }
+
+ /**
+ * Add media content details to a media-link entry
+ *
+ * @param feedIri The feed iri
+ * @param entry The entry object
+ * @param entryObj
+ * @param request The request context
+ */
+ protected String addMediaContent(IRI feedIri, Entry entry, T entryObj, RequestContext request)
+ throws ResponseContextException {
+ String name = getMediaName(entryObj);
+
+ IRI mediaIri = new IRI(getLink(name, entryObj, feedIri, request));
+ String mediaLink = mediaIri.toString();
+ entry.setContent(mediaIri, getContentType(entryObj));
+ entry.addLink(mediaLink, "edit-media");
+
+ return mediaLink;
+ }
+
+ /**
+ * Create a media entry
+ *
+ * @param request The request context
+ */
+ protected ResponseContext createMediaEntry(RequestContext request) {
+ try {
+ T entryObj = postMedia(request.getContentType(), request.getSlug(), request.getInputStream(), request);
+
+ IRI feedUri = getFeedIRI(entryObj, request);
+
+ Entry entry = AbstractAtompubProvider.getAbdera(request).getFactory().newEntry();
+ addEntryDetails(request, entry, feedUri, entryObj);
+ addMediaContent(feedUri, entry, entryObj, request);
+
+ String location = getLink(entryObj, feedUri, request, true);
+ return buildPostMediaEntryResponse(location, entry);
+ } catch (UnsupportedOperationException e) {
+ return UNSUPPORTED_TYPE.apply(request);
+ } catch (IOException e) {
+ return new EmptyResponseContext(500);
+ } catch (ResponseContextException e) {
+ return createErrorResponse(e);
+ }
+ }
+
+ /**
+ * Create a regular entry
+ *
+ * @param request The request context
+ */
+ protected ResponseContext createNonMediaEntry(RequestContext request) {
+ try {
+ Entry entry = getEntryFromRequest(request);
+ if (entry != null) {
+ if (!MorePredicates.VALID_ENTRY.apply(entry))
+ return new EmptyResponseContext(400);
+
+ entry.setUpdated(DateTime.now());
+
+ T entryObj =
+ postEntry(entry.getTitle(), entry.getId(), entry.getSummary(), entry.getUpdated(), entry
+ .getAuthors(), entry.getContentElement(), request);
+
+ entry.getIdElement().setValue(getId(entryObj));
+
+ IRI feedUri = getFeedIRI(entryObj, request);
+
+ String link = getLink(entryObj, feedUri, request);
+ entry.addLink(link, "edit");
+
+ String location = getLink(entryObj, feedUri, request, true);
+ return buildCreateEntryResponse(location, entry);
+ } else {
+ return new EmptyResponseContext(400);
+ }
+ } catch (ResponseContextException e) {
+ return createErrorResponse(e);
+ }
+ }
+
+ protected Entry getEntryFromCollectionProvider(RequestContext request) throws ResponseContextException {
+ String id = getResourceName(request);
+ T entryObj = getEntry(id, request);
+
+ if (entryObj == null) {
+ return null;
+ }
+
+ IRI feedIri = new IRI(getFeedIriForEntry(entryObj, request));
+ return getEntryFromCollectionProvider(entryObj, feedIri, request);
+ }
+
+ Entry getEntryFromCollectionProvider(T entryObj, IRI feedIri, RequestContext request)
+ throws ResponseContextException {
+ Abdera abdera = AbstractAtompubProvider.getAbdera(request);
+ Factory factory = abdera.getFactory();
+ Entry entry = factory.newEntry();
+
+ return buildEntry(entryObj, entry, feedIri, request);
+ }
+
+ /**
+ * Build the entry from the source object
+ *
+ * @param entryObj The source object
+ * @param entry The entry to build
+ * @param feedIri The feed IRI
+ * @param request The request context
+ */
+ private Entry buildEntry(T entryObj, Entry entry, IRI feedIri, RequestContext request)
+ throws ResponseContextException {
+ addEntryDetails(request, entry, feedIri, entryObj);
+
+ if (isMediaEntry(entryObj)) {
+ addMediaContent(feedIri, entry, entryObj, request);
+ } else {
+ addContent(entry, entryObj, request);
+ }
+
+ return entry;
+ }
+
+}
Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/AbstractEntityCollectionAdapter.java
------------------------------------------------------------------------------
svn:executable = *
Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/AbstractEntityCollectionAdapter.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/DefaultAtompubProvider.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/DefaultAtompubProvider.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/DefaultAtompubProvider.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/DefaultAtompubProvider.java Wed Feb 1 17:54:54 2012
@@ -0,0 +1,126 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. The ASF licenses this file to You
+ * 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.protocol.server.impl;
+
+import java.util.Collection;
+
+import javax.security.auth.Subject;
+
+import org.apache.abdera2.common.protocol.DefaultWorkspaceManager;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.common.protocol.Request;
+import org.apache.abdera2.common.protocol.RouteManager;
+import org.apache.abdera2.common.protocol.Target;
+import org.apache.abdera2.common.protocol.TargetBuilder;
+import org.apache.abdera2.common.protocol.TargetType;
+import org.apache.abdera2.common.protocol.WorkspaceInfo;
+import org.apache.abdera2.common.protocol.WorkspaceManager;
+
+import com.google.common.base.Function;
+
+/**
+ * The DefaultProvider is the default Provider implementation for Abdera. It supports multiple collections and assumes a
+ * simple http://.../{collection}/{entry} URL structure. Media-link entries are not supported.
+ */
+public class DefaultAtompubProvider
+ extends AbstractAtompubProvider {
+
+ protected Function<RequestContext,Target> targetResolver;
+ protected Function<Request,Subject> subjectResolver;
+ protected TargetBuilder<?> targetBuilder;
+ protected RouteManager<TargetType,RequestContext,String> routeManager;
+
+ public DefaultAtompubProvider() {
+ this("/");
+ }
+
+ public DefaultAtompubProvider(String base) {
+ super(new DefaultWorkspaceManager());
+ if (base == null)
+ base = "/";
+ routeManager =
+ RouteManager.<TargetType,RequestContext,String>make()
+ .with("service", base, TargetType.TYPE_SERVICE)
+ .with("feed", base + ":collection", TargetType.TYPE_COLLECTION)
+ .with("entry", base + ":collection/:entry", TargetType.TYPE_ENTRY)
+ .with("categories", base + ":collection/:entry;categories", TargetType.TYPE_CATEGORIES)
+ .get();
+ targetBuilder = routeManager;
+ targetResolver = routeManager;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public RouteManager getRouteManager() {
+ return routeManager;
+ }
+
+ protected Function<RequestContext,Target> getTargetResolver(RequestContext request) {
+ return targetResolver;
+ }
+
+ public void setTargetResolver(Function<RequestContext,Target> targetResolver) {
+ this.targetResolver = targetResolver;
+ }
+
+ protected Function<Request,Subject> getSubjectResolver(RequestContext request) {
+ return subjectResolver;
+ }
+
+ public void setSubjectResolver(Function<Request,Subject> subjectResolver) {
+ this.subjectResolver = subjectResolver;
+ }
+
+ public Function<RequestContext,Target> getTargetResolver() {
+ return targetResolver;
+ }
+
+ public Function<Request,Subject> getSubjectResolver() {
+ return subjectResolver;
+ }
+
+ public WorkspaceManager getWorkspaceManager() {
+ return workspaceManager;
+ }
+
+ public void setWorkspaceManager(WorkspaceManager workspaceManager) {
+ this.workspaceManager = workspaceManager;
+ }
+
+ @SuppressWarnings("rawtypes")
+ public TargetBuilder getTargetBuilder() {
+ return (TargetBuilder)targetBuilder;
+ }
+
+ public void setTargetBuilder(TargetBuilder<?> targetBuilder) {
+ this.targetBuilder = targetBuilder;
+ }
+
+ public void addWorkspace(WorkspaceInfo workspace) {
+ ((DefaultWorkspaceManager)getWorkspaceManager()).addWorkspace(workspace);
+ }
+
+ public void addWorkspaces(Collection<WorkspaceInfo> workspaces) {
+ for (WorkspaceInfo w : workspaces)
+ ((DefaultWorkspaceManager)getWorkspaceManager()).addWorkspace(w);
+ }
+
+ @SuppressWarnings("rawtypes")
+ protected TargetBuilder getTargetBuilder(Request request) {
+ return (TargetBuilder)targetBuilder;
+ }
+}
Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/DefaultAtompubProvider.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/SimpleCategoriesInfo.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/SimpleCategoriesInfo.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/SimpleCategoriesInfo.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/SimpleCategoriesInfo.java Wed Feb 1 17:54:54 2012
@@ -0,0 +1,140 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. The ASF licenses this file to You
+ * 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.protocol.server.impl;
+
+import java.io.Serializable;
+import java.util.Iterator;
+
+import org.apache.abdera2.common.misc.MoreFunctions;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.model.Categories;
+import org.apache.abdera2.protocol.server.model.AtompubCategoriesInfo;
+import org.apache.abdera2.protocol.server.model.AtompubCategoryInfo;
+
+import com.google.common.base.Supplier;
+import com.google.common.collect.ImmutableList;
+
+public class SimpleCategoriesInfo implements AtompubCategoriesInfo, Serializable {
+
+ public static Generator make() {
+ return new Generator();
+ }
+
+ public static class Generator implements Supplier<AtompubCategoriesInfo> {
+ String href;
+ String scheme;
+ boolean fixed;
+ final ImmutableList.Builder<AtompubCategoryInfo> list =
+ ImmutableList.builder();
+ public Generator href(String href) {
+ this.href = href;
+ return this;
+ }
+ public Generator scheme(String scheme) {
+ this.scheme = scheme;
+ return this;
+ }
+ public Generator fixed() {
+ this.fixed = true;
+ return this;
+ }
+ public Generator category(AtompubCategoryInfo info) {
+ this.list.add(info);
+ return this;
+ }
+ public AtompubCategoriesInfo get() {
+ return new SimpleCategoriesInfo(this);
+ }
+
+ }
+
+ private static final long serialVersionUID = 8732335394387909260L;
+
+ private final String href;
+ private final String scheme;
+ private final boolean fixed;
+ private final ImmutableList<AtompubCategoryInfo> list;
+
+ protected SimpleCategoriesInfo(Generator gen) {
+ this.href = gen.href;
+ this.scheme = gen.scheme;
+ this.fixed = gen.fixed;
+ this.list = gen.list.build();
+ }
+
+ public String getHref(RequestContext request) {
+ return href;
+ }
+
+ public String getScheme(RequestContext request) {
+ return scheme;
+ }
+
+ public boolean isFixed(RequestContext request) {
+ return fixed;
+ }
+
+ public Iterator<AtompubCategoryInfo> iterator() {
+ return list.iterator();
+ }
+
+ public int hashCode() {
+ return MoreFunctions.genHashCode(1, fixed, href, list, scheme);
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final SimpleCategoriesInfo other = (SimpleCategoriesInfo)obj;
+ if (fixed != other.fixed)
+ return false;
+ if (href == null) {
+ if (other.href != null)
+ return false;
+ } else if (!href.equals(other.href))
+ return false;
+ if (list == null) {
+ if (other.list != null)
+ return false;
+ } else if (!list.equals(other.list))
+ return false;
+ if (scheme == null) {
+ if (other.scheme != null)
+ return false;
+ } else if (!scheme.equals(other.scheme))
+ return false;
+ return true;
+ }
+
+ public Categories asCategoriesElement(RequestContext request) {
+ Categories cats = AbstractAtompubProvider.getAbdera(request).getFactory().newCategories();
+ if (href != null)
+ cats.setHref(href);
+ else {
+ cats.setFixed(fixed);
+ cats.setScheme(scheme);
+ for (AtompubCategoryInfo cat : this)
+ cats.addCategory(cat.asCategoryElement(request));
+ }
+ return cats;
+ }
+}
Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/SimpleCategoriesInfo.java
------------------------------------------------------------------------------
svn:mime-type = text/plain
Added: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/SimpleCategoryInfo.java
URL: http://svn.apache.org/viewvc/abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/SimpleCategoryInfo.java?rev=1239237&view=auto
==============================================================================
--- abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/SimpleCategoryInfo.java (added)
+++ abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/SimpleCategoryInfo.java Wed Feb 1 17:54:54 2012
@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. The ASF licenses this file to You
+ * 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. For additional information regarding
+ * copyright in this work, please see the NOTICE file in the top level
+ * directory of this distribution.
+ */
+package org.apache.abdera2.protocol.server.impl;
+
+import java.io.Serializable;
+
+import org.apache.abdera2.common.misc.MoreFunctions;
+import org.apache.abdera2.common.protocol.RequestContext;
+import org.apache.abdera2.model.Category;
+import org.apache.abdera2.protocol.server.model.AtompubCategoryInfo;
+
+import com.google.common.base.Supplier;
+
+public class SimpleCategoryInfo implements AtompubCategoryInfo, Serializable {
+
+ public static Generator make() {
+ return new Generator();
+ }
+
+ public static class Generator implements Supplier<AtompubCategoryInfo> {
+ String label;
+ String term;
+ String scheme;
+ public Generator label(String label) {
+ this.label = label;
+ return this;
+ }
+ public Generator term(String term) {
+ this.term = term;
+ return this;
+ }
+ public Generator scheme(String scheme) {
+ this.scheme = scheme;
+ return this;
+ }
+ public AtompubCategoryInfo get() {
+ return new SimpleCategoryInfo(this);
+ }
+
+ }
+
+ private static final long serialVersionUID = -4013333222147077975L;
+ private final String label;
+ private final String term;
+ private final String scheme;
+
+ protected SimpleCategoryInfo(Generator gen) {
+ this.label = gen.label;
+ this.term = gen.term;
+ this.scheme = gen.scheme;
+ }
+
+
+ public String getLabel(RequestContext request) {
+ return label;
+ }
+
+ public String getScheme(RequestContext request) {
+ return scheme;
+ }
+
+ public String getTerm(RequestContext request) {
+ return term;
+ }
+
+ public int hashCode() {
+ return MoreFunctions.genHashCode(1, label, scheme, term);
+ }
+
+ public boolean equals(Object obj) {
+ if (this == obj)
+ return true;
+ if (obj == null)
+ return false;
+ if (getClass() != obj.getClass())
+ return false;
+ final SimpleCategoryInfo other = (SimpleCategoryInfo)obj;
+ if (label == null) {
+ if (other.label != null)
+ return false;
+ } else if (!label.equals(other.label))
+ return false;
+ if (scheme == null) {
+ if (other.scheme != null)
+ return false;
+ } else if (!scheme.equals(other.scheme))
+ return false;
+ if (term == null) {
+ if (other.term != null)
+ return false;
+ } else if (!term.equals(other.term))
+ return false;
+ return true;
+ }
+
+ public Category asCategoryElement(RequestContext request) {
+ Category cat = AbstractAtompubProvider.getAbdera(request).getFactory().newCategory();
+ cat.setTerm(term);
+ if (scheme != null)
+ cat.setScheme(scheme);
+ if (label != null)
+ cat.setLabel(label);
+ return cat;
+ }
+}
Propchange: abdera/abdera2-server/server/src/main/java/org/apache/abdera2/protocol/server/impl/SimpleCategoryInfo.java
------------------------------------------------------------------------------
svn:mime-type = text/plain