Java tutorial
/******************************************************************************* * 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); } }