net.mindengine.blogix.BlogixMain.java Source code

Java tutorial

Introduction

Here is the source code for net.mindengine.blogix.BlogixMain.java

Source

/*******************************************************************************
* Copyright 2013 Ivan Shubin http://mindengine.net
* 
* 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 net.mindengine.blogix;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.net.URISyntaxException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;

import net.mindengine.blogix.compiler.BlogixCompiler;
import net.mindengine.blogix.config.BlogixConfig;
import net.mindengine.blogix.export.Exporter.BlogixExporter;
import net.mindengine.blogix.web.BlogixServer;

import org.apache.commons.io.FileUtils;
import org.apache.commons.io.IOUtils;

public class BlogixMain {

    private static final Object NO_INSTANCE = null;
    private static final String _BLOGIX_SUFFIX = ".blogix";

    private static Method findCommandMethod(String name) {
        Method[] methods = BlogixMain.class.getDeclaredMethods();
        for (Method method : methods) {
            if (Modifier.isStatic(method.getModifiers()) && method.getName().equals("cmd_" + name)) {
                return method;
            }
        }
        return null;
    }

    public static void main(String[] args) throws Exception {
        processConsoleCommands(args);
    }

    private static void processConsoleCommands(String[] args)
            throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        if (args.length > 0) {
            invokeCommand(args[0], shift(args));
        } else {
            printGlobalHelp();
        }
    }

    @SuppressWarnings("unused")
    private static void cmd_help(String[] args) {
        if (args.length > 0) {
            printCommandHelp(args[0]);
        } else {
            printGlobalHelp();
        }
    }

    private static void printCommandHelp(String command) {
        try {
            info(IOUtils.toString(BlogixMain.class.getResourceAsStream("/help-command-" + command + ".txt")));
        } catch (Exception e) {
            info("There is no command \"" + command + "\"");
            System.exit(1);
        }
    }

    private static void printGlobalHelp() {
        try {
            info(IOUtils.toString(BlogixMain.class.getResourceAsStream("/help.txt")));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @SuppressWarnings("unused")
    private static void cmd_export(String[] args) throws IOException, URISyntaxException {
        String dest = "export";
        if (args.length > 0) {
            dest = args[0];
        }

        File destinationDir = new File(dest);
        if (!destinationDir.exists()) {
            destinationDir.mkdirs();
        }
        BlogixExporter exporter = new BlogixExporter(destinationDir);
        info("Exporting all routes to \"" + dest + "\"");

        File publicDir = new File("public");
        if (publicDir.exists()) {
            File publicExportDir = new File(destinationDir.getAbsolutePath() + File.separator + "public");
            publicExportDir.mkdir();
            FileUtils.copyDirectory(publicDir, publicExportDir);
        }
        exporter.exportAll();
    }

    @SuppressWarnings("unused")
    private static void cmd_compile() {
        BlogixCompiler compiler = new BlogixCompiler();
        File sourceDir = new File("src");
        if (!sourceDir.exists()) {
            throw new RuntimeException("There is no src folder");
        }
        compiler.setSourceDir(sourceDir);

        File binDir = new File("bin");
        if (!binDir.exists()) {
            binDir.mkdirs();
        }
        compiler.setClassesDir(binDir);

        info("Compiling project...");
        compiler.compile();
    }

    @SuppressWarnings("unused")
    private static void cmd_run() throws Exception {
        BlogixServer server = new BlogixServer();
        server.setPort(BlogixConfig.getConfig().getBlogixServerPort());
        info("Launching blogix web server...");
        server.startServer();
    }

    @SuppressWarnings("unused")
    private static void cmd_show(String entryType) {
        File fileDir = new File("db" + File.separator + entryType);
        if (fileDir.exists() && fileDir.isDirectory()) {
            File[] files = fileDir.listFiles();
            for (File file : files) {
                if (file.isFile() && file.getName().endsWith(".blogix")) {
                    System.out.println(trimBlogixSuffixFromEntryFileName(file.getName()));
                }
            }
        } else {
            error("There is no such entry type \"" + entryType + "\" in db");
        }
    }

    private static void cmd_init(String websiteType) throws IOException {
        String appPath = getAppPath();
        File templatesDir = new File(appPath + File.separator + "templates");
        if (!templatesDir.exists()) {
            error("Incorrect path to application: " + appPath);
        }

        for (File templateDir : templatesDir.listFiles()) {
            if (templateDir.isDirectory() && templateDir.getName().equals(websiteType)) {
                initWebsiteFromTemplate(templateDir);
                info("Done! Initialized " + websiteType);
                return;
            }
        }
        error("There is no such template: " + websiteType);
    }

    @SuppressWarnings("unused")
    private static void cmd_new(String[] args) throws Exception {
        if (args.length > 1) {
            String entryType = args[0];
            String title = args[1];
            if (entryType.equals("post")) {
                createPost(title);
            } else if (entryType.equals("doc")) {
                createDoc(title);
            } else if (entryType.equals("category")) {
                createCategory(title);
            } else
                error("There is no such entry: " + entryType);
        } else {
            error("Wrong ammount of arguments");
        }
    }

    @SuppressWarnings("unused")
    private static void cmd_delete(String[] args) {
        if (args.length > 1) {
            String entryType = args[0];
            String id = args[1];
            String entryFolder = getEntryFolderForType(entryType);
            if (entryFolderExists(entryFolder)) {
                File entryFile = new File(
                        "db" + File.separator + entryFolder + File.separator + id + _BLOGIX_SUFFIX);
                if (entryFile.exists()) {
                    entryFile.delete();
                    info("Removed " + entryFile.getPath());
                } else
                    error("No such entry '" + id + "' for type '" + entryType + "'");
            } else
                error("There is no such type: " + entryType);

        } else
            error("Not enough arguments");
    }

    @SuppressWarnings("unused")
    private static void cmd_attach(String[] args) throws IOException {
        if (args.length > 2) {
            String entryType = args[0];
            String id = args[1];
            String entryFolder = getEntryFolderForType(entryType);

            if (id.equals("last")) {
                id = getLastEntryInFolder(entryFolder);
            }
            if (entryExists(entryFolder, id)) {
                for (int i = 2; i < args.length; i++) {
                    attachFileToEntry(args[i], entryFolder, id);
                }
            } else
                error("Entry '" + id + "' does not exist in " + entryFolder);

        } else
            error("Not enough arguments");
    }

    private static void attachFileToEntry(String filePath, String entryFolder, String id) throws IOException {
        File fileSrc = new File(filePath);
        if (fileSrc.exists()) {
            String name = fileSrc.getName();
            String destPath = "db" + File.separator + entryFolder + File.separator + id + "." + name;
            File fileDest = new File(destPath);
            FileUtils.copyFile(fileSrc, fileDest);

            info("Attached " + destPath);
        }
    }

    private static boolean entryExists(String entryFolder, String id) {
        return new File("db" + File.separator + entryFolder + File.separator + id + _BLOGIX_SUFFIX).exists();
    }

    //Returns id of entry with the latest creation date
    private static String getLastEntryInFolder(String entryFolder) {
        File folder = new File("db" + File.separator + entryFolder);
        File[] files = folder.listFiles();

        ArrayList<File> entryFiles = new ArrayList<File>();
        for (File file : files) {
            if (file.getName().endsWith(_BLOGIX_SUFFIX)) {
                entryFiles.add(file);
            }
        }
        Collections.sort(entryFiles, byLastModified());
        if (entryFiles.size() > 0) {
            return trimBlogixSuffixFromEntryFileName(entryFiles.get(0).getName());
        }
        error("There are no entries in '" + entryFolder + "'");
        return null;
    }

    private static Comparator<File> byLastModified() {
        return new Comparator<File>() {
            @Override
            public int compare(File fileA, File fileB) {
                int diff = (int) (fileB.lastModified() - fileA.lastModified());
                if (diff == 0) {
                    diff = fileB.getName().compareTo(fileA.getName());
                }
                return diff;
            }
        };
    }

    private static boolean entryFolderExists(String entryFolder) {
        return new File("db" + File.separator + entryFolder).exists();
    }

    private static String getEntryFolderForType(String entryType) {
        if (entryType.endsWith("y")) {
            return entryType.substring(0, entryType.length() - 1) + "ies";
        } else
            return entryType + "s";
    }

    private static void createCategory(String title) throws Exception {
        if (title.isEmpty()) {
            error("Title should not be empty");
        }
        StringBuffer buff = new StringBuffer();
        buff.append("----\n");
        buff.append("name\n");
        buff.append("   ");
        buff.append(title);
        buff.append("\n");

        String fileName = title.toLowerCase().replaceAll("\\s+", " ").replaceAll("\\s", "-");
        String fullPath = "db" + File.separator + "categories" + File.separator + fileName + _BLOGIX_SUFFIX;
        File file = new File(fullPath);
        file.createNewFile();
        FileUtils.writeStringToFile(file, buff.toString());
        info("created " + fullPath);
    }

    private static void createPost(String title) throws Exception {
        String id = blogixDatePrefix() + convertTitleToId(title);
        createPostTo("posts", id, title);
    }

    private static void createDoc(String title) throws Exception {
        createPostTo("docs", convertTitleToId(title), title);
    }

    private static void createPostTo(String folderName, String id, String title) throws Exception {
        if (title.isEmpty()) {
            error("Title should not be empty");
        }
        StringBuffer buff = new StringBuffer();
        buff.append("--------------------------------\n");
        buff.append("title\n");
        buff.append("   ");
        buff.append(title);
        buff.append("\n");
        buff.append("--------------------------------\n");
        buff.append("date\n");
        buff.append("   ");
        buff.append(currentDateInBlogixFormat());
        buff.append("\n");
        buff.append("--------------------------------\n");
        buff.append("allowComments\n");
        buff.append("   true");
        buff.append("\n");
        buff.append("--------------------------------\n");
        buff.append("categories\n");
        buff.append("   \n================================\n");

        String fullPath = "db" + File.separator + folderName + File.separator + id + _BLOGIX_SUFFIX;
        File file = new File(fullPath);
        file.createNewFile();
        FileUtils.writeStringToFile(file, buff.toString());
        info("created " + fullPath);
    }

    private static String convertTitleToId(String title) {
        return title.toLowerCase().replaceAll("[^\\dA-Za-z\\.\\-]", " ").replaceAll("\\s+", "-");
    }

    private static String blogixDatePrefix() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(new Date()) + "-";
    }

    private static Object currentDateInBlogixFormat() {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
        return sdf.format(new Date());
    }

    private static void initWebsiteFromTemplate(File templateDir) throws IOException {
        FileUtils.copyDirectory(templateDir, new File("."));
    }

    private static String getAppPath() {
        String path = System.getProperty("blogix.app.path");
        if (path == null || path.isEmpty()) {
            error("Incorrect invokation. Property blogix.app.path is not specified");
        }
        return path;
    }

    private static void error(String message) {
        info(message);
        System.exit(1);
    }

    private static void info(String text) {
        System.out.println(text);
    }

    private static String[] shift(String[] args) {
        if (args.length > 0) {
            return Arrays.copyOfRange(args, 1, args.length);
        } else
            return new String[0];
    }

    private static void invokeCommand(String name, String[] args)
            throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        Method method = findCommandMethod(name);
        if (method == null) {
            info("Unknown command \"" + name + "\"");
            System.exit(1);
        }

        if (method.getParameterTypes().length == 0) {
            method.invoke(NO_INSTANCE);
        } else {
            invokeCommandWithArguments(method, args);
        }
    }

    private static void invokeCommandWithArguments(Method method, String[] args)
            throws IllegalArgumentException, IllegalAccessException, InvocationTargetException {
        Class<?>[] parameterTypes = method.getParameterTypes();
        if (parameterTypes[0].equals(String.class)) {
            method.invoke(NO_INSTANCE, args[0]);
        } else {
            method.invoke(NO_INSTANCE, new Object[] { args });
        }

    }

    private static String trimBlogixSuffixFromEntryFileName(String name) {
        return name.substring(0, name.length() - 7);
    }
}