io.starter.datamodel.Sys.java Source code

Java tutorial

Introduction

Here is the source code for io.starter.datamodel.Sys.java

Source

package io.starter.datamodel;

/*
 * --------- BEGIN COPYRIGHT NOTICE ---------
 * Copyright 2012-2014 Starter Inc.
 * 
 * This file is part of Starter.
 * 
 * Starter is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation, either version 3 of
 * the License, or (at your option) any later version.
 * 
 * Starter is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License along with Starter.
 * 
 * If not, see <http://www.gnu.org/licenses/>.
 * 
 * ---------- END COPYRIGHT NOTICE ----------
 */
import io.starter.messaging.SNSMobilePush;
import io.starter.messaging.tools.NotificationMessageGenerator;
import io.starter.model.Device;
import io.starter.model.Syslog;
import io.starter.model.User;
import io.starter.security.dao.MyBatisConnectionFactory;
import io.starter.util.Logger;
import io.starter.util.SystemConstants;

import java.io.BufferedInputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.net.HttpURLConnection;
import java.net.URL;
import java.net.URLConnection;
import java.sql.Connection;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.CountDownLatch;

import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.xml.transform.Source;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import javax.xml.transform.stream.StreamSource;

import org.apache.ibatis.session.SqlSession;
import org.apache.ibatis.session.SqlSessionFactory;
import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

/**
 * System handling
 * 
 * fetch system log fetch statistics edit/delete users, groups, content send
 * system messages
 * 
 * 
 * @author John McMahon Copyright 2013 Starter Inc., all rights reserved.
 * 
 */
@Path("/system")
public class Sys implements SystemConstants {

    private final String txt = "starter";

    private Map counters = new HashMap();

    /**
     * add a counter to the system stats
     * 
     * @param name
     * @param ct
     */
    public void incrementCounter(String name, Object ct) {

        Object existing = counters.get(name);
        if (existing != null) {
            // attempt to treat as a number, fail to String
            try {
                if (existing instanceof Float) {
                    float fnf = Float.parseFloat(existing.toString());
                    float fnadd = Float.parseFloat(ct.toString());
                    // increment by new value
                    fnf += fnadd;
                    // update the counter
                    counters.put(name, new Float(fnf));

                } else if (existing instanceof Integer) {
                    int fni = Integer.parseInt(existing.toString());
                    int fnadd = Integer.parseInt(ct.toString());
                    // increment by new value
                    fni += fnadd;
                    // update the counter
                    counters.put(name, new Integer(fni));
                }
                // is it an integer or a real float?
            } catch (NumberFormatException xf) {
                // cannot be "added", if it's a string append or replace?
                counters.put(name, ct);
            }
        } else {
            counters.put(name, ct);
        }
    }

    /**
     * Get the /1.0/application.wadl
     * 
     * TODO: implement extended WADL Apply XSLT to the WADL output to generate
     * human-readable api docs per: https://wikis.oracle.com/display/Jersey/WADL
     * 
     * 
     * @return
     * @throws IOException
     * @throws TransformerException
     */
    @GET
    @Path("apidocs")
    @Produces(MediaType.TEXT_HTML)
    public String getWADL(@Context HttpServletRequest servletRequest, @Context HttpServletResponse servletResponse)
            throws IOException, TransformerException {

        servletResponse.addHeader("Access-Control-Allow-Origin", "*");

        // Transform the WADL to HTML using XSLT
        TransformerFactory factory = TransformerFactory.newInstance();

        // Make a URL to the XML
        String iserv = servletRequest.getScheme() + "://" + servletRequest.getServerName() + ":"
                + servletRequest.getServerPort() + "/" + SystemConstants.REST_BASE_PATH + "/";
        URL url = new URL(iserv + WADL_SOURCE_URL);

        URLConnection con = url.openConnection();
        con.setDoOutput(true);
        Source text = new StreamSource(con.getInputStream());

        // path to the XSLT
        URL urlx = new URL(SystemConstants.REST_API_SERVER_HOST + "/wadl_html_doc.xslt");
        HttpURLConnection urlConnection = (HttpURLConnection) urlx.openConnection();

        InputStream is = null;

        is = new BufferedInputStream(urlConnection.getInputStream());

        Source xslt = new StreamSource(is);

        Transformer transformer = factory.newTransformer(xslt);
        servletResponse.setContentType("text/html");
        OutputStream ous = servletResponse.getOutputStream();

        transformer.transform(text, new StreamResult(ous));
        ous.flush();
        ous.close();

        return "ok";
    }

