Java tutorial
/* * Blackwater-S - Server Interface * Copyright (C) 2014-2015 Hugo MIARD * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package com.hmiard.blackwater.projects; import com.hmiard.blackwater.Start; import com.hmiard.blackwater.screens.NewProjectAppScreen.NewProjectAppScreenPresenter; import com.hmiard.blackwater.utils.ChildProcess; import com.hmiard.blackwater.utils.ConsoleEmulator; import com.hmiard.blackwater.utils.Parser; import org.apache.commons.io.FileUtils; import org.codehaus.jettison.json.JSONException; import org.codehaus.jettison.json.JSONObject; import java.awt.*; import java.io.*; import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.nio.file.Paths; import java.util.ArrayList; import java.util.Date; import java.util.Properties; import java.util.Random; public class Builder { /** * Building a new project. * * @param projectName String * @param serverNames ArrayList * @param location String */ public static void buildNewProject(String projectName, ArrayList<String> serverNames, String location, ConsoleEmulator consoleListener) { try { consoleListener.clean(); consoleListener.push("Project creation started...\n\n"); projectName = projectName.substring(0, 1).toUpperCase() + projectName.substring(1); String projectUrl = location + "\\" + projectName; buildFolder(projectUrl); buildFolder(projectUrl + "\\bin"); buildFolder(projectUrl + "\\src"); buildFolder(projectUrl + "\\.blackwater"); ArrayList<String> realServerNames = new ArrayList<>(); for (String name : serverNames) realServerNames.add(name.replace("!", "")); // Creating the configuration Properties configuration = new Properties(); File tokens = new File(projectUrl + "\\.blackwater\\tokens.properties"); configuration.setProperty("PATH", projectUrl); configuration.setProperty("NAME", projectName); configuration.setProperty("SERVERS", Parser.parseArrayToStringList(",", realServerNames)); configuration.setProperty("LAST_UPDATE", new Date().toString()); configuration.store(new FileOutputStream(tokens), "Blackwater build version : " + Start.VERSION); consoleListener.push("Tokens generated.\n"); // Creating composer.json... JSONObject composerJSON = new JSONObject(); JSONObject autoload = new JSONObject(); JSONObject psr0 = new JSONObject(); JSONObject require = new JSONObject(); autoload.put("psr-0", psr0); composerJSON.put("autoload", autoload); composerJSON.put("require", require); require.put("blackwater/blackwaterp", Start.blackwaterpVersion); File composer = new File(projectUrl + "\\composer.json"); if (!composer.createNewFile()) { consoleListener.push("\nWeird composer stuff happened... Aborting.\n"); return; } BufferedWriter cw = new BufferedWriter(new FileWriter(composer.getAbsoluteFile())); String content = composerJSON.toString(4).replaceAll("\\\\", ""); cw.write(content); cw.close(); consoleListener.push("File created : composer.json\n"); // Creating the servers... consoleListener.push("Server creation started...\n"); for (String name : serverNames) if (name.charAt(0) == '!') appendServer(projectUrl, name.replace("!", ""), consoleListener, false); else appendServer(projectUrl, name, consoleListener, true); // Copying composer.phar consoleListener.push("Installing local composer wrapper...\n"); copyFile(new File("resources/packages/composer.phar"), new File(composer.getParent() + "\\bin\\composer.phar")); // Building... consoleListener.push("Building dependencies...\n"); new Thread(new ChildProcess("php bin/composer.phar install", composer.getParentFile(), consoleListener, () -> { NewProjectAppScreenPresenter presenter = (NewProjectAppScreenPresenter) consoleListener.app; presenter.projectCreatedCallback(projectUrl, consoleListener); })).start(); } catch (JSONException | IOException e) { e.printStackTrace(); } } /** * Appending a new server to a project. * * @param projectRoot String * @param serverName String * @param consoleListener ConsoleEmulator * @param needsDb Boolean */ public static Boolean appendServer(String projectRoot, String serverName, ConsoleEmulator consoleListener, Boolean needsDb) { try { serverName = serverName.substring(0, 1).toUpperCase() + serverName.substring(1).toLowerCase(); String shortServerName = serverName; serverName += "Server"; String src = projectRoot + "\\src\\" + serverName; File checker = new File(projectRoot + "\\src\\" + serverName); File composerJSON = new File(projectRoot + "\\composer.json"); if (checker.exists() && checker.isDirectory()) { consoleListener.push("This server already exists ! Operation aborted."); return false; } if (!composerJSON.exists()) { consoleListener.push("File composer.json is missing ! Operation aborted."); return false; } if (needsDb) copyFolder(new File("resources/packages/DefaultApp"), new File(src)); else copyFolder(new File("resources/packages/NoDbApp"), new File(src)); FileOutputStream writer; File core = new File(src + "\\BlackwaterDefaultApp.php"); File qf = new File(src + "\\DefaultAppQueryFactory.php"); File bootstrap = new File(src + "\\bin\\init.php"); String coreContent = readFile(core.getAbsolutePath()); coreContent = coreContent.replace("BlackwaterDefaultApp", serverName); File newCore = new File(src + "\\" + serverName + ".php"); if (newCore.createNewFile() && core.delete()) { writer = new FileOutputStream(newCore); writer.write(coreContent.getBytes()); writer.flush(); writer.close(); } if (needsDb) { String qfContent = readFile(qf.getAbsolutePath()); qfContent = qfContent.replace("BlackwaterDefaultApp", serverName); qfContent = qfContent.replace("DefaultApp", shortServerName); File newQf = new File(src + "\\" + shortServerName + "QueryFactory.php"); if (newQf.createNewFile() && qf.delete()) { writer = new FileOutputStream(newQf); writer.write(qfContent.getBytes()); writer.flush(); writer.close(); } } String bootsrapContent = readFile(bootstrap.getAbsolutePath()); Random r = new Random(); bootsrapContent = bootsrapContent.replace("Default", shortServerName); bootsrapContent = bootsrapContent.replace("8080", String.valueOf(r.nextInt(2000) + 7000)); writer = new FileOutputStream(bootstrap); writer.write(bootsrapContent.getBytes()); writer.flush(); writer.close(); JSONObject composer = new JSONObject(readFile(composerJSON.getAbsolutePath())); JSONObject autoload = composer.getJSONObject("autoload"); JSONObject psr0 = autoload.getJSONObject("psr-0"); psr0.put(serverName, "src"); BufferedWriter cw = new BufferedWriter(new FileWriter(composerJSON.getAbsoluteFile())); String content = composer.toString(4).replaceAll("\\\\", ""); cw.write(content); cw.close(); consoleListener.push(serverName + " created !\n"); } catch (JSONException | IOException e) { e.printStackTrace(); } return true; } /** * Deleting a server from a project. * * @param projectRoot String * @param serverName String * @param listener ConsoleEmulator * @return Boolean */ public static Boolean deleteServer(String projectRoot, String serverName, ConsoleEmulator listener) { serverName = serverName.substring(0, 1).toUpperCase() + serverName.substring(1).toLowerCase(); serverName += "Server"; File checker = new File(projectRoot + "\\src\\" + serverName); File composerJSON = new File(projectRoot + "\\composer.json"); if (!checker.exists()) { listener.push("This server is missing ! Operation aborted."); return false; } if (!composerJSON.exists()) { listener.push("File composer.json is missing ! Operation aborted."); return false; } try { FileUtils.deleteDirectory(checker); if (checker.exists()) { listener.push("Woops ! It seems impossible to delete " + checker.getAbsolutePath()); return false; } JSONObject composer = new JSONObject(readFile(composerJSON.getAbsolutePath())); JSONObject autoload = composer.getJSONObject("autoload"); JSONObject psr0 = autoload.getJSONObject("psr-0"); psr0.remove(serverName); BufferedWriter cw = new BufferedWriter(new FileWriter(composerJSON.getAbsoluteFile())); String content = composer.toString(4).replaceAll("\\\\", ""); cw.write(content); cw.close(); listener.push("\n" + serverName + " was deleted successfully !\n"); } catch (JSONException | IOException e) { e.printStackTrace(); } return true; } /** * Simple directory creation ; * won't erase the existing directory if it already exists. * * @param url String */ public static void buildFolder(String url) { File folder = new File(url); if (folder.exists() && folder.isDirectory()) { Start.displayWarning("The directory " + url + " already exists !"); return; } if (!folder.mkdir()) System.out.println("Cannot create the following folder : " + url); } /** * Copying a file by 1/2 Mo blocks * * @param src File * @param dest File * @return Boolean */ public static Boolean copyFile(File src, File dest) { try { try (FileInputStream sourceFile = new FileInputStream(src)) { FileOutputStream destinationFile = null; try { destinationFile = new FileOutputStream(dest); byte buffer[] = new byte[512 * 1024]; int n; while ((n = sourceFile.read(buffer)) != -1) { destinationFile.write(buffer, 0, n); } } finally { if (destinationFile != null) destinationFile.close(); } } } catch (IOException e) { e.printStackTrace(); return false; } return true; } /** * Recursively copying a folder. * * @param src File * @param dest File * @throws IOException */ public static void copyFolder(File src, File dest) throws IOException { if (src.isDirectory()) { if (!dest.exists()) dest.mkdir(); String files[] = src.list(); for (String file : files) copyFolder(new File(src, file), new File(dest, file)); } else { InputStream in = new FileInputStream(src); OutputStream out = new FileOutputStream(dest); byte[] buffer = new byte[1024]; int length; while ((length = in.read(buffer)) > 0) out.write(buffer, 0, length); in.close(); out.close(); } } /** * Utility fonction. Return an UTF-8 encoded string from a file. * * @param path String * @return String * @throws IOException */ public static String readFile(String path) throws IOException { byte[] encoded = Files.readAllBytes(Paths.get(path)); return new String(encoded, StandardCharsets.UTF_8); } /** * Asking the OS to open a directory or a file. * * @param path String * @throws IOException */ public static void openPath(String path) throws IOException { if (Desktop.isDesktopSupported()) { Desktop.getDesktop().open(new File(path)); } } }