Home
Categories
Dictionary
Download
Project Details
Changes Log
FAQ
License

Groovy logger tutorial



This tutorial explains how to use the Script logger

Overview

We will define a small application showing a tree of elements, and use a script which will be able to show messages, and hyperlinks allowing to go to elements in the tree.

Create the overall application

      public class GroovySwingLogger extends JFrame {
         private DefaultTreeModel treeModel = null;
         private DefaultSwingScriptLogger logger = null;
         private final Map<TreeElement, TreeElement> elements = new HashMap<>();
         private final Map<TreeElement, DefaultMutableTreeNode> elementToNode = new HashMap<>();
         private JTree tree = null;

         public GroovySwingLogger() {
           super("Groovy SwingLogger");
           this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
           setup();
         }

         private void setup() {
           JMenuBar mbar = new JMenuBar();
           this.setJMenuBar(mbar);
           JMenu fileMenu = new JMenu("File");
           mbar.add(fileMenu);
           AbstractAction exitAction = new AbstractAction("Exit") {
             @Override
             public void actionPerformed(ActionEvent e) {
               System.exit(0);
             }
           };
           fileMenu.add(exitAction);
           createContent();
         }

         private void populateTree(DefaultMutableTreeNode root) {
           TreeElement element = new TreeElement("http:/my.site", "element1");
           elements.put(element, element);
           DefaultMutableTreeNode node = new DefaultMutableTreeNode(element);
           root.add(node);
           elementToNode.put(element, node);
           element = new TreeElement("http:/mysite", "element2");
           elements.put(element, element);
           node = new DefaultMutableTreeNode(element);
           root.add(node);
           elementToNode.put(element, node);
           element = new TreeElement("http:/mysite2", "element3");
           elements.put(element, element);
           node = new DefaultMutableTreeNode(element);
           root.add(node);
           elementToNode.put(element, node);
         }

         private void createContent() {
           Container pane = this.getContentPane();
           pane.setLayout(new BorderLayout());
           DefaultMutableTreeNode root = new DefaultMutableTreeNode("root");
           populateTree(root);
           treeModel = new DefaultTreeModel(root);
           tree = new JTree(treeModel);
           tree.setBorder(BorderFactory.createEmptyBorder(5, 5, 10, 10));
           pane.add(tree, BorderLayout.CENTER);
         }

         public static void main(String[] args) {
           GroovySwingLogger groovyTest = new GroovySwingLogger();
           groovyTest.pack();
           groovyTest.setVisible(true);
         }
      }
The TreeElement class which is used in the tree maintains a namespace and a name and has the following code:
      public class TreeElement {
         public final String namespace;
         public final String name;

         public TreeElement(String namespace, String name) {
           this.namespace = namespace;
           this.name = name;
         }

         @Override
         public String toString() {
           return namespace + ":" + name;
         }

         @Override
         public int hashCode() {
           int hash = 7;
           hash = 79 * hash + Objects.hashCode(this.namespace);
           hash = 79 * hash + Objects.hashCode(this.name);
           return hash;
         }

         @Override
         public boolean equals(Object obj) {
           if (this == obj) {
             return true;
           }
           if (obj == null) {
             return false;
           }
           if (getClass() != obj.getClass()) {
             return false;
           }
           final TreeElement other = (TreeElement) obj;
           return true;
         }
      }
We have the following GUI:
swinglogger

Define the Script interface

Our interface will be very simple. We will have the following definition for the interface.
      public interface Script {
        public void process(TreeElement element);
      }

Define the Groovy script wrapper and integrate the script

We will extend the GroovyScriptWrapper in the Groovy language to define that our scripts implement our script interface.

