com.sun.syndication.propono.atom.server.AtomServlet.java Source code

Java tutorial

Introduction

Here is the source code for com.sun.syndication.propono.atom.server.AtomServlet.java

Source

/*
 * Copyright 2007 Apache Software Foundation
 * 
 * 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 com.sun.syndication.propono.atom.server;

import com.sun.syndication.feed.atom.Content;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Writer;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.jdom.Document;
import org.jdom.output.Format;
import org.jdom.output.XMLOutputter;
import com.sun.syndication.feed.atom.Entry;
import com.sun.syndication.feed.atom.Feed;
import com.sun.syndication.feed.atom.Link;
import com.sun.syndication.io.WireFeedOutput;
import com.sun.syndication.io.impl.Atom10Generator;
import com.sun.syndication.io.impl.Atom10Parser;
import com.sun.syndication.propono.atom.common.AtomService;
import com.sun.syndication.propono.atom.common.Categories;
import com.sun.syndication.propono.utils.Utilities;
import java.io.BufferedReader;
import java.util.Collections;
import java.util.Iterator;
import javax.servlet.ServletConfig;

/**
 * Atom Servlet implements Atom protocol by calling an 
 * {@link com.sun.syndication.propono.atom.server.AtomHandler}
 * implementation. This servlet takes care of parsing incoming XML into ROME
 * Atom {@link com.sun.syndication.feed.atom.Entry} objects, passing those to the handler and serializing
 * to the response the entries and feeds returned by the handler.
 */
public class AtomServlet extends HttpServlet {

    /**
     * Get feed type support by Servlet, "atom_1.0"
     */
    public static final String FEED_TYPE = "atom_1.0";
    private static String contextDirPath = null;

    private static Log log = LogFactory.getFactory().getInstance(AtomServlet.class);

    static {
        Atom10Parser.setResolveURIs(true);
    }

    //-----------------------------------------------------------------------------
    /**
     * Create an Atom request handler.
     * TODO: make AtomRequestHandler implementation configurable.
     */
    private AtomHandler createAtomRequestHandler(HttpServletRequest request, HttpServletResponse response)
            throws ServletException {
        AtomHandlerFactory ahf = AtomHandlerFactory.newInstance();
        return ahf.newAtomHandler(request, response);
    }

    //-----------------------------------------------------------------------------
    /**
     * Handles an Atom GET by calling handler and writing results to response.
     */
    protected void doGet(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        log.debug("Entering");
        AtomHandler handler = createAtomRequestHandler(req, res);
        String userName = handler.getAuthenticatedUsername();
        if (userName != null) {
            AtomRequest areq = new AtomRequestImpl(req);
            try {
                if (handler.isAtomServiceURI(areq)) {
                    // return an Atom Service document
                    AtomService service = handler.getAtomService(areq);
                    Document doc = service.serviceToDocument();
                    res.setContentType("application/atomsvc+xml; charset=utf-8");
                    Writer writer = res.getWriter();
                    XMLOutputter outputter = new XMLOutputter();
                    outputter.setFormat(Format.getPrettyFormat());
                    outputter.output(doc, writer);
                    writer.close();
                    res.setStatus(HttpServletResponse.SC_OK);
                } else if (handler.isCategoriesURI(areq)) {
                    Categories cats = handler.getCategories(areq);
                    res.setContentType("application/xml");
                    Writer writer = res.getWriter();
                    Document catsDoc = new Document();
                    catsDoc.setRootElement(cats.categoriesToElement());
                    XMLOutputter outputter = new XMLOutputter();
                    outputter.output(catsDoc, writer);
                    writer.close();
                    res.setStatus(HttpServletResponse.SC_OK);
                } else if (handler.isCollectionURI(areq)) {
                    // return a collection
                    Feed col = handler.getCollection(areq);
                    col.setFeedType(FEED_TYPE);
                    WireFeedOutput wireFeedOutput = new WireFeedOutput();
                    Document feedDoc = wireFeedOutput.outputJDom(col);
                    res.setContentType("application/atom+xml; charset=utf-8");
                    Writer writer = res.getWriter();
                    XMLOutputter outputter = new XMLOutputter();
                    outputter.setFormat(Format.getPrettyFormat());
                    outputter.output(feedDoc, writer);
                    writer.close();
                    res.setStatus(HttpServletResponse.SC_OK);
                } else if (handler.isEntryURI(areq)) {
                    // return an entry
                    Entry entry = handler.getEntry(areq);
                    if (entry != null) {
                        res.setContentType("application/atom+xml; type=entry; charset=utf-8");
                        Writer writer = res.getWriter();
                        Atom10Generator.serializeEntry(entry, writer);
                        writer.close();
                    } else {
                        res.setStatus(HttpServletResponse.SC_NOT_FOUND);
                    }
                } else if (handler.isMediaEditURI(areq)) {
                    AtomMediaResource entry = handler.getMediaResource(areq);
                    res.setContentType(entry.getContentType());
                    res.setContentLength((int) entry.getContentLength());
                    Utilities.copyInputToOutput(entry.getInputStream(), res.getOutputStream());
                    res.getOutputStream().flush();
                    res.getOutputStream().close();
                } else {
                    res.setStatus(HttpServletResponse.SC_NOT_FOUND);
                }
            } catch (AtomException ae) {
                res.sendError(ae.getStatus(), ae.getMessage());
                log.debug("ERROR processing GET", ae);
            } catch (Exception e) {
                res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
                log.debug("ERROR processing GET", e);
            }
        } else {
            res.setHeader("WWW-Authenticate", "BASIC realm=\"AtomPub\"");
            res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        }
        log.debug("Exiting");
    }

