com.magnet.plugin.r2m.generator.Generator.java Source code

Java tutorial

Introduction

Here is the source code for com.magnet.plugin.r2m.generator.Generator.java

Source

/*
 * Copyright (c) 2014 Magnet Systems, Inc.
 * All rights reserved.
 *
 * 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.magnet.plugin.r2m.generator;

import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.progress.ProgressIndicator;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.magnet.plugin.r2m.api.models.ApiMethodModel;
import com.magnet.plugin.r2m.api.models.RequestHeaderModel;
import com.magnet.plugin.r2m.helpers.ControllerHistoryManager;
import com.magnet.plugin.r2m.helpers.FileHelper;
import com.magnet.plugin.common.Logger;
import com.magnet.plugin.r2m.helpers.RestByExampleKeywords;
import com.magnet.plugin.r2m.messages.R2MMessages;
import com.magnet.plugin.r2m.project.CacheManager;
import com.magnet.plugin.r2m.project.ProjectManager;
import com.magnet.tools.cli.simple.SimpleGenCommand;
import org.apache.commons.io.FileUtils;
import org.apache.commons.lang.exception.ExceptionUtils;

import javax.swing.*;
import java.io.File;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;

/**
 * Captures all generation operation
 */
public class Generator {

    private final Project project;
    private final String packageName;
    private final String controllerName;
    private final CacheManager cacheManager;

    public Generator(Project project, String packageName, String controllerName) {
        this.project = project;
        this.packageName = packageName;
        this.controllerName = controllerName;
        this.cacheManager = new CacheManager(project, packageName, controllerName);
    }

    /**
     * Create a method file in the cache dir (not in the project directory yet)
     * @param methodModel method model
     */
    public void createMethodFile(ApiMethodModel methodModel) {
        PrintWriter writer = null;
        try {
            File dir = cacheManager.getControllerExamplesFolder();
            if (!dir.exists() && !dir.mkdirs()) {
                Logger.error("Couldn't generate " + dir);
            }
            String methodName = methodModel.getRequestModel().getMethodName();
            File methodFile = new File(dir, methodName + CacheManager.EXAMPLE_FILE_EXTENSION);

            writer = new PrintWriter(methodFile, "UTF-8");

            // +Name section
            writer.println(RestByExampleKeywords.NAME_TOKEN + " " + methodName);
            writer.println();

            // +Request section
            writer.println(RestByExampleKeywords.REQUEST_TOKEN);
            writer.println(methodModel.getRequestModel().getHttpMethod().toString() + " "
                    + methodModel.getRequestModel().getTemplateUrl());

            // +Headers request sub-section
            writer.println(RestByExampleKeywords.HEADERS_TOKEN);
            for (RequestHeaderModel header : methodModel.getRequestModel().getHeaders()) {
                writer.println(header.getName() + " : " + header.getValue());
            }

            // +Body request sub-section
            writer.println(RestByExampleKeywords.BODY_TOKEN);
            String body = methodModel.getRequestModel().getRequest();
            if (!body.isEmpty()) {
                writer.println(body);
            }
            writer.println();

            //+Response section
            writer.println(RestByExampleKeywords.RESPONSE_TOKEN);

            //+Body response sub-section
            writer.println(RestByExampleKeywords.BODY_TOKEN);
            writer.println(methodModel.getResponseModel().getBody());

            Logger.info(Generator.class, "Created cached method definition : " + methodFile);
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (writer != null) {
                writer.close();
            }
        }
    }

