├── gradle └── wrapper │ ├── gradle-wrapper.jar │ └── gradle-wrapper.properties ├── src └── main │ ├── resources │ ├── CCIS_Icon.png │ ├── Dependencies.json │ ├── log4j2.xml │ └── iwsTemplate.xml │ └── java │ └── covers1624 │ ├── ccintelli │ ├── module │ │ ├── SimpleEntry.java │ │ ├── ModuleEntry.java │ │ ├── OrderEntry.java │ │ ├── LibraryEntry.java │ │ └── Module.java │ ├── gui │ │ ├── GroupNode.java │ │ ├── ModuleNode.java │ │ ├── InformationDialog.java │ │ ├── ProcessingDialog.java │ │ ├── GuiFields.java │ │ ├── CCIntelliSetupConsole.java │ │ └── SetupDialog.java │ ├── util │ │ ├── ATFileFilter.java │ │ ├── EnumLanguageLevel.java │ │ ├── ResourceWalker.java │ │ ├── logging │ │ │ ├── GuiLogAppender.java │ │ │ ├── CCIntelliSetupFileAppender.java │ │ │ └── LogHelper.java │ │ └── Utils.java │ ├── launch │ │ ├── RecentWorkspaceSerializer.java │ │ ├── SetupSerializer.java │ │ └── Launch.java │ └── workspace │ │ ├── WorkspaceGenerator.java │ │ ├── RunConfigGenerator.java │ │ └── ProjectGenerator.java │ ├── launchwrapper │ ├── util │ │ ├── ThreadUtils.java │ │ ├── Triple.java │ │ ├── PairKV.java │ │ └── Downloader.java │ ├── gui │ │ ├── ILauncherDisplay.java │ │ ├── NullLaunchDisplay.java │ │ └── LauncherGui.java │ ├── LaunchHandler.java │ ├── digest │ │ ├── MD5SumCruncher.java │ │ └── MD5Sum.java │ ├── os │ │ └── OSManager.java │ ├── internal │ │ └── PreLauncher.java │ └── LauncherDownloader.java │ └── util │ ├── NodeListIterator.java │ └── XMLUtils.java ├── .gitignore ├── settings.gradle ├── gradlew.bat └── gradlew /gradle/wrapper/gradle-wrapper.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCBProject/CCIntelliSetup/master/gradle/wrapper/gradle-wrapper.jar -------------------------------------------------------------------------------- /src/main/resources/CCIS_Icon.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/TheCBProject/CCIntelliSetup/master/src/main/resources/CCIS_Icon.png -------------------------------------------------------------------------------- /gradle/wrapper/gradle-wrapper.properties: -------------------------------------------------------------------------------- 1 | #Mon Sep 14 12:28:28 PDT 2015 2 | distributionBase=GRADLE_USER_HOME 3 | distributionPath=wrapper/dists 4 | zipStoreBase=GRADLE_USER_HOME 5 | zipStorePath=wrapper/dists 6 | distributionUrl=https\://services.gradle.org/distributions/gradle-2.7-bin.zip 7 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/module/SimpleEntry.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.module; 2 | 3 | /** 4 | * Created by covers1624 on 21/01/2017. 5 | */ 6 | public class SimpleEntry extends OrderEntry { 7 | 8 | protected SimpleEntry(Type type) { 9 | super(type, false, Scope.NONE); 10 | } 11 | } 12 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # exclude all 2 | 3 | /* 4 | 5 | # Include important folders 6 | 7 | # Gradle stuff 8 | !gradle/ 9 | !gradlew 10 | !gradlew.bat 11 | !build.gradle 12 | !build.properties 13 | !settings.gradle 14 | 15 | # Other Files. 16 | !LICENSE 17 | !README.md 18 | 19 | # Include git important files 20 | !.gitmodules 21 | !.gitignore 22 | 23 | # Include Important Folders 24 | !src/ 25 | !libs/ 26 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/gui/GroupNode.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.gui; 2 | 3 | import javax.swing.tree.DefaultMutableTreeNode; 4 | 5 | /** 6 | * Created by brandon3055 on 23/01/2017. 7 | */ 8 | public class GroupNode extends DefaultMutableTreeNode { 9 | public final String group; 10 | 11 | public GroupNode(String group) { 12 | super(group, true); 13 | this.group = group; 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /src/main/java/covers1624/launchwrapper/util/ThreadUtils.java: -------------------------------------------------------------------------------- 1 | package covers1624.launchwrapper.util; 2 | 3 | /** 4 | * Created by covers1624 on 2/16/2016. 5 | */ 6 | public class ThreadUtils { 7 | 8 | public static void hangThread(long millis) { 9 | try { 10 | Thread.sleep(millis); 11 | } catch (InterruptedException e) { 12 | System.err.println("Unable to hang thread..."); 13 | e.printStackTrace(); 14 | } 15 | } 16 | 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/gui/ModuleNode.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.gui; 2 | 3 | import covers1624.ccintelli.module.Module; 4 | 5 | import javax.swing.tree.DefaultMutableTreeNode; 6 | 7 | /** 8 | * Created by brandon3055 on 23/01/2017. 9 | */ 10 | public class ModuleNode extends DefaultMutableTreeNode { 11 | public final Module module; 12 | 13 | public ModuleNode(Module module) { 14 | super(module.NAME, false); 15 | this.module = module; 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/util/ATFileFilter.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.util; 2 | 3 | import org.apache.commons.io.filefilter.AbstractFileFilter; 4 | 5 | import java.io.File; 6 | 7 | /** 8 | * Created by covers1624 on 11/02/2017. 9 | */ 10 | public class ATFileFilter extends AbstractFileFilter { 11 | //TODO, Actually regex the file to see if it is an AT file. 12 | @Override 13 | public boolean accept(File file) { 14 | return file.isFile() && file.getAbsolutePath().endsWith("_at.cfg"); 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /src/main/java/covers1624/launchwrapper/util/Triple.java: -------------------------------------------------------------------------------- 1 | package covers1624.launchwrapper.util; 2 | 3 | /** 4 | * Created by covers1624 on 2/01/2017. 5 | */ 6 | public class Triple { 7 | 8 | private A a; 9 | private B b; 10 | private C c; 11 | 12 | public Triple(A a, B b, C c) { 13 | this.a = a; 14 | this.b = b; 15 | this.c = c; 16 | } 17 | 18 | public A getA() { 19 | return a; 20 | } 21 | 22 | public B getB() { 23 | return b; 24 | } 25 | 26 | public void setC(C c) { 27 | this.c = c; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /src/main/java/covers1624/launchwrapper/gui/ILauncherDisplay.java: -------------------------------------------------------------------------------- 1 | package covers1624.launchwrapper.gui; 2 | 3 | import java.net.URL; 4 | 5 | /** 6 | * Created by covers1624 on 2/15/2016. 7 | */ 8 | public interface ILauncherDisplay { 9 | 10 | void init(); 11 | 12 | void dispose(); 13 | 14 | void resetProgress(int sizeGuess); 15 | 16 | void updateProgress(int fullLength); 17 | 18 | void updateProgressString(String string, Object... data); 19 | 20 | boolean shouldClose(); 21 | 22 | void setPokeThread(Thread thread); 23 | 24 | void onDownloadFail(String file, URL url, Exception e); 25 | 26 | } 27 | -------------------------------------------------------------------------------- /src/main/java/covers1624/launchwrapper/LaunchHandler.java: -------------------------------------------------------------------------------- 1 | package covers1624.launchwrapper; 2 | 3 | import covers1624.launchwrapper.internal.PreLauncher; 4 | 5 | import java.io.File; 6 | import java.io.InputStream; 7 | 8 | /** 9 | * Created by covers1624 on 1/01/2017. 10 | */ 11 | public class LaunchHandler { 12 | 13 | public static void runPreLaunch(String name, InputStream json, File libsDirectory, File nativesDirectory, File cacheStore) { 14 | PreLauncher.runInternal(libsDirectory); 15 | LauncherDownloader.checkDependencies(name, json, libsDirectory, nativesDirectory, cacheStore); 16 | } 17 | 18 | } 19 | -------------------------------------------------------------------------------- /settings.gradle: -------------------------------------------------------------------------------- 1 | /* 2 | * This settings file was auto generated by the Gradle buildInit task 3 | * by 'sunstrike' at '21/11/13 14:14' with Gradle 1.9 4 | * 5 | * The settings file is used to specify which projects to include in your build. 6 | * In a single project build this file can be empty or even removed. 7 | * 8 | * Detailed information about configuring a multi-project build in Gradle can be found 9 | * in the user guide at http://gradle.org/docs/1.9/userguide/multi_project_builds.html 10 | */ 11 | 12 | /* 13 | // To declare projects as part of a multi-project build use the 'include' method 14 | include 'shared' 15 | include 'api' 16 | include 'services:webservice' 17 | */ 18 | 19 | rootProject.name = 'CCIntelliSetup' 20 | -------------------------------------------------------------------------------- /src/main/java/covers1624/launchwrapper/util/PairKV.java: -------------------------------------------------------------------------------- 1 | package covers1624.launchwrapper.util; 2 | 3 | import java.util.Map; 4 | 5 | /** 6 | * Created by covers1624 on 6/13/2016. 7 | */ 8 | public class PairKV implements Map.Entry { 9 | 10 | private K key; 11 | private V value; 12 | 13 | public PairKV(K key, V value) { 14 | this.key = key; 15 | this.value = value; 16 | } 17 | 18 | @Override 19 | public K getKey() { 20 | return key; 21 | } 22 | 23 | @Override 24 | public V getValue() { 25 | return value; 26 | } 27 | 28 | @Override 29 | public V setValue(V value) { 30 | V oldValue = this.value; 31 | this.value = value; 32 | return oldValue; 33 | } 34 | 35 | @Override 36 | public String toString() { 37 | return "Pair: " + key.toString() + " | " + value.toString(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /src/main/java/covers1624/util/NodeListIterator.java: -------------------------------------------------------------------------------- 1 | package covers1624.util; 2 | 3 | import org.w3c.dom.Node; 4 | import org.w3c.dom.NodeList; 5 | 6 | import java.util.Iterator; 7 | 8 | /** 9 | * Created by covers1624 on 28/02/2017. 10 | */ 11 | public class NodeListIterator implements Iterator, Iterable { 12 | 13 | private final NodeList list; 14 | private int index; 15 | 16 | public NodeListIterator(NodeList list) { 17 | this.list = list; 18 | } 19 | 20 | @Override 21 | public boolean hasNext() { 22 | return list != null && index < list.getLength(); 23 | } 24 | 25 | @Override 26 | public Node next() { 27 | Node object = list.item(index); 28 | if (object != null) { 29 | index++; 30 | } 31 | return object; 32 | } 33 | 34 | @Override 35 | public Iterator iterator() { 36 | return this; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /src/main/java/covers1624/launchwrapper/gui/NullLaunchDisplay.java: -------------------------------------------------------------------------------- 1 | package covers1624.launchwrapper.gui; 2 | 3 | import java.net.URL; 4 | 5 | /** 6 | * Created by covers1624 on 1/01/2017. 7 | */ 8 | public class NullLaunchDisplay implements ILauncherDisplay { 9 | 10 | @Override 11 | public void init() { 12 | } 13 | 14 | @Override 15 | public void dispose() { 16 | } 17 | 18 | @Override 19 | public void resetProgress(int sizeGuess) { 20 | } 21 | 22 | @Override 23 | public void updateProgress(int fullLength) { 24 | } 25 | 26 | @Override 27 | public void updateProgressString(String string, Object... data) { 28 | } 29 | 30 | @Override 31 | public boolean shouldClose() { 32 | return false; 33 | } 34 | 35 | @Override 36 | public void setPokeThread(Thread thread) { 37 | } 38 | 39 | @Override 40 | public void onDownloadFail(String file, URL url, Exception e) { 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /src/main/java/covers1624/launchwrapper/digest/MD5SumCruncher.java: -------------------------------------------------------------------------------- 1 | package covers1624.launchwrapper.digest; 2 | 3 | import java.io.File; 4 | import java.io.FileInputStream; 5 | import java.security.MessageDigest; 6 | 7 | /** 8 | * Created by covers1624 on 2/16/2016. 9 | */ 10 | public class MD5SumCruncher { 11 | 12 | public static MD5Sum calculateFileSum(File file) { 13 | MD5Sum sum = null; 14 | try { 15 | MessageDigest messageDigest = MessageDigest.getInstance("MD5"); 16 | FileInputStream fileInputStream = new FileInputStream(file); 17 | int bytesRead; 18 | byte[] smallBuffer = new byte[1024]; 19 | while ((bytesRead = fileInputStream.read(smallBuffer)) != -1) { 20 | messageDigest.update(smallBuffer, 0, bytesRead); 21 | } 22 | fileInputStream.close(); 23 | sum = new MD5Sum(messageDigest.digest()); 24 | } catch (Exception e) { 25 | 26 | } 27 | if (sum == null) { 28 | sum = new MD5Sum("This is a blank MD5 Sum"); 29 | } 30 | return sum; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /src/main/java/covers1624/launchwrapper/digest/MD5Sum.java: -------------------------------------------------------------------------------- 1 | package covers1624.launchwrapper.digest; 2 | 3 | 4 | /** 5 | * Created by covers1624 on 2/15/2016. 6 | */ 7 | public class MD5Sum { 8 | 9 | private String hexString; 10 | 11 | public MD5Sum(byte[] hexBytes) { 12 | StringBuilder stringBuilder = new StringBuilder(); 13 | for (byte hexByte : hexBytes) { 14 | stringBuilder.append(Integer.toString((hexByte & 0xFF) + 0x100, 16).substring(1)); 15 | } 16 | hexString = stringBuilder.toString(); 17 | } 18 | 19 | public MD5Sum(String hexString) { 20 | this.hexString = hexString; 21 | } 22 | 23 | public String getHexString() { 24 | return hexString; 25 | } 26 | 27 | @Override 28 | public String toString() { 29 | return getHexString().toUpperCase(); 30 | } 31 | 32 | @Override 33 | public boolean equals(Object obj) { 34 | if (obj instanceof MD5Sum) { 35 | MD5Sum sum = (MD5Sum) obj; 36 | return sum.toString().equals(toString()); 37 | } 38 | return false; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/resources/Dependencies.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": [ 3 | { 4 | "url": "http://jcenter.bintray.com/com/google/guava/guava/20.0/guava-20.0.jar", 5 | "md5": "F32A8A2524620DBECC9F6BF6A20C293F" 6 | }, 7 | { 8 | "url": "http://jcenter.bintray.com/org/apache/commons/commons-io/1.3.2/commons-io-1.3.2.jar", 9 | "md5": "903C04D1FB5D4DC81D95E4BE93FF7ECD" 10 | }, 11 | { 12 | "url": "http://jcenter.bintray.com/org/apache/commons/commons-compress/1.9/commons-compress-1.9.jar", 13 | "md5": "6C9CE8534B9E4C17E5DEA7A97425245C" 14 | }, 15 | { 16 | "url" : "http://jcenter.bintray.com/org/apache/logging/log4j/log4j-core/2.5/log4j-core-2.5.jar", 17 | "md5" : "DD0E3E0B404083EC69618AABB50B8AC0" 18 | }, 19 | { 20 | "url" : "http://jcenter.bintray.com/org/apache/logging/log4j/log4j-api/2.5/log4j-api-2.5.jar", 21 | "md5" : "B006C549EE3D523388AA4DF022324830" 22 | }, 23 | { 24 | "url" : "http://maven.covers1624.net/com/bulenkov/darkula/darcula.jar", 25 | "md5" : "189A81314C5435DCEDCB8331BCD0483E" 26 | } 27 | ] 28 | } 29 | -------------------------------------------------------------------------------- /src/main/resources/log4j2.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/util/EnumLanguageLevel.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.util; 2 | 3 | /** 4 | * Created by covers1624 on 17/02/2017. 5 | */ 6 | public enum EnumLanguageLevel { 7 | 8 | JDK_1_6("1.6", "JDK_1_6"), 9 | JDK_1_7("1.7", "JDK_1_7"), 10 | JDK_1_8("1.8", "JDK_1_8"); 11 | 12 | private final String GUI_NAME; 13 | private final String XML_NAME; 14 | 15 | EnumLanguageLevel(String guiName, String xmlName) { 16 | this.GUI_NAME = guiName; 17 | this.XML_NAME = xmlName; 18 | } 19 | 20 | public String getGuiName() { 21 | return GUI_NAME; 22 | } 23 | 24 | public String getXMLName() { 25 | return XML_NAME; 26 | } 27 | 28 | public String getBytecodeTarget() { 29 | return GUI_NAME; 30 | } 31 | 32 | public static EnumLanguageLevel fromName(String name) { 33 | for (EnumLanguageLevel level : values()) { 34 | if (level.GUI_NAME.equals(name) || level.XML_NAME.equals(name)) { 35 | return level; 36 | } 37 | } 38 | throw new IllegalArgumentException("Unknown EnumLanguageLevel: " + name); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/covers1624/launchwrapper/os/OSManager.java: -------------------------------------------------------------------------------- 1 | package covers1624.launchwrapper.os; 2 | 3 | /** 4 | * Created by covers1624 on 2/17/2016. 5 | */ 6 | public class OSManager { 7 | 8 | private static EnumOS currOs; 9 | 10 | static { 11 | String osType = System.getProperty("os.name").toLowerCase(); 12 | if (osType.contains("win")) { 13 | currOs = EnumOS.WINDOWS; 14 | } else if (osType.contains("mac")) { 15 | currOs = EnumOS.OSX; 16 | } else if (osType.contains("solaris") || osType.contains("sunos")) { 17 | currOs = EnumOS.SOLARIS; 18 | } else if (osType.contains("linux") || osType.contains("unix")) { 19 | currOs = EnumOS.LINUX; 20 | } else { 21 | currOs = EnumOS.UNKNOWN; 22 | } 23 | 24 | } 25 | 26 | public static EnumOS getCurrentOS() { 27 | return currOs; 28 | } 29 | 30 | public static EnumOS parseFromString(String osType) { 31 | switch (osType) { 32 | case "windows": 33 | return EnumOS.WINDOWS; 34 | case "osx": 35 | return EnumOS.OSX; 36 | case "unix": 37 | return EnumOS.LINUX; 38 | default: 39 | return EnumOS.UNKNOWN; 40 | } 41 | } 42 | 43 | public enum EnumOS { 44 | LINUX, 45 | WINDOWS, 46 | OSX, 47 | SOLARIS, 48 | UNKNOWN; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/util/ResourceWalker.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.util; 2 | 3 | import org.apache.commons.io.DirectoryWalker; 4 | import org.apache.commons.io.filefilter.IOFileFilter; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.util.ArrayList; 9 | import java.util.Collection; 10 | import java.util.LinkedList; 11 | import java.util.List; 12 | 13 | /** 14 | * Created by covers1624 on 11/02/2017. 15 | */ 16 | public class ResourceWalker extends DirectoryWalker { 17 | 18 | private File folder; 19 | private List files; 20 | 21 | public ResourceWalker(IOFileFilter fileFilter) { 22 | super(fileFilter, -1); 23 | } 24 | 25 | public void setFolder(File folder) { 26 | reset(); 27 | this.folder = folder; 28 | } 29 | 30 | public void reset() { 31 | files = null; 32 | folder = null; 33 | } 34 | 35 | public List startWalk() throws IOException { 36 | files = new LinkedList<>(); 37 | 38 | walk(folder, new ArrayList()); 39 | 40 | return files; 41 | } 42 | 43 | @Override 44 | protected void handleFile(File file, int depth, Collection results) throws IOException { 45 | files.add(file); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/module/ModuleEntry.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.module; 2 | 3 | import com.google.gson.JsonObject; 4 | import org.w3c.dom.Document; 5 | import org.w3c.dom.Element; 6 | 7 | /** 8 | * Created by covers1624 on 21/01/2017. 9 | */ 10 | public class ModuleEntry extends OrderEntry { 11 | 12 | public String NAME; 13 | 14 | public ModuleEntry(String name, boolean export, Scope scope) { 15 | super(Type.MODULE, export, scope); 16 | this.NAME = name; 17 | } 18 | 19 | @Override 20 | public Element createElement(Document document) { 21 | Element element = super.createElement(document); 22 | element.setAttribute("module-name", NAME); 23 | return element; 24 | } 25 | 26 | public JsonObject toJson() { 27 | JsonObject object = new JsonObject(); 28 | object.addProperty("export", export); 29 | object.addProperty("scope", scope.name); 30 | object.addProperty("module", NAME); 31 | return object; 32 | } 33 | 34 | public static ModuleEntry fromJson(JsonObject element) { 35 | boolean export = element.get("export").getAsBoolean(); 36 | Scope scope = Scope.fromString(element.get("scope").getAsString()); 37 | String name = element.get("module").getAsString(); 38 | return new ModuleEntry(name, export, scope); 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/gui/InformationDialog.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.gui; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | 5 | import javax.swing.*; 6 | import javax.swing.event.HyperlinkEvent; 7 | import javax.swing.event.HyperlinkListener; 8 | import java.awt.*; 9 | import java.util.List; 10 | 11 | /** 12 | * Created by covers1624 on 19/02/2017. 13 | */ 14 | public class InformationDialog { 15 | 16 | private final String title; 17 | private final Component parent; 18 | private final List data; 19 | 20 | public InformationDialog(String title, Component parent, List data) { 21 | this.title = title; 22 | this.parent = parent; 23 | this.data = ImmutableList.copyOf(data); 24 | } 25 | 26 | public void dispaly() { 27 | StringBuilder builder = new StringBuilder(); 28 | builder.append(""); 29 | for (String line : data) { 30 | builder.append("
"); 31 | builder.append(line); 32 | } 33 | builder.append(""); 34 | JEditorPane pane = new JEditorPane("text/html", builder.toString()); 35 | pane.setAutoscrolls(true); 36 | pane.setEditable(false); 37 | pane.setOpaque(false); 38 | pane.addHyperlinkListener(e -> { 39 | try { 40 | if (e.getEventType().equals(HyperlinkEvent.EventType.ACTIVATED)) { 41 | Desktop.getDesktop().browse(e.getURL().toURI()); 42 | } 43 | } catch (Exception ignored) { 44 | } 45 | }); 46 | JOptionPane.showMessageDialog(parent, pane, title, -1); 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/util/logging/GuiLogAppender.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.util.logging; 2 | 3 | import covers1624.ccintelli.launch.Launch; 4 | import org.apache.logging.log4j.core.Filter; 5 | import org.apache.logging.log4j.core.Layout; 6 | import org.apache.logging.log4j.core.LogEvent; 7 | import org.apache.logging.log4j.core.appender.AbstractAppender; 8 | import org.apache.logging.log4j.core.config.plugins.Plugin; 9 | import org.apache.logging.log4j.core.config.plugins.PluginAttribute; 10 | import org.apache.logging.log4j.core.config.plugins.PluginElement; 11 | import org.apache.logging.log4j.core.config.plugins.PluginFactory; 12 | 13 | import java.io.Serializable; 14 | 15 | /** 16 | * Created by covers1624 on 18/02/2017. 17 | */ 18 | @Plugin (name = "GuiAppender", category = "Core", elementType = "appender", printObject = true) 19 | public class GuiLogAppender extends AbstractAppender { 20 | 21 | protected GuiLogAppender(String name, Filter filter, Layout layout, boolean ignoreExceptions) { 22 | super(name, filter, layout, ignoreExceptions); 23 | } 24 | 25 | @PluginFactory 26 | public static GuiLogAppender createAppender(@PluginAttribute ("name") String name, @PluginAttribute ("ignoreExceptions") String ignore, @PluginElement ("Layout") Layout layout, @PluginElement ("Filters") Filter filter) { 27 | return new GuiLogAppender(name, filter, layout, Boolean.parseBoolean(ignore)); 28 | } 29 | 30 | @Override 31 | public void append(LogEvent event) { 32 | if (Launch.console != null) { 33 | Launch.console.println(getLayout().toSerializable(event).toString()); 34 | } 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /src/main/java/covers1624/util/XMLUtils.java: -------------------------------------------------------------------------------- 1 | package covers1624.util; 2 | 3 | import org.w3c.dom.Document; 4 | import org.w3c.dom.Element; 5 | import org.w3c.dom.Node; 6 | 7 | import java.util.Objects; 8 | 9 | /** 10 | * Created by covers1624 on 28/02/2017. 11 | */ 12 | public class XMLUtils { 13 | 14 | /** 15 | * Walks the provided elements child nodes for the first Element node. 16 | * 17 | * @param element The element in which to walk the child nodes 18 | * @return The first element, Null if no Element nodes exist. 19 | */ 20 | public static Element getFirstElementNode(Element element) { 21 | for (Node node : new NodeListIterator(element.getChildNodes())) { 22 | if (node.getNodeType() == Node.ELEMENT_NODE) { 23 | return ((Element) node); 24 | } 25 | } 26 | return null; 27 | } 28 | 29 | /** 30 | * Walks the provided elements child nodes for the first Element node with the given name. 31 | * 32 | * @param element The element in which to walk the child nodes 33 | * @param name The name for the child element to find. 34 | * @return The first element, Null if no Element nodes exist with the given name. 35 | */ 36 | public static Element getFirstElementNode(Element element, String name) { 37 | for (Node node : new NodeListIterator(element.getChildNodes())) { 38 | if (node.getNodeType() == Node.ELEMENT_NODE && Objects.equals(node.getNodeName(), name)) { 39 | return ((Element) node); 40 | } 41 | } 42 | return null; 43 | } 44 | 45 | public static Element createAndAdd(Document document, Element parent, String name) { 46 | Element element = document.createElement(name); 47 | parent.appendChild(element); 48 | return element; 49 | } 50 | 51 | } 52 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/module/OrderEntry.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.module; 2 | 3 | import com.google.common.base.Strings; 4 | import org.w3c.dom.Document; 5 | import org.w3c.dom.Element; 6 | 7 | import java.util.LinkedHashMap; 8 | import java.util.Map; 9 | import java.util.Map.Entry; 10 | 11 | /** 12 | * Created by covers1624 on 21/01/2017. 13 | */ 14 | public abstract class OrderEntry { 15 | 16 | public final Type type; 17 | public boolean export; 18 | public Scope scope; 19 | public Map extra = new LinkedHashMap<>(); 20 | 21 | protected OrderEntry(Type type, boolean export, Scope scope) { 22 | this.type = type; 23 | this.export = export; 24 | this.scope = scope; 25 | } 26 | 27 | public Element createElement(Document document) { 28 | Element element = document.createElement("orderEntry"); 29 | element.setAttribute("type", type.name); 30 | if (export) { 31 | element.setAttribute("exported", ""); 32 | } 33 | if (scope != Scope.NONE) { 34 | element.setAttribute("scope", scope.name); 35 | } 36 | if (!extra.isEmpty()) { 37 | for (Entry entry : extra.entrySet()) { 38 | element.setAttribute(entry.getKey(), entry.getValue()); 39 | } 40 | } 41 | return element; 42 | } 43 | 44 | public enum Type { 45 | SOURCE_FOLDER("sourceFolder"), 46 | INHERITED_JDK("inheritedJdk"), 47 | MODULE_LIBRARY("module-library"), 48 | MODULE("module"); 49 | 50 | String name; 51 | 52 | Type(String name) { 53 | this.name = name; 54 | } 55 | } 56 | 57 | public enum Scope { 58 | NONE(""), 59 | //Wont gen in the xml. 60 | COMPILE("COMPILE"), 61 | TEST("TEST"), 62 | RUNTIME("RUNTIME"), 63 | PROVIDED("PROVIDED"); 64 | 65 | String name; 66 | 67 | Scope(String name) { 68 | this.name = name; 69 | } 70 | 71 | public static Scope fromString(String name) { 72 | if (Strings.isNullOrEmpty(name)) { 73 | return NONE; 74 | } 75 | for (Scope scope : Scope.values()) { 76 | if (scope.name.equals(name)) { 77 | return scope; 78 | } 79 | } 80 | return NONE; 81 | } 82 | } 83 | 84 | } 85 | -------------------------------------------------------------------------------- /src/main/java/covers1624/launchwrapper/internal/PreLauncher.java: -------------------------------------------------------------------------------- 1 | package covers1624.launchwrapper.internal; 2 | 3 | import covers1624.launchwrapper.digest.MD5Sum; 4 | import covers1624.launchwrapper.digest.MD5SumCruncher; 5 | import covers1624.launchwrapper.gui.LauncherGui; 6 | import covers1624.launchwrapper.util.Downloader; 7 | 8 | import java.io.File; 9 | import java.lang.reflect.Method; 10 | import java.net.URL; 11 | import java.net.URLClassLoader; 12 | import java.util.HashMap; 13 | import java.util.Map; 14 | import java.util.Map.Entry; 15 | 16 | /** 17 | * Created by covers1624 on 1/01/2017. 18 | */ 19 | public class PreLauncher { 20 | 21 | private static final Map depMap = new HashMap<>(); 22 | 23 | static { 24 | try { 25 | depMap.put(new URL("http://jcenter.bintray.com/com/google/code/gson/gson/2.8.0/gson-2.8.0.jar"), new MD5Sum("A42F1F5BFA4E6F123DDCAB3DE7E0FF81")); 26 | } catch (Exception e) { 27 | e.printStackTrace(); 28 | } 29 | } 30 | 31 | 32 | public static void runInternal(File libsDir) { 33 | System.out.println("[INFO]: Running Launcher setup.."); 34 | File launcherLibsDir = new File(libsDir, "launcher"); 35 | if (!launcherLibsDir.exists()) { 36 | launcherLibsDir.mkdirs(); 37 | } 38 | LauncherGui gui = new LauncherGui("Covers1624 LauncherWrapper"); 39 | gui.init(); 40 | try { 41 | for (Entry entry : depMap.entrySet()) { 42 | String fileName = entry.getKey().toString().substring(entry.getKey().toString().lastIndexOf("/") + 1); 43 | File libFile = new File(launcherLibsDir, fileName); 44 | MD5Sum local = MD5SumCruncher.calculateFileSum(libFile); 45 | //System.out.println(local); 46 | if (!local.equals(entry.getValue())) { 47 | Downloader.download(fileName, entry.getKey(), launcherLibsDir, gui); 48 | } 49 | Downloader.injectLibToClassLoader(libFile); 50 | } 51 | } catch (Exception e) { 52 | throw new RuntimeException("Unable to run pre launcher!", e); 53 | } finally { 54 | gui.dispose(); 55 | } 56 | System.out.println("[INFO]: Launcher setup done. Launching launcher!"); 57 | } 58 | 59 | 60 | } 61 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/launch/RecentWorkspaceSerializer.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.launch; 2 | 3 | import com.google.gson.JsonArray; 4 | import com.google.gson.JsonElement; 5 | import com.google.gson.JsonParser; 6 | import com.google.gson.internal.Streams; 7 | import com.google.gson.stream.JsonReader; 8 | import com.google.gson.stream.JsonWriter; 9 | 10 | import java.io.File; 11 | import java.io.FileReader; 12 | import java.io.FileWriter; 13 | import java.util.LinkedList; 14 | import java.util.List; 15 | 16 | /** 17 | * Created by covers1624 on 18/02/2017. 18 | */ 19 | public class RecentWorkspaceSerializer { 20 | 21 | private final File FILE; 22 | 23 | public RecentWorkspaceSerializer(File file) { 24 | 25 | FILE = file; 26 | } 27 | 28 | public List load() { 29 | List files = new LinkedList<>(); 30 | try { 31 | if (!FILE.exists()) { 32 | return files; 33 | } 34 | JsonParser parser = new JsonParser(); 35 | JsonReader reader = new JsonReader(new FileReader(FILE)); 36 | reader.setLenient(true); 37 | JsonElement element = parser.parse(reader); 38 | for (JsonElement entry : element.getAsJsonArray()) { 39 | files.add(new File(entry.getAsString())); 40 | } 41 | 42 | } catch (Exception e) { 43 | throw new RuntimeException("Unable to parse recent workspaces.", e); 44 | } 45 | 46 | return files; 47 | } 48 | 49 | public void save(List files) { 50 | files = cleanList(files); 51 | if (files.isEmpty()) { 52 | FILE.delete(); 53 | return; 54 | } 55 | try { 56 | JsonWriter writer = new JsonWriter(new FileWriter(FILE)); 57 | writer.setLenient(true); 58 | writer.setIndent(" "); 59 | JsonArray array = new JsonArray(); 60 | for (File file : files) { 61 | array.add(file.getAbsolutePath()); 62 | } 63 | Streams.write(array, writer); 64 | writer.flush(); 65 | 66 | } catch (Exception e) { 67 | throw new RuntimeException("Unable to save recent workspaces.", e); 68 | } 69 | } 70 | 71 | private static List cleanList(List files) { 72 | List ret = new LinkedList<>(); 73 | for (File file : files) { 74 | if (!ret.contains(file)) { 75 | ret.add(file); 76 | } 77 | } 78 | return ret; 79 | } 80 | 81 | } 82 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/util/Utils.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.util; 2 | 3 | import covers1624.launchwrapper.os.OSManager; 4 | import org.apache.commons.io.FileUtils; 5 | 6 | import java.io.File; 7 | import java.io.IOException; 8 | import java.security.AccessController; 9 | import java.security.PrivilegedAction; 10 | 11 | /** 12 | * Created by covers1624 on 20/01/2017. 13 | */ 14 | public class Utils { 15 | 16 | public static void tryCreateFile(File file) { 17 | if (!file.exists()) { 18 | try { 19 | if (!file.createNewFile()) { 20 | throw new Exception(); 21 | } 22 | } catch (Exception e) { 23 | throw new RuntimeException("Unable to create file: " + file.getAbsolutePath(), e); 24 | } 25 | } 26 | } 27 | 28 | public static void tryCreateDirectory(File dir) { 29 | if (!dir.exists()) { 30 | try { 31 | if (!dir.mkdirs()) { 32 | throw new Exception(); 33 | } 34 | } catch (Exception e) { 35 | throw new RuntimeException("Unable to create directory: " + dir.getAbsolutePath(), e); 36 | } 37 | } 38 | } 39 | 40 | public static void archiveFile(File current, File archive) throws IOException { 41 | if (current.exists()) { 42 | if (!archive.exists()) { 43 | Utils.tryCreateFile(archive); 44 | } 45 | FileUtils.copyFile(current, archive); 46 | } 47 | } 48 | 49 | public static File getWorkingDirectory(String folder) { 50 | return AccessController.doPrivileged((PrivilegedAction) () -> getWorkingDirectory_do(folder)); 51 | } 52 | 53 | private static File getWorkingDirectory_do(String folder) { 54 | 55 | String homeDir = System.getProperty("user.home"); 56 | File file; 57 | 58 | switch (OSManager.getCurrentOS()) { 59 | case OSX: 60 | file = new File(homeDir + "Library/Application Support/" + folder); 61 | break; 62 | case WINDOWS: 63 | case LINUX: 64 | case SOLARIS: 65 | case UNKNOWN: 66 | default: 67 | file = new File(homeDir, "." + folder + "/"); 68 | break; 69 | } 70 | tryCreateDirectory(file); 71 | if (!file.exists()) { 72 | throw new RuntimeException("Unable to create the working directory: " + file.getAbsolutePath()); 73 | } 74 | return file; 75 | } 76 | 77 | } 78 | -------------------------------------------------------------------------------- /gradlew.bat: -------------------------------------------------------------------------------- 1 | @if "%DEBUG%" == "" @echo off 2 | @rem ########################################################################## 3 | @rem 4 | @rem Gradle startup script for Windows 5 | @rem 6 | @rem ########################################################################## 7 | 8 | @rem Set local scope for the variables with windows NT shell 9 | if "%OS%"=="Windows_NT" setlocal 10 | 11 | @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 12 | set DEFAULT_JVM_OPTS= 13 | 14 | set DIRNAME=%~dp0 15 | if "%DIRNAME%" == "" set DIRNAME=. 16 | set APP_BASE_NAME=%~n0 17 | set APP_HOME=%DIRNAME% 18 | 19 | @rem Find java.exe 20 | if defined JAVA_HOME goto findJavaFromJavaHome 21 | 22 | set JAVA_EXE=java.exe 23 | %JAVA_EXE% -version >NUL 2>&1 24 | if "%ERRORLEVEL%" == "0" goto init 25 | 26 | echo. 27 | echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 28 | echo. 29 | echo Please set the JAVA_HOME variable in your environment to match the 30 | echo location of your Java installation. 31 | 32 | goto fail 33 | 34 | :findJavaFromJavaHome 35 | set JAVA_HOME=%JAVA_HOME:"=% 36 | set JAVA_EXE=%JAVA_HOME%/bin/java.exe 37 | 38 | if exist "%JAVA_EXE%" goto init 39 | 40 | echo. 41 | echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% 42 | echo. 43 | echo Please set the JAVA_HOME variable in your environment to match the 44 | echo location of your Java installation. 45 | 46 | goto fail 47 | 48 | :init 49 | @rem Get command-line arguments, handling Windowz variants 50 | 51 | if not "%OS%" == "Windows_NT" goto win9xME_args 52 | if "%@eval[2+2]" == "4" goto 4NT_args 53 | 54 | :win9xME_args 55 | @rem Slurp the command line arguments. 56 | set CMD_LINE_ARGS= 57 | set _SKIP=2 58 | 59 | :win9xME_args_slurp 60 | if "x%~1" == "x" goto execute 61 | 62 | set CMD_LINE_ARGS=%* 63 | goto execute 64 | 65 | :4NT_args 66 | @rem Get arguments from the 4NT Shell from JP Software 67 | set CMD_LINE_ARGS=%$ 68 | 69 | :execute 70 | @rem Setup the command line 71 | 72 | set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar 73 | 74 | @rem Execute Gradle 75 | "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% 76 | 77 | :end 78 | @rem End local scope for the variables with windows NT shell 79 | if "%ERRORLEVEL%"=="0" goto mainEnd 80 | 81 | :fail 82 | rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of 83 | rem the _cmd.exe /c_ return code! 84 | if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 85 | exit /b 1 86 | 87 | :mainEnd 88 | if "%OS%"=="Windows_NT" endlocal 89 | 90 | :omega 91 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/launch/SetupSerializer.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.launch; 2 | 3 | import com.google.gson.JsonArray; 4 | import com.google.gson.JsonElement; 5 | import com.google.gson.JsonObject; 6 | import com.google.gson.JsonParser; 7 | import com.google.gson.internal.Streams; 8 | import com.google.gson.stream.JsonReader; 9 | import com.google.gson.stream.JsonWriter; 10 | import covers1624.ccintelli.gui.GuiFields; 11 | import covers1624.ccintelli.module.Module; 12 | 13 | import java.io.File; 14 | import java.io.FileReader; 15 | import java.io.FileWriter; 16 | import java.io.IOException; 17 | 18 | /** 19 | * Created by covers1624 on 19/02/2017. 20 | */ 21 | public class SetupSerializer { 22 | 23 | public static void readSetup(File json) throws IOException { 24 | 25 | JsonReader reader = new JsonReader(new FileReader(json)); 26 | reader.setLenient(true); 27 | JsonParser parser = new JsonParser(); 28 | JsonObject object = parser.parse(reader).getAsJsonObject(); 29 | JsonArray array = object.getAsJsonArray("modules"); 30 | for (JsonElement element : array) { 31 | Module module = Module.fromJson(element.getAsJsonObject()); 32 | if (!containsModule(module)) { 33 | GuiFields.modules.add(module); 34 | } 35 | } 36 | for (JsonElement element : object.getAsJsonArray("core_plugins")) { 37 | GuiFields.fmlCorePlugins.add(element.getAsString()); 38 | } 39 | GuiFields.vmArgs.clear(); 40 | for (JsonElement element : object.getAsJsonArray("vm_args")) { 41 | GuiFields.vmArgs.add(element.getAsString()); 42 | } 43 | } 44 | 45 | public static void writeSetup(File json) throws IOException { 46 | JsonWriter writer = new JsonWriter(new FileWriter(json)); 47 | writer.setLenient(true); 48 | writer.setIndent(" "); 49 | 50 | JsonObject object = new JsonObject(); 51 | JsonArray moduleArray = new JsonArray(); 52 | for (Module module : GuiFields.modules) { 53 | //if (!module.NAME.equals("Forge")) { 54 | moduleArray.add(module.toJson()); 55 | //} 56 | } 57 | object.add("modules", moduleArray); 58 | JsonArray corePlugins = new JsonArray(); 59 | for (String corePlugin : GuiFields.fmlCorePlugins) { 60 | corePlugins.add(corePlugin); 61 | } 62 | object.add("core_plugins", corePlugins); 63 | 64 | JsonArray vmArgs = new JsonArray(); 65 | for (String arg : GuiFields.vmArgs) { 66 | vmArgs.add(arg); 67 | } 68 | object.add("vm_args", vmArgs); 69 | 70 | Streams.write(object, writer); 71 | writer.flush(); 72 | } 73 | 74 | private static boolean containsModule(Module test) { 75 | for (Module suspect : GuiFields.modules) { 76 | if (suspect.NAME.equals(test.NAME)) { 77 | return true; 78 | } 79 | } 80 | return false; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/module/LibraryEntry.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.module; 2 | 3 | import com.google.common.base.Strings; 4 | import org.w3c.dom.Document; 5 | import org.w3c.dom.Element; 6 | import org.w3c.dom.Node; 7 | import org.w3c.dom.NodeList; 8 | 9 | /** 10 | * Created by covers1624 on 21/01/2017. 11 | */ 12 | public class LibraryEntry extends OrderEntry { 13 | 14 | private final String CLASSES_ROOT; 15 | private final String JAVADOC_ROOT; 16 | private final String SOURCES_ROOT; 17 | 18 | protected LibraryEntry(boolean export, Scope scope, String classesRoot, String javadocRoot, String sourcesRoot) { 19 | super(Type.MODULE_LIBRARY, export, scope); 20 | CLASSES_ROOT = classesRoot; 21 | JAVADOC_ROOT = javadocRoot; 22 | SOURCES_ROOT = sourcesRoot; 23 | } 24 | 25 | @Override 26 | public Element createElement(Document document) { 27 | Element element = super.createElement(document); 28 | Element libElement = document.createElement("library"); 29 | Element classesElement = document.createElement("CLASSES"); 30 | Element javadocElement = document.createElement("JAVADOC"); 31 | Element sourcesElement = document.createElement("SOURCES"); 32 | 33 | if (!Strings.isNullOrEmpty(CLASSES_ROOT)) { 34 | Element root = document.createElement("root"); 35 | root.setAttribute("url", CLASSES_ROOT); 36 | classesElement.appendChild(root); 37 | } 38 | if (!Strings.isNullOrEmpty(JAVADOC_ROOT)) { 39 | Element root = document.createElement("root"); 40 | root.setAttribute("url", JAVADOC_ROOT); 41 | javadocElement.appendChild(root); 42 | } 43 | if (!Strings.isNullOrEmpty(SOURCES_ROOT)) { 44 | Element root = document.createElement("root"); 45 | root.setAttribute("url", SOURCES_ROOT); 46 | sourcesElement.appendChild(root); 47 | } 48 | libElement.appendChild(classesElement); 49 | libElement.appendChild(javadocElement); 50 | libElement.appendChild(sourcesElement); 51 | element.appendChild(libElement); 52 | return element; 53 | } 54 | 55 | public static LibraryEntry fromElement(Element element, boolean export, Scope scope) { 56 | String classes = null; 57 | String javadoc = null; 58 | String sources = null; 59 | NodeList nodes = element.getChildNodes(); 60 | for (int i = 0; i < nodes.getLength(); i++) { 61 | Node node = nodes.item(i); 62 | if (node.getNodeType() == Node.ELEMENT_NODE) { 63 | Element nodeElement = ((Element) node); 64 | switch (nodeElement.getTagName()) { 65 | case "CLASSES": 66 | if (nodeElement.hasChildNodes()) { 67 | classes = ((Element) nodeElement.getElementsByTagName("root").item(0)).getAttribute("url"); 68 | } 69 | break; 70 | case "JAVADOC": 71 | if (nodeElement.hasChildNodes()) { 72 | javadoc = ((Element) nodeElement.getElementsByTagName("root").item(0)).getAttribute("url"); 73 | } 74 | break; 75 | case "SOURCES": 76 | if (nodeElement.hasChildNodes()) { 77 | sources = ((Element) nodeElement.getElementsByTagName("root").item(0)).getAttribute("url"); 78 | } 79 | break; 80 | } 81 | } 82 | } 83 | return new LibraryEntry(export, scope, classes, javadoc, sources); 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/gui/ProcessingDialog.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.gui; 2 | 3 | import covers1624.ccintelli.launch.Launch; 4 | 5 | import javax.swing.*; 6 | import java.awt.event.ActionEvent; 7 | import java.awt.event.ActionListener; 8 | import java.awt.event.WindowAdapter; 9 | import java.awt.event.WindowEvent; 10 | 11 | public class ProcessingDialog extends JDialog { 12 | 13 | /** 14 | * Creates new form ProcessingDialog 15 | */ 16 | public ProcessingDialog(java.awt.Frame parent, String message) { 17 | super(parent, true); 18 | initComponents(); 19 | jTextField1.setText(message); 20 | 21 | pack(); 22 | } 23 | 24 | /** 25 | * This method is called from within the constructor to initialize the form. 26 | * WARNING: Do NOT modify this code. The content of this method is always 27 | * regenerated by the Form Editor. 28 | */ 29 | @SuppressWarnings("unchecked") 30 | // 31 | private void initComponents() { 32 | 33 | jButton1 = new JButton(); 34 | jTextField1 = new JTextField(); 35 | 36 | setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); 37 | addWindowListener(new WindowAdapter() { 38 | public void windowClosing(WindowEvent evt) { 39 | formWindowClosing(evt); 40 | } 41 | }); 42 | 43 | jButton1.setText("Open Console"); 44 | jButton1.addActionListener(new ActionListener() { 45 | public void actionPerformed(ActionEvent evt) { 46 | openConsoleButton(evt); 47 | } 48 | }); 49 | 50 | jTextField1.setEditable(false); 51 | jTextField1.setHorizontalAlignment(JTextField.CENTER); 52 | jTextField1.setText("jTextField1"); 53 | 54 | GroupLayout layout = new GroupLayout(getContentPane()); 55 | getContentPane().setLayout(layout); 56 | layout.setHorizontalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) 57 | .addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup() 58 | .addContainerGap() 59 | .addGroup(layout.createParallelGroup(GroupLayout.Alignment.TRAILING) 60 | .addComponent(jTextField1) 61 | .addComponent(jButton1, GroupLayout.DEFAULT_SIZE, 477, Short.MAX_VALUE)) 62 | .addContainerGap()) 63 | ); 64 | layout.setVerticalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) 65 | .addGroup(layout.createSequentialGroup() 66 | .addContainerGap() 67 | .addComponent(jTextField1, GroupLayout.DEFAULT_SIZE, 113, Short.MAX_VALUE) 68 | .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) 69 | .addComponent(jButton1)) 70 | ); 71 | 72 | pack(); 73 | }// 74 | 75 | private void openConsoleButton(ActionEvent evt) { 76 | Launch.console.setVisible(true); 77 | } 78 | 79 | /** 80 | * Called when the user attempts to close the window 81 | */ 82 | private void formWindowClosing(WindowEvent evt) { 83 | } 84 | 85 | // Variables declaration - do not modify 86 | private JButton jButton1; 87 | private JTextField jTextField1; 88 | // End of variables declaration 89 | } 90 | -------------------------------------------------------------------------------- /src/main/java/covers1624/launchwrapper/util/Downloader.java: -------------------------------------------------------------------------------- 1 | package covers1624.launchwrapper.util; 2 | 3 | import covers1624.launchwrapper.LauncherDownloader; 4 | import covers1624.launchwrapper.gui.ILauncherDisplay; 5 | 6 | import java.io.*; 7 | import java.lang.reflect.Method; 8 | import java.net.URL; 9 | import java.net.URLClassLoader; 10 | import java.net.URLConnection; 11 | import java.nio.ByteBuffer; 12 | 13 | /** 14 | * Created by covers1624 on 1/01/2017. 15 | */ 16 | public class Downloader { 17 | 18 | public static void download(String fileName, URL url, File downloadFolder, ILauncherDisplay display) { 19 | download(url, new File(downloadFolder, fileName), display); 20 | } 21 | 22 | public static void download(URL url, File lib, ILauncherDisplay display) { 23 | try { 24 | display.updateProgressString("Downloading file %s", url.toString()); 25 | System.out.println("[INFO]: Downloading file " + url.toString()); 26 | URLConnection urlConnection = url.openConnection(); 27 | urlConnection.setConnectTimeout(5000); 28 | urlConnection.setReadTimeout(5000); 29 | urlConnection.setRequestProperty("User-Agent", "Covers1624 LaunchWrapper downloader."); 30 | int expectedSize = urlConnection.getContentLength(); 31 | try { 32 | if (!lib.exists()) { 33 | lib.createNewFile(); 34 | } 35 | FileOutputStream fos = new FileOutputStream(lib); 36 | copyISManaged(urlConnection.getInputStream(), fos, expectedSize, display); 37 | } catch (Exception e) { 38 | lib.deleteOnExit(); 39 | throw e; 40 | } 41 | } catch (Exception e) { 42 | display.onDownloadFail(lib.toString().substring(lib.toString().lastIndexOf("/") + 1), url, e); 43 | } 44 | } 45 | 46 | public static void copyISManaged(InputStream input, FileOutputStream out, int avail, ILauncherDisplay display) throws IOException { 47 | ByteBuffer downloadBuffer = ByteBuffer.allocateDirect(avail); 48 | downloadBuffer.clear(); 49 | 50 | int bytesRead; 51 | int fullLength = 0; 52 | 53 | display.resetProgress(avail); 54 | try { 55 | display.setPokeThread(Thread.currentThread()); 56 | 57 | byte[] smallBuffer = new byte[1024]; 58 | while ((bytesRead = input.read(smallBuffer)) > 0) { 59 | downloadBuffer.put(smallBuffer, 0, bytesRead); 60 | fullLength += bytesRead; 61 | display.updateProgress(fullLength); 62 | } 63 | input.close(); 64 | display.setPokeThread(null); 65 | downloadBuffer.limit(fullLength); 66 | downloadBuffer.position(0); 67 | } catch (InterruptedIOException e) { 68 | Thread.interrupted(); 69 | throw new RuntimeException("Stop"); 70 | } 71 | downloadBuffer.position(0); 72 | out.getChannel().write(downloadBuffer); 73 | out.flush(); 74 | out.close(); 75 | } 76 | 77 | public static void injectLibToClassLoader(File file) throws Exception { 78 | if (file.isDirectory()) { 79 | return; 80 | } 81 | System.out.println("[INFO]: Adding lib: " + file.getAbsolutePath().substring(file.getAbsolutePath().lastIndexOf(File.separatorChar) + 1)); 82 | Method method = URLClassLoader.class.getDeclaredMethod("addURL", URL.class); 83 | method.setAccessible(true); 84 | method.invoke(ClassLoader.getSystemClassLoader(), file.toURI().toURL()); 85 | } 86 | } 87 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/gui/GuiFields.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.gui; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | import covers1624.ccintelli.launch.Launch; 5 | import covers1624.ccintelli.launch.SetupSerializer; 6 | import covers1624.ccintelli.module.Module; 7 | import covers1624.ccintelli.module.ModuleEntry; 8 | import covers1624.ccintelli.module.OrderEntry.Scope; 9 | import covers1624.ccintelli.util.EnumLanguageLevel; 10 | import covers1624.ccintelli.util.logging.LogHelper; 11 | 12 | import java.io.File; 13 | import java.io.IOException; 14 | import java.util.ArrayList; 15 | import java.util.LinkedList; 16 | import java.util.List; 17 | 18 | /** 19 | * Created by brandon3055 on 23/01/2017. 20 | */ 21 | public class GuiFields { 22 | 23 | //The order of the entries in this list will be the order they show. 24 | //I can apply a comparator to the list before display to sort it. 25 | public static List modules = new LinkedList<>(); 26 | public static Module forgeModule; 27 | public static List fmlCorePlugins = new LinkedList<>(); 28 | public static List vmArgs = new LinkedList<>(ImmutableList.of("-Xmx4G", "-Xms1G")); 29 | 30 | public static EnumLanguageLevel projectLangLevel = EnumLanguageLevel.JDK_1_8; 31 | public static EnumLanguageLevel projectBytecodeLevel = EnumLanguageLevel.JDK_1_8; 32 | 33 | static { 34 | forgeModule = new Module(); 35 | forgeModule.NAME = "Forge"; 36 | forgeModule.CONTENT_ROOT = new File(Launch.SETUP_DIR, "Forge"); 37 | forgeModule.sourceFolders.addAll(findModuleSrc(forgeModule)); 38 | forgeModule.langLevel = forgeModule.bytecodeLevel = EnumLanguageLevel.JDK_1_6; 39 | modules.add(forgeModule); 40 | } 41 | 42 | public static List findModuleSrc(Module module) { 43 | List list = new ArrayList<>(); 44 | 45 | if (module.NAME.equals("Forge")) { 46 | list.add(new File(module.CONTENT_ROOT, "src/main/java").getAbsolutePath()); 47 | list.add(new File(module.CONTENT_ROOT, "src/main/resources").getAbsolutePath()); 48 | list.add(new File(module.CONTENT_ROOT, "projects/Forge/src/main/java").getAbsolutePath()); 49 | list.add(new File(module.CONTENT_ROOT, "projects/Forge/src/main/resources").getAbsolutePath()); 50 | list.add(new File(module.CONTENT_ROOT, "projects/Forge/src/main/start").getAbsolutePath()); 51 | } else { 52 | list.add(new File(module.CONTENT_ROOT, "src/main/java").getAbsolutePath()); 53 | list.add(new File(module.CONTENT_ROOT, "src/main/resources").getAbsolutePath()); 54 | } 55 | 56 | return list; 57 | } 58 | 59 | public static void onModuleAdded(Module module) { 60 | modules.add(module); 61 | module.orderEntries.add(new ModuleEntry("Forge", false, Scope.PROVIDED)); 62 | forgeModule.orderEntries.add(new ModuleEntry(module.NAME, false, Scope.RUNTIME)); 63 | } 64 | 65 | public static void importSetup(File fileToImport) { 66 | try { 67 | int before = modules.size(); 68 | SetupSerializer.readSetup(fileToImport); 69 | LogHelper.info("Successfully imported %s modules from: %s", modules.size() - before, fileToImport.getAbsolutePath()); 70 | } catch (IOException e) { 71 | LogHelper.errorError("Exception was thrown whilst importing modules from: %s", e, fileToImport.getAbsolutePath()); 72 | } 73 | } 74 | 75 | public static void exportSetup(File targetFile) { 76 | try { 77 | SetupSerializer.writeSetup(targetFile); 78 | LogHelper.info("Successfully exported %s modules to: %s", modules.size() - 1, targetFile.getAbsolutePath()); 79 | } catch (IOException e) { 80 | LogHelper.errorError("Exception was thrown whilst exporting modules to: %s", e, targetFile.getAbsolutePath()); 81 | } 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/launch/Launch.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.launch; 2 | 3 | import covers1624.ccintelli.gui.CCIntelliSetupConsole; 4 | import covers1624.ccintelli.gui.CCIntelliSetupMainWindow; 5 | import covers1624.ccintelli.gui.SetupDialog; 6 | import covers1624.ccintelli.util.Utils; 7 | import covers1624.ccintelli.util.logging.LogHelper; 8 | import covers1624.launchwrapper.LaunchHandler; 9 | 10 | import javax.swing.*; 11 | import java.io.File; 12 | import java.util.LinkedList; 13 | import java.util.List; 14 | 15 | /** 16 | * Created by covers1624 on 19/01/2017. 17 | */ 18 | public class Launch { 19 | 20 | private static boolean SHOULD_EXIT = false; 21 | 22 | public static File WORKING_DIR; 23 | public static File LIB_DIR; 24 | public static File SAVES_DIR; 25 | 26 | public static File SETUP_DIR; 27 | public static File WORKSPACE; 28 | public static File MODULES; 29 | public static File PROJECT_RUN; 30 | public static File PROJECT_OUTPUT; 31 | 32 | public static File FORGE; 33 | 34 | public static CCIntelliSetupConsole console; 35 | public static CCIntelliSetupMainWindow window; 36 | 37 | public static String COMPILER_SELECT = "Eclipse"; 38 | public static boolean NOT_NULL_ASSERTIONS = false; 39 | 40 | private static final List RUNNABLES = new LinkedList<>(); 41 | 42 | public static void main(String[] args) throws Exception { 43 | 44 | WORKING_DIR = Utils.getWorkingDirectory("ccintelli"); 45 | LIB_DIR = new File(WORKING_DIR, "libs"); 46 | SAVES_DIR = new File(WORKING_DIR, "saves"); 47 | Utils.tryCreateDirectory(LIB_DIR); 48 | Utils.tryCreateDirectory(SAVES_DIR); 49 | 50 | LaunchHandler.runPreLaunch("CCIntelliSetup", Launch.class.getResourceAsStream("/Dependencies.json"), LIB_DIR, null, null); 51 | UIManager.setLookAndFeel("com.bulenkov.darcula.DarculaLaf"); 52 | console = new CCIntelliSetupConsole(); 53 | 54 | RecentWorkspaceSerializer workspaceSerializer = new RecentWorkspaceSerializer(new File(WORKING_DIR, "recents.json")); 55 | List recents = new LinkedList<>(workspaceSerializer.load()); 56 | SetupDialog setup = new SetupDialog(recents); 57 | SETUP_DIR = setup.getDirectory(); 58 | 59 | if (SETUP_DIR == null) { 60 | LogHelper.info("No workspace selected. Canceling launch!"); 61 | return; 62 | } 63 | recents.add(0, SETUP_DIR);//Inject last to top of the list. 64 | workspaceSerializer.save(recents); 65 | 66 | WORKSPACE = new File(SETUP_DIR, "Workspace"); 67 | PROJECT_RUN = new File(WORKSPACE, "run"); 68 | PROJECT_OUTPUT = new File(WORKSPACE, "out"); 69 | MODULES = new File(WORKSPACE, "Modules"); 70 | FORGE = new File(SETUP_DIR, "Forge"); 71 | 72 | console.setVisible(true); 73 | window = new CCIntelliSetupMainWindow(); 74 | window.setVisible(true); 75 | 76 | LogHelper.info("CCIntelliSetup \\o/"); 77 | 78 | while (!shouldExit()) { 79 | List runnableCopy; 80 | synchronized (RUNNABLES) { 81 | runnableCopy = new LinkedList<>(RUNNABLES); 82 | } 83 | 84 | for (Runnable runnable : runnableCopy) { 85 | try { 86 | runnable.run(); 87 | } catch (Exception e) { 88 | LogHelper.warnError("Exception thrown whilst running a scheduled task.", e); 89 | } 90 | } 91 | 92 | synchronized (RUNNABLES) { 93 | RUNNABLES.removeAll(runnableCopy); 94 | } 95 | } 96 | 97 | window.dispose(); 98 | console.dispose(); 99 | } 100 | 101 | public static synchronized void scheduleTask(Runnable runnable) { 102 | synchronized (RUNNABLES) { 103 | RUNNABLES.add(runnable); 104 | } 105 | } 106 | 107 | public static boolean shouldExit() { 108 | return SHOULD_EXIT; 109 | } 110 | 111 | public static void exit() { 112 | SHOULD_EXIT = true; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /src/main/java/covers1624/launchwrapper/gui/LauncherGui.java: -------------------------------------------------------------------------------- 1 | package covers1624.launchwrapper.gui; 2 | 3 | import javax.swing.*; 4 | import java.awt.*; 5 | import java.awt.event.WindowAdapter; 6 | import java.awt.event.WindowEvent; 7 | import java.net.URL; 8 | 9 | /** 10 | * Created by covers1624 on 2/15/2016. 11 | */ 12 | public class LauncherGui extends JOptionPane implements ILauncherDisplay { 13 | 14 | private JDialog dialog; 15 | private JLabel activity; 16 | private JProgressBar progressBar; 17 | boolean stop; 18 | private Thread pokeThread; 19 | private String name; 20 | 21 | public LauncherGui(String name) { 22 | this.name = name; 23 | } 24 | 25 | @Override 26 | public void init() { 27 | setMessageType(JOptionPane.INFORMATION_MESSAGE); 28 | setMessage(makeProgress()); 29 | setOptions(new Object[] { "Stop" }); 30 | addPropertyChangeListener(evt -> { 31 | if (evt.getSource() == LauncherGui.this && evt.getPropertyName().equals(VALUE_PROPERTY)) { 32 | requestClose("This will stop " + name + " from launching.\nAre you sure you want to do this?"); 33 | } 34 | }); 35 | dialog = new JDialog(null, "Hello", Dialog.ModalityType.MODELESS); 36 | dialog.setIconImage(Toolkit.getDefaultToolkit().createImage(LauncherGui.class.getResource("/CCIS_Icon.png"))); 37 | dialog.setResizable(false); 38 | dialog.setLocationRelativeTo(null); 39 | dialog.add(this); 40 | updateUI(); 41 | dialog.pack(); 42 | dialog.setMinimumSize(new Dimension(640, 197)); 43 | dialog.setVisible(true); 44 | dialog.setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); 45 | dialog.addWindowListener(new WindowAdapter() { 46 | @Override 47 | public void windowClosing(WindowEvent e) { 48 | requestClose("Closing this will stop " + name + " from launching\nAre you sure you want to do this?"); 49 | } 50 | }); 51 | } 52 | 53 | @Override 54 | public void dispose() { 55 | dialog.setVisible(false); 56 | dialog.dispose(); 57 | } 58 | 59 | private Box makeProgress() { 60 | Box box = Box.createVerticalBox(); 61 | box.add(Box.createRigidArea(new Dimension(0, 10))); 62 | JLabel welcomeLabel = new JLabel("Setting up " + name + "!"); 63 | box.add(welcomeLabel); 64 | activity = new JLabel("Working on..."); 65 | box.add(activity); 66 | box.add(Box.createRigidArea(new Dimension(0, 10))); 67 | progressBar = new JProgressBar(0, 100); 68 | progressBar.setStringPainted(true); 69 | box.add(progressBar); 70 | box.add(Box.createRigidArea(new Dimension(0, 30))); 71 | 72 | return box; 73 | } 74 | 75 | protected void requestClose(String message) { 76 | int close = JOptionPane.showConfirmDialog(dialog, message, "Are you sure you want to stop?", JOptionPane.YES_NO_OPTION, JOptionPane.WARNING_MESSAGE); 77 | if (close == YES_OPTION) { 78 | dialog.dispose(); 79 | } 80 | stop = true; 81 | if (pokeThread != null) { 82 | pokeThread.interrupt(); 83 | } 84 | } 85 | 86 | @Override 87 | public void resetProgress(int sizeGuess) { 88 | if (progressBar != null) { 89 | progressBar.getModel().setRangeProperties(0, 0, 0, sizeGuess, false); 90 | } 91 | } 92 | 93 | @Override 94 | public void updateProgress(int fullLength) { 95 | if (progressBar != null) { 96 | progressBar.getModel().setValue(fullLength); 97 | } 98 | } 99 | 100 | @Override 101 | public void updateProgressString(String string, Object... data) { 102 | if (activity != null) { 103 | activity.setText(String.format(string, data)); 104 | } 105 | } 106 | 107 | @Override 108 | public boolean shouldClose() { 109 | return stop; 110 | } 111 | 112 | @Override 113 | public void setPokeThread(Thread thread) { 114 | pokeThread = thread; 115 | } 116 | 117 | @Override 118 | public void onDownloadFail(String file, URL url, Exception e) { 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/gui/CCIntelliSetupConsole.java: -------------------------------------------------------------------------------- 1 | /* 2 | * To change this license header, choose License Headers in Project Properties. 3 | * To change this template file, choose Tools | Templates 4 | * and open the template in the editor. 5 | */ 6 | package covers1624.ccintelli.gui; 7 | 8 | import javax.swing.*; 9 | import java.awt.*; 10 | import java.awt.event.WindowAdapter; 11 | import java.awt.event.WindowEvent; 12 | /** 13 | * @author brandon3055 14 | */ 15 | public class CCIntelliSetupConsole extends javax.swing.JFrame { 16 | public CCIntelliSetupConsole() { 17 | setIconImage(Toolkit.getDefaultToolkit().createImage(CCIntelliSetupMainWindow.class.getResource("/CCIS_Icon.png"))); 18 | initComponents(); 19 | addWindowListener(new WindowAdapter() { 20 | @Override 21 | public void windowClosing(WindowEvent e) { 22 | tryClose(); 23 | } 24 | }); 25 | closeButton.addActionListener(e -> tryClose()); 26 | setModalExclusionType(Dialog.ModalExclusionType.APPLICATION_EXCLUDE); 27 | } 28 | 29 | private void tryClose() { 30 | setVisible(false); 31 | } 32 | 33 | public void setStatus(final String statusText) { 34 | SwingUtilities.invokeLater(() -> statusLabel.setText(statusText)); 35 | } 36 | 37 | private void print(final String appendText) { 38 | SwingUtilities.invokeLater(() -> consoleTextPane.setText(consoleTextPane.getText() + appendText)); 39 | } 40 | 41 | public void println(String newLine) { 42 | print(newLine); 43 | } 44 | 45 | /** 46 | * This method is called from within the constructor to initialize the form. 47 | * WARNING: Do NOT modify this code. The content of this method is always 48 | * regenerated by the Form Editor. 49 | */ 50 | @SuppressWarnings("unchecked") 51 | // 52 | private void initComponents() { 53 | 54 | scrollPane = new JScrollPane(); 55 | consoleTextPane = new JTextPane(); 56 | buttonPane = new JPanel(); 57 | closeButton = new JButton(); 58 | statusPanel = new JPanel(); 59 | statusLabel = new JLabel(); 60 | 61 | setDefaultCloseOperation(WindowConstants.DO_NOTHING_ON_CLOSE); 62 | setTitle("CCIntelliSetup Console"); 63 | 64 | consoleTextPane.setEditable(false); 65 | //consoleTextPane.setText(""); 66 | scrollPane.setViewportView(consoleTextPane); 67 | 68 | closeButton.setText("Close"); 69 | 70 | GroupLayout buttonPaneLayout = new GroupLayout(buttonPane); 71 | buttonPane.setLayout(buttonPaneLayout); 72 | buttonPaneLayout.setHorizontalGroup(buttonPaneLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(GroupLayout.Alignment.TRAILING, buttonPaneLayout.createSequentialGroup().addContainerGap(362, Short.MAX_VALUE).addComponent(closeButton).addContainerGap())); 73 | buttonPaneLayout.setVerticalGroup(buttonPaneLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(buttonPaneLayout.createSequentialGroup().addGap(0, 0, 0).addComponent(closeButton).addGap(0, 0, Short.MAX_VALUE))); 74 | 75 | statusLabel.setHorizontalAlignment(SwingConstants.CENTER); 76 | statusLabel.setText(""); 77 | 78 | GroupLayout statusPanelLayout = new GroupLayout(statusPanel); 79 | statusPanel.setLayout(statusPanelLayout); 80 | statusPanelLayout.setHorizontalGroup(statusPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(statusPanelLayout.createSequentialGroup().addContainerGap().addComponent(statusLabel, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE).addContainerGap())); 81 | statusPanelLayout.setVerticalGroup(statusPanelLayout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(statusPanelLayout.createSequentialGroup().addContainerGap().addComponent(statusLabel, GroupLayout.DEFAULT_SIZE, 18, Short.MAX_VALUE))); 82 | 83 | GroupLayout layout = new GroupLayout(getContentPane()); 84 | getContentPane().setLayout(layout); 85 | layout.setHorizontalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING).addComponent(buttonPane, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE).addComponent(statusPanel, GroupLayout.Alignment.TRAILING, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE).addComponent(scrollPane)); 86 | layout.setVerticalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING).addGroup(GroupLayout.Alignment.TRAILING, layout.createSequentialGroup().addComponent(statusPanel, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addComponent(scrollPane, GroupLayout.DEFAULT_SIZE, 278, Short.MAX_VALUE).addPreferredGap(LayoutStyle.ComponentPlacement.RELATED).addComponent(buttonPane, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE).addContainerGap())); 87 | 88 | pack(); 89 | }// 90 | 91 | // Variables declaration - do not modify 92 | private JPanel buttonPane; 93 | private JButton closeButton; 94 | private JTextPane consoleTextPane; 95 | private JScrollPane scrollPane; 96 | private JLabel statusLabel; 97 | private JPanel statusPanel; 98 | // End of variables declaration 99 | } 100 | -------------------------------------------------------------------------------- /gradlew: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | ############################################################################## 4 | ## 5 | ## Gradle start up script for UN*X 6 | ## 7 | ############################################################################## 8 | 9 | # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. 10 | DEFAULT_JVM_OPTS="" 11 | 12 | APP_NAME="Gradle" 13 | APP_BASE_NAME=`basename "$0"` 14 | 15 | # Use the maximum available, or set MAX_FD != -1 to use that value. 16 | MAX_FD="maximum" 17 | 18 | warn ( ) { 19 | echo "$*" 20 | } 21 | 22 | die ( ) { 23 | echo 24 | echo "$*" 25 | echo 26 | exit 1 27 | } 28 | 29 | # OS specific support (must be 'true' or 'false'). 30 | cygwin=false 31 | msys=false 32 | darwin=false 33 | case "`uname`" in 34 | CYGWIN* ) 35 | cygwin=true 36 | ;; 37 | Darwin* ) 38 | darwin=true 39 | ;; 40 | MINGW* ) 41 | msys=true 42 | ;; 43 | esac 44 | 45 | # For Cygwin, ensure paths are in UNIX format before anything is touched. 46 | if $cygwin ; then 47 | [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` 48 | fi 49 | 50 | # Attempt to set APP_HOME 51 | # Resolve links: $0 may be a link 52 | PRG="$0" 53 | # Need this for relative symlinks. 54 | while [ -h "$PRG" ] ; do 55 | ls=`ls -ld "$PRG"` 56 | link=`expr "$ls" : '.*-> \(.*\)$'` 57 | if expr "$link" : '/.*' > /dev/null; then 58 | PRG="$link" 59 | else 60 | PRG=`dirname "$PRG"`"/$link" 61 | fi 62 | done 63 | SAVED="`pwd`" 64 | cd "`dirname \"$PRG\"`/" >&- 65 | APP_HOME="`pwd -P`" 66 | cd "$SAVED" >&- 67 | 68 | CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar 69 | 70 | # Determine the Java command to use to start the JVM. 71 | if [ -n "$JAVA_HOME" ] ; then 72 | if [ -x "$JAVA_HOME/jre/sh/java" ] ; then 73 | # IBM's JDK on AIX uses strange locations for the executables 74 | JAVACMD="$JAVA_HOME/jre/sh/java" 75 | else 76 | JAVACMD="$JAVA_HOME/bin/java" 77 | fi 78 | if [ ! -x "$JAVACMD" ] ; then 79 | die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME 80 | 81 | Please set the JAVA_HOME variable in your environment to match the 82 | location of your Java installation." 83 | fi 84 | else 85 | JAVACMD="java" 86 | which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. 87 | 88 | Please set the JAVA_HOME variable in your environment to match the 89 | location of your Java installation." 90 | fi 91 | 92 | # Increase the maximum file descriptors if we can. 93 | if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then 94 | MAX_FD_LIMIT=`ulimit -H -n` 95 | if [ $? -eq 0 ] ; then 96 | if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then 97 | MAX_FD="$MAX_FD_LIMIT" 98 | fi 99 | ulimit -n $MAX_FD 100 | if [ $? -ne 0 ] ; then 101 | warn "Could not set maximum file descriptor limit: $MAX_FD" 102 | fi 103 | else 104 | warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" 105 | fi 106 | fi 107 | 108 | # For Darwin, add options to specify how the application appears in the dock 109 | if $darwin; then 110 | GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" 111 | fi 112 | 113 | # For Cygwin, switch paths to Windows format before running java 114 | if $cygwin ; then 115 | APP_HOME=`cygpath --path --mixed "$APP_HOME"` 116 | CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` 117 | 118 | # We build the pattern for arguments to be converted via cygpath 119 | ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` 120 | SEP="" 121 | for dir in $ROOTDIRSRAW ; do 122 | ROOTDIRS="$ROOTDIRS$SEP$dir" 123 | SEP="|" 124 | done 125 | OURCYGPATTERN="(^($ROOTDIRS))" 126 | # Add a user-defined pattern to the cygpath arguments 127 | if [ "$GRADLE_CYGPATTERN" != "" ] ; then 128 | OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" 129 | fi 130 | # Now convert the arguments - kludge to limit ourselves to /bin/sh 131 | i=0 132 | for arg in "$@" ; do 133 | CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` 134 | CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option 135 | 136 | if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition 137 | eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` 138 | else 139 | eval `echo args$i`="\"$arg\"" 140 | fi 141 | i=$((i+1)) 142 | done 143 | case $i in 144 | (0) set -- ;; 145 | (1) set -- "$args0" ;; 146 | (2) set -- "$args0" "$args1" ;; 147 | (3) set -- "$args0" "$args1" "$args2" ;; 148 | (4) set -- "$args0" "$args1" "$args2" "$args3" ;; 149 | (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 150 | (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 151 | (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 152 | (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 153 | (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 154 | esac 155 | fi 156 | 157 | # Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules 158 | function splitJvmOpts() { 159 | JVM_OPTS=("$@") 160 | } 161 | eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS 162 | JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" 163 | 164 | exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" 165 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/gui/SetupDialog.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.gui; 2 | 3 | import com.google.common.collect.ImmutableList; 4 | 5 | import javax.swing.*; 6 | import java.awt.*; 7 | import java.io.File; 8 | 9 | /** 10 | * Created by brandon3055 on 17/02/2017. 11 | */ 12 | public class SetupDialog extends JDialog { 13 | private JPanel jPanel1; 14 | private JButton buttonOK; 15 | private JButton buttonCancel; 16 | private JTextField directoryField; 17 | private JButton chooseButton; 18 | private JComboBox recentBox; 19 | 20 | public SetupDialog() { 21 | this(ImmutableList.of()); 22 | } 23 | 24 | public SetupDialog(java.util.List recents) { 25 | setIconImage(Toolkit.getDefaultToolkit().createImage(SetupDialog.class.getResource("/CCIS_Icon.png"))); 26 | initComponents(); 27 | setModal(true); 28 | recentBox.addItemListener(e -> directoryField.setText(e.getItem().toString())); 29 | setTitle("Select Workspace Directory"); 30 | pack(); 31 | for (File file : recents) { 32 | recentBox.addItem(file.getAbsoluteFile()); 33 | } 34 | 35 | setSize(600, getHeight()); 36 | Dimension dim = Toolkit.getDefaultToolkit().getScreenSize(); 37 | this.setLocation(dim.width / 2 - this.getSize().width / 2, dim.height / 2 - this.getSize().height / 2); 38 | 39 | if (recents.isEmpty()) { 40 | directoryField.setText(new File("").getAbsolutePath()); 41 | } 42 | else { 43 | directoryField.setText(recents.get(0).getAbsolutePath()); 44 | } 45 | } 46 | 47 | @SuppressWarnings("unchecked") 48 | // 49 | private void initComponents() { 50 | 51 | jPanel1 = new JPanel(); 52 | JLabel jLabel1 = new JLabel(); 53 | directoryField = new JTextField(); 54 | chooseButton = new JButton(); 55 | JLabel jLabel2 = new JLabel(); 56 | recentBox = new JComboBox<>(); 57 | buttonCancel = new JButton(); 58 | buttonOK = new JButton(); 59 | 60 | setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE); 61 | 62 | jLabel1.setText("Select Workspace Directory"); 63 | 64 | chooseButton.setText("..."); 65 | chooseButton.addActionListener(evt -> onSelect()); 66 | 67 | jLabel2.setText("Recent:"); 68 | 69 | buttonCancel.setText("Cancel"); 70 | buttonCancel.addActionListener(evt -> onCancel()); 71 | 72 | buttonOK.setText("OK"); 73 | buttonOK.addActionListener(evt -> onOK()); 74 | 75 | GroupLayout jPanel1Layout = new GroupLayout(jPanel1); 76 | jPanel1.setLayout(jPanel1Layout); 77 | jPanel1Layout.setHorizontalGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) 78 | .addGroup(jPanel1Layout.createSequentialGroup() 79 | .addContainerGap() 80 | .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) 81 | .addGroup(jPanel1Layout.createSequentialGroup() 82 | .addComponent(directoryField) 83 | .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) 84 | .addComponent(chooseButton)) 85 | .addComponent(jLabel1, GroupLayout.DEFAULT_SIZE, 652, Short.MAX_VALUE) 86 | .addGroup(jPanel1Layout.createSequentialGroup() 87 | .addComponent(jLabel2) 88 | .addGap(0, 0, Short.MAX_VALUE)) 89 | .addComponent(recentBox, 0, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 90 | .addGroup(GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() 91 | .addGap(0, 0, Short.MAX_VALUE) 92 | .addComponent(buttonOK, GroupLayout.PREFERRED_SIZE, 70, GroupLayout.PREFERRED_SIZE) 93 | .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) 94 | .addComponent(buttonCancel))) 95 | .addContainerGap()) 96 | ); 97 | jPanel1Layout.setVerticalGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) 98 | .addGroup(jPanel1Layout.createSequentialGroup() 99 | .addContainerGap() 100 | .addComponent(jLabel1) 101 | .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) 102 | .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) 103 | .addComponent(directoryField, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) 104 | .addComponent(chooseButton)) 105 | .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.LEADING) 106 | .addGroup(jPanel1Layout.createSequentialGroup() 107 | .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) 108 | .addComponent(jLabel2) 109 | .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED) 110 | .addComponent(recentBox, GroupLayout.PREFERRED_SIZE, GroupLayout.DEFAULT_SIZE, GroupLayout.PREFERRED_SIZE) 111 | .addContainerGap(63, Short.MAX_VALUE)) 112 | .addGroup(GroupLayout.Alignment.TRAILING, jPanel1Layout.createSequentialGroup() 113 | .addPreferredGap(LayoutStyle.ComponentPlacement.RELATED, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 114 | .addGroup(jPanel1Layout.createParallelGroup(GroupLayout.Alignment.BASELINE) 115 | .addComponent(buttonCancel) 116 | .addComponent(buttonOK)) 117 | .addContainerGap()))) 118 | ); 119 | 120 | GroupLayout layout = new GroupLayout(getContentPane()); 121 | getContentPane().setLayout(layout); 122 | layout.setHorizontalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) 123 | .addComponent(jPanel1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 124 | ); 125 | layout.setVerticalGroup(layout.createParallelGroup(GroupLayout.Alignment.LEADING) 126 | .addComponent(jPanel1, GroupLayout.DEFAULT_SIZE, GroupLayout.DEFAULT_SIZE, Short.MAX_VALUE) 127 | ); 128 | 129 | }// 130 | 131 | public File getDirectory() { 132 | setVisible(true); 133 | if (directoryField.getText().isEmpty()) { 134 | return null; 135 | } 136 | return new File(directoryField.getText()); 137 | } 138 | 139 | private void onOK() { 140 | dispose(); 141 | } 142 | 143 | private void onCancel() { 144 | directoryField.setText(""); 145 | dispose(); 146 | } 147 | 148 | private void onSelect() { 149 | JFileChooser chooser = new JFileChooser(); 150 | chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); 151 | chooser.setCurrentDirectory(new File(directoryField.getText())); 152 | 153 | if (chooser.showOpenDialog(this) == JFileChooser.APPROVE_OPTION) { 154 | directoryField.setText(chooser.getSelectedFile().getAbsolutePath()); 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/workspace/WorkspaceGenerator.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.workspace; 2 | 3 | import com.google.common.base.Strings; 4 | import covers1624.ccintelli.gui.GuiFields; 5 | import covers1624.ccintelli.launch.Launch; 6 | import covers1624.ccintelli.launch.SetupSerializer; 7 | import covers1624.ccintelli.module.Module; 8 | import covers1624.ccintelli.util.ATFileFilter; 9 | import covers1624.ccintelli.util.ResourceWalker; 10 | import covers1624.ccintelli.util.Utils; 11 | import covers1624.ccintelli.util.logging.LogHelper; 12 | import org.apache.commons.io.IOUtils; 13 | 14 | import java.io.*; 15 | import java.util.HashMap; 16 | import java.util.LinkedList; 17 | import java.util.List; 18 | import java.util.Map; 19 | import java.util.Map.Entry; 20 | 21 | /** 22 | * Created by covers1624 on 10/02/2017. 23 | */ 24 | public class WorkspaceGenerator { 25 | 26 | public static List forgeATLines; 27 | public static Map> moduleAtLines; 28 | 29 | public static void generateWorkspace(String projectName) { 30 | LogHelper.info("Generating Workspace."); 31 | Utils.tryCreateDirectory(Launch.WORKSPACE); 32 | Utils.tryCreateDirectory(Launch.MODULES); 33 | Utils.tryCreateDirectory(Launch.PROJECT_RUN); 34 | Utils.tryCreateDirectory(Launch.PROJECT_OUTPUT); 35 | mergeATs(); 36 | runForgeSetup(); 37 | exportModules(); 38 | ProjectGenerator.generateWorkspace(projectName); 39 | RunConfigGenerator.generateRunConfigs(projectName); 40 | exportCurrentSetup(projectName); 41 | LogHelper.info("Done!"); 42 | } 43 | 44 | public static void runForgeSetup() { 45 | LogHelper.info("Starting forge setup."); 46 | try { 47 | File forge = GuiFields.forgeModule.CONTENT_ROOT; 48 | String gradlew = new File(forge, "gradlew.bat").getAbsolutePath(); 49 | ProcessBuilder builder = new ProcessBuilder(); 50 | builder.directory(forge.getAbsoluteFile()); 51 | builder.command(gradlew, "clean", "setupForge"); 52 | runProcessAndLog(builder.start()); 53 | } catch (Exception e) { 54 | throw new RuntimeException("Something went wrong running forges gradle tasks!", e); 55 | } 56 | } 57 | 58 | public static void exportModules() { 59 | LogHelper.info("Generating modules.."); 60 | for (Module module : GuiFields.modules) { 61 | if (module.NAME.equals("Forge")) { 62 | module = Module.buildForgeModule(new File(module.CONTENT_ROOT, "projects/Forge/Forge.iml"), module); 63 | } 64 | File moduleXML = new File(Launch.MODULES, module.NAME + ".iml"); 65 | Utils.tryCreateFile(moduleXML); 66 | module.writeXML(moduleXML); 67 | } 68 | } 69 | 70 | public static void mergeATs() { 71 | LogHelper.info("Starting AccessTransformer merge."); 72 | forgeATLines = new LinkedList<>(); 73 | moduleAtLines = new HashMap<>(); 74 | List forgeAtFiles = findATFilesForModule(GuiFields.forgeModule); 75 | for (File atFile : forgeAtFiles) { 76 | forgeATLines.addAll(parseATFile(atFile)); 77 | } 78 | for (Module module : GuiFields.modules) { 79 | if (module.NAME.equals("Forge")) { 80 | continue; 81 | } 82 | List atLines = new LinkedList<>(); 83 | for (File file : findATFilesForModule(module)) { 84 | atLines.addAll(parseATFile(file)); 85 | } 86 | moduleAtLines.put(module.NAME, atLines); 87 | } 88 | 89 | List finalModAtLines = new LinkedList<>(); 90 | finalModAtLines.add("# Auto generated AT file by CCIntelliSetup, Contains at lines from all modules during setup."); 91 | for (Entry> entry : moduleAtLines.entrySet()) { 92 | finalModAtLines.add(""); 93 | finalModAtLines.add("# AT Lines for: " + entry.getKey()); 94 | for (String atLine : entry.getValue()) { 95 | if (finalModAtLines.contains(atLine)) { 96 | LogHelper.info("Skipping at line from module %s as already exists, %s", entry.getKey(), atLine); 97 | continue; 98 | } else if (forgeATLines.contains(atLine)) { 99 | LogHelper.warn("AT Line from module %s already exists in forges at file! \"%s\"", entry.getKey(), atLine); 100 | continue; 101 | } 102 | finalModAtLines.add(atLine); 103 | } 104 | } 105 | try { 106 | File atFile = new File(GuiFields.forgeModule.CONTENT_ROOT, "src/main/resources/merged_at.cfg"); 107 | Utils.tryCreateFile(atFile); 108 | PrintWriter writer = new PrintWriter(atFile); 109 | for (String atLine : finalModAtLines) { 110 | writer.println(atLine); 111 | } 112 | writer.flush(); 113 | writer.close(); 114 | } catch (Exception e) { 115 | e.printStackTrace(); 116 | } 117 | 118 | } 119 | 120 | public static List parseATFile(File file) { 121 | List lines = new LinkedList<>(); 122 | try { 123 | BufferedReader reader = new BufferedReader(new FileReader(file)); 124 | 125 | String line; 126 | while ((line = reader.readLine()) != null) { 127 | if (Strings.isNullOrEmpty(line) || line.startsWith("#")) { 128 | continue; 129 | } 130 | int tag = line.indexOf("#"); 131 | if (tag != -1) { 132 | line = line.substring(0, tag).trim(); 133 | } 134 | lines.add(line); 135 | } 136 | IOUtils.closeQuietly(reader); 137 | 138 | } catch (Exception e) { 139 | e.printStackTrace(); 140 | } 141 | return lines; 142 | } 143 | 144 | public static List findATFilesForModule(Module module) { 145 | List files = new LinkedList<>(); 146 | ResourceWalker walker = new ResourceWalker(new ATFileFilter()); 147 | for (String srcFolder : module.sourceFolders) { 148 | File srcFile = new File(srcFolder); 149 | walker.setFolder(srcFile); 150 | try { 151 | files.addAll(walker.startWalk()); 152 | } catch (IOException e) { 153 | e.printStackTrace(); 154 | } 155 | } 156 | return files; 157 | } 158 | 159 | private static void runProcessAndLog(Process process) throws Exception { 160 | boolean firstLine = false; 161 | Launch.console.setStatus("Waiting for Gradle to start.."); 162 | while (process.isAlive()) { 163 | BufferedReader reader = new BufferedReader(new InputStreamReader(process.getInputStream())); 164 | 165 | String line; 166 | while ((line = reader.readLine()) != null) { 167 | if (!firstLine) { 168 | Launch.console.setStatus("Running Gradle task.."); 169 | firstLine = true; 170 | } 171 | LogHelper.info(line); 172 | } 173 | } 174 | } 175 | 176 | private static void exportCurrentSetup(String projectName) { 177 | try { 178 | File export = new File(Launch.WORKSPACE, projectName + ".json"); 179 | SetupSerializer.writeSetup(export); 180 | LogHelper.info("Your current workspace has been exported to: " + export.getAbsoluteFile().getPath()); 181 | } catch (Exception e) { 182 | LogHelper.errorError("Exception was thrown whilst exporting setup..", e); 183 | } 184 | } 185 | 186 | } 187 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/module/Module.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.module; 2 | 3 | import com.google.gson.JsonArray; 4 | import com.google.gson.JsonElement; 5 | import com.google.gson.JsonObject; 6 | import covers1624.ccintelli.launch.Launch; 7 | import covers1624.ccintelli.module.OrderEntry.Scope; 8 | import covers1624.ccintelli.module.OrderEntry.Type; 9 | import covers1624.ccintelli.util.EnumLanguageLevel; 10 | import covers1624.ccintelli.util.Utils; 11 | import covers1624.ccintelli.util.logging.LogHelper; 12 | import org.w3c.dom.Document; 13 | import org.w3c.dom.Element; 14 | import org.w3c.dom.Node; 15 | import org.w3c.dom.NodeList; 16 | 17 | import javax.xml.parsers.DocumentBuilder; 18 | import javax.xml.parsers.DocumentBuilderFactory; 19 | import javax.xml.transform.OutputKeys; 20 | import javax.xml.transform.Transformer; 21 | import javax.xml.transform.TransformerFactory; 22 | import javax.xml.transform.dom.DOMSource; 23 | import javax.xml.transform.stream.StreamResult; 24 | import java.io.File; 25 | import java.util.LinkedList; 26 | import java.util.List; 27 | 28 | /** 29 | * Created by covers1624 on 21/01/2017. 30 | */ 31 | public class Module { 32 | 33 | public String NAME; 34 | public String GROUP = ""; 35 | public File CONTENT_ROOT; 36 | public List sourceFolders = new LinkedList<>(); 37 | public List orderEntries = new LinkedList<>(); 38 | public EnumLanguageLevel langLevel = EnumLanguageLevel.JDK_1_8; 39 | public EnumLanguageLevel bytecodeLevel = EnumLanguageLevel.JDK_1_8; 40 | 41 | public void writeXML(File file) { 42 | try { 43 | Utils.tryCreateFile(file); 44 | 45 | DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 46 | DocumentBuilder builder = factory.newDocumentBuilder(); 47 | Document document = builder.newDocument(); 48 | document.setXmlVersion("1.0"); 49 | document.setXmlStandalone(true); 50 | 51 | Element moduleElement = document.createElement("module"); 52 | document.appendChild(moduleElement); 53 | moduleElement.setAttribute("relativePaths", "false"); 54 | moduleElement.setAttribute("type", "JAVA_MODULE"); 55 | moduleElement.setAttribute("version", "4"); 56 | 57 | Element componentElement = document.createElement("component"); 58 | moduleElement.appendChild(componentElement); 59 | componentElement.setAttribute("name", "NewModuleRootManager"); 60 | componentElement.setAttribute("inherit-compiler-output", "true"); 61 | componentElement.setAttribute("LANGUAGE_LEVEL", langLevel.getXMLName()); 62 | 63 | componentElement.appendChild(document.createElement("exclude-output")); 64 | 65 | Element contentElement = document.createElement("content"); 66 | componentElement.appendChild(contentElement); 67 | contentElement.setAttribute("url", "file://" + CONTENT_ROOT.getAbsolutePath()); 68 | for (String srcFolder : sourceFolders) { 69 | Element element = document.createElement("sourceFolder"); 70 | contentElement.appendChild(element); 71 | element.setAttribute("url", "file://" + srcFolder); 72 | element.setAttribute("isTestSource", "false"); 73 | } 74 | for (OrderEntry entry : orderEntries) { 75 | if (entry == null) { 76 | LogHelper.error("Found null order entry for module %s", NAME); 77 | continue; 78 | } 79 | componentElement.appendChild(entry.createElement(document)); 80 | } 81 | 82 | TransformerFactory transformerFactory = TransformerFactory.newInstance(); 83 | Transformer transformer = transformerFactory.newTransformer(); 84 | transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 85 | transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); 86 | DOMSource source = new DOMSource(document); 87 | StreamResult result = new StreamResult(file); 88 | transformer.transform(source, result); 89 | } catch (Exception e) { 90 | LogHelper.fatalError("Unable to create module iml!", e); 91 | } 92 | } 93 | 94 | public static Module buildForgeModule(File currentXML, Module forgeModule) { 95 | try { 96 | 97 | DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 98 | DocumentBuilder builder = factory.newDocumentBuilder(); 99 | Document document = builder.parse(currentXML); 100 | document.getDocumentElement().normalize(); 101 | Element moduleElement = document.getDocumentElement(); 102 | Node componentElement = moduleElement.getElementsByTagName("component").item(0); 103 | NodeList list = componentElement.getChildNodes(); 104 | for (int i = 0; i < list.getLength(); i++) { 105 | Node node = list.item(i); 106 | if (node.getNodeType() == Node.ELEMENT_NODE) { 107 | Element entryElement = ((Element) node); 108 | if (entryElement.hasAttribute("type")) { 109 | String type = entryElement.getAttribute("type"); 110 | switch (type) { 111 | case "sourceFolder": 112 | OrderEntry entry = new SimpleEntry(Type.SOURCE_FOLDER); 113 | entry.extra.put("forTests", entryElement.getAttribute("forTests")); 114 | forgeModule.orderEntries.add(entry); 115 | break; 116 | case "inheritedJdk": 117 | forgeModule.orderEntries.add(new SimpleEntry(Type.INHERITED_JDK)); 118 | break; 119 | case "module-library": 120 | //boolean exported = entryElement.hasAttribute("exported"); 121 | Scope scope = Scope.fromString(entryElement.getAttribute("scope")); 122 | NodeList nodes = entryElement.getChildNodes(); 123 | for (int j = 0; j < nodes.getLength(); j++) { 124 | Node node1 = nodes.item(j); 125 | if (node1.getNodeType() == Node.ELEMENT_NODE) { 126 | forgeModule.orderEntries.add(LibraryEntry.fromElement(((Element) node1), true, scope)); 127 | break; 128 | } 129 | } 130 | 131 | break; 132 | default: 133 | LogHelper.warn("Unknown type for Forge's OrderEntries in module file! Type=%s File=%s", type, currentXML.getAbsoluteFile()); 134 | break; 135 | } 136 | } 137 | } 138 | } 139 | 140 | return forgeModule; 141 | } catch (Exception e) { 142 | throw new RuntimeException("Unable to parse existing forge XML!", e); 143 | } 144 | } 145 | 146 | public JsonElement toJson() { 147 | 148 | JsonObject object = new JsonObject(); 149 | object.addProperty("name", NAME); 150 | object.addProperty("group", GROUP); 151 | 152 | object.addProperty("content_root", CONTENT_ROOT.getAbsolutePath().replace(Launch.SETUP_DIR.getAbsolutePath(), "").substring(1)); 153 | 154 | object.addProperty("language_level", langLevel.name()); 155 | object.addProperty("bytecode_level", bytecodeLevel.name()); 156 | JsonArray array = new JsonArray(); 157 | for (OrderEntry entry : orderEntries) { 158 | if (entry instanceof ModuleEntry) { 159 | array.add(((ModuleEntry) entry).toJson()); 160 | } 161 | } 162 | object.add("module_entries", array); 163 | 164 | JsonArray srcDirs = new JsonArray(); 165 | for (String file : sourceFolders) { 166 | srcDirs.add(file.replace(Launch.SETUP_DIR.getAbsolutePath(), "").substring(1)); 167 | } 168 | 169 | object.add("src_dirs", srcDirs); 170 | 171 | return object; 172 | } 173 | 174 | public static Module fromJson(JsonObject object) { 175 | 176 | Module module = new Module(); 177 | module.NAME = object.get("name").getAsString(); 178 | module.GROUP = object.get("group").getAsString(); 179 | String contentRoot = object.get("content_root").getAsString(); 180 | module.CONTENT_ROOT = new File(Launch.SETUP_DIR, contentRoot); 181 | module.langLevel = EnumLanguageLevel.fromName(object.get("language_level").getAsString()); 182 | module.bytecodeLevel = EnumLanguageLevel.fromName(object.get("bytecode_level").getAsString()); 183 | 184 | for (JsonElement moduleElement : object.getAsJsonArray("module_entries")) { 185 | module.orderEntries.add(ModuleEntry.fromJson(moduleElement.getAsJsonObject())); 186 | } 187 | 188 | for (JsonElement element : object.getAsJsonArray("src_dirs")) { 189 | module.sourceFolders.add(Launch.SETUP_DIR.getAbsolutePath() + "/" + element.getAsString()); 190 | } 191 | 192 | return module; 193 | } 194 | 195 | } 196 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/util/logging/CCIntelliSetupFileAppender.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.util.logging; 2 | 3 | import covers1624.ccintelli.launch.Launch; 4 | import org.apache.logging.log4j.core.Filter; 5 | import org.apache.logging.log4j.core.Layout; 6 | import org.apache.logging.log4j.core.LogEvent; 7 | import org.apache.logging.log4j.core.appender.AbstractOutputStreamAppender; 8 | import org.apache.logging.log4j.core.appender.rolling.*; 9 | import org.apache.logging.log4j.core.config.Configuration; 10 | import org.apache.logging.log4j.core.config.plugins.*; 11 | import org.apache.logging.log4j.core.layout.PatternLayout; 12 | import org.apache.logging.log4j.core.net.Advertiser; 13 | import org.apache.logging.log4j.core.util.Booleans; 14 | import org.apache.logging.log4j.core.util.Integers; 15 | 16 | import java.io.Serializable; 17 | import java.util.HashMap; 18 | import java.util.Map; 19 | import java.util.zip.Deflater; 20 | 21 | /** 22 | * Created by covers1624 on 18/02/2017. 23 | * Mainly just a carbon copy of RollingRandomAccessFileAppender, Credits to apache. 24 | */ 25 | @Plugin (name = "CCIntelliFileAppender", category = "Core", elementType = "appender", printObject = true) 26 | public class CCIntelliSetupFileAppender extends AbstractOutputStreamAppender { 27 | 28 | private static final long serialVersionUID = 1L; 29 | 30 | private final String fileName; 31 | private final String filePattern; 32 | private Object advertisement; 33 | private final Advertiser advertiser; 34 | 35 | public CCIntelliSetupFileAppender(final String name, final Layout layout, final Filter filter, final RollingFileManager manager, final String fileName, final String filePattern, final boolean ignoreExceptions, final boolean immediateFlush, final int bufferSize, final Advertiser advertiser) { 36 | super(name, layout, filter, ignoreExceptions, immediateFlush, manager); 37 | if (advertiser != null) { 38 | final Map configuration = new HashMap<>(layout.getContentFormat()); 39 | configuration.put("contentType", layout.getContentType()); 40 | configuration.put("name", name); 41 | advertisement = advertiser.advertise(configuration); 42 | } 43 | this.fileName = fileName; 44 | this.filePattern = filePattern; 45 | this.advertiser = advertiser; 46 | } 47 | 48 | @Override 49 | public void stop() { 50 | super.stop(); 51 | if (advertiser != null) { 52 | advertiser.unadvertise(advertisement); 53 | } 54 | } 55 | 56 | @Override 57 | public void append(final LogEvent event) { 58 | final RollingRandomAccessFileManager manager = (RollingRandomAccessFileManager) getManager(); 59 | manager.checkRollover(event); 60 | 61 | // Leverage the nice batching behaviour of async Loggers/Appenders: 62 | // we can signal the file manager that it needs to flush the buffer 63 | // to disk at the end of a batch. 64 | // From a user's point of view, this means that all log events are 65 | // _always_ available in the log file, without incurring the overhead 66 | // of immediateFlush=true. 67 | manager.setEndOfBatch(event.isEndOfBatch()); 68 | super.append(event); 69 | } 70 | 71 | /** 72 | * Returns the File name for the Appender. 73 | * 74 | * @return The file name. 75 | */ 76 | public String getFileName() { 77 | return fileName; 78 | } 79 | 80 | /** 81 | * Returns the file pattern used when rolling over. 82 | * 83 | * @return The file pattern. 84 | */ 85 | public String getFilePattern() { 86 | return filePattern; 87 | } 88 | 89 | /** 90 | * Returns the size of the file manager's buffer. 91 | * 92 | * @return the buffer size 93 | */ 94 | public int getBufferSize() { 95 | return getManager().getBufferSize(); 96 | } 97 | 98 | /** 99 | * Create a RollingRandomAccessFileAppender. 100 | * 101 | * @param fileName The name of the file that is actively written to. 102 | * (required). 103 | * @param filePattern The pattern of the file name to use on rollover. 104 | * (required). 105 | * @param append If true, events are appended to the file. If false, the 106 | * file is overwritten when opened. Defaults to "true" 107 | * @param name The name of the Appender (required). 108 | * @param immediateFlush When true, events are immediately flushed. Defaults 109 | * to "true". 110 | * @param bufferSizeStr The buffer size, defaults to {@value RollingRandomAccessFileManager#DEFAULT_BUFFER_SIZE}. 111 | * @param policy The triggering policy. (required). 112 | * @param strategy The rollover strategy. Defaults to 113 | * DefaultRolloverStrategy. 114 | * @param layout The layout to use (defaults to the default PatternLayout). 115 | * @param filter The Filter or null. 116 | * @param ignore If {@code "true"} (default) exceptions encountered when appending events are logged; otherwise 117 | * they are propagated to the caller. 118 | * @param advertise "true" if the appender configuration should be 119 | * advertised, "false" otherwise. 120 | * @param advertiseURI The advertised URI which can be used to retrieve the 121 | * file contents. 122 | * @param config The Configuration. 123 | * @return A RollingRandomAccessFileAppender. 124 | */ 125 | @PluginFactory 126 | public static CCIntelliSetupFileAppender createAppender(@PluginAttribute ("fileName") String fileName, @PluginAttribute ("filePattern") String filePattern, @PluginAttribute ("append") String append, @PluginAttribute ("name") String name, @PluginAttribute ("immediateFlush") String immediateFlush, @PluginAttribute ("bufferSize") String bufferSizeStr, @PluginElement ("Policy") TriggeringPolicy policy, @PluginElement ("Strategy") RolloverStrategy strategy, @PluginElement ("Layout") Layout layout, @PluginElement ("Filter") Filter filter, @PluginAttribute ("ignoreExceptions") String ignore, @PluginAttribute ("advertise") String advertise, @PluginAttribute ("advertiseURI") String advertiseURI, @PluginConfiguration Configuration config) { 127 | 128 | final boolean isAppend = Booleans.parseBoolean(append, true); 129 | final boolean ignoreExceptions = Booleans.parseBoolean(ignore, true); 130 | final boolean isFlush = Booleans.parseBoolean(immediateFlush, true); 131 | final boolean isAdvertise = Boolean.parseBoolean(advertise); 132 | final int bufferSize = Integers.parseInt(bufferSizeStr, RollingRandomAccessFileManager.DEFAULT_BUFFER_SIZE); 133 | 134 | if (name == null) { 135 | LOGGER.error("No name provided for FileAppender"); 136 | return null; 137 | } 138 | 139 | if (fileName == null) { 140 | LOGGER.error("No filename was provided for FileAppender with name " + name); 141 | return null; 142 | } 143 | 144 | if (filePattern == null) { 145 | LOGGER.error("No filename pattern provided for FileAppender with name " + name); 146 | return null; 147 | } 148 | 149 | if (policy == null) { 150 | LOGGER.error("A TriggeringPolicy must be provided"); 151 | return null; 152 | } 153 | fileName = Launch.WORKING_DIR.getAbsolutePath() + "/" + fileName; 154 | filePattern = Launch.WORKING_DIR.getAbsolutePath() + "/" + filePattern; 155 | if (strategy == null) { 156 | strategy = DefaultRolloverStrategy.createStrategy(null, null, null, String.valueOf(Deflater.DEFAULT_COMPRESSION), null, true, config); 157 | } 158 | 159 | if (layout == null) { 160 | layout = PatternLayout.createDefaultLayout(); 161 | } 162 | 163 | final RollingRandomAccessFileManager manager = RollingRandomAccessFileManager.getRollingRandomAccessFileManager(fileName, filePattern, isAppend, isFlush, bufferSize, policy, strategy, advertiseURI, layout); 164 | if (manager == null) { 165 | return null; 166 | } 167 | 168 | return new CCIntelliSetupFileAppender(name, layout, filter, manager, fileName, filePattern, ignoreExceptions, isFlush, bufferSize, isAdvertise ? config.getAdvertiser() : null); 169 | } 170 | 171 | } 172 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/util/logging/LogHelper.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.util.logging; 2 | 3 | import org.apache.logging.log4j.Level; 4 | import org.apache.logging.log4j.LogManager; 5 | import org.apache.logging.log4j.Logger; 6 | 7 | /** 8 | * Created by covers1624 on 3/21/2016. 9 | */ 10 | public class LogHelper { 11 | 12 | private static Logger logger = LogManager.getLogger("CCIntelli"); 13 | 14 | /** 15 | * Log with a supplied level. 16 | */ 17 | public static void log(Level logLevel, Object object) { 18 | logger.log(logLevel, String.valueOf(object)); 19 | } 20 | 21 | public static void log(Level logLevel, Object object, Throwable throwable) { 22 | logger.log(logLevel, String.valueOf(object), throwable); 23 | } 24 | 25 | //Standard log entries. 26 | 27 | public static void all(Object object) { 28 | log(Level.ALL, object); 29 | } 30 | 31 | public static void debug(Object object) { 32 | log(Level.DEBUG, object); 33 | } 34 | 35 | public static void error(Object object) { 36 | log(Level.ERROR, object); 37 | } 38 | 39 | public static void fatal(Object object) { 40 | log(Level.FATAL, object); 41 | } 42 | 43 | public static void info(Object object) { 44 | log(Level.INFO, object); 45 | } 46 | 47 | public static void off(Object object) { 48 | log(Level.OFF, object); 49 | } 50 | 51 | public static void trace(Object object) { 52 | log(Level.TRACE, object); 53 | } 54 | 55 | public static void warn(Object object) { 56 | log(Level.WARN, object); 57 | } 58 | 59 | //log with format. 60 | 61 | public static void all(String object, Object... format) { 62 | log(Level.ALL, String.format(object, format)); 63 | } 64 | 65 | public static void debug(String object, Object... format) { 66 | log(Level.DEBUG, String.format(object, format)); 67 | } 68 | 69 | public static void error(String object, Object... format) { 70 | log(Level.ERROR, String.format(object, format)); 71 | } 72 | 73 | public static void fatal(String object, Object... format) { 74 | log(Level.FATAL, String.format(object, format)); 75 | } 76 | 77 | public static void info(String object, Object... format) { 78 | log(Level.INFO, String.format(object, format)); 79 | } 80 | 81 | public static void off(String object, Object... format) { 82 | log(Level.OFF, String.format(object, format)); 83 | } 84 | 85 | public static void trace(String object, Object... format) { 86 | log(Level.TRACE, String.format(object, format)); 87 | } 88 | 89 | public static void warn(String object, Object... format) { 90 | log(Level.WARN, String.format(object, format)); 91 | } 92 | 93 | //Log Throwable with format. 94 | 95 | public static void allError(String object, Throwable throwable, Object... format) { 96 | log(Level.ALL, String.format(object, format), throwable); 97 | } 98 | 99 | public static void debugError(String object, Throwable throwable, Object... format) { 100 | log(Level.DEBUG, String.format(object, format), throwable); 101 | } 102 | 103 | public static void errorError(String object, Throwable throwable, Object... format) { 104 | log(Level.ERROR, String.format(object, format), throwable); 105 | } 106 | 107 | public static void fatalError(String object, Throwable throwable, Object... format) { 108 | log(Level.FATAL, String.format(object, format), throwable); 109 | } 110 | 111 | public static void infoError(String object, Throwable throwable, Object... format) { 112 | log(Level.INFO, String.format(object, format), throwable); 113 | } 114 | 115 | public static void offError(String object, Throwable throwable, Object... format) { 116 | log(Level.OFF, String.format(object, format), throwable); 117 | } 118 | 119 | public static void traceError(String object, Throwable throwable, Object... format) { 120 | log(Level.TRACE, String.format(object, format), throwable); 121 | } 122 | 123 | public static void warnError(String object, Throwable throwable, Object... format) { 124 | log(Level.WARN, String.format(object, format), throwable); 125 | } 126 | 127 | //Log throwable. 128 | public static void allError(String object, Throwable throwable) { 129 | log(Level.ALL, object, throwable); 130 | } 131 | 132 | public static void debugError(String object, Throwable throwable) { 133 | log(Level.DEBUG, object, throwable); 134 | } 135 | 136 | public static void errorError(String object, Throwable throwable) { 137 | log(Level.ERROR, object, throwable); 138 | } 139 | 140 | public static void fatalError(String object, Throwable throwable) { 141 | log(Level.FATAL, object, throwable); 142 | } 143 | 144 | public static void infoError(String object, Throwable throwable) { 145 | log(Level.INFO, object, throwable); 146 | } 147 | 148 | public static void offError(String object, Throwable throwable) { 149 | log(Level.OFF, object, throwable); 150 | } 151 | 152 | public static void traceError(String object, Throwable throwable) { 153 | log(Level.TRACE, object, throwable); 154 | } 155 | 156 | public static void warnError(String object, Throwable throwable) { 157 | log(Level.WARN, object, throwable); 158 | } 159 | 160 | //Log with trace element. 161 | public static void bigAll(String format, Object... data) { 162 | StackTraceElement[] trace = Thread.currentThread().getStackTrace(); 163 | all("****************************************"); 164 | all("* " + format, data); 165 | for (int i = 2; i < 8 && i < trace.length; i++) { 166 | all("* at %s%s", trace[i].toString(), i == 7 ? "..." : ""); 167 | } 168 | all("****************************************"); 169 | } 170 | 171 | public static void bigDebug(String format, Object... data) { 172 | StackTraceElement[] trace = Thread.currentThread().getStackTrace(); 173 | debug("****************************************"); 174 | debug("* " + format, data); 175 | for (int i = 2; i < 8 && i < trace.length; i++) { 176 | debug("* at %s%s", trace[i].toString(), i == 7 ? "..." : ""); 177 | } 178 | debug("****************************************"); 179 | } 180 | 181 | public static void bigError(String format, Object... data) { 182 | StackTraceElement[] trace = Thread.currentThread().getStackTrace(); 183 | error("****************************************"); 184 | error("* " + format, data); 185 | for (int i = 2; i < 8 && i < trace.length; i++) { 186 | error("* at %s%s", trace[i].toString(), i == 7 ? "..." : ""); 187 | } 188 | error("****************************************"); 189 | } 190 | 191 | public static void bigFatal(String format, Object... data) { 192 | StackTraceElement[] trace = Thread.currentThread().getStackTrace(); 193 | fatal("****************************************"); 194 | fatal("* " + format, data); 195 | for (int i = 2; i < 8 && i < trace.length; i++) { 196 | fatal("* at %s%s", trace[i].toString(), i == 7 ? "..." : ""); 197 | } 198 | fatal("****************************************"); 199 | } 200 | 201 | public static void bigInfo(String format, Object... data) { 202 | StackTraceElement[] trace = Thread.currentThread().getStackTrace(); 203 | info("****************************************"); 204 | info("* " + format, data); 205 | for (int i = 2; i < 8 && i < trace.length; i++) { 206 | info("* at %s%s", trace[i].toString(), i == 7 ? "..." : ""); 207 | } 208 | info("****************************************"); 209 | } 210 | 211 | public static void bigOff(String format, Object... data) { 212 | StackTraceElement[] trace = Thread.currentThread().getStackTrace(); 213 | off("****************************************"); 214 | off("* " + format, data); 215 | for (int i = 2; i < 8 && i < trace.length; i++) { 216 | off("* at %s%s", trace[i].toString(), i == 7 ? "..." : ""); 217 | } 218 | off("****************************************"); 219 | } 220 | 221 | public static void bigTrace(String format, Object... data) { 222 | StackTraceElement[] trace = Thread.currentThread().getStackTrace(); 223 | trace("****************************************"); 224 | trace("* " + format, data); 225 | for (int i = 2; i < 8 && i < trace.length; i++) { 226 | trace("* at %s%s", trace[i].toString(), i == 7 ? "..." : ""); 227 | } 228 | trace("****************************************"); 229 | } 230 | 231 | public static void bigWarn(String format, Object... data) { 232 | StackTraceElement[] trace = Thread.currentThread().getStackTrace(); 233 | warn("****************************************"); 234 | warn("* " + format, data); 235 | for (int i = 2; i < 8 && i < trace.length; i++) { 236 | warn("* at %s%s", trace[i].toString(), i == 7 ? "..." : ""); 237 | } 238 | warn("****************************************"); 239 | } 240 | } 241 | -------------------------------------------------------------------------------- /src/main/resources/iwsTemplate.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 13 | 14 | 15 | 28 | 29 | 39 | 40 | 41 | 48 | 51 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 106 | 107 | 108 | 119 | 120 | 121 | 131 | 132 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 194 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | localhost 222 | 5050 223 | 224 | 225 | 226 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/workspace/RunConfigGenerator.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.workspace; 2 | 3 | import covers1624.ccintelli.gui.GuiFields; 4 | import covers1624.ccintelli.launch.Launch; 5 | import org.w3c.dom.Document; 6 | import org.w3c.dom.Element; 7 | 8 | import javax.xml.parsers.DocumentBuilder; 9 | import javax.xml.parsers.DocumentBuilderFactory; 10 | import javax.xml.transform.OutputKeys; 11 | import javax.xml.transform.Transformer; 12 | import javax.xml.transform.TransformerFactory; 13 | import javax.xml.transform.dom.DOMSource; 14 | import javax.xml.transform.stream.StreamResult; 15 | import java.io.File; 16 | import java.util.ArrayList; 17 | import java.util.List; 18 | 19 | import static covers1624.util.XMLUtils.createAndAdd; 20 | import static covers1624.util.XMLUtils.getFirstElementNode; 21 | 22 | /** 23 | * Created by covers1624 on 20/02/2017. 24 | */ 25 | public class RunConfigGenerator { 26 | 27 | public static void generateRunConfigs(String projectName) { 28 | File workspaceIWS = new File(Launch.WORKSPACE, projectName + ".iws"); 29 | try { 30 | List vmArgs = new ArrayList<>(); 31 | 32 | vmArgs.addAll(GuiFields.vmArgs); 33 | 34 | if (!GuiFields.fmlCorePlugins.isEmpty()) { 35 | StringBuilder builder = new StringBuilder("-Dfml.coreMods.load="); 36 | boolean hasFirst = false; 37 | for (String corePlugin : GuiFields.fmlCorePlugins) { 38 | if (hasFirst) { 39 | builder.append(","); 40 | } 41 | hasFirst = true; 42 | builder.append(corePlugin); 43 | } 44 | vmArgs.add(builder.toString()); 45 | } 46 | 47 | DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 48 | DocumentBuilder builder = factory.newDocumentBuilder(); 49 | Document document = builder.parse(RunConfigGenerator.class.getResourceAsStream("/iwsTemplate.xml")); 50 | document.getDocumentElement().normalize(); 51 | 52 | Element documentElement = document.getDocumentElement(); 53 | Element componentElement = getFirstElementNode(documentElement, "component"); 54 | { 55 | Element clientRun = createAndAdd(document, componentElement, "configuration"); 56 | clientRun.setAttribute("factoryName", "Application"); 57 | clientRun.setAttribute("type", "Application"); 58 | clientRun.setAttribute("name", "Minecraft Client"); 59 | clientRun.setAttribute("default", "false"); 60 | Element extension = createAndAdd(document, clientRun, "extension"); 61 | extension.setAttribute("runner", "idea"); 62 | extension.setAttribute("merge", "false"); 63 | extension.setAttribute("enabled", "false"); 64 | extension.setAttribute("name", "coverage"); 65 | Element mainClassOpt = createAndAdd(document, clientRun, "option"); 66 | mainClassOpt.setAttribute("value", "GradleStart"); 67 | mainClassOpt.setAttribute("name", "MAIN_CLASS_NAME"); 68 | StringBuilder argBuilder = new StringBuilder(); 69 | boolean hasFirst = false; 70 | for (String arg : vmArgs) { 71 | if (hasFirst) { 72 | argBuilder.append(" "); 73 | } 74 | hasFirst = true; 75 | argBuilder.append(arg); 76 | } 77 | Element vmArgsOpt = createAndAdd(document, clientRun, "option"); 78 | vmArgsOpt.setAttribute("value", argBuilder.toString()); 79 | vmArgsOpt.setAttribute("name", "VM_PARAMETERS"); 80 | Element progArgsOpt = createAndAdd(document, clientRun, "option"); 81 | progArgsOpt.setAttribute("value", ""); 82 | progArgsOpt.setAttribute("name", "PROGRAM_PARAMETERS"); 83 | Element workingDirOpt = createAndAdd(document, clientRun, "option"); 84 | workingDirOpt.setAttribute("value", "file://" + Launch.PROJECT_RUN.getAbsoluteFile().getPath()); 85 | workingDirOpt.setAttribute("name", "WORKING_DIRECTORY"); 86 | Element altJERpathEnableOpt = createAndAdd(document, clientRun, "option"); 87 | altJERpathEnableOpt.setAttribute("value", "false"); 88 | altJERpathEnableOpt.setAttribute("name", "ALTERNATIVE_JRE_PATH_ENABLED"); 89 | Element aldJrePathOpt = createAndAdd(document, clientRun, "option"); 90 | aldJrePathOpt.setAttribute("name", "ALTERNATIVE_JRE_PATH"); 91 | Element swingInspecOpt = createAndAdd(document, clientRun, "option"); 92 | swingInspecOpt.setAttribute("value", "false"); 93 | swingInspecOpt.setAttribute("name", "ENABLE_SWING_INSPECTOR"); 94 | Element envVarsOpt = createAndAdd(document, clientRun, "option"); 95 | envVarsOpt.setAttribute("name", "ENV_VARIABLES"); 96 | Element passParentEnvsOpt = createAndAdd(document, clientRun, "option"); 97 | passParentEnvsOpt.setAttribute("value", "true"); 98 | passParentEnvsOpt.setAttribute("name", "PASS_PARENT_ENVS"); 99 | 100 | Element moduleClassPathElement = createAndAdd(document, clientRun, "module"); 101 | moduleClassPathElement.setAttribute("name", GuiFields.forgeModule.NAME); 102 | createAndAdd(document, clientRun, "envs"); 103 | createAndAdd(document, clientRun, "method"); 104 | } 105 | { 106 | Element serverRun = createAndAdd(document, componentElement, "configuration"); 107 | serverRun.setAttribute("factoryName", "Application"); 108 | serverRun.setAttribute("type", "Application"); 109 | serverRun.setAttribute("name", "Minecraft Server"); 110 | serverRun.setAttribute("default", "false"); 111 | Element extension = createAndAdd(document, serverRun, "extension"); 112 | extension.setAttribute("runner", "idea"); 113 | extension.setAttribute("merge", "false"); 114 | extension.setAttribute("enabled", "false"); 115 | extension.setAttribute("name", "coverage"); 116 | Element mainClassOpt = createAndAdd(document, serverRun, "option"); 117 | mainClassOpt.setAttribute("value", "GradleStartServer"); 118 | mainClassOpt.setAttribute("name", "MAIN_CLASS_NAME"); 119 | StringBuilder argBuilder = new StringBuilder(); 120 | boolean hasFirst = false; 121 | for (String arg : vmArgs) { 122 | if (hasFirst) { 123 | argBuilder.append(" "); 124 | } 125 | hasFirst = true; 126 | argBuilder.append(arg); 127 | } 128 | Element vmArgsOpt = createAndAdd(document, serverRun, "option"); 129 | vmArgsOpt.setAttribute("value", argBuilder.toString()); 130 | vmArgsOpt.setAttribute("name", "VM_PARAMETERS"); 131 | Element progArgsOpt = createAndAdd(document, serverRun, "option"); 132 | progArgsOpt.setAttribute("value", ""); 133 | progArgsOpt.setAttribute("name", "PROGRAM_PARAMETERS"); 134 | Element workingDirOpt = createAndAdd(document, serverRun, "option"); 135 | workingDirOpt.setAttribute("value", "file://" + Launch.PROJECT_RUN.getAbsoluteFile().getPath()); 136 | workingDirOpt.setAttribute("name", "WORKING_DIRECTORY"); 137 | Element altJERpathEnableOpt = createAndAdd(document, serverRun, "option"); 138 | altJERpathEnableOpt.setAttribute("value", "false"); 139 | altJERpathEnableOpt.setAttribute("name", "ALTERNATIVE_JRE_PATH_ENABLED"); 140 | Element aldJrePathOpt = createAndAdd(document, serverRun, "option"); 141 | aldJrePathOpt.setAttribute("name", "ALTERNATIVE_JRE_PATH"); 142 | Element swingInspecOpt = createAndAdd(document, serverRun, "option"); 143 | swingInspecOpt.setAttribute("value", "false"); 144 | swingInspecOpt.setAttribute("name", "ENABLE_SWING_INSPECTOR"); 145 | Element envVarsOpt = createAndAdd(document, serverRun, "option"); 146 | envVarsOpt.setAttribute("name", "ENV_VARIABLES"); 147 | Element passParentEnvsOpt = createAndAdd(document, serverRun, "option"); 148 | passParentEnvsOpt.setAttribute("value", "true"); 149 | passParentEnvsOpt.setAttribute("name", "PASS_PARENT_ENVS"); 150 | 151 | Element moduleClassPathElement = createAndAdd(document, serverRun, "module"); 152 | moduleClassPathElement.setAttribute("name", GuiFields.forgeModule.NAME); 153 | createAndAdd(document, serverRun, "envs"); 154 | createAndAdd(document, serverRun, "method"); 155 | } 156 | 157 | Element listElement = getFirstElementNode(componentElement, "list"); 158 | listElement.setAttribute("size", "2"); 159 | Element clientChild = createAndAdd(document, listElement, "item"); 160 | clientChild.setAttribute("itemvalue", "Application.Minecraft Client"); 161 | clientChild.setAttribute("class", "java.lang.String"); 162 | clientChild.setAttribute("index", "0"); 163 | 164 | Element serverChild = createAndAdd(document, listElement, "item"); 165 | serverChild.setAttribute("itemvalue", "Application.Minecraft Server"); 166 | serverChild.setAttribute("class", "java.lang.String"); 167 | serverChild.setAttribute("index", "1"); 168 | 169 | TransformerFactory transformerFactory = TransformerFactory.newInstance(); 170 | Transformer transformer = transformerFactory.newTransformer(); 171 | transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 172 | transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); 173 | DOMSource source = new DOMSource(document); 174 | StreamResult result = new StreamResult(workspaceIWS); 175 | transformer.transform(source, result); 176 | 177 | } catch (Exception e) { 178 | e.printStackTrace(); 179 | //throw new RuntimeException("Exception thrown whilst generating run configs.", e); 180 | } 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /src/main/java/covers1624/launchwrapper/LauncherDownloader.java: -------------------------------------------------------------------------------- 1 | package covers1624.launchwrapper; 2 | 3 | import com.google.gson.JsonArray; 4 | import com.google.gson.JsonElement; 5 | import com.google.gson.JsonObject; 6 | import com.google.gson.JsonParser; 7 | import com.google.gson.stream.JsonReader; 8 | import covers1624.launchwrapper.digest.MD5Sum; 9 | import covers1624.launchwrapper.digest.MD5SumCruncher; 10 | import covers1624.launchwrapper.gui.ILauncherDisplay; 11 | import covers1624.launchwrapper.gui.LauncherGui; 12 | import covers1624.launchwrapper.os.OSManager; 13 | import covers1624.launchwrapper.os.OSManager.EnumOS; 14 | import covers1624.launchwrapper.util.Downloader; 15 | import covers1624.launchwrapper.util.PairKV; 16 | import covers1624.launchwrapper.util.ThreadUtils; 17 | 18 | import java.io.*; 19 | import java.lang.reflect.Field; 20 | import java.net.URL; 21 | import java.util.*; 22 | import java.util.Map.Entry; 23 | import java.util.jar.JarFile; 24 | import java.util.zip.ZipEntry; 25 | 26 | /** 27 | * Created by covers1624 on 2/15/2016. 28 | */ 29 | public class LauncherDownloader { 30 | 31 | private static ILauncherDisplay display; 32 | private static boolean DEBUG = Boolean.parseBoolean(System.getProperty("covers1624.launchwrapper.debug", "false")); 33 | 34 | private static Map, File> downloadSumMap = new HashMap<>(); 35 | private static Map>> nativeExtractMap = new HashMap<>(); 36 | 37 | private static List invalidFiles = new ArrayList<>(); 38 | 39 | private static String name; 40 | private static InputStream dependenciesStream; 41 | private static File libsDirectory; 42 | private static File nativesDirectory; 43 | private static File cacheStore; 44 | 45 | public static void checkDependencies(String name, InputStream dependenciesFile, File libsDirectory, File nativesDirectory, File cacheStore) { 46 | info("[INFO]: LaunchWrapper is setting up!"); 47 | LauncherDownloader.name = name; 48 | LauncherDownloader.dependenciesStream = dependenciesFile; 49 | LauncherDownloader.libsDirectory = libsDirectory; 50 | LauncherDownloader.nativesDirectory = nativesDirectory; 51 | LauncherDownloader.cacheStore = cacheStore; 52 | 53 | display = new LauncherGui(name); 54 | display.init(); 55 | 56 | try { 57 | parseJson(); 58 | deleteFiles(); 59 | doDownloadAndExtract(); 60 | 61 | finish(); 62 | } catch (Exception e) { 63 | throw new RuntimeException(e); 64 | } finally { 65 | if (display != null) { 66 | display.dispose(); 67 | } 68 | injectDependencies(); 69 | hackNatives(); 70 | } 71 | info("[INFO]: LaunchWrapper has finished!"); 72 | 73 | } 74 | 75 | private static void parseJson() throws Exception { 76 | EnumOS currOS = OSManager.getCurrentOS(); 77 | JsonReader reader = new JsonReader(new InputStreamReader(dependenciesStream)); 78 | JsonParser parser = new JsonParser(); 79 | JsonObject object = parser.parse(reader).getAsJsonObject(); 80 | 81 | JsonArray deps = object.getAsJsonArray("dependencies"); 82 | if (nativesDirectory == null) { 83 | info("[INFO]: LaunchWrapper will not parse natives as the folder is null."); 84 | } 85 | 86 | for (JsonElement e : deps) { 87 | JsonObject dep = e.getAsJsonObject(); 88 | URL url = new URL(dep.get("url").getAsString()); 89 | MD5Sum md5 = new MD5Sum(dep.get("md5").getAsString()); 90 | File downloadFile = parseURLToFile(url, libsDirectory); 91 | boolean markedForRemoval = false; 92 | if (dep.has("os")) { 93 | EnumOS os = OSManager.parseFromString(dep.get("os").getAsString()); 94 | if (!os.equals(currOS)) { 95 | markedForRemoval = true; 96 | } 97 | } 98 | if (dep.has("natives") && nativesDirectory != null) { 99 | downloadFile = parseURLToFile(url, cacheStore); 100 | List> natives = new ArrayList<>(); 101 | for (JsonElement nE : dep.getAsJsonArray("natives")) { 102 | JsonObject nat = nE.getAsJsonObject(); 103 | String file = nat.get("file").getAsString(); 104 | MD5Sum nSum = new MD5Sum(nat.get("md5").getAsString()); 105 | natives.add(new PairKV<>(file, nSum)); 106 | if (markedForRemoval) { 107 | invalidFiles.add(new File(nativesDirectory, file)); 108 | } 109 | } 110 | if (!markedForRemoval) { 111 | nativeExtractMap.put(downloadFile, natives); 112 | } 113 | } 114 | 115 | if (markedForRemoval) { 116 | invalidFiles.add(downloadFile); 117 | } else { 118 | downloadSumMap.put(new PairKV<>(url, md5), downloadFile); 119 | } 120 | } 121 | List libFolderList = new ArrayList<>(); 122 | addAllFilesList(libsDirectory, libFolderList); 123 | for (Entry, File> entry : downloadSumMap.entrySet()) { 124 | if (entry.getValue().exists()) { 125 | if (!entry.getKey().getValue().equals(MD5SumCruncher.calculateFileSum(entry.getValue()))) { 126 | invalidFiles.add(entry.getValue()); 127 | } 128 | } 129 | } 130 | for (File file : libFolderList) { 131 | PairKV pair = getValueFromKey(downloadSumMap, file); 132 | if (pair == null) { 133 | invalidFiles.add(file); 134 | } 135 | } 136 | 137 | if (nativesDirectory != null) { 138 | List nativeFolderList = new ArrayList<>(); 139 | addAllFilesList(nativesDirectory, nativeFolderList); 140 | for (Entry>> entry : nativeExtractMap.entrySet()) { 141 | if (entry.getKey().exists()) { 142 | PairKV sumPair = getValueFromKey(downloadSumMap, entry.getKey()); 143 | if (sumPair == null) { 144 | invalidFiles.add(entry.getKey()); 145 | continue; 146 | } 147 | if (!sumPair.getValue().equals(MD5SumCruncher.calculateFileSum(entry.getKey()))) { 148 | invalidFiles.add(entry.getKey()); 149 | } 150 | for (PairKV pair : entry.getValue()) { 151 | File nFile = new File(nativesDirectory, pair.getKey()); 152 | if (nFile.exists()) { 153 | if (!pair.getValue().equals(MD5SumCruncher.calculateFileSum(nFile))) { 154 | invalidFiles.add(nFile); 155 | } 156 | } 157 | } 158 | } 159 | } 160 | 161 | List allNativesExtract = new ArrayList<>(); 162 | for (List> list : nativeExtractMap.values()) { 163 | for (PairKV pair : list) { 164 | File nFile = new File(nativesDirectory, pair.getKey()); 165 | allNativesExtract.add(nFile); 166 | } 167 | } 168 | 169 | for (File file : nativeFolderList) { 170 | if (!allNativesExtract.contains(file)) { 171 | invalidFiles.add(file); 172 | } 173 | } 174 | } 175 | 176 | Collections.sort(invalidFiles); 177 | 178 | if (DEBUG) { 179 | info("[DEBUG]: Invalid Files:"); 180 | for (File file : invalidFiles) { 181 | info("[DEBUG]: " + file); 182 | info("[DEBUG]: \t%s", MD5SumCruncher.calculateFileSum(file)); 183 | } 184 | 185 | info("[DEBUG]: Files to download:"); 186 | for (Entry, File> entry : downloadSumMap.entrySet()) { 187 | info("[DEBUG]: " + entry.getKey().getKey()); 188 | info("[DEBUG]: \t%s", entry.getKey().getValue()); 189 | info("[DEBUG]: \t%s", entry.getValue()); 190 | } 191 | info("[DEBUG]: Natives to extract:"); 192 | for (Entry>> entry : nativeExtractMap.entrySet()) { 193 | info("[DEBUG]: " + entry.getKey()); 194 | for (PairKV pair : entry.getValue()) { 195 | info("[DEBUG]: \t%s", pair.getKey()); 196 | info("[DEBUG]: \t\t%s", pair.getValue()); 197 | } 198 | } 199 | } 200 | } 201 | 202 | private static void deleteFiles() { 203 | boolean shouldExit = false; 204 | for (File file : invalidFiles) { 205 | if (file.exists()) { 206 | if (!file.delete()) { 207 | shouldExit = true; 208 | info("[WARN]: Unable to delete file! Marked for delete on exit and the program will have to be launched again."); 209 | info("[WARN]: If this message appears again. You will have to manually delete the file."); 210 | info("[WARN]: File: %s", file.getAbsoluteFile()); 211 | file.deleteOnExit(); 212 | } 213 | } 214 | } 215 | if (shouldExit) { 216 | info("[WARN]: Exiting as Files were not properly deleted."); 217 | System.exit(-1); 218 | throw new RuntimeException("Files failed to delete.");//This shouldn't be called but meh. 219 | } 220 | } 221 | 222 | private static void doDownloadAndExtract() throws IOException { 223 | for (Entry, File> entry : downloadSumMap.entrySet()) { 224 | if (!entry.getKey().getValue().equals(MD5SumCruncher.calculateFileSum(entry.getValue()))) { 225 | Downloader.download(entry.getKey().getKey(), entry.getValue(), display); 226 | } 227 | } 228 | if (nativesDirectory != null) { 229 | for (Entry>> entry : nativeExtractMap.entrySet()) { 230 | info("[DEBUG]: " + entry.getKey()); 231 | JarFile jar = new JarFile(entry.getKey()); 232 | for (PairKV pair : entry.getValue()) { 233 | ZipEntry zipEntry = jar.getEntry(pair.getKey()); 234 | File nativeFile = new File(nativesDirectory, pair.getKey()); 235 | if (!pair.getValue().equals(MD5SumCruncher.calculateFileSum(nativeFile))) { 236 | info("[DEBUG]: Extracting file: " + pair.getKey()); 237 | if (!nativeFile.exists()) { 238 | nativeFile.createNewFile(); 239 | } 240 | InputStream stream = jar.getInputStream(zipEntry); 241 | Downloader.copyISManaged(stream, new FileOutputStream(nativeFile), stream.available(), display); 242 | } 243 | } 244 | } 245 | } 246 | } 247 | 248 | private static void info(Object obj, Object... format) { 249 | System.out.println(String.format(obj.toString(), format)); 250 | } 251 | 252 | private static void injectDependencies() { 253 | File[] files = libsDirectory.listFiles(); 254 | try { 255 | if (files != null) { 256 | for (File file : files) { 257 | Downloader.injectLibToClassLoader(file); 258 | } 259 | } else { 260 | System.err.println("Libs folder empty... This is probably a bug."); 261 | throw new RuntimeException("Libs folder empty."); 262 | } 263 | } catch (Exception e) { 264 | info("[WARN]: Error occurred whilst adding libs."); 265 | e.printStackTrace(); 266 | System.exit(-1); 267 | } 268 | } 269 | 270 | private static void hackNatives() { 271 | if (nativesDirectory != null) { 272 | System.out.println("Injecting natives dir to ClassLoader.."); 273 | try { 274 | String paths = System.getProperty("java.library.path"); 275 | String nativesDir = nativesDirectory.getAbsolutePath(); 276 | 277 | paths = (paths == null || paths.isEmpty()) ? nativesDir : (paths + File.pathSeparator + nativesDir); 278 | System.setProperty("java.library.path", paths); 279 | 280 | // hack the classloader now. 281 | Field sysPathsField = ClassLoader.class.getDeclaredField("sys_paths"); 282 | sysPathsField.setAccessible(true); 283 | sysPathsField.set(null, null); 284 | } catch (Throwable t) { 285 | System.err.println("Error occurred whilst hacking natives to the ClassLoader.."); 286 | t.printStackTrace(); 287 | System.exit(-1); 288 | } 289 | } 290 | } 291 | 292 | private static K getValueFromKey(Map map, V value) { 293 | for (Entry entry : map.entrySet()) { 294 | if (entry.getValue().equals(value)) { 295 | return entry.getKey(); 296 | } 297 | } 298 | return null; 299 | } 300 | 301 | private static void addAllFilesList(File folderToList, List list) { 302 | File[] files = folderToList.listFiles(); 303 | if (files != null) { 304 | for (File file : files) { 305 | if (!file.isDirectory()) { 306 | list.add(file); 307 | } 308 | } 309 | } 310 | } 311 | 312 | private static File parseURLToFile(URL url, File folder) { 313 | String str = url.toString(); 314 | return new File(folder, str.substring(str.lastIndexOf("/") + 1)); 315 | } 316 | 317 | private static void finish() { 318 | display.resetProgress(1); 319 | display.updateProgress(1); 320 | display.setPokeThread(null); 321 | display.updateProgressString("Dependencies downloaded! Launching.."); 322 | ThreadUtils.hangThread(500); 323 | } 324 | } 325 | -------------------------------------------------------------------------------- /src/main/java/covers1624/ccintelli/workspace/ProjectGenerator.java: -------------------------------------------------------------------------------- 1 | package covers1624.ccintelli.workspace; 2 | 3 | import com.google.common.base.Strings; 4 | import com.google.common.collect.ImmutableList; 5 | import com.google.common.collect.ImmutableMap; 6 | import covers1624.ccintelli.gui.GuiFields; 7 | import covers1624.ccintelli.launch.Launch; 8 | import covers1624.ccintelli.module.Module; 9 | import covers1624.ccintelli.util.logging.LogHelper; 10 | import org.w3c.dom.Document; 11 | import org.w3c.dom.Element; 12 | 13 | import javax.xml.parsers.DocumentBuilder; 14 | import javax.xml.parsers.DocumentBuilderFactory; 15 | import javax.xml.transform.OutputKeys; 16 | import javax.xml.transform.Transformer; 17 | import javax.xml.transform.TransformerFactory; 18 | import javax.xml.transform.dom.DOMSource; 19 | import javax.xml.transform.stream.StreamResult; 20 | import java.io.File; 21 | import java.util.*; 22 | import java.util.Map.Entry; 23 | 24 | /** 25 | * Created by covers1624 on 11/02/2017. 26 | */ 27 | public class ProjectGenerator { 28 | 29 | private static List> resourceExtensionAttributes; 30 | private static List> wildcardResoaurceAttibutes; 31 | private static List> javadocGenerationAttributes; 32 | 33 | static { 34 | List> tempMap = new LinkedList<>(); 35 | 36 | tempMap.add(ImmutableMap.of("name", ".+\\.(properties|xml|html|dtd|tld)")); 37 | tempMap.add(ImmutableMap.of("name", ".+\\.(gif|png|jpeg|jpg)")); 38 | 39 | resourceExtensionAttributes = ImmutableList.copyOf(tempMap); 40 | tempMap.clear(); 41 | 42 | tempMap.add(ImmutableMap.of("name", "!?*.class")); 43 | tempMap.add(ImmutableMap.of("name", "!?*.scala")); 44 | tempMap.add(ImmutableMap.of("name", "!?*.groovy")); 45 | tempMap.add(ImmutableMap.of("name", "!?*.java")); 46 | wildcardResoaurceAttibutes = ImmutableList.copyOf(tempMap); 47 | tempMap.clear(); 48 | 49 | tempMap.add(ImmutableMap.of("name", "OUTPUT_DIRECTORY")); 50 | tempMap.add(ImmutableMap.of("name", "OPTION_SCOPE", "value", "protected")); 51 | tempMap.add(ImmutableMap.of("name", "OPTION_HIERARCHY", "value", "true")); 52 | tempMap.add(ImmutableMap.of("name", "OPTION_NAVIGATOR", "value", "true")); 53 | tempMap.add(ImmutableMap.of("name", "OPTION_INDEX", "value", "true")); 54 | tempMap.add(ImmutableMap.of("name", "OPTION_SEPARATE_INDEX", "value", "true")); 55 | tempMap.add(ImmutableMap.of("name", "OPTION_DOCUMENT_TAG_USE", "value", "false")); 56 | tempMap.add(ImmutableMap.of("name", "OPTION_DOCUMENT_TAG_AUTHOR", "value", "false")); 57 | tempMap.add(ImmutableMap.of("name", "OPTION_DOCUMENT_TAG_VERSION", "value", "false")); 58 | tempMap.add(ImmutableMap.of("name", "OPTION_DOCUMENT_TAG_DEPRECATED", "value", "false")); 59 | tempMap.add(ImmutableMap.of("name", "OPTION_DEPRECATED_LIST", "value", "false")); 60 | tempMap.add(ImmutableMap.of("name", "OTHER_OPTIONS", "value", "")); 61 | tempMap.add(ImmutableMap.of("name", "HEAP_SIZE")); 62 | tempMap.add(ImmutableMap.of("name", "LOCALE")); 63 | tempMap.add(ImmutableMap.of("name", "OPEN_IN_BROWSER", "value", "true")); 64 | javadocGenerationAttributes = ImmutableList.copyOf(tempMap); 65 | } 66 | 67 | 68 | public static void generateWorkspace(String projectName) { 69 | LogHelper.info("Generating Project configuration.."); 70 | File workspaceIPR = new File(Launch.WORKSPACE, projectName + ".ipr"); 71 | try { 72 | 73 | DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 74 | DocumentBuilder builder = factory.newDocumentBuilder(); 75 | Document document = builder.newDocument(); 76 | document.setXmlVersion("1.0"); 77 | document.setXmlStandalone(true); 78 | 79 | Element projectElement = document.createElement("project"); 80 | document.appendChild(projectElement); 81 | 82 | projectElement.setAttribute("version", "4"); 83 | {// Compiler 84 | Element compilerComponent = document.createElement("component"); 85 | projectElement.appendChild(compilerComponent); 86 | compilerComponent.setAttribute("name", "CompilerConfiguration"); 87 | 88 | Element defaultCompiler = document.createElement("option"); 89 | compilerComponent.appendChild(defaultCompiler); 90 | defaultCompiler.setAttribute("value", Launch.COMPILER_SELECT); 91 | defaultCompiler.setAttribute("name", "DEFAULT_COMPILER"); 92 | 93 | Element notNullAssertions = document.createElement("addNotNullAssertions"); 94 | compilerComponent.appendChild(notNullAssertions); 95 | notNullAssertions.setAttribute("enabled", String.valueOf(Launch.NOT_NULL_ASSERTIONS).toLowerCase(Locale.US)); 96 | 97 | Element resourceExtensions = document.createElement("resourceExtensions"); 98 | compilerComponent.appendChild(resourceExtensions); 99 | appendBatchedAttributes(document, resourceExtensions, "entry", resourceExtensionAttributes); 100 | 101 | Element wildResourcePatterns = document.createElement("wildcardResourcePatterns"); 102 | compilerComponent.appendChild(wildResourcePatterns); 103 | appendBatchedAttributes(document, wildResourcePatterns, "entry", wildcardResoaurceAttibutes); 104 | 105 | Element annotationProcessing = document.createElement("annotationProcessing"); 106 | compilerComponent.appendChild(annotationProcessing); 107 | annotationProcessing.setAttribute("enabled", "false"); 108 | annotationProcessing.setAttribute("useClasspath", "true"); 109 | 110 | Element bytecodeLevel = document.createElement("bytecodeTargetLevel"); 111 | compilerComponent.appendChild(bytecodeLevel); 112 | bytecodeLevel.setAttribute("target", GuiFields.projectBytecodeLevel.getBytecodeTarget()); 113 | 114 | List> moduleByteCodeLevels = new LinkedList<>(); 115 | for (Module module : GuiFields.modules) { 116 | moduleByteCodeLevels.add(ImmutableMap.of("name", module.NAME, "target", module.bytecodeLevel.getBytecodeTarget())); 117 | } 118 | appendBatchedAttributes(document, bytecodeLevel, "module", moduleByteCodeLevels); 119 | } 120 | 121 | {// Copyright 122 | Element copyrightComponent = document.createElement("component"); 123 | projectElement.appendChild(copyrightComponent); 124 | copyrightComponent.setAttribute("name", "CopyrightManager"); 125 | copyrightComponent.setAttribute("default", ""); 126 | copyrightComponent.appendChild(document.createElement("module2copyright")); 127 | } 128 | 129 | {// DependencyValidation 130 | Element dependencyCoponent = document.createElement("component"); 131 | projectElement.appendChild(dependencyCoponent); 132 | dependencyCoponent.setAttribute("name", "DependencyValidationManager"); 133 | Element option1 = document.createElement("option"); 134 | dependencyCoponent.appendChild(option1); 135 | option1.setAttribute("name", "SKIP_IMPORT_STATEMENTS"); 136 | option1.setAttribute("value", "false"); 137 | } 138 | 139 | {// Encoding 140 | Element encodingComponent = document.createElement("component"); 141 | projectElement.appendChild(encodingComponent); 142 | encodingComponent.setAttribute("name", "Encoding"); 143 | encodingComponent.setAttribute("useUTFGuessing", "true"); 144 | encodingComponent.setAttribute("native2AsciiForPropertiesFiles", "false"); 145 | } 146 | 147 | {// GradleUiSettings 148 | Element gradleSettingElement = document.createElement("component"); 149 | projectElement.appendChild(gradleSettingElement); 150 | gradleSettingElement.setAttribute("name", "GradleUISettings"); 151 | Element setting1 = document.createElement("setting"); 152 | gradleSettingElement.appendChild(setting1); 153 | setting1.setAttribute("name", "root"); 154 | } 155 | 156 | {// GradleUiSettings2 157 | Element gradleSettingElement = document.createElement("component"); 158 | projectElement.appendChild(gradleSettingElement); 159 | gradleSettingElement.setAttribute("name", "GradleUISettings2"); 160 | Element setting1 = document.createElement("setting"); 161 | gradleSettingElement.appendChild(setting1); 162 | setting1.setAttribute("name", "root"); 163 | } 164 | 165 | {// IdProvider 166 | Element idProviderComponent = document.createElement("component"); 167 | projectElement.appendChild(idProviderComponent); 168 | idProviderComponent.setAttribute("name", "IdProvider"); 169 | idProviderComponent.setAttribute("IDEtalkID", "11DA1DB66DD62DDA1ED602B7079FE97C"); 170 | } 171 | 172 | {// JavadocGeneration 173 | Element javadocGenerationComponent = document.createElement("component"); 174 | projectElement.appendChild(javadocGenerationComponent); 175 | javadocGenerationComponent.setAttribute("name", "javadocGenerationManager"); 176 | appendBatchedAttributes(document, javadocGenerationComponent, "option", javadocGenerationAttributes); 177 | } 178 | 179 | {// Modules! 180 | Element moduleComponent = document.createElement("component"); 181 | projectElement.appendChild(moduleComponent); 182 | moduleComponent.setAttribute("name", "ProjectModuleManager"); 183 | Element modulesElement = document.createElement("modules"); 184 | moduleComponent.appendChild(modulesElement); 185 | 186 | for (Module module : GuiFields.modules) { 187 | Element moduleElement = document.createElement("module"); 188 | modulesElement.appendChild(moduleElement); 189 | File file = new File(Launch.MODULES, module.NAME + ".iml"); 190 | moduleElement.setAttribute("filepath", file.getAbsolutePath()); 191 | moduleElement.setAttribute("fileurl", "file://" + file.getAbsolutePath()); 192 | if (!Strings.isNullOrEmpty(module.GROUP)) { 193 | moduleElement.setAttribute("group", module.GROUP); 194 | } 195 | } 196 | } 197 | 198 | { //ProjectRoot 199 | Element projectRootComponent = document.createElement("component"); 200 | projectElement.appendChild(projectRootComponent); 201 | projectRootComponent.setAttribute("name", "ProjectRootManager"); 202 | projectRootComponent.setAttribute("version", "2"); 203 | projectRootComponent.setAttribute("languageLevel", GuiFields.projectLangLevel.getXMLName());//TODO See other TODO above. 204 | projectRootComponent.setAttribute("assert-keyword", "true"); 205 | projectRootComponent.setAttribute("jdk-15", "true"); 206 | projectRootComponent.setAttribute("project-jdk-type", "JavaSDK"); 207 | projectRootComponent.setAttribute("assert-jdk-15", "true"); 208 | projectRootComponent.setAttribute("project-jdk-name", "1.8"); 209 | 210 | Element outputElement = document.createElement("output"); 211 | projectRootComponent.appendChild(outputElement); 212 | outputElement.setAttribute("url", "file://" + Launch.PROJECT_OUTPUT.getAbsolutePath()); 213 | } 214 | 215 | TransformerFactory transformerFactory = TransformerFactory.newInstance(); 216 | Transformer transformer = transformerFactory.newTransformer(); 217 | transformer.setOutputProperty(OutputKeys.INDENT, "yes"); 218 | transformer.setOutputProperty("{http://xml.apache.org/xslt}indent-amount", "2"); 219 | DOMSource source = new DOMSource(document); 220 | StreamResult result = new StreamResult(workspaceIPR); 221 | transformer.transform(source, result); 222 | } catch (Exception e) { 223 | throw new RuntimeException("Something went wrong generating the Workspace.ipr", e); 224 | } 225 | } 226 | 227 | public static void appendBatchedAttributes(Document document, Element parent, String elementName, List> valueMap) { 228 | for (Map values : valueMap) { 229 | Element element = document.createElement(elementName); 230 | parent.appendChild(element); 231 | for (Entry entry : values.entrySet()) { 232 | element.setAttribute(entry.getKey(), entry.getValue()); 233 | } 234 | } 235 | } 236 | 237 | } 238 | --------------------------------------------------------------------------------