photosharing.api.conx.ProfileDefinition.java Source code

Java tutorial

Introduction

Here is the source code for photosharing.api.conx.ProfileDefinition.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.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;

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.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 Profile in IBM Connections <a
 * href="http://ibm.co/1K1rZZX">Profile API</a>
 * 
 * @author Paul Bastide <pbastide@us.ibm.com>
 * 
 */
public class ProfileDefinition implements APIDefinition {

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

    /**
     * generate the api url with a given userid the format is atom and supports
     * json (change atom to json)
     * 
     * @param userid
     * @return url of the api
     */
    private String getApiUrl(String userid) {
        Configuration config = Configuration.getInstance(null);
        String apiUrl = config.getValue(Configuration.BASEURL) + "/profiles/atom/profile.do?userid=" + userid;
        return apiUrl;
    }

    /**
     * generates the api url to retrieve the logged in user id the format is
     * atom/xml
     * 
     * @return url of the service api
     */
    private String getApiUrlForServiceDoc() {
        Configuration config = Configuration.getInstance(null);
        String apiUrl = config.getValue(Configuration.BASEURL) + "/profiles/atom/profileService.do";
        return apiUrl;
    }

    /**
     * retrieves a profile based on the person's userid
     * 
     * @see photosharing.api.base.APIDefinition#run(javax.servlet.http.HttpServletRequest,
     *      javax.servlet.http.HttpServletResponse)
     */
    @Override
    public void run(HttpServletRequest request, HttpServletResponse response) {

        /**
         * check if query is empty, send SC_PRECONDITION_FAILED - 412
         */
        String query = request.getParameter("uid");
        if (query == null || query.isEmpty()) {
            response.setStatus(HttpStatus.SC_PRECONDITION_FAILED);
        }

        /**
         * get the users bearer token
         */
        HttpSession session = request.getSession(false);

        Object oData = session.getAttribute(OAuth20Handler.CREDENTIALS);
        if (oData == null) {
            logger.warning("OAuth20Data is null");
        }

        OAuth20Data data = (OAuth20Data) oData;
        String bearer = data.getAccessToken();

        try {

            /**
             * Example URL:
             * http://localhost:9080/photoSharing/api/profile?uid=self maps to
             * https://apps.collabservnext.com/profiles/atom/profileService.do
             * 
             * and results in an id for the self user, this data is ideally cached on the client. 
             */
            if (query.compareTo("self") == 0) {
                String apiUrl = getApiUrlForServiceDoc();

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

                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 - 403
                if (code == HttpStatus.SC_FORBIDDEN) {
                    response.sendRedirect("./api/logout");
                }

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

                // Content is returned 
                // OK (200)
                else if (code == HttpStatus.SC_OK) {
                    InputStream in = hr.getEntity().getContent();

                    // Converts the XML to JSON
                    // Alternatively, one can parse the XML using XPATH
                    String jsonString = org.apache.wink.json4j.utils.XML.toJson(in);
                    logger.info("json string is " + jsonString);

                    JSONObject jsonObj = new JSONObject(jsonString);
                    JSONObject workspace = jsonObj.getJSONObject("service").getJSONObject("workspace")
                            .getJSONObject("collection");
                    String id = workspace.getString("userid");

                    query = id;
                } else {
                    JSONObject obj = new JSONObject();
                    obj.put("error", "unexpected content");
                }

            }

            /**
             * The query should be cleansed before passing it to the backend
             * cleansing can incorporate checking that the id is a number
             * 
             * example URL
             * http://localhost:9080/photoSharing/api/profile?uid=20131674 maps
             * to https
             * ://apps.collabservnext.com/profiles/atom/profile.do?userid
             * =20131674
             * 
             * example response {"img":
             * "https:\/\/apps.collabservnext.com\/profiles\/photo.do?key=fef1b5f3-586f-4470-ab0a-a9d4251fe1ec&lastMod=1443607729019","name":"P
             * a u l Demo","email":"demo@us.ibm.com"}
             * 
             */
            String apiUrl = getApiUrl(query);
            Request get = Request.Get(apiUrl);
            get.addHeader("Authorization", "Bearer " + bearer);

            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
            // SC_FORBIDDEN (403)
            if (code == HttpStatus.SC_FORBIDDEN) {
                response.sendRedirect("./api/logout");
            }

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

            // Content is returned OK (200)
            else if (code == HttpStatus.SC_OK) {
                InputStream in = hr.getEntity().getContent();

                // Converts the XML to JSON
                // Alternatively, one can parse the XML using XPATH
                String jsonString = org.apache.wink.json4j.utils.XML.toJson(in);
                logger.info("json string is " + jsonString);

                JSONObject jsonObj = new JSONObject(jsonString);

                JSONObject entry = jsonObj.getJSONObject("feed").getJSONObject("entry");
                logger.info("entry" + entry);

                // Check if the Entry exists for the given id
                if (entry != null) {
                    // Start Building the Response
                    String name = "";
                    String image = "";
                    String email = "";

                    JSONObject contributor = entry.getJSONObject("contributor");
                    name = contributor.getString("name");
                    email = contributor.getString("email");

                    JSONArray links = entry.getJSONArray("link");

                    // Scans through the links and finds the profile image
                    // XPath is much more efficient
                    boolean found = false;
                    int idx = 0;
                    int len = links.length();
                    while (!found && idx < len) {
                        JSONObject link = links.getJSONObject(idx);

                        String type = link.getString("type");
                        if (type != null && !type.isEmpty() && type.compareTo("image") == 0) {
                            found = true;
                            image = link.getString("href");
                        }

                        idx++;
                    }

                    // Build the json to send back
                    JSONObject profile = new JSONObject();
                    profile.put("name", name);
                    profile.put("email", email);
                    profile.put("img", image);
                    profile.put("userid", query);

                    // Write output streams
                    ServletOutputStream out = response.getOutputStream();
                    profile.write(out);

                } else {
                    // There is no Entry for the user with the id.
                    response.setStatus(HttpStatus.SC_NOT_FOUND);
                    PrintWriter out = response.getWriter();
                    out.println("User does not exist");

                }

            }

            // Unexpected status
            else {
                JSONObject obj = new JSONObject();
                obj.put("error", "unexpected content");
                //Should serialize result

                response.setStatus(HttpStatus.SC_INTERNAL_SERVER_ERROR);
            }

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

    }

}