    //-----------------------------------------------------------------------------
    /**
     * Handles an Atom POST by calling handler to identify URI, reading/parsing
     * data, calling handler and writing results to response.
     */
    protected void doPost(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        log.debug("Entering");
        AtomHandler handler = createAtomRequestHandler(req, res);
        String userName = handler.getAuthenticatedUsername();
        if (userName != null) {
            AtomRequest areq = new AtomRequestImpl(req);
            try {
                if (handler.isCollectionURI(areq)) {

                    if (req.getContentType().startsWith("application/atom+xml")) {

                        // parse incoming entry
                        Entry entry = Atom10Parser.parseEntry(
                                new BufferedReader(new InputStreamReader(req.getInputStream(), "UTF-8")), null);

                        // call handler to post it
                        Entry newEntry = handler.postEntry(areq, entry);

                        // set Location and Content-Location headers                        
                        for (Iterator it = newEntry.getOtherLinks().iterator(); it.hasNext();) {
                            Link link = (Link) it.next();
                            if ("edit".equals(link.getRel())) {
                                res.addHeader("Location", link.getHrefResolved());
                                break;
                            }
                        }
                        for (Iterator it = newEntry.getAlternateLinks().iterator(); it.hasNext();) {
                            Link link = (Link) it.next();
                            if ("alternate".equals(link.getRel())) {
                                res.addHeader("Content-Location", link.getHrefResolved());
                                break;
                            }
                        }

                        // write entry back out to response
                        res.setStatus(HttpServletResponse.SC_CREATED);
                        res.setContentType("application/atom+xml; type=entry; charset=utf-8");

                        Writer writer = res.getWriter();
                        Atom10Generator.serializeEntry(newEntry, writer);
                        writer.close();

                    } else if (req.getContentType() != null) {

                        // get incoming title and slug from HTTP header
                        String title = areq.getHeader("Title");

                        // create new entry for resource, set title and type
                        Entry resource = new Entry();
                        resource.setTitle(title);
                        Content content = new Content();
                        content.setType(areq.getContentType());
                        resource.setContents(Collections.singletonList(content));

                        // hand input stream off to hander to post file
                        Entry newEntry = handler.postMedia(areq, resource);

                        // set Location and Content-Location headers
                        for (Iterator it = newEntry.getOtherLinks().iterator(); it.hasNext();) {
                            Link link = (Link) it.next();
                            if ("edit".equals(link.getRel())) {
                                res.addHeader("Location", link.getHrefResolved());
                                break;
                            }
                        }
                        for (Iterator it = newEntry.getAlternateLinks().iterator(); it.hasNext();) {
                            Link link = (Link) it.next();
                            if ("alternate".equals(link.getRel())) {
                                res.addHeader("Content-Location", link.getHrefResolved());
                                break;
                            }
                        }

                        res.setStatus(HttpServletResponse.SC_CREATED);
                        res.setContentType("application/atom+xml; type=entry; charset=utf-8");

                        Writer writer = res.getWriter();
                        Atom10Generator.serializeEntry(newEntry, writer);
                        writer.close();

                    } else {
                        res.sendError(HttpServletResponse.SC_UNSUPPORTED_MEDIA_TYPE,
                                "No content-type specified in request");
                    }

                } else {
                    res.sendError(HttpServletResponse.SC_NOT_FOUND, "Invalid collection specified in request");
                }
            } catch (AtomException ae) {
                res.sendError(ae.getStatus(), ae.getMessage());
                log.debug("ERROR processing POST", ae);
            } catch (Exception e) {
                res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
                log.debug("ERROR processing POST", e);
            }
        } else {
            res.setHeader("WWW-Authenticate", "BASIC realm=\"AtomPub\"");
            res.sendError(HttpServletResponse.SC_UNAUTHORIZED);
        }
        log.debug("Exiting");
    }

