photosharing.api.conx.CommentsDefinition.java Source code

Java tutorial

Introduction

Here is the source code for photosharing.api.conx.CommentsDefinition.java

Source

/**
 *  Copyright IBM Corp. 2016
 *
 * 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 photosharing.api.conx;

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.logging.Logger;

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

import org.apache.commons.io.IOUtils;
import org.apache.http.HttpResponse;
import org.apache.http.HttpStatus;
import org.apache.http.client.fluent.Executor;
import org.apache.http.client.fluent.Request;
import org.apache.http.client.fluent.Response;
import org.apache.http.entity.ByteArrayEntity;
import org.apache.wink.json4j.JSONArray;
import org.apache.wink.json4j.JSONException;
import org.apache.wink.json4j.JSONObject;
import org.xml.sax.SAXException;

import photosharing.api.Configuration;
import photosharing.api.ExecutorUtil;
import photosharing.api.base.APIDefinition;
import photosharing.api.oauth.OAuth20Data;
import photosharing.api.oauth.OAuth20Handler;

/**
 * The class calls the API for a File Comments in IBM Connections <a
 * href="http://ibm.co/1S6f2AW">File Comments API</a>
 * 
 * @author Paul Bastide <pbastide@us.ibm.com>
 * 
 */
public class CommentsDefinition implements APIDefinition {

    // Logger
    private static String className = CommentsDefinition.class.getName();
    private Logger logger = Logger.getLogger(className);

    /**
     * generate the base api url for files
     * 
     * you can use the path component {basic} / {oauth}
     * 
     * @return {String} url representing the api
     */
    private String getApiUrl() {
        Configuration config = Configuration.getInstance(null);
        StringBuilder builder = new StringBuilder();
        builder.append(config.getValue(Configuration.BASEURL));
        builder.append("/files/basic/api");
        return builder.toString();
    }

    /**
     * creates the formatted comment
     * 
     * @param content
     *            the string representing the comment
     * @return {String} xml representing a comment
     */
    private String generateComment(String content) {
        StringBuilder builder = new StringBuilder();
        builder.append(
                "<?xml version=\"1.0\" encoding=\"UTF-8\"?><entry xmlns=\"http://www.w3.org/2005/Atom\" xmlns:app=\"http://www.w3.org/2007/app\" xmlns:snx=\"http://www.ibm.com/xmlns/prod/sn\"><category scheme=\"tag:ibm.com,2006:td/type\" term=\"comment\" label=\"comment\"/><content type=\"text\">");
        builder.append(content);
        builder.append("</content></entry>");
        return builder.toString();
    }

    /**
     * gets the nonce url so one can <a href="http://ibm.co/1fG83gY">Get a
     * Cryptographic Key</a>
     * 
     * you can use the path component {basic} / {oauth}
     * 
     * @return {String} URL to get Nonce
     */
    private String getNonceUrl() {
        Configuration config = Configuration.getInstance(null);
        StringBuilder builder = new StringBuilder();
        builder.append(config.getValue(Configuration.BASEURL));
        builder.append("/files/basic/api/nonce");
        return builder.toString();
    }

