pt.webdetails.cdv.CdvContentGenerator.java Source code

Java tutorial

Introduction

Here is the source code for pt.webdetails.cdv.CdvContentGenerator.java

Source

/*!
* Copyright 2002 - 2013 Webdetails, a Pentaho company. All rights reserved.
*
* This software was developed by Webdetails and is provided under the terms
* of the Mozilla Public License, Version 2.0, or any later version. You may not use
* this file except in compliance with the license. If you need a copy of the license,
* please go to http://mozilla.org/MPL/2.0/. The Initial Developer is Webdetails.
*
* Software distributed under the Mozilla Public License is distributed on an "AS IS"
* basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. Please refer to
* the license for the specific language governing your rights and limitations.
*/

package pt.webdetails.cdv;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.json.JSONException;
import org.json.JSONObject;
import org.pentaho.platform.api.engine.IParameterProvider;
import org.pentaho.platform.engine.core.system.PentahoSessionHolder;
import pt.webdetails.cdv.operations.PushWarningsHandler;
import pt.webdetails.cdv.plugin.CdvConfig;
import pt.webdetails.cdv.util.CdvEnvironment;
import pt.webdetails.cpf.InterPluginCall;
import pt.webdetails.cpf.RestRequestHandler;
import pt.webdetails.cpf.Result;
import pt.webdetails.cpf.Util;
import pt.webdetails.cpf.VersionChecker;
import pt.webdetails.cpf.WrapperUtils;
import pt.webdetails.cpf.annotations.AccessLevel;
import pt.webdetails.cpf.annotations.Exposed;
import pt.webdetails.cpf.persistence.PersistenceEngine;
import pt.webdetails.cpf.repository.api.IBasicFile;
import pt.webdetails.cpf.repository.api.IBasicFileFilter;
import pt.webdetails.cpf.repository.api.IRWAccess;
import pt.webdetails.cpf.repository.api.IReadAccess;
import pt.webdetails.cpf.repository.api.IUserContentAccess;
import pt.webdetails.cpf.utils.CharsetHelper;
import pt.webdetails.cpf.utils.MimeTypes;
import pt.webdetails.cpf.utils.PluginUtils;

