Package net.raymanoz.ui

Source Code of net.raymanoz.ui.GUIInteractionStrategy

package net.raymanoz.ui;

import java.awt.EventQueue;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JButton;
import java.awt.FlowLayout;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.awt.datatransfer.Clipboard;
import java.awt.datatransfer.StringSelection;
import java.awt.event.ActionListener;
import java.awt.event.ActionEvent;
import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException;
import javax.swing.text.SimpleAttributeSet;
import javax.swing.text.StyleConstants;
import javax.swing.text.StyleContext;
import javax.swing.text.StyledDocument;

import net.raymanoz.command.MigrateCallBack;
import net.raymanoz.config.ApplicationProperties;
import net.raymanoz.config.ApplicationPropertiesImpl;
import net.raymanoz.config.Configuration;
import net.raymanoz.config.ConfigurationImpl;
import net.raymanoz.config.ScriptStatus;
import net.raymanoz.migrate.Script;
import net.raymanoz.migrate.UMigrate;
import net.raymanoz.util.FileUtil;
import net.raymanoz.util.FileUtilImpl;
import net.raymanoz.util.PlainProperties;
import net.raymanoz.util.Properties;
import net.raymanoz.util.StreamUtilImpl;

import java.awt.Color;
import java.awt.GridBagLayout;
import java.awt.GridBagConstraints;
import java.awt.Insets;
import java.awt.Toolkit;

import javax.swing.JOptionPane;
import javax.swing.SwingConstants;
import javax.swing.JTextPane;
import javax.swing.JScrollPane;
import javax.swing.SwingWorker;
import javax.swing.border.TitledBorder;
import javax.swing.GroupLayout;
import javax.swing.GroupLayout.Alignment;
import javax.swing.JProgressBar;
import java.awt.CardLayout;
import java.awt.event.WindowEvent;
import java.awt.event.WindowAdapter;
import java.io.IOException;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import javax.swing.LayoutStyle.ComponentPlacement;
import java.awt.Component;


public class GUIInteractionStrategy implements UserInteractionStrategy {

  private static final Log LOG = LogFactory.getLog(GUIInteractionStrategy.class);
  private String message;
  private MigrateCallBack migrateCallBack;
  private Configuration config;

  public GUIInteractionStrategy(Configuration config, String message) {
    this.message = message;
    this.config = config;
  }

  private JFrame frame;

  /**
   * Launch the application.
   * @throws InterruptedException
   */
 
  static Configuration defaultConfig(){
    Properties uMigrateProperties = PlainProperties.createFromResource("uMigrate.properties");
    ApplicationProperties applicationProperties = new ApplicationPropertiesImpl(uMigrateProperties);
    FileUtil fileUtil = new FileUtilImpl(new StreamUtilImpl());
    return new ConfigurationImpl(applicationProperties, fileUtil, uMigrateProperties);
  }
 
