Package com.google.feedserver.adapters

Source Code of com.google.feedserver.adapters.AbstractManagedCollectionAdapter

/*
* Copyright 2008 Google Inc.
*
* 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 com.google.feedserver.adapters;

import com.google.feedserver.adapters.FeedServerAdapterException.Reason;
import com.google.feedserver.config.FeedServerConfiguration;
import com.google.feedserver.config.GlobalServerConfiguration;
import com.google.feedserver.config.NamespacedAdapterConfiguration;
import com.google.feedserver.config.NamespacedFeedConfiguration;
import com.google.feedserver.config.PerNamespaceServerConfiguration;
import com.google.feedserver.config.UserInfo;
import com.google.feedserver.metadata.FeedInfo;
import com.google.feedserver.metadata.SimpleFeedInfo;
import com.google.feedserver.util.FeedServerUtil;
import com.google.feedserver.util.XmlUtil;

import org.apache.abdera.Abdera;
import org.apache.abdera.model.Base;
import org.apache.abdera.model.Content;
import org.apache.abdera.model.Document;
import org.apache.abdera.model.Entry;
import org.apache.abdera.model.Feed;
import org.apache.abdera.parser.Parser;
import org.apache.abdera.protocol.server.ProviderHelper;
import org.apache.abdera.protocol.server.RequestContext;
import org.apache.abdera.protocol.server.ResponseContext;
import org.apache.abdera.protocol.server.Target;
import org.apache.abdera.protocol.server.provider.managed.CollectionAdapterConfiguration;
import org.apache.abdera.protocol.server.provider.managed.FeedConfiguration;
import org.apache.abdera.protocol.server.provider.managed.ManagedCollectionAdapter;
import org.xml.sax.SAXException;

import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;

/**
* This class tries to aggregate common functions that will be used in most of
* the adapters and tries to remove the duplication that would happen. It also
* provides utility functions for adapters.
*
* Ideally all the code here should get pulled up into
* {@link ManagedCollectionAdapter}.
*
* @author abhinavk@gmail.com (Abhinav Khandelwal)
*
*/
public abstract class AbstractManagedCollectionAdapter extends ManagedCollectionAdapter {

  public static final String PARAM_ENTRY = "entry";
  public static final String PARAM_FEED = "feed";
  public static final String PARAM_USER = "user";
  public static final String PARAM_NAMESPACE = "namespace";
  public static final String PARAM_FEED_TYPE = "feedType";
  public static final String USER_INFO = "__user_info__";
  public static final String ENCODING_UTF_8 = "UTF-8";
  public static final String CATEGORY_PARAMETER = "category";

  protected final XmlUtil xmlUtil;

  protected AbstractManagedCollectionAdapter(Abdera abdera, FeedConfiguration config) {
    super(abdera, config);
    xmlUtil = new XmlUtil();
  }

  public ResponseContext deleteEntry(RequestContext request) {
    String entryId = getEntryId(request);
    try {
      deleteEntry(request, entryId);
      return sendSuccessfulDeleteResponse();
    } catch (FeedServerAdapterException e) {
      return sendErrorResponse(request, e);
    }
  }

  public ResponseContext getEntry(RequestContext request) {
    String entryId = getEntryId(request);

    try {
      Entry entry = retrieveEntry(request, entryId);
      if (null == entry) {
        return sendNotFoundResponse(request);
      } else {
        return sendResponse(request, entry.getDocument(), 200);
      }
    } catch (FeedServerAdapterException e) {
      return sendErrorResponse(request, e);
    }
  }

  public ResponseContext getFeed(RequestContext request) {
    try {
      Feed feed = retrieveFeed(request);
      return feed != null ? sendResponse(request, feed.getDocument(), 200)
          : sendNotFoundResponse(request);
    } catch (FeedServerAdapterException e) {
      return sendErrorResponse(request, e);
    }
  }