Create the ScriptWrapper

      public class GroovySwingLogger extends JFrame {
         private ScriptWrapper<Script> wrapper = null;
            private DefaultTreeModel treeModel = null;
         private final Map<TreeElement, TreeElement> elements = new HashMap<>();
         private final Map<TreeElement, DefaultMutableTreeNode> elementToNode = new HashMap<>();
         private JTree tree = null;

         public GroovySwingLogger() {
           super("Groovy SwingLogger");
           this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
           setup();
         }

         private void setup() {
           JMenuBar mbar = new JMenuBar();
           this.setJMenuBar(mbar);
           JMenu fileMenu = new JMenu("File");
           mbar.add(fileMenu);
           AbstractAction openAction = new AbstractAction("Open Script") {
                @Override
                public void actionPerformed(ActionEvent e) {
                  createScriptObject();
                }
              };
              fileMenu.add(openAction);

           AbstractAction exitAction = new AbstractAction("Exit") {
             @Override
             public void actionPerformed(ActionEvent e) {
               System.exit(0);
             }
           };
           fileMenu.add(exitAction);
           createContent();
         }

         private void populateTree(DefaultMutableTreeNode root) {
           ...
         }

         private void createContent() {
           ...
         }

         public static void main(String[] args) {
           GroovySwingLogger groovyTest = new GroovySwingLogger();
           groovyTest.pack();
           groovyTest.setVisible(true);
         }

         private boolean createScriptObject() {
              ...
            }

            private File openScript() {
              JFileChooser chooser = new JFileChooser("Open Script");
              chooser.setCurrentDirectory(new File(System.getProperty("user.dir")));
              chooser.setDialogType(JFileChooser.OPEN_DIALOG);
              chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
              int ret = chooser.showOpenDialog(null);
              if (ret == JFileChooser.APPROVE_OPTION) {
                return chooser.getSelectedFile();
              } else {
                return null;
              }
            }
      }

Integrate the script execution and show the logger

Now we will code the methods which will create and execute the script:
      private boolean createScriptObject() {
         File file = openScript(); // there is nothing specific in this code
         if (file == null) {
           return false;
         }
         // we create the groovy script wrapper with our script interface
         wrapper = new GroovyScriptWrapper<Script>() {
         };
         wrapper.logExceptions(true);
         SwingExceptionListener listener = new SwingExceptionListener();
         listener.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         wrapper.installScript(file);
         executeScript();
         return true;
      }

      private File openScript() {
         JFileChooser chooser = new JFileChooser("Open Script");
         chooser.setCurrentDirectory(new File(System.getProperty("user.dir")));
         chooser.setDialogType(JFileChooser.OPEN_DIALOG);
         chooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
         int ret = chooser.showOpenDialog(null);
         if (ret == JFileChooser.APPROVE_OPTION) {
           return chooser.getSelectedFile();
         } else {
           return null;
         }
      }

      private void executeScript() {
         ...
      }
But for the logger to be visible, we must add it explictly:
      public class GroovySwingLogger extends JFrame {
         private DefaultSwingScriptLogger logger = null;

         private boolean createScriptObject() {
           File file = openScript(); // there is nothing specific in this code
           if (file == null) {
             return false;
           }
           // we create the groovy script wrapper with our script interface
           wrapper = new GroovyScriptWrapper<Script>() {
           };
           wrapper.logExceptions(true);
           logger = new DefaultSwingScriptLogger();
              wrapper.setScriptLogger(logger);
           SwingExceptionListener listener = new SwingExceptionListener();
           listener.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
           wrapper.installScript(file);
           executeScript();
           return true;
         }
      }
And now we will code the script execution: we will iterate on all the TreeElements in our tree:
      private void executeScript() {
         logger.setVisible(true); // we must make the logger area visible at the start of the script
         Script script = wrapper.getScript();
         Iterator<TreeElement> it = elements.values().iterator();
         while (it.hasNext()) {
           TreeElement element = it.next();
           script.process(element);
         }
      }
Also we need to import the TreeElement classpath in our script:
      private boolean createScriptObject() {
         File file = openScript(); // there is nothing specific in this code
         if (file == null) {
           return false;
         }
         // we create the groovy script wrapper with our script interface
         wrapper = new GroovyScriptWrapper<Script>() {
         };
         wrapper.logExceptions(true);
         logger = new DefaultSwingScriptLogger();
         wrapper.setScriptLogger(logger);
         SwingExceptionListener listener = new SwingExceptionListener();
         wrapper.addImports(TreeElement.class);
         listener.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         wrapper.installScript(file);
         executeScript();
         return true;
      }