  public static void main(String[] args) throws IOException {
    //UMigrate.main(new String[]{"migrate"});
    final GUIInteractionStrategy window = new GUIInteractionStrategy(defaultConfig(), "Test");
    MigrateCallBack migrateCallBack = new MigrateCallBack() {
     
      @Override
      public Set<String> variablesRequiringDialogInOutstanding() {
        Set<String>result = new java.util.HashSet<String>();
        /*result.add("PWD_One");
        result.add("PWD_Two");
        result.add("PWD_Three");/**/
        return result;
      }
     
      @Override
      public String summary() {
        return "A test Summary\nOf what needs Migrating";
      }
     
     
      private void fakeScript(UserInteractionStrategy userInteractionStrategy){
        final int count = 5;
        final int sleepMs = 100;
        userInteractionStrategy.scriptOutputLine(String.format("Count %d times every %d ms", count, sleepMs));
        for(int idx=0;idx<count;idx++){
          userInteractionStrategy.scriptOutputLine("count: " + idx);
          try {
            Thread.sleep(sleepMs);
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      }
     
      @Override
      public void doMigration() {
        for(int idx = 0; idx < noScriptsToMigrate(); idx++){
          final int scriptIdx = idx + 1;
          Script script = new Script() {
           
            @Override
            public Set<String> variablesRequiringDialog() {
              return null;
            }
           
            @Override
            public long getPatch() {
              return scriptIdx;
            }
           
            @Override
            public String getFileName() {
              return String.format("Script %d", scriptIdx);
            }
           
            @Override
            public long getDBVersion() {
              return 2;
            }
           
            @Override
            public ScriptStatus execute(UserInteractionStrategy userInteractionStrategy) {
              fakeScript(userInteractionStrategy);
              return ScriptStatus.COMPLETED;
            }
           
            @Override
            public String description() {
              return String.format("Script %d", scriptIdx);
            }
           
            @Override
            public String condtionStatus() {
              return "OK";
            }
           
            @Override
            public int compareTo(Script o) {
              return 0;
            }
          };
          window.scriptStatusMessage(idx, script, ScriptStatus.STARTED);
          fakeScript(window);
          window.scriptStatusMessage(idx, script, ScriptStatus.COMPLETED);
        }
        window.completed("Completed", false);
      }

      @Override
      public int noScriptsToMigrate() {
        return 20;
      }
    };
    window.startUIProcess(migrateCallBack);
    /**/
  }
  private JTextPane txtToBeApplied;
  private JTextPane txtCurrentActions;
  private JTextPane txtSqlOutput;
 
  @Override
  public boolean startUIProcess(final MigrateCallBack migrateCallBack) {
    this.migrateCallBack = migrateCallBack;
    EventQueue.invokeLater(new Runnable() {
      public void run() {
        try {
          initialize();
          frame.setVisible(true);
          frame.setTitle(config.getMigrationMessage() + " - " +  message);
        } catch (Exception e) {
          e.printStackTrace();
        }
      }
    });
    return true;
  }

  final private List<String> lastScriptOutput = new ArrayList<String>();
  private String lastMessage = "";
 
  void copyToClipBoard(String text){
    if (text == null||text.trim().isEmpty()) return;
    StringSelection stringSelection = new StringSelection(text);
    Clipboard clipboard = Toolkit.getDefaultToolkit().getSystemClipboard();
    clipboard.setContents( stringSelection, null );     
  }

  void copyStatusScriptToClipBoard(){
    StyledDocument doc = txtStatus.getStyledDocument();
    try {
      copyToClipBoard(doc.getText(0, doc.getLength()));
    } catch (BadLocationException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
 
  private interface InformationPublish {
    void publish();
  }
 
  private class MigrateWorker extends SwingWorker<Void, InformationPublish> {

    @Override
    protected Void doInBackground() throws Exception {
      migrateCallBack.doMigration();
      return null;
    }
   
    @Override
    protected void process(List<InformationPublish> publishedItems) {
      for(InformationPublish info: publishedItems){
        info.publish();
      }
    }
   
    @Override
    public void done() {
      running = false
    }
   
    void publishInfo(InformationPublish info){
      publish(info)
    }
   
  }
  private MigrateWorker migrateWorker;

  @Override
  public void scriptStatusMessage(final int scriptIdx, final Script script, final ScriptStatus status) {
    if (migrateWorker == null) return;
    migrateWorker.publishInfo(new InformationPublish() {
     
      @Override
      public void publish() {
        if (status == ScriptStatus.STARTED) lastScriptOutput.clear();
        lastMessage = status + " " + script.description();
        displayStatusMessage(lastMessage);
        displayScriptLine("\n" + lastMessage + "\n", true);
      }
    });
  }

  void displayStatusMessage(String message) {
    StyledDocument doc = txtCurrentActions.getStyledDocument();
    try {
      progressBar.setValue(progressBar.getValue() + 1);
      doc.insertString(doc.getLength(), message + "\n", null);
    } catch (BadLocationException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }

  @Override
  public void errorMessage(final String message) {
    if (migrateWorker == null) return;
    migrateWorker.publishInfo(new InformationPublish() {
     
      @Override
      public void publish() {
        JOptionPane.showMessageDialog(frame, message, "Error Applying Scripts", JOptionPane.DEFAULT_OPTION);
      }
    });
  }

  @Override
  public void scriptOutputLine(final String line) {
    if (migrateWorker == null) return;
    migrateWorker.publishInfo(new InformationPublish() {
     
      @Override
      public void publish() {
        lastScriptOutput.add(line);
        displayScriptLine(line, false);
      }
    });
  }
 
  AttributeSet scriptAttributeSet(boolean isStatus){
    if (!isStatus) return null;
    StyleContext sc = StyleContext.getDefaultStyleContext();
    AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, Color.DARK_GRAY);
    aset = sc.addAttribute(aset, StyleConstants.Bold, true);
    return aset;
  }
 
  private void displayScriptLine(String line, boolean isStatus){
    StyledDocument doc = txtSqlOutput.getStyledDocument();
    try {
      doc.insertString(doc.getLength(), line + "\n", scriptAttributeSet(isStatus));
    } catch (BadLocationException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
 
  private void switchCard(String cardName){
    clWizard.show(pnlWizard, cardName);
  }

  final static String CARD_PROGRESS = "progress";
  final static String CARD_FINISHED = "finished";
  private JPanel pnlWizard;
  private CardLayout clWizard;
  private JProgressBar progressBar;
  private JTextPane txtStatus;
 
  boolean updatePropertiesValues(String desc, Set<String> properties){
    if (properties == null || properties.size() == 0) return true;
    Properties uMigrateProperties = config.uMigrateProperties();
    Map<String, String> map = MissingPropertyDialog.askForValues(properties, uMigrateProperties, desc);
    if (map == null) return false;
    for(Entry<String, String> m: map.entrySet()){
      uMigrateProperties.setProperty(m.getKey(), m.getValue());
    }
    return true;
  }
 
  void onCreate(){
    try {
      Set<String> properties = config.getConnectionVariablesRequiringDialog();
      if (!updatePropertiesValues("Read Current Database Script", properties)){
        insertStatusMessage("User Aborted setting Values to check Database Script", true);
        switchCard(CARD_FINISHED);
        return;
      }
     txtToBeApplied.setText(migrateCallBack.summary());
     if (migrateCallBack.noScriptsToMigrate() == 0){
       insertStatusMessage("Nothing to Do - database is already at Script Level", false);
       switchCard(CARD_FINISHED);
       return;
     }
    }
    catch(Exception e){
      txtStatus.setText("Error Looking up Current version of database\n" + e);
      switchCard(CARD_FINISHED);
    }
  }
 
  AttributeSet attributeSet(boolean iserror){
    if (!iserror) return null;
    StyleContext sc = StyleContext.getDefaultStyleContext();
    AttributeSet aset = sc.addAttribute(SimpleAttributeSet.EMPTY, StyleConstants.Foreground, Color.red);
    aset = sc.addAttribute(aset, StyleConstants.Bold, true);
    return aset;
  }
 
  void insertStatusMessage(String message, boolean isError){
    StyledDocument doc = txtStatus.getStyledDocument();
    try {
      doc.insertString(doc.getLength(), message + "\n", attributeSet(isError));
    } catch (BadLocationException e) {
      // TODO Auto-generated catch block
      e.printStackTrace();
    }
  }
 
  boolean running = false;
 
  void startProcess(){
    if (!updatePropertiesValues("Missing Values", migrateCallBack.variablesRequiringDialogInOutstanding())){
      insertStatusMessage("User Aborted setting Values to required Migrate Database", true);
      switchCard(CARD_FINISHED);
      return;
    }
    final int noScriptsToApply = migrateCallBack.noScriptsToMigrate();
    switchCard(CARD_PROGRESS);
    progressBar.setMinimum(0);
    progressBar.setMaximum(2 * noScriptsToApply);
    progressBar.setValue(0);
    migrateWorker = new MigrateWorker();
    running = true;
    migrateWorker.execute();
  }
 
  boolean canClose(){
    if (!running) return true;
    final String errorMessage = "Currently running Migration Scripts - exiting causes issues";
    final String title = "Exit while Running Migration Scripts";
    boolean result = JOptionPane.showConfirmDialog(frame, errorMessage, title, JOptionPane.OK_CANCEL_OPTION) == JOptionPane.OK_OPTION;
    if (result) LOG.info("User accepted exit while migrating");
    return result;
  }
 
  void close(){
    if (canClose()) {
      frame.dispose();
      //System.exit(0);
    }
  }
 
  @Override
  public void completed(final String status, final boolean successful) {
    if (migrateWorker == null) return;
    migrateWorker.publishInfo(new InformationPublish() {
     
      @Override
      public void publish() {
        insertStatusMessage(status, !successful);
        if (!successful) {
          JOptionPane.showMessageDialog(frame, "Not All scripts applied successfully", "Finished", JOptionPane.ERROR_MESSAGE);
          insertStatusMessage("Not All scripts applied successfully", true);
          insertStatusMessage("\n" + lastMessage + "\n", true);
          if (lastScriptOutput.size() > 0) insertStatusMessage("Last Script Output:", false);
          for(String line: lastScriptOutput){
            insertStatusMessage(line, false);
          }
        }
        else {
          JOptionPane.showMessageDialog(frame, "All scripts applied/skipped successfully");
          insertStatusMessage("All scripts applied/skipped successfully", false);
        }
        txtStatus.setCaretPosition(0);
        switchCard(CARD_FINISHED)
      }
    });
  }
 
 
  private void initialize() {
    frame = new JFrame();
    frame.addWindowListener(new WindowAdapter() {
      @Override
      public void windowOpened(WindowEvent arg0) {
        onCreate();      
      }
      @Override
      public void windowClosing(WindowEvent arg0) {
        close();
      }
    });
    frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
    frame.setBounds(100, 100, 943, 560);
   
    JPanel panel = new JPanel();
    panel.setAlignmentX(Component.LEFT_ALIGNMENT);
    panel.setBorder(new TitledBorder(null, "To be Applied", TitledBorder.LEADING, TitledBorder.TOP, null, null));
    panel.setLayout(null);
   
    JScrollPane scrollPane = new JScrollPane();
    scrollPane.setBounds(13, 25, 875, 97);
    panel.add(scrollPane);
   
    txtToBeApplied = new JTextPane();
    txtToBeApplied.setEditable(false);
    scrollPane.setViewportView(txtToBeApplied);
   
    pnlWizard = new JPanel();
    clWizard = new CardLayout(0, 0);
    pnlWizard.setLayout(clWizard);
   
    JPanel panel_3 = new JPanel();
    FlowLayout flowLayout = (FlowLayout) panel_3.getLayout();
    flowLayout.setAlignment(FlowLayout.LEFT);
    pnlWizard.add(panel_3, "name_139454654370795");
   
    final JPanel pnlProgress = new JPanel();

    JButton btnApply = new JButton("Apply");
    btnApply.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        startProcess();
      }
    });
    btnApply.setHorizontalAlignment(SwingConstants.LEFT);
    panel_3.add(btnApply);
   
    JButton btnAbort = new JButton("Abort");
    btnAbort.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        close();
      }
    });
    panel_3.add(btnAbort);
   
    pnlWizard.add(pnlProgress, CARD_PROGRESS);
    GridBagLayout gbl_pnlProgress = new GridBagLayout();
    gbl_pnlProgress.columnWidths = new int[]{913, 0};
    gbl_pnlProgress.rowHeights = new int[] {20, 80, 0, 0};
    gbl_pnlProgress.columnWeights = new double[]{1.0, Double.MIN_VALUE};
    gbl_pnlProgress.rowWeights = new double[]{0.0, 0.0, 1.0, Double.MIN_VALUE};
    pnlProgress.setLayout(gbl_pnlProgress);
   
    progressBar = new JProgressBar();
    GridBagConstraints gbc_progressBar = new GridBagConstraints();
    gbc_progressBar.fill = GridBagConstraints.HORIZONTAL;
    gbc_progressBar.anchor = GridBagConstraints.NORTH;
    gbc_progressBar.insets = new Insets(5, 5, 5, 5);
    gbc_progressBar.gridx = 0;
    gbc_progressBar.gridy = 0;
    pnlProgress.add(progressBar, gbc_progressBar);
   
    JPanel panel_1 = new JPanel();
    panel_1.setBorder(new TitledBorder(null, "Current Action", TitledBorder.LEFT, TitledBorder.TOP, null, null));
    GridBagConstraints gbc_panel_1 = new GridBagConstraints();
    gbc_panel_1.fill = GridBagConstraints.BOTH;
    gbc_panel_1.gridx = 0;
    gbc_panel_1.gridy = 1;
    pnlProgress.add(panel_1, gbc_panel_1);
    GridBagLayout gbl_panel_1 = new GridBagLayout();
    gbl_panel_1.columnWidths = new int[]{875, 0};
    gbl_panel_1.rowHeights = new int[]{41, 0};
    gbl_panel_1.columnWeights = new double[]{0.0, Double.MIN_VALUE};
    gbl_panel_1.rowWeights = new double[]{0.0, Double.MIN_VALUE};
    panel_1.setLayout(gbl_panel_1);
   
    JScrollPane scrollPane_3 = new JScrollPane();
    GridBagConstraints gbc_scrollPane_3 = new GridBagConstraints();
    gbc_scrollPane_3.fill = GridBagConstraints.BOTH;
    gbc_scrollPane_3.gridx = 0;
    gbc_scrollPane_3.gridy = 0;
    panel_1.add(scrollPane_3, gbc_scrollPane_3);
   
    txtCurrentActions = new JTextPane();
    scrollPane_3.setViewportView(txtCurrentActions);
   
    JPanel panel_5 = new JPanel();
    panel_5.setBorder(new TitledBorder(null, "SQL Output", TitledBorder.LEADING, TitledBorder.TOP, null, null));
    GridBagConstraints gbc_panel_5 = new GridBagConstraints();
    gbc_panel_5.fill = GridBagConstraints.BOTH;
    gbc_panel_5.gridx = 0;
    gbc_panel_5.gridy = 2;
    pnlProgress.add(panel_5, gbc_panel_5);
    GridBagLayout gbl_panel_5 = new GridBagLayout();
    gbl_panel_5.columnWidths = new int[]{0, 0};
    gbl_panel_5.rowHeights = new int[]{0, 0};
    gbl_panel_5.columnWeights = new double[]{1.0, Double.MIN_VALUE};
    gbl_panel_5.rowWeights = new double[]{1.0, Double.MIN_VALUE};
    panel_5.setLayout(gbl_panel_5);
   
    JScrollPane scrollPane_2 = new JScrollPane();
    GridBagConstraints gbc_scrollPane_2 = new GridBagConstraints();
    gbc_scrollPane_2.fill = GridBagConstraints.BOTH;
    gbc_scrollPane_2.gridx = 0;
    gbc_scrollPane_2.gridy = 0;
    panel_5.add(scrollPane_2, gbc_scrollPane_2);
   
    txtSqlOutput = new JTextPane();
    scrollPane_2.setViewportView(txtSqlOutput);

    final JPanel pnlSuccess = new JPanel();
    pnlSuccess.setBorder(null);
    pnlSuccess.setAlignmentY(Component.TOP_ALIGNMENT);
    pnlSuccess.setAlignmentX(Component.LEFT_ALIGNMENT);
    pnlWizard.add(pnlSuccess, CARD_FINISHED);
   
    JButton btnClose = new JButton("Close");
    btnClose.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent e) {
        close();
      }
    });
   
    JScrollPane scrollPane_1 = new JScrollPane();
    scrollPane_1.setBorder(new TitledBorder(null, "Status", TitledBorder.LEADING, TitledBorder.TOP, null, null));
    scrollPane_1.setAlignmentY(Component.TOP_ALIGNMENT);
   
    txtStatus = new JTextPane();
    scrollPane_1.setViewportView(txtStatus);
   
    JButton btnCopyStatus = new JButton("Copy Status");
    btnCopyStatus.addActionListener(new ActionListener() {
      public void actionPerformed(ActionEvent arg0) {
        copyStatusScriptToClipBoard();
      }
    });
    GroupLayout gl_pnlSuccess = new GroupLayout(pnlSuccess);
    gl_pnlSuccess.setHorizontalGroup(
      gl_pnlSuccess.createParallelGroup(Alignment.LEADING)
        .addGroup(gl_pnlSuccess.createSequentialGroup()
          .addComponent(btnClose)
          .addGap(18)
          .addComponent(btnCopyStatus)
          .addContainerGap(723, Short.MAX_VALUE))
        .addComponent(scrollPane_1, GroupLayout.DEFAULT_SIZE, 901, Short.MAX_VALUE)
    );
    gl_pnlSuccess.setVerticalGroup(
      gl_pnlSuccess.createParallelGroup(Alignment.LEADING)
        .addGroup(gl_pnlSuccess.createSequentialGroup()
          .addGroup(gl_pnlSuccess.createParallelGroup(Alignment.BASELINE)
            .addComponent(btnClose)
            .addComponent(btnCopyStatus))
          .addGap(5)
          .addComponent(scrollPane_1, GroupLayout.DEFAULT_SIZE, 316, Short.MAX_VALUE))
    );
    pnlSuccess.setLayout(gl_pnlSuccess);
    GroupLayout groupLayout = new GroupLayout(frame.getContentPane());
    groupLayout.setHorizontalGroup(
      groupLayout.createParallelGroup(Alignment.TRAILING)
        .addGroup(groupLayout.createSequentialGroup()
          .addContainerGap()
          .addGroup(groupLayout.createParallelGroup(Alignment.LEADING)
            .addGroup(groupLayout.createSequentialGroup()
              .addComponent(pnlWizard, GroupLayout.PREFERRED_SIZE, 901, Short.MAX_VALUE)
              .addGap(12))
            .addGroup(groupLayout.createSequentialGroup()
              .addComponent(panel, GroupLayout.DEFAULT_SIZE, 901, Short.MAX_VALUE)
              .addContainerGap())))
    );
    groupLayout.setVerticalGroup(
      groupLayout.createParallelGroup(Alignment.LEADING)
        .addGroup(groupLayout.createSequentialGroup()
          .addGap(7)
          .addComponent(panel, GroupLayout.PREFERRED_SIZE, 136, GroupLayout.PREFERRED_SIZE)
          .addPreferredGap(ComponentPlacement.UNRELATED)
          .addComponent(pnlWizard, GroupLayout.DEFAULT_SIZE, 346, Short.MAX_VALUE)
          .addGap(13))
    );
    frame.getContentPane().setLayout(groupLayout);

  }
}
TOP

Related Classes of net.raymanoz.ui.GUIInteractionStrategy

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.