info.jtrac.web.RestMultiActionController.java Source code

Java tutorial

Introduction

Here is the source code for info.jtrac.web.RestMultiActionController.java

Source

/*
 * Copyright 2002-2005 the original author or authors.
 *
 * 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 info.jtrac.web;

import info.jtrac.domain.InvalidRefIdException;
import info.jtrac.domain.Item;
import info.jtrac.domain.ItemSearch;
import info.jtrac.domain.Space;
import info.jtrac.domain.User;
import info.jtrac.util.XmlUtils;
import info.jtrac.wicket.ItemListPage;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.util.List;
import java.util.StringTokenizer;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.codec.binary.Base64;
import org.apache.wicket.PageParameters;
import org.apache.wicket.protocol.http.RequestUtils;
import org.apache.wicket.util.value.ValueMap;
import org.dom4j.Document;
import org.dom4j.Element;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.mvc.multiaction.MethodNameResolver;
import org.springframework.web.servlet.mvc.multiaction.NoSuchRequestHandlingMethodException;

/**
 * Spring MultiActionController that handles REST requests
 * returns XML messages
 */
public class RestMultiActionController extends AbstractMultiActionController {

    /**
     * custom MethodNameResolver is configured that checks the value of an expected
     * paramter called "method" in the request and formats the value that may be
     * in the form of  "namespace.subnamespace.action" into "namespaceSubnamespaceAction"
     * or more like a java method name
     */
    public RestMultiActionController() {
        setMethodNameResolver(new MethodNameResolver() {
            @Override
            public String getHandlerMethodName(HttpServletRequest request)
                    throws NoSuchRequestHandlingMethodException {
                String temp = request.getParameter("method");
                if (temp == null) {
                    return null;
                }
                StringBuffer sb = new StringBuffer();
                for (int i = 0; i < temp.length(); i++) {
                    char c = temp.charAt(i);
                    if (c == '.') {
                        i++;
                        c = temp.charAt(i);
                        sb.append(Character.toUpperCase(c));
                    } else {
                        sb.append(c);
                    }
                }
                return sb.toString();
            }
        });
    }

    /**
     * override Spring template method as a crude interceptor
     * here we are doing HTTP basic authentication TODO better security
     */
    @Override
    protected ModelAndView handleRequestInternal(HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        if (!authenticate(request)) {
            String title = "Basic realm=\"JTrac Remote API\"";
            response.setHeader("WWW-Authenticate", title);
            response.setStatus(401);
            return null;
        } else {
            return super.handleRequestInternal(request, response);
        }
    }

    private boolean authenticate(HttpServletRequest request) {
        String authHeader = request.getHeader("Authorization");
        logger.debug("auth header: " + authHeader);
        if (authHeader == null) {
            return false;
        }
        StringTokenizer st = new StringTokenizer(authHeader);
        if (st.hasMoreTokens()) {
            String basic = st.nextToken();
            if (basic.equalsIgnoreCase("Basic")) {
                String credentials = st.nextToken();
                Base64 decoder = new Base64();
                String userPass = new String(decoder.decode(credentials.getBytes()));
                int p = userPass.indexOf(":");
                if (p == -1) {
                    return false;
                }
                String loginName = userPass.substring(0, p);
                String password = userPass.substring(p + 1);
                User user = jtrac.loadUser(loginName);
                if (user == null) {
                    return false;
                }
                String encoded = jtrac.encodeClearText(password);
                if (user.getPassword().equals(encoded)) {
                    request.setAttribute("user", user);
                    return true;
                }
            }
        }
        return false;
    }

    private void writeXml(Document document, HttpServletResponse response) throws Exception {
        writeXml(document.getRootElement(), response);
    }

    private void writeXml(Element element, HttpServletResponse response) throws Exception {
        initXmlResponse(response);
        element.write(response.getWriter());
    }

    private void initXmlResponse(HttpServletResponse response) {
        applyCacheSeconds(response, 0, true);
        response.setContentType("text/xml");
    }

    private String getContent(HttpServletRequest request) throws Exception {
        InputStream is = request.getInputStream();
        int ch;
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        while ((ch = is.read()) != -1) {
            baos.write((byte) ch);
        }
        return new String(baos.toByteArray());
    }

    //============================ REQUEST HANDLERS ============================

    public void versionGet(HttpServletRequest request, HttpServletResponse response) throws Exception {
        Document d = XmlUtils.getNewDocument("version");
        Element root = d.getRootElement();
        root.addAttribute("number", jtrac.getReleaseVersion());
        root.addAttribute("timestamp", jtrac.getReleaseTimestamp());
        writeXml(d, response);
    }

    public void itemGet(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String refId = request.getParameter("refId");
        Item item = null;
        try {
            item = jtrac.loadItemByRefId(refId);
        } catch (InvalidRefIdException e) {
            // TODO
        }
        // TODO if item == null
        if (item == null) {
            return;
        }
        Element e = item.getAsXml();
        writeXml(e, response);
    }

    public void itemPut(HttpServletRequest request, HttpServletResponse response) throws Exception {
        logger.debug(getContent(request));
        Document d = XmlUtils.getNewDocument("success");
        Element root = d.getRootElement();
        root.addElement("refId").addText("FOOBAR-123");
        writeXml(d, response);
    }

    public void spaceUsersGet(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String prefixCode = request.getParameter("prefixCode");
        Space space = jtrac.loadSpace(prefixCode);
        Document d = XmlUtils.getNewDocument("users");
        Element root = d.getRootElement();
        root.addAttribute("prefixCode", prefixCode);
        List<User> users = jtrac.findUsersForSpace(space.getId());
        for (User user : users) {
            root.addElement("user").addAttribute("loginName", user.getLoginName()).addText(user.getName());
        }
        writeXml(d, response);
    }

    public void itemSearchGet(HttpServletRequest request, HttpServletResponse response) throws Exception {
        String queryString = request.getQueryString();
        logger.debug("parsing queryString: " + queryString);
        ValueMap map = new ValueMap();
        RequestUtils.decodeParameters(queryString, map);
        logger.debug("decoded: " + map);
        User user = (User) request.getAttribute("user");
        PageParameters params = new PageParameters(map);
        ItemSearch itemSearch = ItemListPage.getItemSearch(jtrac, user, params);
        initXmlResponse(response);
        jtrac.writeAsXml(itemSearch, response.getWriter());
    }

    public void itemAllGet(HttpServletRequest request, HttpServletResponse response) throws Exception {
        // GOD mode!
        User user = (User) request.getAttribute("user");
        if (!user.isSuperUser()) {
            // TODO error code
            return;
        }
        initXmlResponse(response);
        jtrac.writeAsXml(response.getWriter());
    }

}