Log content in the logger

We will use the following Groovy script:
      public void process(TreeElement element) {
         logger.append(element.toString());
      }
We have the following result:
swingloggerlog Now we will allow hyperlinks in the logs. For that we will use a LinkIndexConverter and a HyperLinkListener.

Create the LinkIndexConverter

Main Article: LinkIndexConverter

We will use the namespace and the name of the TreeElement to convert to and from a link ID:
      public class GroovySwingLogger extends JFrame implements LinkIndexConverter<TreeElement> {
      private boolean createScriptObject() {
         File file = openScript(); // there is nothing specific in this code
         if (file == null) {
           return false;
         }
         // we create the groovy script wrapper with our script interface
         wrapper = new GroovyScriptWrapper<Script>() {
         };
         wrapper.logExceptions(true);
         logger = new DefaultSwingScriptLogger();
         logger.registerLinkIndexConverter(this);
         wrapper.setScriptLogger(logger);
         SwingExceptionListener listener = new SwingExceptionListener();
         wrapper.addImports(TreeElement.class);
         listener.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
         wrapper.installScript(file);
         executeScript();
         return true;
      }  
         @Override
            public String getLinkFromObject(TreeElement element) {
              return element.namespace + "$" + element.name;
            }      
      
            @Override
            public TreeElement getObjectFromLink(String linkID) {
              int index = linkID.indexOf("$");
              if (index != -1) {
                String namespace = linkID.substring(0, index);
                String name = linkID.substring(index + 1);
                TreeElement key = new TreeElement(namespace, name);
                if (elements.containsKey(key)) {
                  return elements.get(key);
                } else {
                  return null;
                }
             } else {
                return null;
             }
            }     
      }

Create the HyperLinkListener

Main Article: HyperLinkListener

We will implement the ScriptLoggerHyperLinkListener.visitHyperlink(Object) method. When the link is visited, we will select the associated node in the tree:
      public class GroovySwingLogger extends JFrame implements LinkIndexConverter<TreeElement>, ScriptLoggerHyperLinkListener<TreeElement> {
         private boolean createScriptObject() {
           File file = openScript(); // there is nothing specific in this code
           if (file == null) {
             return false;
           }
           // we create the groovy script wrapper with our script interface
           wrapper = new GroovyScriptWrapper<Script>() {
           };
           wrapper.logExceptions(true);
           logger = new DefaultSwingScriptLogger();
           logger.registerLinkIndexConverter(this);
           logger.registerHyperLinkListener(this);
           wrapper.setScriptLogger(logger);
           SwingExceptionListener listener = new SwingExceptionListener();
           wrapper.addImports(TreeElement.class);
           listener.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
           wrapper.installScript(file);
           executeScript();
           return true;   
         }
      }
      
         @Override
         public void visitHyperLink(TreeElement element) {
           if (elements.containsKey(element)) {
             DefaultMutableTreeNode node = elementToNode.get(element);
             TreePath path = new TreePath(node.getPath());
             tree.setSelectionPath(path);
           }
         }      

Log hyperlinked content in the logger

With the following Groovy script:
      public void process(TreeElement element) {
         HyperlinkElement linkElt = new HyperlinkElement(element.name, element);
         logger.appendObjectLink(linkElt);
      }
We have the following result:
hyperlinksObjectsTuto1
With the following Groovy script:
      public void process(TreeElement element) {
         HyperlinkElement linkElt = new HyperlinkElement(element.name, element);
         logger.appendObjectLinks("The element is %1", linkElt);
      }
We have the following result:
hyperlinksObjects

See also


Categories: tutorials

Copyright 2019-2020 Herve Girod. All Rights Reserved. Documentation and source under the BSD licence