  public ResponseContext postEntry(RequestContext request) {
    Entry inputEntry;
    try {
      inputEntry = getInputEntry(request);
    } catch (IOException e) {
      return sendErrorResponse(request, e);
    }

    try {
      Entry newEntry = createEntry(request, inputEntry);
      return sendResponseWithEditLink(request, newEntry, 201);
    } catch (FeedServerAdapterException e) {
      return sendErrorResponse(request, e);
    }
  }

  public ResponseContext putEntry(RequestContext request) {
    Entry inputEntry;
    try {
      inputEntry = getInputEntry(request);
    } catch (IOException e) {
      return sendErrorResponse(request, e);
    }

    String entryId = getEntryId(request);
    try {
      Entry newEntry = updateEntry(request, entryId, inputEntry);
      return sendResponseWithEditLink(request, newEntry, 200);
    } catch (FeedServerAdapterException e) {
      return sendErrorResponse(request, e);
    }
  }

  protected ResponseContext sendErrorResponse(RequestContext request, IOException e) {
    return ProviderHelper.servererror(request, e.getMessage(), e);
  }

  protected ResponseContext sendErrorResponse(RequestContext request, FeedServerAdapterException e) {
    switch(e.getReason()) {
      case NOT_AUTHORIZED:
        return ProviderHelper.forbidden(request, e.getMessage());

      case ENTRY_DOES_NOT_EXIST:
        return ProviderHelper.notfound(request, e.getMessage());

      case ENTITY_DATA_INVALID:
      case INVALID_INPUT:
        return ProviderHelper.badrequest(request, e.getMessage());

      case ENTRY_ALREADY_EXISTS:
        return ProviderHelper.conflict(request, e.getMessage());

      default:
        return ProviderHelper.servererror(request, e.getMessage(), e);
    }
  }

  protected ResponseContext sendSuccessfulDeleteResponse() {
    return ProviderHelper.nocontent();
  }

  private ResponseContext sendNotFoundResponse(RequestContext request) {
    return ProviderHelper.notfound(request);
  }

  private ResponseContext sendResponseWithEditLink(RequestContext request, Entry newEntry,
      int responseCode) {
    if (newEntry != null) {
      Document<Entry> newEntryDoc = newEntry.getDocument();
      String loc = newEntry.getEditLinkResolvedHref().toString();
      return sendResponse(request, newEntryDoc, responseCode).setLocation(loc);
    } else {
      return sendNotFoundResponse(request);
    }
  }

  private ResponseContext sendResponse(RequestContext request, Base document, int responseCode) {
    if (null == document) {
      return sendNotFoundResponse(request);
    } else {
      return ProviderHelper.returnBase(document, responseCode, null);
    }
  }

  protected String getEntryId(RequestContext request) {
    Target target = request.getTarget();
    String entryId = target.getParameter(PARAM_ENTRY);
    return entryId;
  }

  protected String getProperty(String key) throws Exception {
    Object val = config.getProperty(key);
    if (val == null) {
      throw new RuntimeException("Configuration property not found");
    }
    if (val instanceof String) {
      return (String) val;
    }
    throw new RuntimeException("Configuration property is not string");
  }

  protected Feed createFeed() {
    String feedTitle = config.getFeedTitle();
    String feedAuthor = config.getFeedAuthor();
   
    Feed feed = abdera.newFeed();
    feed.setId(config.getFeedUri());
    feed.setTitle(feedTitle == null ? "feed" : feedTitle);
    feed.setUpdated(new Date());
    feed.addAuthor(feedAuthor == null ? getServerName() : feedAuthor);

    return feed;
  }

  protected void addEditLinkToEntry(Entry entry) {
    if (ProviderHelper.getEditUriFromEntry(entry) == null) {
      setEntryIdIfNull(entry);
      entry.addLink(entry.getId().toString(), "edit");
    }
  }

  protected void setEntryIdIfNull(Entry entry) {
    // if there is no id in Entry, assign one.
    if (entry.getId() != null) {
      return;
    }
    String uuidUri = abdera.getFactory().newUuidUri();
    String[] segments = uuidUri.split(":");
    String entryId = segments[segments.length - 1];
    entry.setId(createEntryIdUri(entryId));
  }

  protected String createEntryIdUri(String entryId) {
    return config.getFeedUri() + "/" + entryId;
  }

