Package org.apache.tuscany.sca.binding.rss.provider

Source Code of org.apache.tuscany.sca.binding.rss.provider.RSSBindingListenerServlet

/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements.  See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership.  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.   
*/
package org.apache.tuscany.sca.binding.rss.provider;

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.net.URLDecoder;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.StringTokenizer;
import java.util.logging.Logger;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.xml.namespace.QName;

import org.apache.commons.codec.binary.Base64;
import org.apache.tuscany.sca.data.collection.Item;
import org.apache.tuscany.sca.databinding.Mediator;
import org.apache.tuscany.sca.interfacedef.DataType;
import org.apache.tuscany.sca.interfacedef.Operation;
import org.apache.tuscany.sca.interfacedef.impl.DataTypeImpl;
import org.apache.tuscany.sca.interfacedef.util.XMLType;
import org.apache.tuscany.sca.invocation.InvocationChain;
import org.apache.tuscany.sca.invocation.Invoker;
import org.apache.tuscany.sca.invocation.Message;
import org.apache.tuscany.sca.invocation.MessageFactory;
import org.apache.tuscany.sca.runtime.Invocable;

import com.sun.syndication.feed.synd.SyndContent;
import com.sun.syndication.feed.synd.SyndContentImpl;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndEntryImpl;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.feed.synd.SyndFeedImpl;
import com.sun.syndication.feed.synd.SyndLink;
import com.sun.syndication.feed.synd.SyndLinkImpl;
import com.sun.syndication.io.FeedException;
import com.sun.syndication.io.SyndFeedOutput;

/**
* An RSS binding listener, implemented as a Servlet and
* registered in a Servlet host provided by the SCA hosting runtime.
*
* @version $Rev: 927191 $ $Date: 2010-03-24 14:41:17 -0700 (Wed, 24 Mar 2010) $
*/
class RSSBindingListenerServlet extends HttpServlet {
    private static final Logger logger = Logger.getLogger(RSSBindingListenerServlet.class.getName());
    private static final long serialVersionUID = 1L;

    private Invocable wire;
    private Invoker getFeedInvoker;
    private Invoker getAllInvoker;
    private Invoker queryInvoker;
    private MessageFactory messageFactory;
    private Mediator mediator;
    private DataType<?> itemClassType;
    private DataType<?> itemXMLType;
    private boolean supportsFeedEntries;

    /**
     * Constructs a new binding listener.
     *
     * @param wire
     * @param messageFactory
     */
    RSSBindingListenerServlet(Invocable wire, MessageFactory messageFactory, Mediator mediator) {
        this.wire = wire;
        this.messageFactory = messageFactory;
        this.mediator = mediator;

        // Get the invokers for the supported operations
        Operation getOperation = null;
        for (InvocationChain invocationChain : this.wire.getInvocationChains()) {
            invocationChain.setAllowsPassByReference(true);
            Operation operation = invocationChain.getTargetOperation();
            String operationName = operation.getName();
            if (operationName.equals("getFeed")) {
                getFeedInvoker = invocationChain.getHeadInvoker();
            } else if (operationName.equals("getAll")) {
                getAllInvoker = invocationChain.getHeadInvoker();
            } else if (operationName.equals("query")) {
                queryInvoker = invocationChain.getHeadInvoker();
            } else if (operationName.equals("get")) {
                getOperation = operation;
            }
        }

        // Determine the collection item type
        if (getOperation != null) {
            itemXMLType = new DataTypeImpl<Class<?>>(String.class.getName(), String.class, String.class);
            Class<?> itemClass = getOperation.getOutputType().getPhysical();
            if (itemClass == SyndEntry.class) {
                supportsFeedEntries = true;
            }
            DataType<XMLType> outputType = getOperation.getOutputType();
            QName qname = outputType.getLogical().getElementName();
            qname = new QName(qname.getNamespaceURI(), itemClass.getSimpleName());
            itemClassType = new DataTypeImpl<XMLType>("java:complexType", itemClass, new XMLType(qname, null));
        }
    }