    /**
     * get nonce as described with nonce <a href="http://ibm.co/1fG83gY">Get a
     * Cryptographic Key</a>
     * 
     * @param bearer
     *            the access token
     * @return {String} the nonce
     */
    private String getNonce(String bearer, HttpServletResponse response) {
        String nonce = "";

        // Build the Request
        Request get = Request.Get(getNonceUrl());
        get.addHeader("Authorization", "Bearer " + bearer);

        try {
            Executor exec = ExecutorUtil.getExecutor();
            Response apiResponse = exec.execute(get);
            HttpResponse hr = apiResponse.returnResponse();

            /**
             * Check the status codes and if 200, convert to String
             */
            int code = hr.getStatusLine().getStatusCode();

            // Checks the Status Code
            if (code == HttpStatus.SC_FORBIDDEN) {
                // Session is no longer valid or access token is expired
                response.setStatus(HttpStatus.SC_FORBIDDEN);
            } else if (code == HttpStatus.SC_UNAUTHORIZED) {
                // User is not authorized
                response.setStatus(HttpStatus.SC_UNAUTHORIZED);
            } else if (code == HttpStatus.SC_OK) {
                // Default to 200
                InputStream in = hr.getEntity().getContent();
                nonce = IOUtils.toString(in);
            } else {
                // SC_BAD_GATEWAY (503)
                response.setStatus(HttpStatus.SC_BAD_GATEWAY);
            }

        } catch (IOException e) {
            response.setHeader("X-Application-Error", e.getClass().getName());
            response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            logger.severe("Issue with get nonce " + e.toString());
        }

        return nonce;
    }

    /**
     * deletes a comment with the given comments api url uses the HTTP method
     * delete
     * 
     * Method: DELETE URL:
     * http://localhost:9080/photoSharing/api/comments?uid=20514318
     * &pid=bf33a9b5-
     * 3042-46f0-a96e-b8742fced7a4&cid=4ec9c9c2-6e21-4815-bd42-91d502d2d427
     * 
     * @param bearer
     *            token
     * @param cid
     *            comment id
     * @param pid
     *            document id
     * @param uid
     *            user id
     * @param response
     * @param nonce
     */
    public void deleteComment(String bearer, String cid, String pid, String uid, HttpServletResponse response,
            String nonce) {
        String apiUrl = getApiUrl() + "/userlibrary/" + uid + "/document/" + pid + "/comment/" + cid + "/entry";

        Request delete = Request.Delete(apiUrl);
        delete.addHeader("Authorization", "Bearer " + bearer);
        delete.addHeader("X-Update-Nonce", nonce);

        try {
            Executor exec = ExecutorUtil.getExecutor();
            Response apiResponse = exec.execute(delete);

            HttpResponse hr = apiResponse.returnResponse();

            /**
             * Check the status codes
             */
            int code = hr.getStatusLine().getStatusCode();

            // Checks the Status Code
            if (code == HttpStatus.SC_FORBIDDEN) {
                // Session is no longer valid or access token is expired
                response.setStatus(HttpStatus.SC_FORBIDDEN);
            } else if (code == HttpStatus.SC_UNAUTHORIZED) {
                // User is not authorized
                response.setStatus(HttpStatus.SC_UNAUTHORIZED);
            } else {
                // Default to SC_NO_CONTENT(204)
                response.setStatus(HttpStatus.SC_NO_CONTENT);
            }

        } catch (IOException e) {
            response.setHeader("X-Application-Error", e.getClass().getName());
            response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            logger.severe("Issue with delete comment" + e.toString());
        }

    }