import javax.servlet.ServletRequest;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.StringWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class CdvContentGenerator extends RestContentGenerator {

    private static final long serialVersionUID = 1L;
    public static final String CDW_EXTENSION = ".cdw";
    public static final String PLUGIN_NAME = "cdv";
    public static final String PLUGIN_PATH = "system/" + CdvContentGenerator.PLUGIN_NAME + "/";
    private static final String UI_PATH = "cdv/presentation/";

    @Override
    public String getPluginName() {
        return PLUGIN_NAME;
    }

    @Exposed(accessLevel = AccessLevel.PUBLIC)
    public void refresh(OutputStream out) {
        CdvLifecycleListener.reInit();
    }

    @Exposed(accessLevel = AccessLevel.PUBLIC)
    public void home(OutputStream out) throws UnsupportedEncodingException, IOException {
        new InterPluginCall(InterPluginCall.CDV, "refreshTests").call();
        callCDE("validations.wcdf", out);
    }

    @Exposed(accessLevel = AccessLevel.PUBLIC)
    public void validations(OutputStream out) throws UnsupportedEncodingException, IOException {
        new InterPluginCall(InterPluginCall.CDV, "refreshTests").call();
        callCDE("validations.wcdf", out);
    }

    @Exposed(accessLevel = AccessLevel.PUBLIC)
    public void alerts(OutputStream out) throws UnsupportedEncodingException, IOException {
        callCDE("alerts.wcdf", out);
    }

    @Exposed(accessLevel = AccessLevel.PUBLIC)
    public void cdaErrors(OutputStream out) throws UnsupportedEncodingException, IOException {
        callCDE("cdaErrors.wcdf", out);
    }

    @Exposed(accessLevel = AccessLevel.PUBLIC)
    public void slowQueries(OutputStream out) throws UnsupportedEncodingException, IOException {
        callCDE("slowQueries.wcdf", out);
    }

    @Exposed(accessLevel = AccessLevel.PUBLIC)
    public void notificationSettings(OutputStream out) throws UnsupportedEncodingException, IOException {
        callCDE("notificationSettings.wcdf", out);
    }

    private JSONObject createTest(String origin, String newPath) throws JSONException {
        JSONObject result = new JSONObject();
        if (!newPath.endsWith(".cdv")) {
            newPath = newPath + ".cdv";
        }
        String newFileName = Util.joinPath(CdvEnvironment.getPluginRepositoryDir(),
                CdvConstants.SolutionFolders.TESTS, newPath);

        IRWAccess pluginRepo = CdvEnvironment.getPluginRepositoryWriter("tests");
        IReadAccess systemRepo = CdvEnvironment.getPluginSystemReader();
        IReadAccess contentRepo = CdvEnvironment.getUserContentAccess();

        try {
            if (pluginRepo.fileExists(newPath)) {
                logger.error("New File already exists, aborting creation of new test");
                result.put("success", "false");
                return result;
            }

            InputStream inputStream;
            if (StringUtils.isEmpty(origin)) {
                inputStream = systemRepo.getFileInputStream("validationTemplate.cdv");
            } else {
                inputStream = contentRepo.getFileInputStream(origin);
            }

            StringWriter writer = new StringWriter();
            IOUtils.copy(inputStream, writer, CharsetHelper.getEncoding());
            String originalTest = writer.toString();

            originalTest = Pattern.compile("path:\\s*['\"].*['\"]\\s*,").matcher(originalTest)
                    .replaceFirst("path: '" + newFileName + "',");
            originalTest = Pattern.compile("name:\\s*['\"].*['\"]\\s*,").matcher(originalTest)
                    .replaceFirst("name: '" + newFileName.substring(newFileName.lastIndexOf("/") + 1)
                            .replaceAll(Matcher.quoteReplacement(".cdv"), "") + "',");
            originalTest = Pattern.compile("createdBy:\\s*['\"].*['\"]\\s*,").matcher(originalTest)
                    .replaceFirst("createdBy: '" + PentahoSessionHolder.getSession().getName() + "',");

            inputStream = new ByteArrayInputStream(originalTest.getBytes(CharsetHelper.getEncoding()));

            pluginRepo.saveFile(newPath, inputStream);
            result.put("success", "true");
            result.put("path", newFileName);
        } catch (IOException ioe) {
            logger.error("Error while creating test file", ioe);
            result.put("success", "false");
        }

        return result;
    }

    private JSONObject copyCDVTestsFromPluginSamples() throws JSONException {
        JSONObject result = new JSONObject();

        IBasicFileFilter cdvFilter = new IBasicFileFilter() {
            public boolean accept(IBasicFile file) {
                return file.getExtension().equals("cdv");
            }
        };

        IUserContentAccess repAccess = CdvEnvironment.getUserContentAccess();

        final List<String> origins = new ArrayList<String>();
        origins.add("plugin-samples/cdv/");
        origins.add("system/cdv/sampleFiles/");
        final String destination = "cdv/tests/";

        if (repAccess.fileExists(destination)) {
            for (String origin : origins) {
                List<IBasicFile> tests = repAccess.listFiles(origin, cdvFilter);
                for (IBasicFile test : tests) {
                    repAccess.copyFile(test.getPath(), destination + test.getName());
                }
            }
            InterPluginCall pluginCall = new InterPluginCall(InterPluginCall.CDV, "refreshTests");
            pluginCall.call();
        } else {
            result.put("success", "false");
            return result;
        }
        result.put("success", "true");
        return result;
    }

    @Exposed(accessLevel = AccessLevel.PUBLIC, outputType = MimeTypes.JSON)
    public void newTest(OutputStream out) throws IOException, JSONException {
        String newName = getRequestParameters().getStringParameter("newName", null);
        JSONObject result = createTest("system/cdv/validationTemplate.cdv", newName);
        writeOut(out, result.toString(2));
    }

    @Exposed(accessLevel = AccessLevel.PUBLIC, outputType = MimeTypes.JSON)
    public void duplicateTest(OutputStream out) throws IOException, JSONException {
        String path = getRequestParameters().getStringParameter("path", null);
        String newName = getRequestParameters().getStringParameter("newName", null);
        JSONObject result;

        //Need to validate this a bit more - ensure that path is in cdv/tests at least
        if (path != null) {
            result = createTest(path, newName);
        } else {
            result = new JSONObject();
            result.put("success", "false");
        }
        writeOut(out, result.toString(2));
    }

    @Exposed(accessLevel = AccessLevel.PUBLIC, outputType = MimeTypes.JSON)
    public void copyCDVTests(OutputStream out) throws IOException, JSONException {
        JSONObject result;

        result = copyCDVTestsFromPluginSamples();
        writeOut(out, result.toString(2));
    }

    //TODO: TEMP!
    @Exposed(accessLevel = AccessLevel.ADMIN, outputType = MimeTypes.PLAIN_TEXT)
    public void deleteTable(OutputStream out) throws IOException {
        String classTable = getRequestParameters().getStringParameter("class", null);
        if (classTable != null) {
            int deleted = PersistenceEngine.getInstance().deleteAll(classTable);
            writeOut(out, "deleted " + deleted + " instances");
        } else {
            writeOut(out, "No class");
        }
    }

    //TODO:TEMP!
    @Exposed(accessLevel = AccessLevel.ADMIN, outputType = MimeTypes.JSON)
    public void listTable(OutputStream out) throws IOException, JSONException {
        String classTable = getRequestParameters().getStringParameter("class", null);

        if (classTable != null) {
            writeOut(out, PushWarningsHandler.listClass(classTable));
        } else {
            writeOut(out, Result.getError("No class"));
        }
    }

    //TODO:TEMP!
    @Exposed(accessLevel = AccessLevel.ADMIN, outputType = MimeTypes.JSON)
    public void listCda(OutputStream out) throws IOException, JSONException {
        String dataAccessId = getRequestParameters().getStringParameter("dataAccessId", null);
        String settingsId = getRequestParameters().getStringParameter("cdaSettingsId", null);

        if (!StringUtils.isEmpty(dataAccessId) && !StringUtils.isEmpty(settingsId)) {
            writeOut(out, PushWarningsHandler.listClass(settingsId, dataAccessId));
        } else {
            writeOut(out, Result.getError("Something missing"));
        }
    }

    //    //TODO:TEMP!
    //    @Exposed(outputType = MimeType.JSON)
    //    public void testCdaStuff(OutputStream out) throws Exception {
    //      JSONObject event = new JSONObject(
    //"{\"plugin\":\"cda\",\"eventType\":\"QueryTooLong\",\"timestamp\":\"1340291929309\",\"event\":{\"duration\":42,
    // \"queryInfo\":{\"dataAccessId\":\"olapQuery\",\"query\":\"some query\",\"cdaSettingsId\":\"testing/testeMdxCat
    // .cda\",\"parameters\":{}}}}");
    //      PushWarningsHandler h = new PushWarningsHandler();
    //      writeOut(out, h.call(event).toString(2));
    //    }
    private void callCDE(String file, OutputStream out) throws UnsupportedEncodingException, IOException {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("solution", "system");
        params.put("path", "cdv/presentation/");
        params.put("file", file);
        params.put("absolute", "false");
        params.put("inferScheme", "false");

        IParameterProvider requestParams = getRequestParameters();
        PluginUtils.copyParametersFromProvider(params, WrapperUtils.wrapParamProvider(requestParams));

        if (requestParams.hasParameter("mode")
                && requestParams.getStringParameter("mode", "Render").equals("edit")) {
            redirectToCdeEditor(out, params);
            return;
        }

        InterPluginCall pluginCall = new InterPluginCall(InterPluginCall.CDE, "Render", params);
        pluginCall.setResponse(getResponse());
        pluginCall.setOutputStream(out);
        pluginCall.run();
    }

    private void redirectToCdeEditor(OutputStream out, Map<String, Object> params) throws IOException {

        StringBuilder urlBuilder = new StringBuilder();
        urlBuilder.append("../pentaho-cdf-dd/edit");
        if (params.size() > 0) {
            urlBuilder.append("?");
        }

        List<String> paramArray = new ArrayList<String>();
        for (String key : params.keySet()) {
            Object value = params.get(key);
            if (value instanceof String) {
                paramArray.add(key + "=" + URLEncoder.encode((String) value, getEncoding()));
            }
        }

        urlBuilder.append(StringUtils.join(paramArray, "&"));
        redirect(urlBuilder.toString());
    }

    @Override
    public RestRequestHandler getRequestHandler() {
        return Router.getBaseRouter();
    }

    @Exposed(accessLevel = AccessLevel.PUBLIC, outputType = MimeTypes.JSON)
    public void about(OutputStream out) throws IOException, JSONException {
        renderInCde(out, getRenderRequestParameters("cdvAbout.wcdf"));

    }

    private Map<String, Object> getRenderRequestParameters(String dashboardName) {
        Map<String, Object> params = new HashMap<String, Object>();
        params.put("solution", "system");
        params.put("path", UI_PATH);
        params.put("file", dashboardName);
        params.put("bypassCache", "true");
        params.put("absolute", "true");
        params.put("inferScheme", "true");
        params.put("root", getRoot());

        //add request parameters
        ServletRequest request = getRequest();
        @SuppressWarnings("unchecked") //should always be String
        Enumeration<String> originalParams = request.getParameterNames();
        // Iterate and put the values there
        while (originalParams.hasMoreElements()) {
            String originalParam = originalParams.nextElement();
            params.put(originalParam, request.getParameter(originalParam));
        }

        return params;
    }

    private void renderInCde(OutputStream out, Map<String, Object> params) throws IOException {
        InterPluginCall pluginCall = new InterPluginCall(InterPluginCall.CDE, "Render", params);
        pluginCall.setResponse(getResponse());
        pluginCall.setOutputStream(out);
        pluginCall.run();
    }

    private String getRoot() {

        ServletRequest wrapper = getRequest();
        String root = wrapper.getServerName() + ":" + wrapper.getServerPort();

        return root;
    }

    @Exposed(accessLevel = AccessLevel.PUBLIC)
    public void checkVersion(OutputStream out) throws IOException, JSONException {
        writeOut(out, getVersionChecker().checkVersion());
    }

    /*@Exposed( accessLevel = AccessLevel.PUBLIC )
    public void refreshNotifications( OutputStream out ) throws IOException, JSONException {
      writeOut( out, getVersionChecker().checkVersion() );
    }  */

    @Exposed(accessLevel = AccessLevel.PUBLIC)
    public void getVersion(OutputStream out) throws IOException, JSONException {
        writeOut(out, getVersionChecker().getVersion());
    }

    public VersionChecker getVersionChecker() {
        return new VersionChecker(CdvConfig.getConfig()) {

            @Override
            protected String getVersionCheckUrl(VersionChecker.Branch branch) {
                switch (branch) {
                case TRUNK:
                    return "http://ci.pentaho.com/job/pentaho-cdv-pentaho/lastSuccessfulBuild/artifact/"
                            + "cdv-pentaho/dist/marketplace.xml";
                case STABLE:
                    return "http://ci.pentaho"
                            + ".com/job/pentaho-cdv-release/lastSuccessfulBuild/artifact/cdv-pentaho/dist/marketplace.xml";
                default:
                    return null;
                }

            }

        };
    }

}