You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ctakes.apache.org by se...@apache.org on 2019/11/30 19:05:57 UTC

svn commit: r1870640 [2/4] - in /ctakes/trunk/ctakes-dockhand: ./ src/ src/main/ src/main/java/ src/main/java/org/ src/main/java/org/apache/ src/main/java/org/apache/ctakes/ src/main/java/org/apache/ctakes/dockhand/ src/main/java/org/apache/ctakes/dock...

Added: ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/progress/NoteMarkupProgressUI.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/progress/NoteMarkupProgressUI.java?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/progress/NoteMarkupProgressUI.java (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/progress/NoteMarkupProgressUI.java Sat Nov 30 19:05:56 2019
@@ -0,0 +1,201 @@
+package org.apache.ctakes.gui.progress;
+
+import org.apache.ctakes.gui.wizard.util.DialogUtil;
+
+import javax.imageio.ImageIO;
+import javax.swing.*;
+import javax.swing.plaf.basic.BasicProgressBarUI;
+import java.awt.*;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 11/10/2019
+ */
+final public class NoteMarkupProgressUI extends BasicProgressBarUI {
+
+//   private static final int ARC_EXTENT = 25;
+
+   static private final int FRAME_COUNT = 7;
+
+   private Image[] _images = new Image[ FRAME_COUNT ];
+
+   private boolean _animating = false;
+   private int _index = 0;
+
+   public NoteMarkupProgressUI() {
+      SwingUtilities.invokeLater( new ImageLoader() );
+   }
+
+   @Override
+   protected void startAnimationTimer() {
+      _animating = true;
+      _index = 0;
+      super.startAnimationTimer();
+   }
+
+   @Override
+   protected void stopAnimationTimer() {
+      _animating = false;
+      _index = 0;
+      super.stopAnimationTimer();
+   }
+
+   @Override
+   protected void installDefaults() {
+      super.installDefaults();
+      progressBar.setBorder( null );
+   }
+
+   @Override
+   protected void paintIndeterminate( final Graphics g, final JComponent component ) {
+      final Graphics2D g2d = (Graphics2D)g;
+      final Image image = _images[ _index ];
+      if ( image == null ) {
+         return;
+      }
+      g2d.drawImage( image, 0, 0, null );
+      if ( _animating ) {
+         _index++;
+         if ( _index == FRAME_COUNT ) {
+            _index = 0;
+         }
+      }
+   }
+
+   @Override
+   protected Rectangle getBox( final Rectangle rectangle ) {
+      return new Rectangle( 0, 0, 200, 200 );
+//      if ( rectangle != null ) {
+//         rectangle.setBounds( progressBar.getBounds() );
+//         return rectangle;
+//      }
+//      return progressBar.getBounds();
+   }
+
+   @Override
+   public Dimension getPreferredSize( final JComponent component ) {
+      return new Dimension( 200, 200 );
+   }
+
+//
+//   public static BufferedImage rotate( final BufferedImage image, final float angle ) {
+//      float radianAngle = (float) Math.toRadians(angle) ;
+//
+//      float sin = (float) Math.abs(Math.sin(radianAngle));
+//      float cos = (float) Math.abs(Math.cos(radianAngle));
+//
+//      int w = image.getWidth() ;
+//      int h = image.getHeight();
+//
+//      int neww = Math.round( w * cos + h * sin );
+//      int newh = Math.round( h * cos + w * sin );
+//
+//      GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
+//      GraphicsDevice gd = ge.getDefaultScreenDevice();
+//      GraphicsConfiguration gc = gd.getDefaultConfiguration();
+//
+//      BufferedImage result = gc.createCompatibleImage(neww, newh, Transparency.TRANSLUCENT);
+//      Graphics2D g = result.createGraphics();
+//
+//      //-----------------------MODIFIED--------------------------------------
+//      g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON) ;
+//      g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC) ;
+//      g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY) ;
+//
+//      AffineTransform at = AffineTransform.getTranslateInstance( (neww - w) / 2, (newh - h) / 2);
+//      at.rotate( radianAngle, w / 2f, h / 2f );
+//      //---------------------------------------------------------------------
+//
+//      g.drawRenderedImage(image, at);
+//      g.dispose();
+//
+//      return result;
+//   }
+//
+//   private void moreRotate( final BufferedImage image ) {
+//      final double rads = Math.toRadians(90);
+//      final double sin = Math.abs(Math.sin(rads));
+//      final double cos = Math.abs(Math.cos(rads));
+//      final int w = (int) Math.floor(image.getWidth() * cos + image.getHeight() * sin);
+//      final int h = (int) Math.floor(image.getHeight() * cos + image.getWidth() * sin);
+//       BufferedImage rotatedImage = new BufferedImage(w, h, image.getType());
+//      final AffineTransform at = new AffineTransform();
+//      at.translate(w / 2, h / 2);
+//      at.rotate(rads,0, 0);
+//      at.translate(-image.getWidth() / 2, -image.getHeight() / 2);
+//      final AffineTransformOp rotateOp = new AffineTransformOp(at, AffineTransformOp.TYPE_BILINEAR);
+//      rotatedImage = rotateOp.filter(image, null );
+//   }
+//
+//
+//   public BufferedImage RotateImage(String imagePath,int degrees) throws IOException{
+//      File file = new File(imagePath);
+//      Image image = ImageIO.read(file);
+//      BufferedImage img= bufferImage(image, BufferedImage.TYPE_INT_RGB);
+//
+//      AffineTransform tx = new AffineTransform();
+//      double radians = (Math.PI / 180) * degrees;
+//
+//      double width = img.getWidth()/2;
+//      double height = img.getHeight()/2;
+//
+//      if(degrees != 180){
+//         tx.translate(height,width);
+//         tx.rotate(radians);
+//         tx.translate(-width,-height);
+//      }else{
+//         tx.rotate(radians,width, height);
+//      }
+//
+//      AffineTransformOp op = new AffineTransformOp( tx, AffineTransformOp.TYPE_BILINEAR );
+//      img = op.filter(img, null);
+//      return img;
+//   }
+
+//   private void createCaduceus() {
+//      try {
+//         final InputStream imageStream = getClass().getResourceAsStream( "/org/apache/ctakes/image/ctakes_logo.jpg" );
+//         if ( imageStream != null ) {
+////            panel.add( new JLabel( new ImageIcon( ImageIO.read( imageStream ), "Apache cTAKES" ) ), BorderLayout.NORTH );
+////         } else {
+////            LOGGER.warning( "No Stream" );
+//         }
+//      } catch ( IOException ioE ) {
+//         DialogUtil.showError( ioE.getMessage() );
+//      }
+//   }
+
+
+   /**
+    * Simple Runnable that loads an icon
+    */
+   private final class ImageLoader implements Runnable {
+      @Override
+      public void run() {
+         final String dir = "/org/apache/ctakes/image/progress/";
+         final String baseName = "TextProcess_200g_";
+         for ( int i = 0; i < FRAME_COUNT; i++ ) {
+            _images[ i ] = loadImage( dir + baseName + i + ".gif" );
+         }
+      }
+
+      private Image loadImage( final String path ) {
+         try {
+            final InputStream imageStream = getClass().getResourceAsStream( path );
+            if ( imageStream != null ) {
+               return ImageIO.read( imageStream );
+               //         } else {
+               //            LOGGER.warning( "No Stream" );
+            }
+         } catch ( IOException ioE ) {
+            DialogUtil.showError( ioE.getMessage() );
+         }
+         return null;
+      }
+   }
+
+
+}

Added: ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/progress/NoteProgressDialog.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/progress/NoteProgressDialog.java?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/progress/NoteProgressDialog.java (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/progress/NoteProgressDialog.java Sat Nov 30 19:05:56 2019
@@ -0,0 +1,109 @@
+package org.apache.ctakes.gui.progress;
+
+
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import java.awt.*;
+
+import static javax.swing.WindowConstants.DO_NOTHING_ON_CLOSE;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 11/30/2019
+ */
+public enum NoteProgressDialog {
+   INSTANCE;
+
+   static public NoteProgressDialog getInstance() {
+      return INSTANCE;
+   }
+
+   private JDialog _dialog;
+   private JLabel _processLabel;
+   private JLabel _progressLabel;
+
+   private void createDialog() {
+      if ( _dialog != null ) {
+         return;
+      }
+      final Frame[] frames = Frame.getFrames();
+      final Frame mainFrame = frames.length > 0 ? frames[ 0 ] : null;
+      _dialog = new JDialog( mainFrame, "Please wait ...", false );
+      _dialog.setDefaultCloseOperation( DO_NOTHING_ON_CLOSE );
+      _dialog.setSize( 700, 300 );
+      _dialog.setLocationRelativeTo( mainFrame );
+
+      final JPanel notePanel = new JPanel();
+      notePanel.setLayout( new BoxLayout( notePanel, BoxLayout.Y_AXIS ) );
+      notePanel.setBackground( Color.WHITE );
+      notePanel.add( Box.createVerticalGlue() );
+      notePanel.add( ProgressNote.getInstance().getComponent() );
+      notePanel.add( Box.createVerticalGlue() );
+
+      final JPanel labelPanel = new JPanel();
+      labelPanel.setLayout( new BoxLayout( labelPanel, BoxLayout.Y_AXIS ) );
+      labelPanel.setBorder( new EmptyBorder( 10, 10, 10, 10 ) );
+      labelPanel.setBackground( Color.WHITE );
+      labelPanel.add( Box.createVerticalGlue() );
+      _processLabel = new JLabel( "" );
+      labelPanel.add( _processLabel );
+      _progressLabel = new JLabel( "" );
+      labelPanel.add( _progressLabel );
+      labelPanel.add( Box.createVerticalGlue() );
+
+      final JPanel panel = new JPanel( new BorderLayout( 10, 10 ) );
+      panel.setBorder( new EmptyBorder( 10, 10, 10, 10 ) );
+      panel.setBackground( Color.WHITE );
+      panel.add( notePanel, BorderLayout.WEST );
+      panel.add( labelPanel, BorderLayout.CENTER );
+
+      _dialog.add( panel );
+   }
+
+   public void setProcess( final String process ) {
+      createDialog();
+      _processLabel.setText( "<HTML><B>" + process + "</B></HTML>" );
+   }
+
+   public void setProgress( final String progress ) {
+      createDialog();
+      _progressLabel.setText( progress );
+   }
+
+   public void setProgress( final int complete, final int total ) {
+      setProgress( "<HTML><B>Progress: </B>" + complete + " / " + total + "</HTML>" );
+   }
+
+
+   public void startProgress() {
+      createDialog();
+      _dialog.setVisible( true );
+      ProgressNote.getInstance().startProgress();
+   }
+
+   public void startProgress( final String process ) {
+      setProcess( process );
+      _dialog.setVisible( true );
+      ProgressNote.getInstance().startProgress();
+   }
+
+   public void startProgress( final String process, final String progress ) {
+      setProcess( process );
+      setProgress( progress );
+      _dialog.setVisible( true );
+      ProgressNote.getInstance().startProgress();
+   }
+
+   public void stopProgress() {
+      if ( _dialog == null ) {
+         return;
+      }
+      ProgressNote.getInstance().stopProgress();
+      _dialog.setVisible( false );
+      _dialog.dispose();
+      _dialog = null;
+   }
+
+
+}

Added: ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/progress/ProgressNote.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/progress/ProgressNote.java?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/progress/ProgressNote.java (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/progress/ProgressNote.java Sat Nov 30 19:05:56 2019
@@ -0,0 +1,45 @@
+package org.apache.ctakes.gui.progress;
+
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 11/10/2019
+ */
+public enum ProgressNote {
+   INSTANCE;
+
+   static public ProgressNote getInstance() {
+      return INSTANCE;
+   }
+
+   private final JProgressBar _progressBar;
+
+   ProgressNote() {
+      UIManager.put( "ProgressBar.repaintInterval", 500 );
+      UIManager.put( "ProgressBar.cycleTime", 3500 );
+      _progressBar = new JProgressBar();
+      _progressBar.setUI( new NoteMarkupProgressUI() );
+      _progressBar.setBackground( Color.WHITE );
+      _progressBar.setVisible( false );
+   }
+
+   public JComponent getComponent() {
+      return _progressBar;
+   }
+
+   public void startProgress() {
+      _progressBar.setVisible( true );
+      _progressBar.setIndeterminate( true );
+   }
+
+   public void stopProgress() {
+      _progressBar.setVisible( false );
+      _progressBar.setIndeterminate( false );
+   }
+
+
+}

Added: ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/AbstractWizardStep.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/AbstractWizardStep.java?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/AbstractWizardStep.java (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/AbstractWizardStep.java Sat Nov 30 19:05:56 2019
@@ -0,0 +1,71 @@
+package org.apache.ctakes.gui.wizard;
+
+
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import java.awt.*;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 10/11/2019
+ */
+abstract public class AbstractWizardStep implements WizardStep {
+
+
+   private final String _name;
+   private final String _description;
+   private JComponent _panel;
+
+   protected AbstractWizardStep( final String name, final String description ) {
+      _name = name;
+      _description = description;
+   }
+
+   abstract protected JComponent createPanel();
+
+   protected JScrollPane wrapInScrollPane( final JComponent component ) {
+      component.setBorder( new EmptyBorder( 5, 5, 5, 5 ) );
+      component.setBackground( Color.WHITE );
+      final JScrollPane scrollPane = new JScrollPane( component );
+      scrollPane.setBorder( null );
+      return scrollPane;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String getName() {
+      return _name;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public String getDescription() {
+      return _description;
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public JComponent getPanel() {
+      if ( _panel == null ) {
+         _panel = createPanel();
+      }
+      return _panel;
+   }
+
+
+   /**
+    * @return the name of the step.
+    */
+   @Override
+   public String toString() {
+      return getName();
+   }
+
+}

Added: ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/ContentsPanel.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/ContentsPanel.java?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/ContentsPanel.java (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/ContentsPanel.java Sat Nov 30 19:05:56 2019
@@ -0,0 +1,48 @@
+package org.apache.ctakes.gui.wizard;
+
+import javax.swing.*;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import java.awt.*;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 10/10/2019
+ */
+final class ContentsPanel {
+
+
+   private final JLabel _mainLabel;
+   private final JScrollPane _scrollPane;
+   private final WizardController _wizardController;
+
+   ContentsPanel( final WizardController wizardController ) {
+      _mainLabel = new JLabel();
+      final Font font = _mainLabel.getFont();
+      final int fontSize = font.getSize();
+      _mainLabel.setFont( font.deriveFont( Font.BOLD ).deriveFont( fontSize * 1.5f ) );
+      _scrollPane = new JScrollPane();
+      _scrollPane.setBorder( null );
+      _wizardController = wizardController;
+      wizardController.addListSelectionListener( new WizardControllerListener() );
+   }
+
+   public JComponent createPanel() {
+      final JPanel panel = new JPanel( new BorderLayout( 10, 10 ) );
+      panel.setBackground( Color.WHITE );
+      panel.add( _mainLabel, BorderLayout.NORTH );
+      panel.add( _scrollPane, BorderLayout.CENTER );
+      return panel;
+   }
+
+
+   private class WizardControllerListener implements ListSelectionListener {
+      public void valueChanged( final ListSelectionEvent event ) {
+         _mainLabel.setText( _wizardController.getCurrentStep().getDescription() );
+         _scrollPane.setViewportView( _wizardController.getCurrentStep().getPanel() );
+      }
+   }
+
+
+}

Added: ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/NavigationPanel.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/NavigationPanel.java?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/NavigationPanel.java (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/NavigationPanel.java Sat Nov 30 19:05:56 2019
@@ -0,0 +1,93 @@
+package org.apache.ctakes.gui.wizard;
+
+
+import javax.swing.*;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.function.BooleanSupplier;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 10/10/2019
+ */
+final class NavigationPanel {
+
+
+   public JComponent createPanel( final WizardController wizardController ) {
+      final TravelAction previous
+            = new TravelAction( wizardController.toPrevious(),
+            wizardController.hasPrevious(),
+            "Previous", "Go to previous step." );
+      wizardController.addListSelectionListener( previous );
+
+      final TravelAction next
+            = new TravelAction( wizardController.toNext(),
+            wizardController.hasNext(),
+            "Next", "Go to next step." );
+      wizardController.addListSelectionListener( next );
+
+      final FinishAction finish
+            = new FinishAction( wizardController,
+            "Finish", "All settings are correct.  Perform finishing move." );
+      wizardController.addListSelectionListener( finish );
+
+      final JPanel panel = new JPanel( new GridLayout( 1, 5, 5, 5 ) );
+      panel.setBackground( Color.WHITE );
+      panel.add( new JLabel() );
+      panel.add( new JLabel() );
+      panel.add( new JButton( previous ) );
+      panel.add( new JButton( next ) );
+      panel.add( new JButton( finish ) );
+      return panel;
+   }
+
+   static private class TravelAction extends AbstractAction implements ListSelectionListener {
+      private final Runnable _traveller;
+      private final BooleanSupplier _travellable;
+
+      private TravelAction( final Runnable traveller,
+                            final BooleanSupplier travellable,
+                            final String name, final String tip ) {
+         super( name );
+         putValue( Action.SHORT_DESCRIPTION, tip );
+         _traveller = traveller;
+         _travellable = travellable;
+      }
+
+      public void actionPerformed( final ActionEvent event ) {
+         _traveller.run();
+      }
+
+      public void valueChanged( final ListSelectionEvent event ) {
+         setEnabled( _travellable.getAsBoolean() );
+      }
+   }
+
+   static private class FinishAction extends AbstractAction implements ListSelectionListener {
+      private final WizardController _wizardController;
+
+      private FinishAction( final WizardController wizardController,
+                            final String name, final String tip ) {
+         super( name );
+         putValue( Action.SHORT_DESCRIPTION, tip );
+         _wizardController = wizardController;
+         setEnabled( _wizardController.getBuildable().getAsBoolean() );
+      }
+
+      public void actionPerformed( final ActionEvent event ) {
+         final ExecutorService executor = Executors.newSingleThreadExecutor();
+         executor.execute( _wizardController.getBuildProcess() );
+      }
+
+      public void valueChanged( final ListSelectionEvent event ) {
+         setEnabled( _wizardController.getBuildable().getAsBoolean() );
+      }
+   }
+
+
+}

Added: ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/SummaryStep.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/SummaryStep.java?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/SummaryStep.java (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/SummaryStep.java Sat Nov 30 19:05:56 2019
@@ -0,0 +1,91 @@
+package org.apache.ctakes.gui.wizard;
+
+
+import javax.swing.*;
+import javax.swing.border.CompoundBorder;
+import javax.swing.border.EmptyBorder;
+import javax.swing.border.LineBorder;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import java.awt.*;
+import java.util.Collection;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 10/14/2019
+ */
+final public class SummaryStep extends AbstractWizardStep implements WizardStep, ListSelectionListener {
+
+
+   private JPanel _panel;
+
+   public SummaryStep( final WizardController wizardController ) {
+      super( "Summary",
+            "Summary of information for your installation." );
+      wizardController.addListSelectionListener( this );
+   }
+
+
+   private void update( final WizardController wizardController ) {
+      _panel.removeAll();
+      final Collection<WizardStep> wizardSteps = wizardController.getWizardSteps();
+
+      for ( WizardStep wizardStep : wizardSteps ) {
+         if ( wizardStep.equals( this ) ) {
+            continue;
+         }
+         _panel.add( createStepComponent( wizardStep ) );
+      }
+   }
+
+
+   private JComponent createStepComponent( final WizardStep wizardStep ) {
+      final JPanel panel = new JPanel( new BorderLayout( 10, 10 ) );
+      panel.setBorder( new EmptyBorder( 10, 10, 10, 10 ) );
+      panel.setBackground( Color.WHITE );
+
+      final JLabel nameLabel = new JLabel( wizardStep.getName() );
+//      final String description = wizardStep.getDescription();
+//      nameLabel.setToolTipText( description );
+      panel.add( nameLabel, BorderLayout.NORTH );
+
+      final JLabel spacer = new JLabel( "     " );
+      spacer.setMinimumSize( new Dimension( 100, 10 ) );
+      spacer.setSize( new Dimension( 100, 10 ) );
+      panel.add( spacer, BorderLayout.WEST );
+
+      final JLabel textArea = new JLabel();
+      textArea.setBorder( new CompoundBorder( LineBorder.createGrayLineBorder(), new EmptyBorder( 5, 5, 5, 5 ) ) );
+      textArea.setVerticalAlignment( SwingConstants.TOP );
+      textArea.setText( wizardStep.getSummaryInfo() );
+//      textArea.setToolTipText( description );
+      panel.add( textArea, BorderLayout.CENTER );
+
+      return panel;
+   }
+
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   protected JComponent createPanel() {
+      _panel = new JPanel();
+      _panel.setLayout( new BoxLayout( _panel, BoxLayout.Y_AXIS ) );
+      return wrapInScrollPane( _panel );
+   }
+
+
+   public void valueChanged( final ListSelectionEvent event ) {
+      final Object source = event.getSource();
+      if ( source != null && source instanceof WizardController ) {
+         final WizardStep step = ((WizardController)source).getCurrentStep();
+         if ( this.equals( step ) ) {
+            update( (WizardController)source );
+         }
+      }
+   }
+
+
+}

Added: ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/TocPanel.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/TocPanel.java?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/TocPanel.java (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/TocPanel.java Sat Nov 30 19:05:56 2019
@@ -0,0 +1,53 @@
+package org.apache.ctakes.gui.wizard;
+
+import org.apache.ctakes.gui.wizard.util.DialogUtil;
+
+import javax.imageio.ImageIO;
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import java.awt.*;
+import java.io.IOException;
+import java.io.InputStream;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 10/10/2019
+ */
+final class TocPanel {
+
+
+   public JComponent createPanel( final WizardController wizardController ) {
+      final JList<WizardStep> stepList = new JList<>( wizardController );
+      stepList.setEnabled( false );
+      stepList.setSelectionModel( wizardController );
+      stepList.setBorder( new EmptyBorder( 50, 5, 5, 5 ) );
+      final Color selectColor = stepList.getSelectionBackground();
+      final Color transColor = new Color( selectColor.getRed(), selectColor.getGreen(), selectColor.getBlue(), 125 );
+      stepList.setSelectionBackground( transColor );
+
+      final JScrollPane scrollPane = new JScrollPane();
+      scrollPane.setBorder( null );
+      scrollPane.setViewportView( stepList );
+
+      final JPanel panel = new JPanel( new BorderLayout( 10, 10 ) );
+      panel.setBackground( Color.WHITE );
+      try {
+         final InputStream imageStream = getClass().getResourceAsStream( "/org/apache/ctakes/image/ctakes_logo.jpg" );
+         if ( imageStream != null ) {
+            panel.add( new JLabel( new ImageIcon( ImageIO.read( imageStream ), "Apache cTAKES" ) ), BorderLayout.NORTH );
+//         } else {
+//            LOGGER.warning( "No Stream" );
+         }
+      } catch ( IOException ioE ) {
+         DialogUtil.showError( ioE.getMessage() );
+      }
+      panel.add( scrollPane, BorderLayout.CENTER );
+
+//      panel.add( ProgressNote.getInstance().getComponent(), BorderLayout.SOUTH );
+
+      return panel;
+   }
+
+
+}

Added: ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/WizardController.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/WizardController.java?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/WizardController.java (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/WizardController.java Sat Nov 30 19:05:56 2019
@@ -0,0 +1,204 @@
+package org.apache.ctakes.gui.wizard;
+
+import javax.swing.*;
+import javax.swing.event.EventListenerList;
+import javax.swing.event.ListDataEvent;
+import javax.swing.event.ListDataListener;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.BooleanSupplier;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 10/10/2019
+ */
+public class WizardController extends DefaultListSelectionModel implements ListModel<WizardStep> {
+
+
+   static private final WizardStep NULL_STEP = new WizardStep() {
+      public String getName() {
+         return "None";
+      }
+
+      public String getDescription() {
+         return "No action available.";
+      }
+
+      public JComponent getPanel() {
+         return new JLabel();
+      }
+   };
+
+   static private final Runnable NULL_BUILD = () -> {
+   };
+
+   private final List<WizardStep> _wizardSteps = new ArrayList<>();
+
+   private final BooleanSupplier DEFAULT_BUILDABLE = () -> !hasNextStep()
+                                                           && getBuildProcess() != null
+                                                           && !NULL_BUILD.equals( getBuildProcess() )
+                                                           &&
+                                                           getWizardSteps().stream().allMatch( WizardStep::finished );
+
+
+   private Runnable _buildProcess = NULL_BUILD;
+   private BooleanSupplier _buildable = DEFAULT_BUILDABLE;
+
+
+   final Runnable toPrevious() {
+      return () -> {
+         if ( hasPreviousStep() ) {
+            setCurrentIndex( getCurrentIndex() - 1 );
+         }
+      };
+   }
+
+   final Runnable toNext() {
+      return () -> {
+         if ( hasNextStep() ) {
+            setCurrentIndex( getCurrentIndex() + 1 );
+         }
+      };
+   }
+
+   final BooleanSupplier hasPrevious() {
+      return this::hasPreviousStep;
+   }
+
+   final BooleanSupplier hasNext() {
+      return this::hasNextStep;
+   }
+
+
+   public WizardController() {
+      setSelectionMode( SINGLE_SELECTION );
+   }
+
+
+   final Runnable getBuildProcess() {
+      return _buildProcess;
+   }
+
+   final public void setBuildProcess( final Runnable build ) {
+      _buildProcess = build;
+   }
+
+
+   final BooleanSupplier getBuildable() {
+      return _buildable;
+   }
+
+   final public void setBuildable( final BooleanSupplier buildable ) {
+      _buildable = buildable;
+   }
+
+
+   final public void addStep( final WizardStep wizardStep ) {
+      _wizardSteps.add( wizardStep );
+   }
+
+   final public List<WizardStep> getWizardSteps() {
+      return Collections.unmodifiableList( _wizardSteps );
+   }
+
+   final void setCurrentIndex( final int index ) {
+      setSelectionInterval( index, index );
+   }
+
+   private int getCurrentIndex() {
+      return getAnchorSelectionIndex();
+   }
+
+   final public WizardStep getCurrentStep() {
+      return getElementAt( getCurrentIndex() );
+   }
+
+   private boolean hasPreviousStep() {
+      return getCurrentIndex() > 0;
+   }
+
+   private boolean hasNextStep() {
+      return getCurrentIndex() < getSize() - 1;
+   }
+
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   final public int getSize() {
+      return _wizardSteps.size();
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   final public WizardStep getElementAt( final int index ) {
+      return _wizardSteps.get( index );
+   }
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void addListDataListener( final ListDataListener listener ) {
+      listenerList.add( ListDataListener.class, listener );
+   }
+
+
+   /**
+    * {@inheritDoc}
+    */
+   @Override
+   public void removeListDataListener( final ListDataListener listener ) {
+      listenerList.remove( ListDataListener.class, listener );
+   }
+
+   /**
+    * Returns an array of all the registered list data listeners.
+    *
+    * @return all of this model's <code>ListDataListener</code>s,
+    * or an empty array if no list data listeners
+    * are currently registered
+    * @see #addListDataListener
+    * @see #removeListDataListener
+    */
+   public ListDataListener[] getListDataListeners() {
+      return listenerList.getListeners( ListDataListener.class );
+   }
+
+
+   /**
+    * @param source the <code>ListModel</code> that changed, typically "this"
+    * @param index0 one end of the new interval
+    * @param index1 the other end of the new interval
+    * @see EventListenerList
+    * @see DefaultListModel
+    */
+   protected void fireContentsChanged( final Object source, final int index0, final int index1 ) {
+      final Object[] listeners = listenerList.getListenerList();
+      ListDataEvent event = null;
+
+      for ( int i = listeners.length - 2; i >= 0; i -= 2 ) {
+         if ( listeners[ i ] == ListDataListener.class ) {
+            if ( event == null ) {
+               event = new ListDataEvent( source, ListDataEvent.CONTENTS_CHANGED, index0, index1 );
+            }
+            ((ListDataListener)listeners[ i + 1 ]).contentsChanged( event );
+         }
+      }
+   }
+
+
+   // TODO : Internal ActionListener class.  Has boolean "firingAction".  Is added to every AbstractWizardStep.
+   //  Each AbstractWizardStep has an actionListener.  That actionListener is added to this controller.
+   //  This actionListener will call the WizardStep ".revalidate()".
+   //  The NavigationPanel will also have an actionListener and a ".revalidate()".
+   //  This way we can constantly update the "Next" and "Finish" buttons as panels are completed.
+   //  TocPanel should probably also have one and set each list item enabled as the wizard progresses.
+
+
+}

Added: ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/WizardPanel.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/WizardPanel.java?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/WizardPanel.java (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/WizardPanel.java Sat Nov 30 19:05:56 2019
@@ -0,0 +1,36 @@
+package org.apache.ctakes.gui.wizard;
+
+
+import javax.swing.*;
+import javax.swing.border.EmptyBorder;
+import java.awt.*;
+
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 9/27/2019
+ */
+final public class WizardPanel {
+
+
+   public JComponent createPanel( final WizardController wizardController ) {
+      final JPanel mainPanel = new JPanel( new BorderLayout( 10, 10 ) );
+      mainPanel.setBorder( new EmptyBorder( 10, 10, 10, 10 ) );
+      mainPanel.setBackground( Color.WHITE );
+
+      final TocPanel tocPanel = new TocPanel();
+      mainPanel.add( tocPanel.createPanel( wizardController ), BorderLayout.WEST );
+
+      final ContentsPanel contentsPanel = new ContentsPanel( wizardController );
+      mainPanel.add( contentsPanel.createPanel(), BorderLayout.CENTER );
+
+      final NavigationPanel navigationPanel = new NavigationPanel();
+      mainPanel.add( navigationPanel.createPanel( wizardController ), BorderLayout.SOUTH );
+
+      wizardController.setCurrentIndex( 0 );
+      return mainPanel;
+   }
+
+
+}

Added: ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/WizardStep.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/WizardStep.java?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/WizardStep.java (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/WizardStep.java Sat Nov 30 19:05:56 2019
@@ -0,0 +1,26 @@
+package org.apache.ctakes.gui.wizard;
+
+import javax.swing.*;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 10/9/2019
+ */
+public interface WizardStep {
+
+   String getName();
+
+   String getDescription();
+
+   JComponent getPanel();
+
+   default boolean finished() {
+      return true;
+   }
+
+   default String getSummaryInfo() {
+      return "";
+   }
+
+}

Added: ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/util/DialogUtil.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/util/DialogUtil.java?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/util/DialogUtil.java (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/util/DialogUtil.java Sat Nov 30 19:05:56 2019
@@ -0,0 +1,106 @@
+package org.apache.ctakes.gui.wizard.util;
+
+
+import org.apache.ctakes.dockhand.gui.DisablerPane;
+import org.apache.ctakes.gui.progress.ProgressNote;
+
+import javax.swing.*;
+import java.awt.*;
+import java.io.File;
+
+import static javax.swing.JOptionPane.ERROR_MESSAGE;
+import static javax.swing.JOptionPane.INFORMATION_MESSAGE;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 11/10/2019
+ */
+final public class DialogUtil {
+
+   private DialogUtil() {
+   }
+
+
+   static public File chooseSaveDir() {
+      final Component rootPane = SwingUtilities.getRoot( DisablerPane.getInstance() );
+      final JFileChooser chooser = new JFileChooser();
+      chooser.setFileSelectionMode( JFileChooser.DIRECTORIES_ONLY );
+      final int decision = chooser.showSaveDialog( rootPane );
+      if ( decision != JFileChooser.APPROVE_OPTION ) {
+         return null;
+      }
+      return chooser.getSelectedFile();
+   }
+
+
+   static public boolean chooseSecondaryInstall( final String name ) {
+      final Component rootPane = SwingUtilities.getRoot( DisablerPane.getInstance() );
+      final int response = JOptionPane.showConfirmDialog( rootPane,
+            name + " was not found in the $PATH.  Would you like to install " + name + "?",
+            "Install " + name,
+            JOptionPane.YES_NO_OPTION );
+      return response == JOptionPane.YES_OPTION;
+   }
+
+
+   static public void showError( final String message ) {
+      final String fullMessage = "<HTML>" + message + "<BR>" + "Press OK to exit.</HTML>";
+      final Component rootPane = SwingUtilities.getRoot( DisablerPane.getInstance() );
+      JOptionPane.showMessageDialog( rootPane, fullMessage, "Error", ERROR_MESSAGE );
+      System.exit( 1 );
+   }
+
+   static public void initInstall() {
+      final Component rootPane = SwingUtilities.getRoot( DisablerPane.getInstance() );
+      rootPane.setCursor( Cursor.getPredefinedCursor( Cursor.WAIT_CURSOR ) );
+      DisablerPane.getInstance().setVisible( true );
+      ProgressNote.getInstance().startProgress();
+   }
+
+
+   static public void showInstallComplete( final String name, final String installPath ) {
+      final Component rootPane = SwingUtilities.getRoot( DisablerPane.getInstance() );
+      DisablerPane.getInstance().setVisible( false );
+      rootPane.setCursor( Cursor.getDefaultCursor() );
+      ProgressNote.getInstance().stopProgress();
+      JOptionPane.showMessageDialog( rootPane, name + " installed at " + installPath );
+   }
+
+
+   static public void showInstallCanceled( final String name ) {
+      final Component rootPane = SwingUtilities.getRoot( DisablerPane.getInstance() );
+      DisablerPane.getInstance().setVisible( false );
+      rootPane.setCursor( Cursor.getDefaultCursor() );
+      ProgressNote.getInstance().stopProgress();
+      JOptionPane.showMessageDialog( rootPane, name + " Installation Cancelled." );
+   }
+
+
+   static public void showProgressDialog( final String title ) {
+      final Component rootPane = SwingUtilities.getRoot( DisablerPane.getInstance() );
+      JProgressBar jProgressBar = new JProgressBar();
+      jProgressBar.setIndeterminate( true );
+      final JOptionPane pane = new JOptionPane( jProgressBar, INFORMATION_MESSAGE );
+      JDialog dialog = pane.createDialog( rootPane, title );
+      //      pane.add(jProgressBar,1);
+      dialog.setVisible( true );
+//      dialog.dispose();
+   }
+
+
+   static public void showInstalledDialog( final String name, final String installPath ) {
+      showMessageDialog( name + " installed at " + installPath );
+   }
+
+   static public void showCanceledDialog( final String name ) {
+      showMessageDialog( name + " Installation Cancelled." );
+   }
+
+   static public void showMessageDialog( final String message ) {
+      final Component rootPane = SwingUtilities.getRoot( DisablerPane.getInstance() );
+      JOptionPane.showMessageDialog( rootPane, message );
+   }
+
+
+}

Added: ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/util/RunnerUtil.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/util/RunnerUtil.java?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/util/RunnerUtil.java (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/util/RunnerUtil.java Sat Nov 30 19:05:56 2019
@@ -0,0 +1,62 @@
+package org.apache.ctakes.gui.wizard.util;
+
+import org.apache.ctakes.dockhand.gui.DisablerPane;
+import org.apache.ctakes.gui.progress.NoteProgressDialog;
+
+import java.util.concurrent.*;
+import java.util.logging.Logger;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 11/29/2019
+ */
+final public class RunnerUtil {
+
+   static private final Logger LOGGER = Logger.getLogger( "RunnerUtil" );
+
+   private RunnerUtil() {
+   }
+
+
+//   static public<T> T runWithProgress( final Callable<T> callable ) {
+//      return runWithProgress( "Please Wait ...", callable );
+//   }
+
+
+   static public <T> T runWithProgress( final String process, final Callable<T> callable ) {
+      startProgress( process );
+
+      final ExecutorService executor = Executors.newSingleThreadExecutor();
+      T result = null;
+      try {
+         final Future<T> future = executor.submit( callable );
+         result = future.get();
+      } catch ( InterruptedException | ExecutionException multE ) {
+         LOGGER.warning( multE.getMessage() );
+      }
+
+      endProgress();
+      return result;
+   }
+
+
+   static private void startProgress( final String process ) {
+//      ProgressNote.getInstance().startProgress();
+      DisablerPane.getInstance().setVisible( true );
+//      final Component rootPane = SwingUtilities.getRoot( DisablerPane.getInstance() );
+//      rootPane.setCursor( Cursor.getPredefinedCursor( Cursor.WAIT_CURSOR ) );
+      NoteProgressDialog.getInstance().startProgress( process );
+   }
+
+
+   static private void endProgress() {
+      DisablerPane.getInstance().setVisible( false );
+//      final Component rootPane = SwingUtilities.getRoot( DisablerPane.getInstance() );
+//      rootPane.setCursor( Cursor.getDefaultCursor() );
+//      ProgressNote.getInstance().stopProgress();
+      NoteProgressDialog.getInstance().stopProgress();
+   }
+
+
+}

Added: ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/util/SystemUtil.java
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/util/SystemUtil.java?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/util/SystemUtil.java (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/java/org/apache/ctakes/gui/wizard/util/SystemUtil.java Sat Nov 30 19:05:56 2019
@@ -0,0 +1,209 @@
+package org.apache.ctakes.gui.wizard.util;
+
+
+import java.io.*;
+import java.net.URL;
+import java.nio.channels.Channels;
+import java.nio.channels.FileChannel;
+import java.nio.channels.ReadableByteChannel;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.StandardCopyOption;
+import java.util.Map;
+import java.util.concurrent.Callable;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipInputStream;
+
+/**
+ * @author SPF , chip-nlp
+ * @version %I%
+ * @since 11/10/2019
+ */
+final public class SystemUtil {
+
+
+   private SystemUtil() {
+   }
+
+   static public final File NO_FILE = new File( "" );
+   static public final String FILE_NOT_FOUND = "FILE_NOT_FOUND";
+
+
+   static public void copyToDisk( final InputStream source, final Path target ) {
+      try {
+         Files.copy( source, target, StandardCopyOption.REPLACE_EXISTING );
+      } catch ( IOException ioE ) {
+         DialogUtil.showError( ioE.getMessage() );
+      }
+   }
+
+
+   static public String findExecutableOnPath( final String name ) {
+      for ( String dirname : System.getenv( "PATH" ).split( File.pathSeparator ) ) {
+         final File testFile = new File( dirname, name );
+         if ( testFile.isFile() && testFile.canExecute() ) {
+            return testFile.getAbsolutePath();
+         }
+      }
+      return FILE_NOT_FOUND;
+   }
+
+
+   static public class FileDownloader implements Callable<File> {
+      private final String _url;
+      private final String _tempPrefix;
+      private final String _tempSuffix;
+
+      public FileDownloader( final String url ) {
+         this( url, "Prefix", "suffix" );
+      }
+
+      public FileDownloader( final String url, final String tempPrefix, final String tempSuffix ) {
+         _url = url;
+         _tempPrefix = tempPrefix;
+         _tempSuffix = tempSuffix;
+      }
+
+      public File call() throws IOException {
+         final File tempZip = File.createTempFile( _tempPrefix, _tempSuffix );
+         tempZip.deleteOnExit();
+         URL url = new URL( _url );
+         try ( ReadableByteChannel readableByteChannel = Channels.newChannel( url.openStream() );
+               FileOutputStream fileOutputStream = new FileOutputStream( tempZip );
+               FileChannel fileChannel = fileOutputStream.getChannel() ) {
+            fileChannel.transferFrom( readableByteChannel, 0, Long.MAX_VALUE );
+         }
+         return tempZip;
+      }
+   }
+
+
+   static private void unzipit( final File zippedFile, final File unzipDir ) throws IOException {
+      final byte[] buffer = new byte[ 1024 ];
+      final ZipInputStream zis = new ZipInputStream( new FileInputStream( zippedFile ) );
+      ZipEntry zipEntry = zis.getNextEntry();
+      while ( zipEntry != null ) {
+         if ( zipEntry.isDirectory() ) {
+            final File newUnzipDir = new File( unzipDir, zipEntry.getName() );
+            newUnzipDir.mkdirs();
+         } else {
+            final File newUnzipFile = newUnzipFile( unzipDir, zipEntry );
+            final FileOutputStream fos = new FileOutputStream( newUnzipFile );
+            int len;
+            while ( (len = zis.read( buffer )) > 0 ) {
+               fos.write( buffer, 0, len );
+            }
+            fos.close();
+         }
+         zipEntry = zis.getNextEntry();
+      }
+      zis.closeEntry();
+      zis.close();
+   }
+
+   static public class FileUnzipper implements Callable<File> {
+      private final File _zip;
+      private final File _unzipDir;
+
+      public FileUnzipper( final File zip, final File unzipDir ) {
+         _zip = zip;
+         _unzipDir = unzipDir;
+      }
+
+      public File call() throws IOException {
+         unzipit( _zip, _unzipDir );
+         return _unzipDir;
+      }
+   }
+
+
+   static private File newUnzipFile( final File unzipDirPath, final ZipEntry zipEntry ) throws IOException {
+      final File unzippedFile = new File( unzipDirPath, zipEntry.getName() );
+
+      final String destDirPath = unzipDirPath.getCanonicalPath();
+      final String destFilePath = unzippedFile.getCanonicalPath();
+
+      if ( !destFilePath.startsWith( destDirPath + File.separator ) ) {
+         throw new IOException( "Entry is outside of the target dir: " + zipEntry.getName() );
+      }
+      return unzippedFile;
+   }
+
+
+   static private boolean runLocally( final String directory, final String command )
+         throws IOException, InterruptedException {
+      final String os = System.getProperty( "os.name" );
+      if ( os.toLowerCase().contains( "windows" ) ) {
+         return runOnWindows( directory, command );
+      } else {
+         return runOnLinux( directory, command );
+      }
+   }
+
+   static private boolean runOnWindows( final String directory, final String command )
+         throws IOException, InterruptedException {
+      final ProcessBuilder processBuilder = new ProcessBuilder();
+      processBuilder.directory( new File( directory ) );
+      final Map<String, String> env = processBuilder.environment();
+      if ( !env.containsKey( "JAVA_HOME" ) ) {
+         env.put( "JAVA_HOME", System.getProperty( "java.home" ) );
+      }
+      processBuilder.command( "cmd.exe", "/c", command.replace( '/', '\\' ) );
+      final Process process = processBuilder.start();
+
+      final BufferedReader reader = new BufferedReader( new InputStreamReader( process.getInputStream() ) );
+      String line;
+      while ( (line = reader.readLine()) != null ) {
+         System.out.println( line );
+      }
+
+      final BufferedReader errors = new BufferedReader( new InputStreamReader( process.getErrorStream() ) );
+      String error;
+      while ( (error = errors.readLine()) != null ) {
+         System.err.println( error );
+      }
+
+      int exitCode = process.waitFor();
+//      System.out.println( "\nCMD Exited with error code : " + exitCode );
+
+      return true;
+   }
+
+
+   static private boolean runOnLinux( final String directory, final String command )
+         throws IOException, InterruptedException {
+      final ProcessBuilder processBuilder = new ProcessBuilder();
+      processBuilder.directory( new File( directory ) );
+      processBuilder.command( "bash", "-c", command );
+      final Process process = processBuilder.start();
+
+      final BufferedReader reader = new BufferedReader( new InputStreamReader( process.getInputStream() ) );
+
+      String line;
+      while ( (line = reader.readLine()) != null ) {
+         System.out.println( line );
+      }
+
+      int exitCode = process.waitFor();
+//      System.out.println( "\nBASH Exited with error code : " + exitCode );
+
+      return true;
+   }
+
+
+   static public class CommandRunner implements Callable<Boolean> {
+      private final String _dir;
+      private final String _command;
+
+      public CommandRunner( final String directory, final String command ) {
+         _dir = directory;
+         _command = command;
+      }
+
+      public Boolean call() throws IOException, InterruptedException {
+         return runLocally( _dir, _command );
+      }
+   }
+
+
+}

Added: ctakes/trunk/ctakes-dockhand/src/main/resources/LICENSE
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/resources/LICENSE?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/resources/LICENSE (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/resources/LICENSE Sat Nov 30 19:05:56 2019
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   Licensed under the Apache License, Version 2.0 (the "License");
+   you may not use this file except in compliance with the License.
+   You may obtain a copy of the License at
+
+       http://www.apache.org/licenses/LICENSE-2.0
+
+   Unless required by applicable law or agreed to in writing, software
+   distributed under the License is distributed on an "AS IS" BASIS,
+   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+   See the License for the specific language governing permissions and
+   limitations under the License.

Added: ctakes/trunk/ctakes-dockhand/src/main/resources/NOTICE
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/resources/NOTICE?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/resources/NOTICE (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/resources/NOTICE Sat Nov 30 19:05:56 2019
@@ -0,0 +1,26 @@
+Apache cTAKES
+Copyright 2013 The Apache Software Foundation
+
+This product includes software developed at
+The Apache Software Foundation (http://www.apache.org/).
+
+Portions of cTAKES were originally developed by
+Mayo Clinic and are licensed to the Apache Software
+Foundation under the "Software Grant License Agreement".
+Copyright (c) 2009 Mayo Foundation for Medical Education 
+and Research (MFMER) 
+
+Portions of cTAKES were originally developed by
+Boston Children's Hospital and are licensed to the Apache Software
+Foundation under the "Software Grant License Agreement".
+Copyright (c) 2012 Boston Children's Hospital.
+
+Portions of cTAKES were originally developed by
+University of Colorado and are licensed to the Apache Software
+Foundation under the "Software Grant License Agreement".
+Copyright (c) 2012 University of Colorado.
+
+Portions of cTAKES were originally developed by
+The MITRE corporation  and are licensed to the Apache Software
+Foundation under the "Software Grant License Agreement".
+Copyright (c) 2012 The MITRE Corporation.

Added: ctakes/trunk/ctakes-dockhand/src/main/resources/log4j.xml
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/resources/log4j.xml?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/resources/log4j.xml (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/resources/log4j.xml Sat Nov 30 19:05:56 2019
@@ -0,0 +1,63 @@
+<?xml version="1.0" encoding="UTF-8" ?> <!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
+<!--
+
+    Licensed to the Apache Software Foundation (ASF) under one
+    or more contributor license agreements.  See the NOTICE file
+    distributed with this work for additional information
+    regarding copyright ownership.  The ASF licenses this file
+    to you under the Apache License, Version 2.0 (the
+    "License"); you may not use this file except in compliance
+    with the License.  You may obtain a copy of the License at
+
+      http://www.apache.org/licenses/LICENSE-2.0
+
+    Unless required by applicable law or agreed to in writing,
+    software distributed under the License is distributed on an
+    "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+    KIND, either express or implied.  See the License for the
+    specific language governing permissions and limitations
+    under the License.
+
+-->
+<log4j:configuration debug="true"
+                     xmlns:log4j='http://jakarta.apache.org/log4j/'>
+   <appender name="consoleAppender" class="org.apache.log4j.ConsoleAppender">
+      <layout class="org.apache.log4j.PatternLayout">
+         <param name="ConversionPattern" value="%d{dd MMM yyyy HH:mm:ss} %5p %c{1} - %m%n"/>
+      </layout>
+   </appender>
+   <appender name="fileAppender" class="org.apache.log4j.RollingFileAppender">
+      <param name="append" value="false"/>
+      <param name="file" value="out/ctakes.log"/>
+      <layout class="org.apache.log4j.PatternLayout">
+         <param name="ConversionPattern" value="%d{ABSOLUTE} %-5p [%c{1}] %m%n"/>
+      </layout>
+   </appender>
+   <!-- noEolAppender  prints a message without prefix or newline -->
+   <appender name="noEolAppender" class="org.apache.log4j.ConsoleAppender">
+      <layout class="org.apache.log4j.PatternLayout">
+         <param name="ConversionPattern" value="%m"/>
+      </layout>
+   </appender>
+   <!-- eolAppender  prints a message and newline without prefix -->
+   <appender name="eolAppender" class="org.apache.log4j.ConsoleAppender">
+      <layout class="org.apache.log4j.PatternLayout">
+         <param name="ConversionPattern" value="%m%n"/>
+      </layout>
+   </appender>
+   <!-- ProgressAppender is useful for dynamically logging progress dots ... -->
+   <logger name="ProgressAppender" additivity="false">
+      <level value="INFO"/>
+      <appender-ref ref="noEolAppender"/>
+   </logger>
+   <!-- ProgressDone is useful for ending the dynamic logging of progress dots ... -->
+   <logger name="ProgressDone" additivity="false">
+      <level value="INFO"/>
+      <appender-ref ref="eolAppender"/>
+   </logger>
+   <root>
+      <level value="INFO"/>
+      <appender-ref ref="consoleAppender"/>
+      <!--  <appender-ref ref="fileAppender" /> -->
+   </root>
+</log4j:configuration> 
\ No newline at end of file

Added: ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/binary/RunPipeline.bat
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/binary/RunPipeline.bat?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/binary/RunPipeline.bat (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/binary/RunPipeline.bat Sat Nov 30 19:05:56 2019
@@ -0,0 +1,24 @@
+::
+:: Licensed to the Apache Software Foundation (ASF) under one
+:: or more contributor license agreements.  See the NOTICE file
+:: distributed with this work for additional information
+:: regarding copyright ownership.  The ASF licenses this file
+:: to you under the Apache License, Version 2.0 (the
+:: "License"); you may not use this file except in compliance
+:: with the License.  You may obtain a copy of the License at
+::
+::   http://www.apache.org/licenses/LICENSE-2.0
+::
+:: Unless required by applicable law or agreed to in writing,
+:: software distributed under the License is distributed on an
+:: "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+:: KIND, either express or implied.  See the License for the
+:: specific language governing permissions and limitations
+:: under the License.
+::
+::
+::   Runs the pipeline in a piper file.
+::
+:: Requires JAVA JDK 1.8+
+::
+java -cp "lib/*" -Dlog4j.configuration=file:log4j.xml -Xms512M -Xmx3g org.apache.ctakes.gui.pipeline.PiperRunnerGui -p DockHandPipeline.piper

Added: ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/binary/RunPipeline.sh
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/binary/RunPipeline.sh?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/binary/RunPipeline.sh (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/binary/RunPipeline.sh Sat Nov 30 19:05:56 2019
@@ -0,0 +1,25 @@
+#!/bin/sh
+#
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements.  See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership.  The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License.  You may obtain a copy of the License at
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied.  See the License for the
+# specific language governing permissions and limitations
+# under the License.
+#
+#
+#   Runs the pipeline in a piper file.
+#
+# Requires JAVA JDK 1.8+
+#
+java -cp "lib/*" -Dlog4j.configuration=file:log4j.xml -Xms512M -Xmx3g org.apache.ctakes.gui.pipeline.PiperRunnerGui -p DockHandPipeline.piper

Added: ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/docker/Dockerfile
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/docker/Dockerfile?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/docker/Dockerfile (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/docker/Dockerfile Sat Nov 30 19:05:56 2019
@@ -0,0 +1,44 @@
+FROM openjdk:8-alpine
+
+RUN apk update && apk add ca-certificates openssl wget unzip maven
+
+## Download apache-tomcat and extract:
+# RUN wget http://mirror.cc.columbia.edu/pub/software/apache/tomcat/tomcat-9/v9.0.14/bin/apache-tomcat-9.0.14.zip
+# RUN unzip apache-tomcat-9.0.14.zip
+RUN wget https://archive.apache.org/dist/tomcat/tomcat-9/v9.0.14/bin/apache-tomcat-9.0.14.zip \
+&& unzip apache-tomcat-9.0.14.zip && rm apache-tomcat-9.0.14.zip
+
+
+RUN mkdir -p /ctakes_src
+COPY pom.xml /ctakes_src/
+COPY TinyRestPipeline.piper /ctakes_src/
+COPY DockhandPipeline.piper /ctakes_src/
+COPY log4j.xml /ctakes_src/
+COPY LICENSE /ctakes_src/
+COPY NOTICE /ctakes_src/
+#  RestServer calls TinyRestPipeline.
+
+WORKDIR /ctakes_src
+
+RUN mvn compile -DskipTests
+#  Don't copy the piper file to resources until mvn compile has created the directories.
+#  Then package can put it in the WAR.
+COPY TinyRestPipeline.piper /ctakes_src/ctakes-core-res/src/main/resources/org/apache/ctakes/core/pipeline/
+COPY DockhandPipeline.piper /ctakes_src/ctakes-core-res/src/main/resources/org/apache/ctakes/core/pipeline/
+
+RUN mvn package
+
+WORKDIR /
+RUN mv /ctakes_src/ctakes_tiny_rest.war /apache-tomcat-9.0.14/webapps/
+
+RUN rm -fr /ctakes_src
+
+ENV TOMCAT_HOME=/apache-tomcat-9.0.14
+
+EXPOSE 8080
+
+
+WORKDIR $TOMCAT_HOME
+RUN chmod u+x bin/*.sh
+
+CMD bin/catalina.sh run

Added: ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/goal/local/pom/attribute_pom.xml
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/goal/local/pom/attribute_pom.xml?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/goal/local/pom/attribute_pom.xml (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/goal/local/pom/attribute_pom.xml Sat Nov 30 19:05:56 2019
@@ -0,0 +1,128 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+   <modelVersion>4.0.0</modelVersion>
+   <groupId>org.apache.ctakes</groupId>
+   <artifactId>dockhand-local</artifactId>
+   <name>Attribute Dockhand</name>
+   <version>4.0.1-SNAPSHOT</version>
+   <description>Discovers Entites and Attributes using Apache cTAKES</description>
+   <packaging>jar</packaging>
+   <url>http://ctakes.apache.org</url>
+   <inceptionYear>2012</inceptionYear>
+
+   <properties>
+      <ctakes.version>4.0.1-SNAPSHOT</ctakes.version>
+      <maven.compiler.source>1.8</maven.compiler.source>
+      <maven.compiler.target>1.8</maven.compiler.target>
+      <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
+   </properties>
+
+   <dependencies>
+
+      <dependency>
+         <groupId>org.apache.ctakes</groupId>
+         <artifactId>ctakes-utils</artifactId>
+         <version>${ctakes.version}</version>
+         <exclusions>
+            <exclusion>
+               <groupId>org.apache.lucene</groupId>
+               <artifactId>lucene-queries</artifactId>
+            </exclusion>
+            <exclusion>
+               <groupId>org.apache.lucene</groupId>
+               <artifactId>lucene-queryparser</artifactId>
+            </exclusion>
+            <exclusion>
+               <groupId>org.apache.lucene</groupId>
+               <artifactId>lucene-analyzers-common</artifactId>
+            </exclusion>
+         </exclusions>
+      </dependency>
+
+      <dependency>
+         <groupId>org.apache.ctakes</groupId>
+         <artifactId>ctakes-dependency-parser</artifactId>
+         <version>${ctakes.version}</version>
+         <exclusions>
+            <exclusion>
+               <groupId>org.apache.ctakes</groupId>
+               <artifactId>ctakes-dependency-parser-res-clear</artifactId>
+            </exclusion>
+            <exclusion>
+               <groupId>org.apache.ctakes</groupId>
+               <artifactId>ctakes-lvg</artifactId>
+            </exclusion>
+         </exclusions>
+      </dependency>
+      <dependency>
+         <groupId>org.apache.ctakes</groupId>
+         <artifactId>ctakes-constituency-parser-res</artifactId>
+         <version>${ctakes.version}</version>
+      </dependency>
+
+      <dependency>
+         <groupId>org.apache.ctakes</groupId>
+         <artifactId>ctakes-dictionary-lookup-fast</artifactId>
+         <version>${ctakes.version}</version>
+      </dependency>
+      <dependency>
+         <groupId>net.sourceforge.ctakesresources</groupId>
+         <artifactId>ctakes-resources-sno_rx</artifactId>
+         <version>4.0.0</version>
+      </dependency>
+
+      <dependency>
+         <groupId>org.apache.ctakes</groupId>
+         <artifactId>ctakes-assertion</artifactId>
+         <version>${ctakes.version}</version>
+      </dependency>
+
+      <dependency>
+         <groupId>org.apache.ctakes</groupId>
+         <artifactId>ctakes-fhir</artifactId>
+         <version>${ctakes.version}</version>
+      </dependency>
+
+   </dependencies>
+
+   <repositories>
+      <repository>
+         <id>apache.snapshots</id>
+         <name>Apache Development Snapshot Repository</name>
+         <url>https://repository.apache.org/content/groups/snapshots/</url>
+         <releases>
+            <enabled>false</enabled>
+         </releases>
+         <snapshots>
+            <enabled>true</enabled>
+         </snapshots>
+      </repository>
+   </repositories>
+
+   <build>
+
+      <plugins>
+
+         <plugin>
+            <artifactId>maven-assembly-plugin</artifactId>
+            <executions>
+               <execution>
+                  <id>bundle-project-sources</id>
+                  <phase>package</phase>
+                  <goals>
+                     <goal>single</goal>
+                  </goals>
+                  <configuration>
+                     <descriptors>
+                        <descriptor>build.xml</descriptor>
+                     </descriptors>
+                     <finalName>apache-ctakes-${project.version}</finalName>
+                  </configuration>
+               </execution>
+            </executions>
+         </plugin>
+
+      </plugins>
+   </build>
+
+</project>
\ No newline at end of file

Added: ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/goal/local/pom/build.xml
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/goal/local/pom/build.xml?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/goal/local/pom/build.xml (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/goal/local/pom/build.xml Sat Nov 30 19:05:56 2019
@@ -0,0 +1,53 @@
+<assembly xmlns="http://maven.apache.org/ASSEMBLY/2.0.0"
+          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+          xsi:schemaLocation="http://maven.apache.org/ASSEMBLY/2.0.0 http://maven.apache.org/xsd/assembly-2.0.0.xsd">
+   <id>bin</id>
+   <formats>
+      <format>dir</format>
+   </formats>
+
+   <dependencySets>
+      <dependencySet>
+         <includes>
+            <include>org.apache.ctakes:dockhand-local</include>
+         </includes>
+         <useTransitiveFiltering>true</useTransitiveFiltering>
+         <fileMode>644</fileMode>
+         <directoryMode>755</directoryMode>
+         <outputDirectory>lib</outputDirectory>
+      </dependencySet>
+   </dependencySets>
+
+
+   <fileSets>
+      <fileSet>
+         <directory>.</directory>
+         <outputDirectory/>
+         <includes>
+            <include>*.piper</include>
+         </includes>
+         <fileMode>644</fileMode>
+         <directoryMode>755</directoryMode>
+      </fileSet>
+   </fileSets>
+
+   <files>
+      <file>
+         <source>LICENSE</source>
+         <outputDirectory/>
+      </file>
+      <file>
+         <source>NOTICE</source>
+         <outputDirectory/>
+      </file>
+      <file>
+         <source>log4j.xml</source>
+         <outputDirectory/>
+      </file>
+      <file>
+         <source>RunPipeline.sh</source>
+         <outputDirectory/>
+      </file>
+   </files>
+
+</assembly>
\ No newline at end of file

Added: ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/goal/local/pom/coreference_pom.xml
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/goal/local/pom/coreference_pom.xml?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/goal/local/pom/coreference_pom.xml (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/goal/local/pom/coreference_pom.xml Sat Nov 30 19:05:56 2019
@@ -0,0 +1,142 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+   <modelVersion>4.0.0</modelVersion>
+   <groupId>org.apache.ctakes</groupId>
+   <artifactId>dockhand-local</artifactId>
+   <name>Coreference Dockhand</name>
+   <version>4.0.1-SNAPSHOT</version>
+   <description>Discovers Coreference Information using Apache cTAKES</description>
+   <packaging>jar</packaging>
+   <url>http://ctakes.apache.org</url>
+   <inceptionYear>2012</inceptionYear>
+
+   <properties>
+      <ctakes.version>4.0.1-SNAPSHOT</ctakes.version>
+   </properties>
+
+   <dependencies>
+
+      <dependency>
+         <groupId>org.apache.ctakes</groupId>
+         <artifactId>ctakes-utils</artifactId>
+         <version>${ctakes.version}</version>
+         <exclusions>
+            <exclusion>
+               <groupId>org.apache.lucene</groupId>
+               <artifactId>lucene-queries</artifactId>
+            </exclusion>
+            <exclusion>
+               <groupId>org.apache.lucene</groupId>
+               <artifactId>lucene-queryparser</artifactId>
+            </exclusion>
+            <exclusion>
+               <groupId>org.apache.lucene</groupId>
+               <artifactId>lucene-analyzers-common</artifactId>
+            </exclusion>
+         </exclusions>
+      </dependency>
+      <dependency>
+         <groupId>org.apache.ctakes</groupId>
+         <artifactId>ctakes-coreference</artifactId>
+         <version>${ctakes.version}</version>
+         <exclusions>
+            <exclusion>
+               <groupId>org.apache.ctakes</groupId>
+               <artifactId>ctakes-clinical-pipeline</artifactId>
+            </exclusion>
+            <exclusion>
+               <groupId>org.apache.ctakes</groupId>
+               <artifactId>ctakes-temporal</artifactId>
+            </exclusion>
+            <exclusion>
+               <groupId>org.apache.ctakes</groupId>
+               <artifactId>ctakes-relation-extractor-res</artifactId>
+            </exclusion>
+         </exclusions>
+      </dependency>
+
+      <dependency>
+         <groupId>org.apache.ctakes</groupId>
+         <artifactId>ctakes-chunker</artifactId>
+         <version>${ctakes.version}</version>
+      </dependency>
+
+      <dependency>
+         <groupId>org.apache.ctakes</groupId>
+         <artifactId>ctakes-dictionary-lookup-fast</artifactId>
+         <version>${ctakes.version}</version>
+      </dependency>
+      <dependency>
+         <groupId>net.sourceforge.ctakesresources</groupId>
+         <artifactId>ctakes-resources-sno_rx</artifactId>
+         <version>4.0.0</version>
+      </dependency>
+
+      <dependency>
+         <groupId>org.apache.ctakes</groupId>
+         <artifactId>ctakes-constituency-parser</artifactId>
+         <version>${ctakes.version}</version>
+      </dependency>
+      <dependency>
+         <groupId>org.apache.ctakes</groupId>
+         <artifactId>ctakes-dependency-parser</artifactId>
+         <version>${ctakes.version}</version>
+         <exclusions>
+            <exclusion>
+               <groupId>org.apache.ctakes</groupId>
+               <artifactId>ctakes-dependency-parser-res-clear</artifactId>
+            </exclusion>
+            <exclusion>
+               <groupId>org.apache.ctakes</groupId>
+               <artifactId>ctakes-lvg</artifactId>
+            </exclusion>
+         </exclusions>
+      </dependency>
+      <dependency>
+         <groupId>org.apache.ctakes</groupId>
+         <artifactId>ctakes-context-tokenizer</artifactId>
+         <version>${ctakes.version}</version>
+      </dependency>
+
+      <dependency>
+         <groupId>org.apache.ctakes</groupId>
+         <artifactId>ctakes-fhir</artifactId>
+         <version>${ctakes.version}</version>
+      </dependency>
+
+      <!--  libsvm for temporal  -->
+      <dependency>
+         <groupId>org.cleartk</groupId>
+         <artifactId>cleartk-ml-libsvm</artifactId>
+         <version>2.0.0</version>
+      </dependency>
+
+   </dependencies>
+
+   <build>
+      <plugins>
+
+         <plugin>
+            <artifactId>maven-assembly-plugin</artifactId>
+            <executions>
+               <execution>
+                  <id>bundle-project-sources</id>
+                  <phase>package</phase>
+                  <goals>
+                     <goal>single</goal>
+                  </goals>
+                  <configuration>
+                     <descriptors>
+                        <descriptor>build.xml</descriptor>
+                     </descriptors>
+                     <finalName>apache-ctakes-${project.version}</finalName>
+                     <outputDirectory>.</outputDirectory>
+                  </configuration>
+               </execution>
+            </executions>
+         </plugin>
+
+      </plugins>
+   </build>
+
+</project>
\ No newline at end of file

Added: ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/goal/local/pom/entity_pom.xml
URL: http://svn.apache.org/viewvc/ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/goal/local/pom/entity_pom.xml?rev=1870640&view=auto
==============================================================================
--- ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/goal/local/pom/entity_pom.xml (added)
+++ ctakes/trunk/ctakes-dockhand/src/main/resources/org/apache/ctakes/dockhand/goal/local/pom/entity_pom.xml Sat Nov 30 19:05:56 2019
@@ -0,0 +1,84 @@
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+   <modelVersion>4.0.0</modelVersion>
+   <groupId>org.apache.ctakes</groupId>
+   <artifactId>dockhand-local</artifactId>
+   <name>Entity Dockhand</name>
+   <version>4.0.1-SNAPSHOT</version>
+   <description>Discovers Entites using Apache cTAKES</description>
+   <packaging>jar</packaging>
+   <url>http://ctakes.apache.org</url>
+   <inceptionYear>2012</inceptionYear>
+
+   <properties>
+      <ctakes.version>4.0.1-SNAPSHOT</ctakes.version>
+   </properties>
+
+   <dependencies>
+
+      <dependency>
+         <groupId>org.apache.ctakes</groupId>
+         <artifactId>ctakes-utils</artifactId>
+         <version>${ctakes.version}</version>
+         <exclusions>
+            <exclusion>
+               <groupId>org.apache.lucene</groupId>
+               <artifactId>lucene-queries</artifactId>
+            </exclusion>
+            <exclusion>
+               <groupId>org.apache.lucene</groupId>
+               <artifactId>lucene-queryparser</artifactId>
+            </exclusion>
+            <exclusion>
+               <groupId>org.apache.lucene</groupId>
+               <artifactId>lucene-analyzers-common</artifactId>
+            </exclusion>
+         </exclusions>
+      </dependency>
+
+      <dependency>
+         <groupId>org.apache.ctakes</groupId>
+         <artifactId>ctakes-dictionary-lookup-fast</artifactId>
+         <version>${ctakes.version}</version>
+      </dependency>
+      <dependency>
+         <groupId>net.sourceforge.ctakesresources</groupId>
+         <artifactId>ctakes-resources-sno_rx</artifactId>
+         <version>4.0.0</version>
+      </dependency>
+
+      <dependency>
+         <groupId>org.apache.ctakes</groupId>
+         <artifactId>ctakes-fhir</artifactId>
+         <version>${ctakes.version}</version>
+      </dependency>
+
+   </dependencies>
+
+   <build>
+      <plugins>
+
+         <plugin>
+            <artifactId>maven-assembly-plugin</artifactId>
+            <executions>
+               <execution>
+                  <id>bundle-project-sources</id>
+                  <phase>package</phase>
+                  <goals>
+                     <goal>single</goal>
+                  </goals>
+                  <configuration>
+                     <descriptors>
+                        <descriptor>build.xml</descriptor>
+                     </descriptors>
+                     <finalName>apache-ctakes-${project.version}</finalName>
+                     <outputDirectory>.</outputDirectory>
+                  </configuration>
+               </execution>
+            </executions>
+         </plugin>
+
+      </plugins>
+   </build>
+
+</project>
\ No newline at end of file