com.iyonger.apm.web.handler.ScriptHandler.java Source code

Java tutorial

Introduction

Here is the source code for com.iyonger.apm.web.handler.ScriptHandler.java

Source

/* 
 * 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 com.iyonger.apm.web.handler;

import com.iyonger.apm.web.configuration.constant.ControllerConstants;
import com.iyonger.apm.web.model.FileEntry;
import com.iyonger.apm.web.model.FileType;
import com.iyonger.apm.web.repository.FileEntryRepository;
import com.iyonger.apm.web.util.FileUtils;
import freemarker.template.Configuration;
import freemarker.template.DefaultObjectWrapper;
import freemarker.template.Template;
import org.apache.commons.io.FilenameUtils;
import org.ngrinder.common.util.PathUtils;
import org.ngrinder.common.util.PropertiesWrapper;
import org.ngrinder.model.User;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;

import java.io.File;
import java.io.StringWriter;
import java.util.*;

import static org.apache.commons.lang.StringUtils.startsWithIgnoreCase;
import static org.ngrinder.common.util.CollectionUtils.newArrayList;
import static org.ngrinder.common.util.ExceptionUtils.processException;

/**
 * Script per language handler. This is the superclass for all sub
 * {@link ScriptHandler}s which implements the specific processing of each
 * language.
 *
 * @author JunHo Yoon
 * @since 3.2
 */
public abstract class ScriptHandler implements ControllerConstants {
    protected static final Logger LOGGER = LoggerFactory.getLogger(JythonScriptHandler.class);
    private final String codemirrorKey;
    private final String title;
    private final String extension;
    private final String key;

    /**
     * Constructor.
     *
     * @param key           key of the script handler
     * @param extension     extension
     * @param title         title of the handler
     * @param codeMirrorKey code mirror key
     */
    public ScriptHandler(String key, String extension, String title, String codeMirrorKey) {
        this.key = key;
        this.extension = extension;
        this.title = title;
        this.codemirrorKey = codeMirrorKey;
    }

    @Autowired
    private FileEntryRepository fileEntryRepository;

    /**
     * Get the display order of {@link ScriptHandler}s.
     *
     * @return order
     */
    public abstract Integer displayOrder();

    public String getCodemirrorKey() {
        return codemirrorKey;
    }

    /**
     * Check if the given fileEntry can be handled by this handler.
     *
     * @param fileEntry fileEntry to be checked
     * @return true if the given fileEntry can be handled
     */
    public boolean canHandle(FileEntry fileEntry) {
        return FilenameUtils.isExtension(fileEntry.getPath(), getExtension());
    }

    public String getExtension() {
        return extension;
    }

    /**
     * Get the handler resolution order.
     * <p/>
     * Less is more prioritized.
     *
     * @return the order of handler resolution
     */
    protected abstract Integer order();

    @SuppressWarnings("SpellCheckingInspection")
    public boolean isValidatable() {
        return true;
    }

    /**
     * Return if it's project handler which implements {@link ProjectsHandler}.
     *
     * @return true if it is.
     */

    @SuppressWarnings("UnusedDeclaration")
    public boolean isProjectHandler() {
        return (this instanceof ProjectHandler);
    }

    /**
     * Prepare the distribution.
     *
     * @param testCaseId       id of the test case. This is for the log identification.
     * @param user             user who will distribute the script.
     * @param scriptEntry      script to be distributed.
     * @param distDir          distribution target dir.
     * @param properties       properties set which is used for detailed distribution control.
     * @param processingResult processing result holder.
     */
    public void prepareDist(Long testCaseId, User user, //
            FileEntry scriptEntry, File distDir, PropertiesWrapper properties,
            ProcessingResultPrintStream processingResult) {
        prepareDefaultFile(distDir, properties);
        List<FileEntry> fileEntries = getLibAndResourceEntries(user, scriptEntry, -1);
        if (scriptEntry.getRevision() != 0) {
            fileEntries.add(scriptEntry);
        }
        String basePath = getBasePath(scriptEntry);
        // Distribute each files in that folder.
        for (FileEntry each : fileEntries) {
            // Directory is not subject to be distributed.
            if (each.getFileType() == FileType.DIR) {
                continue;
            }
            File toDir = new File(distDir, calcDistSubPath(basePath, each));
            processingResult.printf("%s is being written.\n", each.getPath());
            LOGGER.info("{} is being written in {} for test {}",
                    new Object[] { each.getPath(), toDir, testCaseId });
            getFileEntryRepository().writeContentTo(user, each.getPath(), toDir);
        }
        processingResult.setSuccess(true);
        prepareDistMore(testCaseId, user, scriptEntry, distDir, properties, processingResult);
    }

    /**
     * Prepare script creation. This method is subject to be extended by the
     * subclasses.
     * <p/>
     * This method is the perfect place if it's necessary to include additional
     * files.
     *
     * @param user                  user
     * @param path                  base path
     * @param fileName              fileName
     * @param name                  name
     * @param url                   url
     * @param createLibAndResources true if lib and resources should be created
     * @return true if process more.
     */
    public boolean prepareScriptEnv(User user, String path, String fileName, String name, String url,
            boolean createLibAndResources, String scriptContent) {
        return true;
    }