    //-----------------------------------------------------------------------------
    /**
     * Handles an Atom PUT by calling handler to identify URI, reading/parsing
     * data, calling handler and writing results to response.
     */
    protected void doPut(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        log.debug("Entering");
        AtomHandler handler = createAtomRequestHandler(req, res);
        String userName = handler.getAuthenticatedUsername();
        if (userName != null) {
            AtomRequest areq = new AtomRequestImpl(req);
            try {
                if (handler.isEntryURI(areq)) {

                    // parse incoming entry
                    Entry unsavedEntry = Atom10Parser.parseEntry(
                            new BufferedReader(new InputStreamReader(req.getInputStream(), "UTF-8")), null);

                    // call handler to put entry
                    handler.putEntry(areq, unsavedEntry);

                    res.setStatus(HttpServletResponse.SC_OK);

                } else if (handler.isMediaEditURI(areq)) {

                    // hand input stream to handler
                    handler.putMedia(areq);

                    res.setStatus(HttpServletResponse.SC_OK);

                } else {
                    res.setStatus(HttpServletResponse.SC_NOT_FOUND);
                }
            } catch (AtomException ae) {
                res.sendError(ae.getStatus(), ae.getMessage());
                log.debug("ERROR processing PUT", ae);
            } catch (Exception e) {
                res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
                log.debug("ERROR processing PUT", e);
            }
        } else {
            res.setHeader("WWW-Authenticate", "BASIC realm=\"AtomPub\"");
            // Wanted to use sendError() here but Tomcat sends 403 forbidden 
            // when I do that, so sticking with setStatus() for time being.
            res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        }
        log.debug("Exiting");
    }

    //-----------------------------------------------------------------------------
    /**
     * Handle Atom DELETE by calling appropriate handler.
     */
    protected void doDelete(HttpServletRequest req, HttpServletResponse res) throws ServletException, IOException {
        log.debug("Entering");
        AtomHandler handler = createAtomRequestHandler(req, res);
        String userName = handler.getAuthenticatedUsername();
        if (userName != null) {
            AtomRequest areq = new AtomRequestImpl(req);
            try {
                if (handler.isEntryURI(areq)) {
                    handler.deleteEntry(areq);
                    res.setStatus(HttpServletResponse.SC_OK);
                } else {
                    res.setStatus(HttpServletResponse.SC_NOT_FOUND);
                }
            } catch (AtomException ae) {
                res.sendError(ae.getStatus(), ae.getMessage());
                log.debug("ERROR processing DELETE", ae);
            } catch (Exception e) {
                res.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR, e.getMessage());
                log.debug("ERROR processing DELETE", e);
            }
        } else {
            res.setHeader("WWW-Authenticate", "BASIC realm=\"AtomPub\"");
            // Wanted to use sendError() here but Tomcat sends 403 forbidden 
            // when I do that, so sticking with setStatus() for time being.
            res.setStatus(HttpServletResponse.SC_UNAUTHORIZED);
        }
        log.debug("Exiting");
    }

    /**
     * Initialize servlet.
     */
    public void init(ServletConfig config) throws ServletException {
        super.init(config);
        contextDirPath = getServletContext().getRealPath("/");

    }

    /**
     * Get absolute path to Servlet context directory.
     */
    public static String getContextDirPath() {
        return contextDirPath;
    }
}