    /**
     * updates a given comment
     * 
     * @param bearer
     *            the accessToken
     * @param cid
     *            the comment id
     * @param pid
     *            the file id
     * @param uid
     *            the library id
     * @param body
     *            the text body
     * @param nonce
     *            the nonce value
     * @param response
     *            the response that is going to get the response
     */
    public void updateComment(String bearer, String cid, String pid, String uid, String body, String nonce,
            HttpServletResponse response) {
        String apiUrl = getApiUrl() + "/userlibrary/" + uid + "/document/" + pid + "/comment/" + cid + "/entry";
        try {
            JSONObject obj = new JSONObject(body);

            String comment = generateComment(obj.getString("comment"));

            // Generate the
            Request put = Request.Put(apiUrl);
            put.addHeader("Authorization", "Bearer " + bearer);
            put.addHeader("X-Update-Nonce", nonce);
            put.addHeader("Content-Type", "application/atom+xml");

            ByteArrayEntity entity = new ByteArrayEntity(comment.getBytes("UTF-8"));
            put.body(entity);

            Executor exec = ExecutorUtil.getExecutor();
            Response apiResponse = exec.execute(put);
            HttpResponse hr = apiResponse.returnResponse();

            /**
             * Check the status codes
             */
            int code = hr.getStatusLine().getStatusCode();

            // Checks the status code for the response
            if (code == HttpStatus.SC_FORBIDDEN) {
                // Session is no longer valid or access token is expired
                response.setStatus(HttpStatus.SC_FORBIDDEN);
            } else if (code == HttpStatus.SC_UNAUTHORIZED) {
                // User is not authorized
                response.setStatus(HttpStatus.SC_UNAUTHORIZED);
            } else {
                // Default to 200
                response.setStatus(HttpStatus.SC_OK);
            }

        } catch (IOException e) {
            response.setHeader("X-Application-Error", e.getClass().getName());
            response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            logger.severe("Issue with update comment" + e.toString());
        } catch (JSONException e) {
            response.setHeader("X-Application-Error", e.getClass().getName());
            response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            logger.severe("Issue with update comments " + e.toString());
            e.printStackTrace();
        }

    }

    /**
     * creates a new comment with a given library id and document id
     * 
     * @param bearer
     *            the accesstoken used to make the request
     * @param pid
     *            the document id
     * @param uid
     *            the library id
     * @param body
     *            the body of the comment
     * @param nonce
     *            the nonce code
     * @param response
     *            the http response that the results are sent to
     */
    public void createComment(String bearer, String pid, String uid, String body, String nonce,
            HttpServletResponse response) {
        String apiUrl = getApiUrl() + "/library/" + uid + "/document/" + pid + "/feed";

        logger.info(apiUrl);

        try {
            JSONObject obj = new JSONObject(body);

            String comment = generateComment(obj.getString("comment"));

            // Generate the
            Request post = Request.Post(apiUrl);
            post.addHeader("Authorization", "Bearer " + bearer);
            post.addHeader("X-Update-Nonce", nonce);
            post.addHeader("Content-Type", "application/atom+xml");

            ByteArrayEntity entity = new ByteArrayEntity(comment.getBytes("UTF-8"));
            post.body(entity);

            Executor exec = ExecutorUtil.getExecutor();
            Response apiResponse = exec.execute(post);
            HttpResponse hr = apiResponse.returnResponse();

            /**
             * Check the status codes
             */
            int code = hr.getStatusLine().getStatusCode();

            // Process the Status Codes
            if (code == HttpStatus.SC_FORBIDDEN) {
                // Session is no longer valid or access token is expired
                response.setStatus(HttpStatus.SC_FORBIDDEN);
            } else if (code == HttpStatus.SC_UNAUTHORIZED) {
                // User is not authorized
                response.setStatus(HttpStatus.SC_UNAUTHORIZED);
            } else if (code == HttpStatus.SC_CREATED) {
                // Default to 201
                response.setStatus(HttpStatus.SC_OK);

                InputStream in = hr.getEntity().getContent();

                String jsonString = org.apache.wink.json4j.utils.XML.toJson(in);

                JSONObject base = new JSONObject(jsonString);
                JSONObject entry = base.getJSONObject("entry");
                JSONObject author = entry.getJSONObject("author");

                String name = author.getString("name");
                String userid = author.getString("userid");
                String date = entry.getString("modified");
                String content = entry.getString("content");
                String cid = entry.getString("uuid");

                // Build the JSON object
                JSONObject commentJSON = new JSONObject();
                commentJSON.put("uid", userid);
                commentJSON.put("author", name);
                commentJSON.put("date", date);
                commentJSON.put("content", content);
                commentJSON.put("cid", cid);

                // Flush the Object to the Stream with content type
                response.setHeader("Content-Type", "application/json");

                PrintWriter out = response.getWriter();
                out.write(commentJSON.toString());
                out.flush();
                out.close();

            }

        } catch (IOException e) {
            response.setHeader("X-Application-Error", e.getClass().getName());
            response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            logger.severe("Issue with create comment " + e.toString());
        } catch (JSONException e) {
            response.setHeader("X-Application-Error ", e.getClass().getName());
            response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            logger.severe("Issue with create comment " + e.toString());
            e.printStackTrace();
        } catch (SAXException e) {
            response.setHeader("X-Application-Error", e.getClass().getName());
            response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            logger.severe("Issue with create comment " + e.toString());
        }
    }