    @Override
    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {

        // No authentication required for a get request

        // Get the request path
        String path = URLDecoder.decode(request.getRequestURI().substring(request.getServletPath().length()), "UTF-8");

        logger.fine("get " + request.getRequestURI());

        // Handle an RSS request
        if (path == null || path.length() == 0 || path.equals("/")) {

            // Return an RSS feed containing the entries in the collection
            SyndFeed feed = null;
            if (supportsFeedEntries) {

                // The service implementation supports feed entries, invoke its getFeed operation
                Message requestMessage = messageFactory.createMessage();
                Message responseMessage = getFeedInvoker.invoke(requestMessage);
                if (responseMessage.isFault()) {
                    throw new ServletException((Throwable)responseMessage.getBody());
                }
                feed = (SyndFeed)responseMessage.getBody();
               
            } else {

                // The service implementation does not support feed entries, invoke its
                // getAll operation to get the data item collection. then create feed entries
                // from the data items
                Message requestMessage = messageFactory.createMessage();
                Message responseMessage;
                if (request.getQueryString() != null) {
                    requestMessage.setBody(new Object[] {request.getQueryString()});
                    responseMessage = queryInvoker.invoke(requestMessage);
                } else {
                    responseMessage = getAllInvoker.invoke(requestMessage);
                }
                if (responseMessage.isFault()) {
                    throw new ServletException((Throwable)responseMessage.getBody());
                }
                org.apache.tuscany.sca.data.collection.Entry<Object, Object>[] collection =
                    (org.apache.tuscany.sca.data.collection.Entry<Object, Object>[])responseMessage.getBody();
                if (collection != null) {
                    // Create the feed
                    feed = new SyndFeedImpl();
                    feed.setTitle("Feed");
                    feed.setDescription("Feed description");
                   
                    for (org.apache.tuscany.sca.data.collection.Entry<Object, Object> entry: collection) {
                        SyndEntry feedEntry = createFeedEntry(entry);
                        feed.getEntries().add(feedEntry);
                    }
                }
            }

            // Convert to an RSS feed
            if (feed != null) {
                response.setContentType("application/rss+xml; charset=utf-8");
                feed.setFeedType("rss_2.0");
                feed.setLink(path);
                SyndFeedOutput syndOutput = new SyndFeedOutput();
                try {
                    syndOutput.output(feed, getWriter(response));
                } catch (FeedException e) {
                    throw new ServletException(e);
                }
            } else {
                response.sendError(HttpServletResponse.SC_NOT_FOUND);
            }
        } else {
            response.sendError(HttpServletResponse.SC_NOT_FOUND);
        }

    }

    /**
     * Create an RSS entry from a data collection entry.
     * @param entry
     * @return
     */
    private SyndEntry createFeedEntry(org.apache.tuscany.sca.data.collection.Entry<Object, Object> entry) {
        Object key = entry.getKey();
        Object data = entry.getData();
        if (data instanceof Item) {
            Item item = (Item)data;
           
            SyndEntry feedEntry = new SyndEntryImpl();
            feedEntry.setUri(key.toString());
            feedEntry.setTitle(item.getTitle());
   
            String value = item.getContents();
            if (value != null) {
                SyndContent content = new SyndContentImpl();
                content.setType("text/xml");
                content.setValue(value);
                List<SyndContent> contents = new ArrayList<SyndContent>();
                contents.add(content);
                feedEntry.setContents(contents);
            }
   
            String href = item.getLink();
            if (href == null) {
                href = key.toString();
            }
            SyndLink link = new SyndLinkImpl();
            link.setRel("edit");
            link.setHref(href);
            feedEntry.getLinks().add(link);
            link = new SyndLinkImpl();
            link.setRel("alternate");
            link.setHref(href);
            feedEntry.getLinks().add(link);
            feedEntry.setLink(href);
   
            Date date = item.getDate();
            if (date == null) {
                date = new Date();
            }
            feedEntry.setPublishedDate(date);
            return feedEntry;
           
        } else if (data != null) {
            SyndEntry feedEntry = new SyndEntryImpl();
            feedEntry.setUri(key.toString());
            feedEntry.setTitle("item");
   
            // Convert the item to XML
            String value = mediator.mediate(data, itemClassType, itemXMLType, null).toString();
           
            SyndContent content = new SyndContentImpl();
            content.setType("text/xml");
            content.setValue(value);
            List<SyndContent> contents = new ArrayList<SyndContent>();
            contents.add(content);
            feedEntry.setContents(contents);
   
            SyndLink link = new SyndLinkImpl();
            link.setRel("edit");
            link.setHref(key.toString());
            feedEntry.getLinks().add(link);
            link = new SyndLinkImpl();
            link.setRel("alternate");
            link.setHref(key.toString());
            feedEntry.getLinks().add(link);
   
            feedEntry.setPublishedDate(new Date());
            return feedEntry;
        } else {
            return null;
        }
    }