  protected Entry getInputEntry(RequestContext request) throws IOException {
    Abdera abdera = request.getAbdera();
    Parser parser = abdera.getParser();
    Entry inputEntry = (Entry) request.getDocument(parser).getRoot();
    return inputEntry;
  }

  @Override
  public ResponseContext extensionRequest(RequestContext request) {
    return ProviderHelper.notallowed(request, ProviderHelper.getDefaultMethods(request));
  }

  @Override
  public ResponseContext getCategories(RequestContext request) {
    return ProviderHelper.notfound(request);
  }

  public abstract Feed retrieveFeed(RequestContext request) throws FeedServerAdapterException;

  public abstract Entry retrieveEntry(RequestContext request, Object entryId)
      throws FeedServerAdapterException;

  public abstract Entry createEntry(RequestContext request, Entry entry)
      throws FeedServerAdapterException;

  public abstract Entry updateEntry(RequestContext request, Object entryId, Entry entry)
      throws FeedServerAdapterException;

  public abstract void deleteEntry(RequestContext request, Object entryId)
      throws FeedServerAdapterException;

  public abstract FeedInfo getFeedInfo(RequestContext request) throws FeedServerAdapterException;

  @Override
  public NamespacedFeedConfiguration getConfiguration() {
    return (NamespacedFeedConfiguration) super.getConfiguration();
  }

  public NamespacedAdapterConfiguration getAdapterConfiguration() {
    return getConfiguration().getAdapterConfiguration();
  }

  public PerNamespaceServerConfiguration getServerConfiguration() {
    return getConfiguration().getServerConfiguration();
  }

  public GlobalServerConfiguration getGolbalServerConfiguration() {
    return getServerConfiguration().getGolbalServerConfiguration();
  }

  protected Entry createEntryFromProperties(Feed feed, Map<String, Object> properties)
      throws FeedServerAdapterException {
    Map<String, Object> contentData = new HashMap<String, Object>();
    Entry entry = feed != null ? feed.addEntry() : abdera.newEntry();
    for (String key : properties.keySet()) {
      if (properties.get(key) == null) {
        continue;
      }
      Object value = properties.get(key);
      if (FeedConfiguration.ENTRY_ELEM_NAME_ID.equals(key)) {
        entry.setId(createEntryIdUri(value.toString()));
      } else if (FeedConfiguration.ENTRY_ELEM_NAME_TITLE.equals(key)) {
        entry.setTitle(value.toString());
      } else if (FeedConfiguration.ENTRY_ELEM_NAME_AUTHOR.equals(key)) {
        entry.addAuthor(value.toString());
      } else if (FeedConfiguration.ENTRY_ELEM_NAME_UPDATED.equals(key)
          && value instanceof java.util.Date) {
        entry.setUpdated((Date) value);
      } else if (FeedConfiguration.ENTRY_ELEM_NAME_LINK.equals(key)) {
        entry.addLink(value.toString());
      }
      contentData.put(key, value);
    }
    if (entry.getUpdated() == null) {
      entry.setUpdated(new Date());
    }
    if (entry.getAuthor() == null) {
      entry.addAuthor(config.getFeedAuthor());
    }
    if (entry.getTitle() == null) {
      entry.setTitle("");
    }
    try {
      entry.setContent(FeedServerUtil.getConfigurationAsXML(contentData), Content.Type.XML);
    } catch (TransformerException e) {
      throw new FeedServerAdapterException(
          FeedServerAdapterException.Reason.BAD_RESPONSE_FROM_REMOTE_SERVER, e.getMessage());
    } catch (ParserConfigurationException e) {
      throw new FeedServerAdapterException(
          FeedServerAdapterException.Reason.BAD_RESPONSE_FROM_REMOTE_SERVER, e.getMessage());
    }
    addEditLinkToEntry(entry);
    return entry;
  }