    /**
     * this method checks things and sends back a 200 if all is OK otherwise an
     * error code is sent
     * 
     * used for system monitoring
     * 
     * @param query
     * @param servletRequest
     * @param servletResponse
     * @return
     * @throws IOException
     * @throws ServletException
     * @throws JSONException
     * @throws SQLException
     */
    @GET
    @Path("systemcheck")
    @Produces(MediaType.APPLICATION_JSON)
    public String getSystemCheck(@Context HttpServletRequest servletRequest,
            @Context HttpServletResponse servletResponse)
            throws IOException, ServletException, JSONException, SQLException {

        JSONObject ret = new JSONObject();
        try {
            SqlSession session = (SqlSession) servletRequest.getAttribute(SESSION_VAR_SQLSESSION);
            Connection connection = session.getConnection();
            ret.put("MyBatis DB Connection Status", connection.isValid(10000));
            return ret.toString();
        } catch (Exception e) {
            servletResponse.sendError(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            return null;
        }
    }

    /**
     * this method returns a JSON string with a summarized set of data for the
     * entire starter system
     * 
     * includes:
     * 
     * Top Content Leader board System-wide Alliances
     * 
     * @param query
     * @param servletRequest
     * @param servletResponse
     * @return
     * @throws IOException
     * @throws ServletException
     * @throws JSONException
     * @throws SQLException
     */
    @GET
    @Path("stats")
    @Produces(MediaType.APPLICATION_JSON)
    public String getStats(@Context HttpServletRequest servletRequest, @Context HttpServletResponse servletResponse)
            throws IOException, ServletException, JSONException, SQLException {

        String jsonStr = "";
        Map namevals = new HashMap();

        // System-wide eazy squeezy

        User u = (User) servletRequest.getSession(true).getAttribute(SESSION_VAR_USER);

        SqlSession session = (SqlSession) servletRequest.getAttribute(SESSION_VAR_SQLSESSION);
        Connection connection = session.getConnection();

        try {

            namevals.put("system.totalusers", this.getValueFromDB("SELECT COUNT(id) as ct FROM user", connection));

            namevals.put("system.totalcontent",
                    this.getValueFromDB("SELECT COUNT(id) as ct FROM content", connection));

            namevals.put("system.totalalliances",
                    this.getValueFromDB("SELECT COUNT(id) as ct FROM role WHERE id > 100", connection));

            namevals.put("system.totalshares", this.getValueFromDB(
                    "SELECT COUNT(id) FROM acl WHERE target_type = 2 AND principle_id = 2 AND principle_type = 1 AND permission = 3",
                    connection));

            namevals.put("system.totalsocialshares", this.getValueFromDB(
                    "SELECT COUNT(syslog.id) as CT FROM syslog WHERE ( event_type = 25 OR event_type = 26) AND syslog.description LIKE '%OK [%' ORDER BY CT desc",
                    connection));

            namevals.put("system.totalratings",
                    this.getValueFromDB("SELECT COUNT(id) as CT FROM content_rating", connection));

            namevals.put("system.totalcategories",
                    this.getValueFromDB("SELECT COUNT(id) as CT FROM category", connection));

            namevals.put("system.totallogins", this.getValueFromDB(
                    "SELECT COUNT(syslog.id) as CT FROM syslog WHERE event_type = 0 AND syslog.description LIKE '%OK [%' ORDER BY CT desc",
                    connection));

            // Top Content -- the easiest
            ContentData cdx = new ContentData();

            String lx = cdx.list("top", servletRequest, servletResponse);
            JSONArray jaray = new JSONArray(lx);

            for (int t = 0; t < jaray.length(); t++) {
                namevals.put("topcontent." + t, jaray.get(t));
            }

            // Leader board
            // Top Content -- the easiest
            if (servletRequest.getParameter("leaderboard") != null) {
                try {
                    lx = UserData.list("leaders", servletRequest, servletResponse);
                    jaray = new JSONArray(lx);
                    int lx1 = jaray.length() - 1;
                    for (int t = 0; t < jaray.length(); t++) {
                        namevals.put("leader." + t, jaray.get(lx1 - t));
                    }
                } catch (Exception e) {
                    ; // couldn't get leaderboard
                }
            }

            // Alliances
            try {
                lx = RoleData.list("top", servletRequest, servletResponse);
                jaray = new JSONArray(lx);
                for (int t = 0; t < jaray.length(); t++) {
                    namevals.put("alliance." + t, jaray.get(t));
                }
            } catch (Exception e) {
                ; // couldn't get alliances
            }

            // JSONify
            jsonStr = new JSONObject(namevals).toString();
            // oh yes, record it for posterity... this is going to come in
            // handy...
            Syslog logEntry = new Syslog();

            logEntry.setDescription("OK [ ANONYMOUS -1 ], [GET] [stats " + jsonStr.substring(0, 100) + "]");

            logEntry.setEventType(SystemConstants.LOG_EVENT_TYPE_SYSTEM_CONTENT);
            logEntry.setSourceId(-1);
            logEntry.setSourceType(SystemConstants.TARGET_TYPE_SYSTEM);
            logEntry.setTimestamp(new java.util.Date(System.currentTimeMillis()));

            session.insert("io.starter.dao.SyslogMapper.insert", logEntry);
            session.commit();

        } catch (Exception x) {
            Logger.log("Getting System Stats Failed: " + x.toString());
        }

        return jsonStr;

    }

    private Object getValueFromDB(String query, Connection connection) throws SQLException {
        float ret = -1;
        Logger.debug("Sys: Executing query [ " + query + " ] took:");
        long start = System.currentTimeMillis();
        java.sql.Statement st = connection.createStatement();
        ResultSet rs = st.executeQuery(query);
        rs.next();
        ret = rs.getFloat(1); // limited valid queries

        rs.close();
        st.close();

        long end = System.currentTimeMillis();
        long duration = (end - start);

        Logger.debug(duration + " milliseconds");
        return ret;

    }

    // This method is called if TEXT_PLAIN is request
    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String getTextLog() {
        return txt;

    }

    // This method is called if XML is request
    @GET
    @Produces(MediaType.TEXT_XML)
    public String getXMLLog() {
        return "<?xml version=\"1.0\"?><system>" + txt + ":" + "</system>";
    }

    // This method is called if HTML is request
    @GET
    @Produces(MediaType.TEXT_HTML)
    public String getHTMLLog() {
        return "<html> " + "<title>" + txt + "</title>" + "<body><h1>" + txt + "<br/><br/>System:<br/>"
                + "</body></h1>" + "</html> ";
    }

    /**
     * 
     * @param params
     * @throws Exception
     * 
     * 
     */
    public static void sendEmail(String url, final User from, String toEmail, Map params, SqlSession session,
            CountDownLatch latch) throws Exception {

        final CountDownLatch ltc = latch;

        if (from == null) {
            throw new ServletException("Sys.sendEmail cannot have a null FROM User.");
        }
        String fromEmail = from.getEmail();
        final String fro = fromEmail;
        final String to = toEmail;
        final Map p = params;
        final String u = url;
        final SqlSession sr = session;

        // TODO: check message sender/recipient validity
        if (!checkEmailValidity(fromEmail)) {
            throw new RuntimeException(
                    fromEmail + " is not a valid email address. SENDING MESSAGE TO " + toEmail + " FAILED");
        }
        // TODO: check mail server if it's a valid message
        if (!checkEmailValidity(toEmail)) {
            throw new RuntimeException(
                    toEmail + " is not a valid email address. SENDING MESSAGE TO " + toEmail + " FAILED");
        }

        // message.setSubject("Testing Email From Starter.io");
        // Send the actual HTML message, as big as you like
        // fetch the content
        final String content = getText(u);

        new Thread(new Runnable() {
            @Override
            public void run() {
                // Sender's email ID needs to be mentioned
                // String sendAccount = "$EMAIL_USER_NAME$";

                // final String username = "$EMAIL_USER_NAME$", password =
                // "hum0rm3";

                // Assuming you are sending email from localhost
                // String host = "gator3083.hostgator.com";

                String sendAccount = "$EMAIL_USER_NAME$";
                final String username = "$EMAIL_USER_NAME$", password = "$EMAIL_USER_PASS$";

                // Assuming you are sending email from localhost
                String host = SystemConstants.EMAIL_SERVER;

                // Get system properties
                Properties props = System.getProperties();

                // Setup mail server
                props.setProperty("mail.smtp.host", host);
                props.put("mail.smtp.auth", "true");
                props.put("mail.smtp.starttls.enable", "true");
                props.put("mail.smtp.port", "587");

                // Get the default Session object.
                Session session = Session.getInstance(props, new javax.mail.Authenticator() {
                    @Override
                    protected PasswordAuthentication getPasswordAuthentication() {
                        return new PasswordAuthentication(username, password);
                    }
                });
                try {
                    // Create a default MimeMessage object.
                    MimeMessage message = new MimeMessage(session);

                    // Set From: header field of the header.
                    message.setFrom(new InternetAddress(sendAccount));
                    // Set To: header field of the header.
                    message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));

                    message.addRecipient(Message.RecipientType.TO, new InternetAddress(sendAccount));

                    // Set Subject: header field
                    Object o = p.get("MESSAGE_SUBJECT");
                    message.setSubject(o.toString());

                    String ctx = new String(content.toString());

                    // TODO: String Rep on the params
                    ctx = stringRep(ctx, p);

                    message.setContent(ctx, "text/html; charset=utf-8");

                    // message.setContent(new Multipart());
                    // Send message
                    Transport.send(message);

                    Logger.log("Sending message to:" + to + " SUCCESS");
                } catch (MessagingException mex) {
                    // mex.printStackTrace();
                    Logger.log("Sending message to:" + to + " FAILED");
                    Logger.error("Sys.sendEmail() failed to send message. Messaging Exception: " + mex.toString());
                }
                // log the data
                Syslog logEntry = new Syslog();

                logEntry.setDescription("OK [ email sent from: " + fro + " to: " + to + "]");

                logEntry.setUserId(from.getId());
                logEntry.setEventType(SystemConstants.LOG_EVENT_TYPE_SEND_EMAIL);
                logEntry.setSourceId(from.getId()); // unknown
                logEntry.setSourceType(SystemConstants.TARGET_TYPE_USER);

                logEntry.setTimestamp(new java.util.Date(System.currentTimeMillis()));
                SqlSessionFactory sqlSessionFactory = MyBatisConnectionFactory.getSqlSessionFactory();
                SqlSession sesh = sqlSessionFactory.openSession(true);

                sesh.insert("io.starter.dao.SyslogMapper.insert", logEntry);
                sesh.commit();
                if (ltc != null)
                    ltc.countDown(); // release the latch
            }
        }).start();

    }

    /**
     * do checks
     * 
     * @param emailAddress
     * @return
     */
    public static boolean checkEmailValidity(String heck) {
        if (heck == null)
            return false;

        int hx = heck.indexOf("@");
        if (hx < 1) // theres an @ with something in front of it
            return false;
        if (heck.lastIndexOf(".") < hx) // the dot is after the @
            return false;
        if (heck.lastIndexOf(".") > heck.length() - 3) // not dot at the end
            return false;

        return true;
    }

    /**
     * search and replace the strings in the input with delimiter %XX_SOMENAME%
     * with the map values:
     * 
     * "SOMENAME", "somevalue"
     * 
     * 
     * @param input
     * @param params
     * @return
     */
    public static String stringRep(String input, Map<String, String> params) {

        if (params == null) {// unchanged
            Logger.warn("Sys.stringRep(): no parameters to replace. String unchanged.");
            return input;
        }

        Set<String> it = params.keySet();
        Iterator<String> its = it.iterator();

        // SEARCH AND REPLACE
        while (its.hasNext()) {
            String key = its.next();
            String o = String.valueOf(params.get(key));
            // transform to the replace string
            String find = "%" + key.toUpperCase() + "%";
            input = input.replace(find, o);

        }
        return input;
    }

    /**
     * get cached URL text
     * 
     * @param url
     * @return
     * @throws Exception
     */
    public static String getText(String url) throws Exception {
        Object o = System.getProperty(url);
        if (o != null) {
            // Logger.log("System.sendEmail text cache hit for: " + url);
            return o.toString();
        } else {
            Logger.log("System.sendEmail text cache MISS for: " + url);
        }
        String oldurl = url;
        if (url.indexOf("?") > -1) {
            url += "&cachebust=" + System.currentTimeMillis();
        } else {
            url += "?cachebust=" + System.currentTimeMillis();
        }

        URL website = new URL(url);

        URLConnection connection = website.openConnection();
        BufferedReader in = new BufferedReader(new InputStreamReader(connection.getInputStream()));

        StringBuilder response = new StringBuilder();
        String inputLine;

        while ((inputLine = in.readLine()) != null)
            response.append(inputLine);

        in.close();

        String strz = response.toString();
        System.setProperty(oldurl, strz);
        return strz;
    }

    /**
     * get the web content
     * 
     * @param url
     * @return
     */
    public String getWebEmailFromURL(String url, Map<?, ?> replacements) {

        return "";
    }

    /**
     * send a push notification to the device
     * 
     * NOTE: Uses Amazon SNS
     * 
     * @param dve
     * @param to
     * @param params
     * @param session
     * @throws IOException
     */
    public static void sendFollowPushNotification(Device dve, User to, Map params, SqlSession session)
            throws IOException {

        String msg = getStarterAppleFollowMessage(to, params);
        SNSMobilePush pu = new SNSMobilePush();
        pu.starterAppleAppNotification(msg, dve.getDeviceId());
    }

    /**
     * send a push notification when a comment submitted
     * 
     * NOTE: Uses Amazon SNS
     * 
     * @param dve
     * @param to
     * @param params
     * @param session
     * @throws IOException
     */
    public static void sendCommentPushNotification(User to, String params, SqlSession session) throws IOException {
        // handle Push notifications
        List Devices = to.getDevices();
        if (Devices == null) {
            return;
        }
        Iterator its = Devices.iterator();
        while (its.hasNext()) {
            Device dve = (Device) its.next();
            String msg = getStarterAppleCommentMessage(to, params);
            SNSMobilePush pu = new SNSMobilePush();
            pu.starterAppleAppNotification(msg, dve.getDeviceId());
        }

    }

    /**
     * send a push notification to the device
     * 
     * NOTE: Uses Amazon SNS
     * 
     * @param dve
     * @param to
     * @param params
     * @param session
     * @throws IOException
     */
    public static void sendSharePushNotification(Device dve, User to, Map params, SqlSession session)
            throws IOException {

        String msg = getStarterAppleShareMessage(to, params);
        SNSMobilePush pu = new SNSMobilePush();
        pu.starterAppleAppNotification(msg, dve.getDeviceId());
    }

    public static String getStarterAppleCommentMessage(User to, String params) {

        Map<String, Object> appleMessageMap = new HashMap<String, Object>();
        Map<String, Object> appMessageMap = new HashMap<String, Object>();
        appMessageMap.put("alert", params);
        appMessageMap.put("badge", to.getStats().size()); // TODO hook up to
        // "seen" counter
        appMessageMap.put("sound", "default");
        appleMessageMap.put("aps", appMessageMap);
        return NotificationMessageGenerator.jsonify(appleMessageMap);
    }

    public static String getStarterAppleShareMessage(User to, Map params) {

        Map<String, Object> appleMessageMap = new HashMap<String, Object>();
        Map<String, Object> appMessageMap = new HashMap<String, Object>();
        appMessageMap.put("alert", params.get("MESSAGE_SUBJECT"));
        appMessageMap.put("badge", to.getStats().size()); // TODO hook up to
        // "seen" counter
        appMessageMap.put("sound", "default");
        appleMessageMap.put("aps", appMessageMap);
        return NotificationMessageGenerator.jsonify(appleMessageMap);
    }

    public static String getStarterAppleFollowMessage(User to, Map params) {

        Map<String, Object> appleMessageMap = new HashMap<String, Object>();
        Map<String, Object> appMessageMap = new HashMap<String, Object>();
        appMessageMap.put("alert", "Good news, " + to.getUsername() + ". " + params.get("SENDER_UN")
                + " is now following you on Starter!");

        appMessageMap.put("badge", 5); // to.getStats().size()); // TODO hook up
        // to "seen" counter
        appMessageMap.put("sound", "default");
        appleMessageMap.put("aps", appMessageMap);
        return NotificationMessageGenerator.jsonify(appleMessageMap);
    }
    /**
     * TODO: create an XLS report of System stats
     * 
     * @param id
     * @return
     * @throws IOException
     * @throws WorkSheetNotFoundException
     * @throws RowNotFoundException
     * @throws CellNotFoundException
     * @throws JSONException
     * @throws Exception
     * @GET
     * @Path("/report/excel/{reportName /{userId}")
     * @Produces({ "application/vnd.ms-excel",
     *             "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
     *             }) public Response exportExcel(@Context HttpServletRequest
     *             servletRequest,
     * @PathParam("reportName") String reportName,
     * @PathParam("userId") int userId,
     * @Context HttpServletResponse servletResponse) throws
     *          XmlPullParserException, IOException, WorkSheetNotFoundException,
     *          RowNotFoundException, CellNotFoundException, JSONException {
     * 
     *          final WorkBookHandle wb = new WorkBookHandle(); // TODO: use //
     *          preformatted Template WorkSheetHandle sheet =
     *          wb.getWorkSheet(0); try { wb.getWorkSheet(1).remove();
     *          wb.getWorkSheet(1).remove(); } catch (Exception x) { ; }
     *          CellHandle titlecell = sheet.add("Starter User Profile", "A1");
     *          titlecell.setFontWeight(Font.BOLD); titlecell.setFontSize(38);
     *          titlecell.setFontColor(new Color(0, 0, 100));
     * 
     *          sheet.add("Series", "A2"); sheet.add("Rating", "B2");
     *          sheet.add("Flags", "C2"); sheet.add("Takedowns", "D2");
     * 
     *          SqlSession session = (SqlSession) servletRequest
     *          .getAttribute(SESSION_VAR_SQLSESSION);
     * 
     *          UserExample example = new UserExample();
     *          io.starter.model.UserExample.Criteria criteria =
     *          example.createCriteria(); // for now hard code ID
     *          criteria.andIdBetween(0, 5); List<?> results =
     *          session.selectList( "io.starter.dao.UserMapper.selectByExample",
     *          example);
     * 
     *          Iterator<?> its = results.iterator(); int t = 2; while
     *          (its.hasNext()) {
     * 
     *          Object o = its.next(); io.starter.model.User u =
     *          (io.starter.model.User) o; // get rating // float score =
     *          UserData.getRatingScore(u, servletRequest, // servletResponse);
     * 
     *          double score = 100 * Math.random();
     * 
     *          Object[] data = { u.getUsername(), new Double(score), new
     *          Double((int) (100 * Math.random())), new Double((int) (100 *
     *          Math.random())), }; sheet.insertRow(t++, data); }
     * 
     *          sheet.setShowGridlines(false); // sheet.setProtected(protect,
     *          password)
     * 
     *          EnumSet<ChartOptions> opts = EnumSet.noneOf(ChartOptions.class);
     *          // chart-specific
     * 
     *          opts.add(ChartOptions.THREED);
     * 
     *          // ChartHandle cx = ChartHandle.createNewChart(sheet,
     *          ChartHandle.PIE, // opts); //
     *          cx.setTitle("Starter Humor Analysis");
     * 
     *          ChartHandle cx = wb.createChart("User Stats", sheet);
     *          cx.setChartType(ChartHandle.BAR);
     * 
     *          short[] cd = { 60, 60, 1000, 1000 }; cx.setCoords(cd);
     * 
     *          for (int z = 3; z <= t; z++) {
     *          cx.addSeriesRange(sheet.getCell("A" + z), new
     *          CellRange(sheet.getSheetName() + "!B2:D2", wb), new
     *          CellRange(sheet.getSheetName() + "!B" + z + ":D" + z, wb),
     *          null); }
     * 
     *          StreamingOutput stream = new StreamingOutput() {
     * @Override public void write(OutputStream output) throws IOException,
     *           WebApplicationException { try { wb.write(output); } catch
     *           (Exception e) { throw new WebApplicationException(e); }
     *           wb.close(); } }; return Response .ok(stream)
     *           .header("content-disposition",
     *           "attachment; filename = export.xls").build(); }
     */
}