    /**
     * Create a data collection entry from an RSS entry.
     * @param feedEntry
     * @return
     */
    private org.apache.tuscany.sca.data.collection.Entry<Object, Object> createEntry(SyndEntry feedEntry) {
        if (feedEntry != null) {
            if (itemClassType.getPhysical() == Item.class) {
                String key = feedEntry.getUri();
               
                Item item = new Item();
                item.setTitle(feedEntry.getTitle());
               
                List<?> contents = feedEntry.getContents();
                if (!contents.isEmpty()) {
                    SyndContent content = (SyndContent)contents.get(0);
                    String value = content.getValue();
                    item.setContents(value);
                }
               
                for (Object l : feedEntry.getLinks()) {
                    SyndLink link = (SyndLink)l;
                    if (link.getRel() == null || "edit".equals(link.getRel())) {
                        String href = link.getHref();
                        if (href.startsWith("null/")) {
                            href = href.substring(5);
                        }
                        item.setLink(href);
                        break;
                    }
                }
               
                item.setDate(feedEntry.getPublishedDate());
               
                return new org.apache.tuscany.sca.data.collection.Entry<Object, Object>(key, item);
               
            } else {
                String key = feedEntry.getUri();
               
                // Create the item from XML
                List<?> contents = feedEntry.getContents();
                if (contents.isEmpty()) {
                    return null;
                }
                SyndContent content = (SyndContent)contents.get(0);
                String value = content.getValue();
                Object data = mediator.mediate(value, itemXMLType, itemClassType, null);

                return new org.apache.tuscany.sca.data.collection.Entry<Object, Object>(key, data);
            }
        } else {
            return null;
        }
    }


    private Writer getWriter(HttpServletResponse response) throws UnsupportedEncodingException, IOException {
        Writer writer = new OutputStreamWriter(response.getOutputStream(), "UTF-8");
        return writer;
    }

    /**
     * Process the authorization header
     *
     * @param request
     * @return
     * @throws ServletException
     */
    private String processAuthorizationHeader(HttpServletRequest request) throws ServletException {
        try {
            String authorization = request.getHeader("Authorization");
            if (authorization != null) {
                StringTokenizer tokens = new StringTokenizer(authorization);
                if (tokens.hasMoreTokens()) {
                    String basic = tokens.nextToken();
                    if (basic.equalsIgnoreCase("Basic")) {
                        String credentials = tokens.nextToken();
                        String userAndPassword = new String(Base64.decodeBase64(credentials.getBytes()));
                        int colon = userAndPassword.indexOf(":");
                        if (colon != -1) {
                            String user = userAndPassword.substring(0, colon);
                            String password = userAndPassword.substring(colon + 1);

                            // Authenticate the User.
                            if (authenticate(user, password)) {
                                return user;
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            throw new ServletException(e);
        }
        return null;
    }

    /**
     * Authenticate a user.
     *
     * @param user
     * @param password
     * @return
     */
    private boolean authenticate(String user, String password) {

        // TODO Handle this using SCA security policies
        //FIXME Why are we using endsWith instead of equals here??
        return ("admin".endsWith(user) && "admin".equals(password));
    }

    /**
     * Reject an unauthorized request.
     *
     * @param response
     */
    private void unauthorized(HttpServletResponse response) throws IOException {
        response.setHeader("WWW-Authenticate", "BASIC realm=\"Tuscany\"");
        response.sendError(HttpServletResponse.SC_UNAUTHORIZED);
    }
}
TOP

Related Classes of org.apache.tuscany.sca.binding.rss.provider.RSSBindingListenerServlet

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.