  public List<Map<String, Object>> getPropertyMapForFeed(Feed feed)
      throws FeedServerAdapterException {
    List<Entry> entries = feed.getEntries();
    List<Map<String, Object>> propertiesList = new ArrayList<Map<String, Object>>(entries.size());
    for (Entry entry : entries) {
      propertiesList.add(getPropertyMapForEntry(entry));
    }
    return propertiesList;
  }

  protected Map<String, Object> getPropertyMapForEntry(Entry entry)
      throws FeedServerAdapterException {
    try {
      Map<String, Object> columns;

      Content content = entry.getContentElement();
      if (content != null) {
        String contentStr = content.getValue();
        columns = parseContent(contentStr);
      } else {
        columns = new HashMap<String, Object>();
      }

      if (entry.getId() != null) {
        columns.put(FeedConfiguration.ENTRY_ELEM_NAME_ID, getEntryId(entry));
      }
      return columns;
    } catch (SAXException e) {
      throw new FeedServerAdapterException(FeedServerAdapterException.Reason.INVALID_INPUT, e
          .getMessage());
    } catch (IOException e) {
      throw new FeedServerAdapterException(FeedServerAdapterException.Reason.INVALID_INPUT, e
          .getMessage());
    } catch (ParserConfigurationException e) {
      throw new FeedServerAdapterException(FeedServerAdapterException.Reason.INVALID_INPUT, e
          .getMessage());
    }
  }

  /**
   * Parse the content data of an Entry into a property map.
   *
   * @param str the contentData
   * @return Property map.
   */
  protected Map<String, Object> parseContent(String str) throws SAXException, IOException,
      ParserConfigurationException {
    return xmlUtil.convertXmlToProperties(str);
  }

  /**
   * Get entry id for an entry.
   *
   * @param entry the entry.
   * @return id of the entry
   */
  public String getEntryId(Entry entry) {
    String uri = entry.getId().toString();
    String[] uriParts = uri.split("/");
    String id = uriParts[uriParts.length - 1];
    return id;
  }

  @SuppressWarnings("unchecked")
  public FeedInfo getFeedInfoFromConfig(RequestContext request) {
    return getFeedInfoFromMap((Map<String, Object>) getConfiguration().getTypeMetadataConfig());
  }

  public FeedInfo getFeedInfoFromMap(Map<String, Object> typeMetadataConfig) {
    return new SimpleFeedInfo(typeMetadataConfig);
  }

  public UserInfo getUserInfoForRequest(RequestContext request) {
    return (UserInfo) request.getAttribute(RequestContext.Scope.REQUEST, USER_INFO);
  }

  public String getUserEmailForRequest(RequestContext request) {
    UserInfo userInfo = getUserInfoForRequest(request);
    return userInfo == null ? null : userInfo.getEmail();
  }

  public FeedInfo getFeedInfoFromXml(String feedInfoXml) throws FeedServerAdapterException {
    try {
      return new SimpleFeedInfo(feedInfoXml);
    } catch (SAXException e) {
      throw new FeedServerAdapterException(FeedServerAdapterException.Reason.BAD_FEED_TYPE_CONFIG,
          e.getMessage());
    } catch (IOException e) {
      throw new FeedServerAdapterException(FeedServerAdapterException.Reason.BAD_FEED_TYPE_CONFIG,
          e.getMessage());
    } catch (ParserConfigurationException e) {
      throw new FeedServerAdapterException(FeedServerAdapterException.Reason.BAD_FEED_TYPE_CONFIG,
          e.getMessage());
    }
  }

  public String getNameSpace() {
    CollectionAdapterConfiguration config = getConfiguration().getAdapterConfiguration();
    if (config instanceof NamespacedAdapterConfiguration) {
      return ((NamespacedAdapterConfiguration) config).getServerConfiguration().getNameSpace();
    }
    return null;
  }

  protected String getHostName() {
    try {
      return InetAddress.getLocalHost().getHostName().toLowerCase();
    } catch (UnknownHostException e) {
      return "localhost";
    }
  }

  protected String getServerName() {
    return "feedserver@" + getHostName() + ":" + FeedServerConfiguration.getIntance().getPort();
  }
}
TOP

Related Classes of com.google.feedserver.adapters.AbstractManagedCollectionAdapter

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.