    /**
     * reads the comments from the comments feed
     * 
     * Example URL
     * http://localhost:9080/photoSharing/api/comments?uid=20514318&pid
     * =bf33a9b5-3042-46f0-a96e-b8742fced7a4
     * 
     * @param bearer
     * @param pid
     * @param uid
     * @param response
     */
    public void readComments(String bearer, String pid, String uid, HttpServletResponse response) {
        String apiUrl = getApiUrl() + "/library/" + uid + "/document/" + pid
                + "/feed?category=comment&sortBy=created&sortOrder=desc";

        logger.info("Executing Request to: " + apiUrl + " " + bearer);

        Request get = Request.Get(apiUrl);
        get.addHeader("Authorization", "Bearer " + bearer);

        try {

            Executor exec = ExecutorUtil.getExecutor();
            Response apiResponse = exec.execute(get);

            HttpResponse hr = apiResponse.returnResponse();

            /**
             * Check the status codes
             */
            int code = hr.getStatusLine().getStatusCode();

            // Session is no longer valid or access token is expired
            if (code == HttpStatus.SC_FORBIDDEN) {
                response.sendRedirect("./api/logout");
            }

            // User is not authorized
            else if (code == HttpStatus.SC_UNAUTHORIZED) {
                response.setStatus(HttpStatus.SC_UNAUTHORIZED);
            }

            // Default to SC_OK (200)
            else if (code == HttpStatus.SC_OK) {
                response.setStatus(HttpStatus.SC_OK);

                InputStream in = hr.getEntity().getContent();
                String jsonString = org.apache.wink.json4j.utils.XML.toJson(in);

                // Logging out the JSON Object
                logger.info(jsonString);

                JSONObject feed = new JSONObject(jsonString).getJSONObject("feed");

                JSONArray comments = new JSONArray();

                JSONArray entries = null;
                try {

                    entries = feed.getJSONArray("entry");

                } catch (JSONException e) {
                    entries = new JSONArray();
                    if (feed.has("entry")) {
                        JSONObject entry = feed.getJSONObject("entry");
                        entries.put(entry);
                    }
                }
                int len = entries.length();
                for (int i = 0; i < len; i++) {
                    JSONObject entry = entries.getJSONObject(i);
                    JSONObject author = entry.getJSONObject("author");

                    String name = author.getString("name");
                    String userid = author.getString("userid");

                    String date = entry.getString("modified");
                    String content = entry.getJSONObject("content").getString("content");
                    String cid = entry.getString("uuid");

                    // Build the JSON object
                    JSONObject commentJSON = new JSONObject();
                    commentJSON.put("uid", userid);
                    commentJSON.put("author", name);
                    commentJSON.put("date", date);
                    commentJSON.put("content", content);
                    commentJSON.put("cid", cid);

                    comments.add(commentJSON);

                }

                // Flush the Object to the Stream with content type
                response.setHeader("Content-Type", "application/json");
                PrintWriter out = response.getWriter();
                out.println(comments.toString());
                out.flush();

            }

        } catch (IOException e) {
            response.setHeader("X-Application-Error", e.getClass().getName());
            response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            logger.severe("Issue with read comments " + e.toString());
        } catch (JSONException e) {
            response.setHeader("X-Application-Error", e.getClass().getName());
            response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            logger.severe("Issue with read comments " + e.toString());
            e.printStackTrace();
        } catch (SAXException e) {
            response.setHeader("X-Application-Error", e.getClass().getName());
            response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            logger.severe("Issue with read comments " + e.toString());
        }
    }