    /**
     * Prepare the distribution more. This method is subject to be extended by
     * the subclass.
     *
     * @param testCaseId       test case id. This is for the log identification.
     * @param user             user
     * @param script           script entry to be distributed.
     * @param distDir          distribution directory
     * @param properties       properties
     * @param processingResult processing result holder
     */
    protected void prepareDistMore(Long testCaseId, User user, FileEntry script, File distDir,
            PropertiesWrapper properties, ProcessingResultPrintStream processingResult) {
    }

    /**
     * Get the appropriated distribution path for the given file entry.
     *
     * @param basePath  distribution base path
     * @param fileEntry fileEntry to be distributed
     * @return the resolved destination path.
     */
    protected String calcDistSubPath(String basePath, FileEntry fileEntry) {
        String path = FilenameUtils.getPath(fileEntry.getPath());
        path = path.substring(basePath.length());
        return path;
    }

    /**
     * Get all resources and lib entries belonging to the given user and
     * scriptEntry.
     *
     * @param user        user
     * @param scriptEntry script entry
     * @param revision    revision of the script entry.
     * @return file entry list
     */
    public List<FileEntry> getLibAndResourceEntries(User user, FileEntry scriptEntry, long revision) {
        String path = FilenameUtils.getPath(scriptEntry.getPath());
        List<FileEntry> fileList = newArrayList();
        for (FileEntry eachFileEntry : getFileEntryRepository().findAll(user, path + "lib/", revision, true)) {
            // Skip jython 2.5... it's already included.
            if (startsWithIgnoreCase(eachFileEntry.getFileName(), "jython-2.5.")
                    || startsWithIgnoreCase(eachFileEntry.getFileName(), "jython-standalone-2.5.")) {
                continue;
            }
            FileType fileType = eachFileEntry.getFileType();
            if (fileType.isLibDistributable()) {
                fileList.add(eachFileEntry);
            }
        }
        for (FileEntry eachFileEntry : getFileEntryRepository().findAll(user, path + "resources/", revision,
                true)) {
            FileType fileType = eachFileEntry.getFileType();
            if (fileType.isResourceDistributable()) {
                fileList.add(eachFileEntry);
            }
        }
        return fileList;
    }

    protected void prepareDefaultFile(File distDir, PropertiesWrapper properties) {
        if (properties.getPropertyBoolean(PROP_CONTROLLER_DIST_LOGBACK)) {
            FileUtils.copyResourceToFile("/logback/logback-worker.xml", new File(distDir, "logback-worker.xml"));
        }
    }

    protected String getBasePath(FileEntry script) {
        return getBasePath(script.getPath());
    }

    /**
     * Get the base path of the given path.
     *
     * @param path path
     * @return base path
     */
    public String getBasePath(String path) {
        return FilenameUtils.getPath(path);
    }

    /**
     * Get executable script path.
     *
     * @param svnPath path in svn
     * @return path executable in agent.
     */
    public String getScriptExecutePath(String svnPath) {
        return FilenameUtils.getName(svnPath);
    }

    /**
     * Check syntax errors for the given content.
     *
     * @param path    path
     * @param content content
     * @return syntax error messages. null if none.
     */
    public abstract String checkSyntaxErrors(String path, String content);

    /**
     * Get the initial script with the given value map.
     *
     * @param values map of initial script referencing values.
     * @return generated string
     */
    /*public String getScriptTemplate(Map<String, Object> values) {
       try {
     Configuration freemarkerConfig = new Configuration();
     ClassPathResource cpr = new ClassPathResource("script_template");
     freemarkerConfig.setDirectoryForTemplateLoading(cpr.getFile());
     freemarkerConfig.setObjectWrapper(new DefaultObjectWrapper());
     Template template = freemarkerConfig.getTemplate("basic_template_" + getExtension() + ".ftl");
     StringWriter writer = new StringWriter();
     template.process(values, writer);
     return writer.toString();
       } catch (Exception e) {
     throw processException("Error while fetching the script template.", e);
       }
    }*/
    public String getScriptTemplate(Map<String, Object> values) {
        try {
            Configuration freemarkerConfig = new Configuration();
            ClassPathResource cpr = new ClassPathResource("script_template");
            freemarkerConfig.setDirectoryForTemplateLoading(cpr.getFile());
            freemarkerConfig.setObjectWrapper(new DefaultObjectWrapper());
            Template template = freemarkerConfig.getTemplate("basic_template_" + getExtension() + ".ftl");
            StringWriter writer = new StringWriter();
            template.process(values, writer);
            return writer.toString();
        } catch (Exception e) {
            throw processException("Error while fetching the script template.", e);
        }

    }

    public String getTitle() {
        return title;
    }

    public String getKey() {
        return key;
    }

    FileEntryRepository getFileEntryRepository() {
        return fileEntryRepository;
    }

    void setFileEntryRepository(FileEntryRepository fileEntryRepository) {
        this.fileEntryRepository = fileEntryRepository;
    }

    /**
     * Get the default quick test file.
     *
     * @param basePath base path
     * @return quick test file
     */
    public FileEntry getDefaultQuickTestFilePath(String basePath) {
        FileEntry fileEntry = new FileEntry();
        fileEntry.setPath(PathUtils.join(basePath, "TestRunner." + getExtension()));
        return fileEntry;
    }
}