diff --git a/README.md b/README.md index 7dc8678..32f6449 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,33 @@ languages. These modules will include the generated code for a parser that can read described data structure from a file / stream and give access to it in a nice, easy-to-comprehend API. +## Build +Install java, maven and, if on windows, git-bash + +First, install dependencies into local maven repository: + +```bash +mvn install:install-file -Dfile=lib/HexLib.jar -DgroupId=at.HexLib -DartifactId=HexLib -Dversion=0.0.0 -Dpackaging=jar -DlocalRepositoryPath=./lib +``` + +Then build project as usual: + +```bash +mvn install +``` + +If you got error: +```bash +[WARNING] The POM for kaitai_struct_visualizer_java:HexLib:jar:0.0.0 is missing, no dependency information available +``` +it means, that you already tried to build project without success and maven cache +unsuccessful state of dependency resolution. Just add switch `-U` to maven invocation +to force maven re-check dependencies: + +```bash +$ mvn -U install +``` + ## Licensing This GUI vis tool project itself is copyright (C) 2016-2019 Kaitai diff --git a/pom.xml b/pom.xml index a50629f..9ce6f71 100644 --- a/pom.xml +++ b/pom.xml @@ -2,56 +2,114 @@ - 4.0.0 - - groupId - kaitai_struct_visualizer_java - 0.5-SNAPSHOT - - - - io.kaitai - kaitai-struct-runtime - 0.8-SNAPSHOT - - - io.kaitai - kaitai-struct-compiler_2.11 - 0.5-SNAPSHOT - - - at.HexLib - HexLib - 0.0.0 - system - ${project.basedir}/lib/HexLib.jar - - - - - - - org.apache.maven.plugins - maven-compiler-plugin - 3.0 - - 1.7 - 1.7 - - - - - - - - - oss-sonatype - oss-sonatype - https://oss.sonatype.org/content/repositories/snapshots/ - - true - - - + 4.0.0 + + groupId + kaitai_struct_visualizer_java + jar + 0.8-SNAPSHOT + + http://kaitai.io + + + + GPL-3.0 + https://opensource.org/licenses/GPL-3.0 + + + + + scm:git:git://github.com/kaitai-io/kaitai_struct_gui.git + scm:git:ssh://github.com:kaitai-io/kaitai_struct_gui.git + https://github.com/kaitai-io/kaitai_struct_gui/tree/master + + + + UTF-8 + + + + + io.kaitai + kaitai-struct-runtime + 0.8 + + + io.kaitai + kaitai-struct-compiler_2.12 + 0.8 + + + at.HexLib + HexLib + 0.0.0 + + + com.github.olivergondza + maven-jdk-tools-wrapper + 0.1 + + + + + + + org.apache.maven.plugins + maven-compiler-plugin + 3.8.1 + + 1.7 + 1.7 + + + + org.apache.maven.plugins + maven-dependency-plugin + 3.1.1 + + + copy-dependencies + prepare-package + + copy-dependencies + + + ${project.build.directory}/lib + + + + + + org.apache.maven.plugins + maven-jar-plugin + 3.2.0 + + + + true + lib/ + io.kaitai.struct.visualizer.MainWindow + + + + + + + + + + + oss-sonatype + oss-sonatype + https://oss.sonatype.org/content/repositories/snapshots/ + + true + + + + local-jars + file://${project.basedir}/lib + + diff --git a/src/main/java/io/kaitai/struct/visualizer/DataNode.java b/src/main/java/io/kaitai/struct/visualizer/DataNode.java index 47e1e03..5a5cde9 100644 --- a/src/main/java/io/kaitai/struct/visualizer/DataNode.java +++ b/src/main/java/io/kaitai/struct/visualizer/DataNode.java @@ -15,22 +15,22 @@ public class DataNode extends DefaultMutableTreeNode { private boolean explored = false; - private int depth; + private final int depth; private Object value; - private Method method; - private String name; - private Integer posStart; - private Integer posEnd; + private final Method method; + private final String name; + private final Integer posStart; + private final Integer posEnd; - public DataNode(int depth, Object value, Method method, String name) { - init(depth, value, method, name, null, null); + public DataNode(int depth, Object value, String name) { + this(depth, value, null, name, null, null); } - public DataNode(int depth, Object value, Method method, Integer posStart, Integer posEnd) { - init(depth, value, method, null, posStart, posEnd); + private DataNode(int depth, Object value, Method method, Integer posStart, Integer posEnd) { + this(depth, value, method, null, posStart, posEnd); } - private void init(int depth, Object value, Method method, String name, Integer posStart, Integer posEnd) { + private DataNode(int depth, Object value, Method method, String name, Integer posStart, Integer posEnd) { this.depth = depth; this.value = value; this.method = method; @@ -101,14 +101,14 @@ public void explore(final DefaultTreeModel model, final PropertyChangeListener p protected List doInBackground() throws Exception { // Here access database if needed setProgress(0); - List children = new ArrayList(); + final List children = new ArrayList<>(); - System.out.println("exploring " + value); + System.out.println("exploring field " + name + ", value = " + value); // Wasn't loaded yet? if (value == null) { DataNode parentNode = (DataNode) parent; - System.out.println("parentNode = " + parentNode); + System.out.println("parentNode: name = " + parentNode.name + "; value = " + parentNode.value); value = method.invoke(parentNode.value); } @@ -129,20 +129,12 @@ protected List doInBackground() throws Exception { if (value instanceof ArrayList) { ArrayList list = (ArrayList) value; - DataNode parentNode = (DataNode) parent; - DebugAids debug = DebugAids.fromStruct((KaitaiStruct) parentNode.value); - - String methodName = method.getName(); for (int i = 0; i < list.size(); i++) { Object el = list.get(i); String arrayIdxStr = String.format("%04d", i); - Integer posStart = debug.getStart(methodName, i); - Integer posEnd = debug.getEnd(methodName, i); - - DataNode dn = new DataNode(depth + 1, el, null, arrayIdxStr); - children.add(dn); + children.add(new DataNode(depth + 1, el, arrayIdxStr)); } } else if (value instanceof KaitaiStruct) { DebugAids debug = DebugAids.fromStruct((KaitaiStruct) value); diff --git a/src/main/java/io/kaitai/struct/visualizer/MainWindow.java b/src/main/java/io/kaitai/struct/visualizer/MainWindow.java index 26bd265..48bab46 100644 --- a/src/main/java/io/kaitai/struct/visualizer/MainWindow.java +++ b/src/main/java/io/kaitai/struct/visualizer/MainWindow.java @@ -5,7 +5,7 @@ public class MainWindow extends JFrame { private static final String APP_NAME = "Kaitai Struct Visualizer"; - private static final String VERSION = "0.5"; + private static final String VERSION = "0.8"; private VisualizerPanel vis; @@ -18,21 +18,9 @@ public MainWindow() throws IOException { setVisible(true); } - public static void main(final String arg[]) throws IOException { - SwingUtilities.invokeLater(new Runnable() { - public void run() { - try { - UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); - MainWindow mw = new MainWindow(); - mw.vis.loadAll(arg[0], arg[1]); - } catch (ClassNotFoundException | - UnsupportedLookAndFeelException | - IllegalAccessException | - InstantiationException | - IOException e) { - e.printStackTrace(); - } - } - }); + public static void main(final String arg[]) throws Exception { + UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); + MainWindow mw = new MainWindow(); + mw.vis.loadAll(arg[0], arg[1]); } } diff --git a/src/main/java/io/kaitai/struct/visualizer/VisualizerPanel.java b/src/main/java/io/kaitai/struct/visualizer/VisualizerPanel.java index d3aea53..c7e2662 100644 --- a/src/main/java/io/kaitai/struct/visualizer/VisualizerPanel.java +++ b/src/main/java/io/kaitai/struct/visualizer/VisualizerPanel.java @@ -1,17 +1,25 @@ package io.kaitai.struct.visualizer; +import java.awt.Point; +import java.io.IOException; +import java.lang.reflect.Method; +import java.util.ArrayList; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + import at.HexLib.library.HexLib; import at.HexLib.library.HexLibSelectionModel; -import io.kaitai.struct.ClassCompiler; +import io.kaitai.struct.CompileLog; import io.kaitai.struct.KaitaiStruct; +import io.kaitai.struct.Main; import io.kaitai.struct.RuntimeConfig; -import io.kaitai.struct.StringLanguageOutputWriter; import io.kaitai.struct.format.ClassSpec; -import io.kaitai.struct.languages.JavaCompiler; +import io.kaitai.struct.formats.JavaClassSpecs; +import io.kaitai.struct.formats.JavaKSYParser; import io.kaitai.struct.languages.JavaCompiler$; + import org.mdkt.compiler.InMemoryJavaCompiler; -import javax.swing.*; import javax.swing.event.TreeExpansionEvent; import javax.swing.event.TreeSelectionEvent; import javax.swing.event.TreeSelectionListener; @@ -19,40 +27,28 @@ import javax.swing.tree.DefaultTreeModel; import javax.swing.tree.ExpandVetoException; import javax.swing.tree.TreePath; -import java.awt.*; -import java.io.IOException; -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.ArrayList; -import java.util.Map; -import java.util.regex.Matcher; -import java.util.regex.Pattern; +import javax.swing.JPanel; +import javax.swing.JScrollPane; +import javax.swing.JSplitPane; +import javax.swing.JTree; public class VisualizerPanel extends JPanel { - private JTree tree; - private DefaultTreeModel model; - private HexLib hexEditor; - private JSplitPane splitPane; + private static final String DEST_PACKAGE = "io.kaitai.struct.visualized"; + private static final Pattern TOP_CLASS_NAME = Pattern.compile("public class (.*?) extends KaitaiStruct"); + + private final JTree tree = new JTree(); + private final DefaultTreeModel model = new DefaultTreeModel(null); + private final HexLib hexEditor = new HexLib(new byte[0]); + private final JSplitPane splitPane; private KaitaiStruct struct; - private Map attrStart; - private Map attrEnd; public VisualizerPanel() throws IOException { super(); - - initialize(); - } - - private void initialize() { - tree = new JTree(); - hexEditor = new HexLib(new byte[] {}); - JScrollPane treeScroll = new JScrollPane(tree); splitPane = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT, treeScroll, hexEditor); - model = new DefaultTreeModel(null); tree.setShowsRootHandles(true); KaitaiTreeListener treeListener = new KaitaiTreeListener(); tree.addTreeWillExpandListener(treeListener); @@ -60,13 +56,9 @@ private void initialize() { tree.setModel(model); } - public void loadAll(String dataFileName, String ksyFileName) { - try { - parseFileWithKSY(ksyFileName, dataFileName); - loadStruct(); - } catch (Exception e) { - throw new RuntimeException(e); - } + public void loadAll(String dataFileName, String ksyFileName) throws Exception { + parseFileWithKSY(ksyFileName, dataFileName); + loadStruct(); } private void loadStruct() throws IOException { @@ -74,7 +66,7 @@ private void loadStruct() throws IOException { byte[] buf = struct._io().readBytesFull(); hexEditor.setByteContent(buf); - DataNode root = new DataNode(0, struct, null, "[root]"); + final DataNode root = new DataNode(0, struct, "[root]"); model.setRoot(root); root.explore(model /*, progressListener */, null); } @@ -83,29 +75,30 @@ public JSplitPane getSplitPane() { return splitPane; } - public static final String DEST_PACKAGE = "io.kaitai.struct.visualized"; - /** * Compiles a given .ksy file into Java class source. * @param ksyFileName * @return Java class source code as a string */ private static String compileKSY(String ksyFileName) { - ClassSpec cs = ClassCompiler.localFileToSpec(ksyFileName); - StringLanguageOutputWriter out = new StringLanguageOutputWriter(JavaCompiler$.MODULE$.indent()); - RuntimeConfig config = new RuntimeConfig( - false, - true, - DEST_PACKAGE, - "", - "" + final ClassSpec spec = JavaKSYParser.fileNameToSpec(ksyFileName); + final JavaClassSpecs specs = new JavaClassSpecs(null, null, spec); + + final RuntimeConfig config = new RuntimeConfig( + true, // debug - required for existing _attrStart/_attrEnd/_arrStart/_arrEnd fields + true, // opaqueTypes + null, // goPackage + DEST_PACKAGE, + "io.kaitai.struct.ByteBufferKaitaiStream", + null, // dotNetNamespace + null, // phpNamespace + null // pythonPackage ); - ClassCompiler cc = new ClassCompiler(cs, new JavaCompiler(config, out)); - cc.compile(); - return out.result(); - } - private final static Pattern TOP_CLASS_NAME = Pattern.compile("public class (.*?) extends KaitaiStruct"); + Main.importAndPrecompile(specs, config).value(); + final CompileLog.SpecSuccess result = Main.compile(specs, spec, JavaCompiler$.MODULE$, config); + return result.files().apply(0).contents(); + } /** * Compiles Java source (given as a string) into bytecode and loads it into current JVM. @@ -159,10 +152,10 @@ public void valueChanged(TreeSelectionEvent event) { if (node.posStart() == null || node.posEnd() == null) return; HexLibSelectionModel select = hexEditor.getSelectionModel(); - ArrayList intervals = new ArrayList(); + ArrayList intervals = new ArrayList<>(); intervals.add(new Point(node.posStart(), node.posEnd())); select.setSelectionIntervals(intervals); - System.out.println("" + node.posStart() + " - " + node.posEnd()); + System.out.println(node.posStart() + " - " + node.posEnd()); } } }