    /**
     * Generate code and method specifications in cache directory (not in project directory yet)
     * @param progressIndicator UI progress indicator
     */
    public void generate(ProgressIndicator progressIndicator) throws Exception {
        try {
            File tempDirPath = cacheManager.getControllerExamplesFolder();
            File codeDirPath = cacheManager.getControllerSourceFolder();

            // Use a list rather than a string to handle command arguments with whitespaces
            List<String> cmdArgs = new ArrayList<String>();
            cmdArgs.add("-f"); // delete target directory if it already exists
            cmdArgs.add("-e");
            cmdArgs.add(tempDirPath.getAbsolutePath());
            //            cmdArgs.add("-v"); // verbose mode
            //            cmdArgs.add("-t"); // tracing mode
            cmdArgs.add("-c");
            cmdArgs.add(controllerName);
            cmdArgs.add("-o");
            cmdArgs.add(codeDirPath.getAbsolutePath());
            //empty json property policy
            cmdArgs.add("-j");
            cmdArgs.add("ignore");
            //generate unit test
            //cmdArgs.add("-u");
            if (!packageName.trim().isEmpty()) {
                cmdArgs.add("-p");
                cmdArgs.add(packageName);
            }
            cmdArgs.add("android");

            //displayIndicatorMessage(progressIndicator, "Generating code...", 40);
            StringBuilder sb = new SimpleGenCommand().execute(cmdArgs);
            Logger.info(FileHelper.class, sb.toString());
        } catch (Exception e) {
            Logger.error(FileHelper.class, "Generation failed with exception");
            Logger.error(FileHelper.class, ExceptionUtils.getStackTrace(e));
            throw e;

        }
    }

    public void makeFilePerformance(ProgressIndicator progressIndicator) {
        progressIndicator.setFraction(0.1);
        try {
            File cachedSourceFolder = cacheManager.getControllerSourceFolder();

            // copy test files
            File generatedTestFiles = new File(cachedSourceFolder, CacheManager.RELATIVE_TEST_DIR);
            File targetTestFolder = ProjectManager.getTestSourceFolderFile(project);
            if (generatedTestFiles.exists()) {
                if (targetTestFolder != null && targetTestFolder.exists()) {
                    // if test filename exists, copy the test into a fileName_latest.java test
                    List<String> testFiles = FileHelper.getCommonTestFiles(project, controllerName, packageName);
                    String fileName = testFiles == null || testFiles.size() == 0 ? null : testFiles.get(0); // assuming one test class
                    if (fileName == null || !fileName.endsWith(".java")) {
                        FileUtils.copyDirectory(generatedTestFiles, targetTestFolder);
                    } else {
                        String newFileName = fileName + ".latest";
                        String header = R2MMessages.getMessage("LATEST_TEST_CLASS_HEADER",
                                fileName.substring(fileName.lastIndexOf('/') + 1));
                        File newFile = new File(generatedTestFiles, newFileName);
                        File oldFile = new File(generatedTestFiles, fileName);
                        String content = FileUtils.readFileToString(oldFile);
                        FileUtils.write(newFile, header);
                        FileUtils.write(newFile, content, true);
                        FileUtils.forceDelete(oldFile);
                        FileUtils.copyDirectory(generatedTestFiles, targetTestFolder);
                    }
                }
                // TODO: the src directory can be confusing, it should be called test,or tests as with ios.
                File rootTestDirectory = new File(cachedSourceFolder, "src");
                FileUtils.deleteDirectory(rootTestDirectory);
            }

            // copy others
            FileUtils.copyDirectory(cachedSourceFolder, ProjectManager.getSourceFolderFile(project));
            ControllerHistoryManager.saveController(project, cacheManager.getControllerFolder().getName());
            File controllerFile = ProjectManager.getControllerFile(project, packageName, controllerName);
            if (null != controllerFile) {
                showControllerFile(controllerFile);
            }
            //displayIndicatorMessage(progressIndicator, "Completed generation", 100);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * Show file in editor
     * @param file file to show
     */
    private void showControllerFile(final File file) {
        //need to be in main dispatcher thread
        SwingUtilities.invokeLater(new Runnable() {
            @Override
            public void run() {
                VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
                if (vFile == null) {
                    return; // do nothing
                }
                FileEditorManager.getInstance(project).openFile(vFile, true);
            }
        });

    }

    // TODO: disabled wherever we call it, somehow the progress indicator is not showing up,
    // TODO: but that's alright because generation is quasi instantaneous
    private static void displayIndicatorMessage(ProgressIndicator progressIndicator, String message, int value)
            throws InterruptedException {
        if (null == progressIndicator) {
            return;
        }
        progressIndicator.setFraction((((double) value) / 100));
        progressIndicator.setText(message);
        Thread.sleep(1000);
    }

}