    /**
     * manages interactions with comments based on method
     * 
     * @see photosharing.api.base.APIDefinition#run(javax.servlet.http.HttpServletRequest,
     *      javax.servlet.http.HttpServletResponse)
     */
    @Override
    public void run(HttpServletRequest request, HttpServletResponse response) {
        // HTTP Method that the request was made with:
        String method = request.getMethod();

        /**
         * get the users bearer token
         */
        HttpSession session = request.getSession(false);
        Object o = session.getAttribute(OAuth20Handler.CREDENTIALS);
        if (o == null) {
            logger.warning("Credential Object is not present");
        } else {
            OAuth20Data data = (OAuth20Data) o;
            String bearer = data.getAccessToken();

            // Create a Comment
            if (method.compareTo("POST") == 0) {
                // Extract the URL parameters from the request
                String pid = request.getParameter("pid");
                String uid = request.getParameter("uid");

                try {
                    String body = IOUtils.toString(request.getInputStream());

                    // Checks the State of the URL parameters
                    if (pid == null || uid == null || body == null || body.isEmpty() || pid.isEmpty()
                            || uid.isEmpty()) {
                        response.setStatus(HttpStatus.SC_PRECONDITION_FAILED);
                    } else {
                        String nonce = getNonce(bearer, response);
                        if (!nonce.isEmpty()) {
                            createComment(bearer, pid, uid, body, nonce, response);
                        }
                    }

                } catch (IOException e) {
                    response.setHeader("X-Application-Error", e.getClass().getName());
                    response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
                    logger.severe("Issue with POST comment" + e.toString());
                }
            }
            // Update a Comment
            else if (method.compareTo("PUT") == 0) {
                // Extract the URL parameters from the request
                String cid = request.getParameter("cid");
                String pid = request.getParameter("pid");
                String uid = request.getParameter("uid");

                try {
                    String body = IOUtils.toString(request.getInputStream());

                    // Checks the State of the URL parameters
                    if (cid == null || pid == null || uid == null || body == null || body.isEmpty() || cid.isEmpty()
                            || pid.isEmpty() || uid.isEmpty()) {
                        response.setStatus(HttpStatus.SC_PRECONDITION_FAILED);
                    } else {
                        String nonce = getNonce(bearer, response);
                        if (!nonce.isEmpty()) {
                            updateComment(bearer, cid, pid, uid, body, nonce, response);
                        }
                    }

                } catch (IOException e) {
                    response.setHeader("X-Application-Error", e.getClass().getName());
                    response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
                    logger.severe("Issue with PUT comment" + e.toString());
                }

            }
            // Delete a Comment
            else if (method.compareTo("DELETE") == 0) {
                // Extract the URL parameters from the request
                String cid = request.getParameter("cid");
                String pid = request.getParameter("pid");
                String uid = request.getParameter("uid");

                // Checks the State of the URL parameters
                if (cid == null || pid == null || uid == null || cid.isEmpty() || pid.isEmpty() || uid.isEmpty()) {
                    response.setStatus(HttpStatus.SC_PRECONDITION_FAILED);
                } else {
                    String nonce = getNonce(bearer, response);

                    if (!nonce.isEmpty()) {
                        deleteComment(bearer, cid, pid, uid, response, nonce);
                    }
                }

            }
            // Read a Comment and default to a GET
            else {
                // Extract the URL parameters from the request
                String pid = request.getParameter("pid");
                String uid = request.getParameter("uid");

                if (pid == null || uid == null || pid.isEmpty() || uid.isEmpty()) {
                    response.setStatus(HttpStatus.SC_PRECONDITION_FAILED);
                } else {
                    readComments(bearer, pid, uid, response);
                }

            }

        }

    }

}