001/**
002 * Copyright (c) 2010 The Regents of the University of California.
003 * All rights reserved.
004 *
005 * '$Author: tao $'
006 * '$Date: 2010-06-03 16:45:10 -0700 (Thu, 03 Jun 2010) $' 
007 * '$Revision: 24730 $'
008 * 
009 * Permission is hereby granted, without written agreement and without
010 * license or royalty fees, to use, copy, modify, and distribute this
011 * software and its documentation for any purpose, provided that the above
012 * copyright notice and the following two paragraphs appear in all copies
013 * of this software.
014 *
015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY
016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF
018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF
019 * SUCH DAMAGE.
020 *
021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES,
022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE
024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF
025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES,
026 * ENHANCEMENTS, OR MODIFICATIONS.
027 *
028 */
029package org.kepler.workflowscheduler.gui.configurationwizard;
030
031import java.awt.BorderLayout;
032import java.awt.Cursor;
033import java.awt.Dimension;
034import java.awt.GridBagConstraints;
035import java.awt.GridBagLayout;
036import java.awt.Insets;
037import java.awt.event.ActionEvent;
038import java.awt.event.ActionListener;
039import java.io.InputStream;
040import java.net.URL;
041import java.net.URLConnection;
042
043import javax.swing.BorderFactory;
044import javax.swing.Box;
045import javax.swing.BoxLayout;
046import javax.swing.JButton;
047import javax.swing.JDialog;
048import javax.swing.JLabel;
049import javax.swing.JOptionPane;
050import javax.swing.JPanel;
051import javax.swing.JTextField;
052
053import org.kepler.configuration.ConfigurationManagerException;
054import org.kepler.configuration.ConfigurationProperty;
055import org.kepler.configuration.NamespaceException;
056import org.kepler.gui.state.StateChangeEvent;
057import org.kepler.gui.state.StateChangeMonitor;
058import org.kepler.module.workflowschedulergui.Initialize;
059import org.kepler.workflowscheduler.gui.WorkflowSchedulerPanel;
060
061import ptolemy.actor.gui.TableauFrame;
062import ptolemy.kernel.util.NamedObj;
063
064
065/**
066 * This dialog provide a interface for user to add a workflow scheduler url
067 * @author tao
068 *
069 */
070public class WorkflowSchedulerURLConfigurationDialog extends JDialog
071{
072  private static final String TITLE = "Workflow URL Configuration";
073  private static final String DEFAULTURL = "http://yourhostname/workflowscheduler/scheduler";
074  private static final int WIDTH = 800;
075  private static final int HEIGHT = 200;
076  static final int LEADSPACESIZE = 50; // leading space of each row
077  static final int TEXTFIELDSIZE = 600;
078  private TableauFrame parent = null;
079  private GridBagConstraints textFieldConstraint = null;
080  private GridBagConstraints labelConstraint = null;
081  private GridBagConstraints lastConstraint = null;
082  private JTextField urlTextField = null;
083  //private CompletingConfigurationListenerInterface completeListener = null;
084
085  /**
086   * Constructor
087   */
088  public WorkflowSchedulerURLConfigurationDialog(TableauFrame parent)
089  {
090    //super(parent);
091    this.parent = parent;
092    //this.completeListener = completeListener;
093    init();
094    this.pack();
095    this.setVisible(true);
096  }
097  
098  /*
099   * Initialize the dialog
100   */
101  private void init()
102  {
103    setPreferredSize(new Dimension(WIDTH, HEIGHT));    
104    if(parent != null)
105    {
106      setLocation(parent.getLocation());
107    }
108    setTitle(TITLE);
109    setModal(true);
110    setLayout(new BorderLayout());
111    initializeGridBagLayout();
112    initMainPanel();
113    initButtonPanel();
114  }
115  
116  /*
117   * Initialize the grid bag layout manager
118   */
119  private void initializeGridBagLayout()
120  {
121    textFieldConstraint = new GridBagConstraints();
122    textFieldConstraint.fill = GridBagConstraints.HORIZONTAL;
123    //lastConstraint.anchor = GridBagConstraints.NORTHWEST;
124    // Give the "last" component as much space as possible
125    textFieldConstraint.weightx = 1.0;
126    //textFieldConstraint.gridwidth = GridBagConstraints.RELATIVE;     
127    textFieldConstraint.insets = new Insets(4, 4, 4, 4);
128
129    lastConstraint = (GridBagConstraints) textFieldConstraint.clone();
130    //These still get as much space as possible, but do
131    //not close out a row
132    lastConstraint.gridwidth = GridBagConstraints.REMAINDER;
133
134    // first component (usually it is a label) on each row
135    labelConstraint = (GridBagConstraints) textFieldConstraint.clone();
136    // Give these as little space as necessary
137    labelConstraint.weightx = 0.0;
138    labelConstraint.gridwidth = 1;
139
140  }
141  
142  /*
143   * Initialize the main panel containing the text field and description
144   */
145  private void initMainPanel()
146  {
147    JPanel mainPanel = new JPanel();
148    GridBagLayout gridbag = new GridBagLayout();
149    mainPanel.setLayout(gridbag);
150    addLeadingSpace(mainPanel, gridbag, labelConstraint);
151    JLabel nameLabel = new JLabel("Workflow Scheduler Server URL          ");
152    WorkflowSchedulerPanel.addComponent(mainPanel, nameLabel, gridbag, labelConstraint);
153    urlTextField = new JTextField();
154    if(Initialize.getSchedulerURL() != null)
155    {
156      urlTextField.setText(Initialize.getSchedulerURL());
157    }
158    else
159    {
160      urlTextField.setText(DEFAULTURL);
161    }
162    
163    WorkflowSchedulerPanel.addFixWidthComponent(mainPanel, urlTextField , gridbag, textFieldConstraint);
164    addEndingSpace(mainPanel, gridbag,lastConstraint);
165    add(mainPanel, BorderLayout.CENTER);
166  }
167  
168  /*
169   * Initialize the panel containing Add and cancel button
170   */
171  private void initButtonPanel()
172  {
173    JPanel buttonPanel = new JPanel();
174    buttonPanel.setLayout(new BoxLayout(buttonPanel, BoxLayout.X_AXIS));
175    buttonPanel.setBorder(BorderFactory.createEmptyBorder(10, 10, 10, 10));
176    buttonPanel.add(Box.createHorizontalGlue());
177    JButton cancelButton = new JButton("Cancel");
178    cancelButton.setPreferredSize(new Dimension(100, 50));
179    cancelButton.addActionListener(new ActionListener()
180    {
181      public void actionPerformed(ActionEvent e)
182      {
183        dispose();
184      }
185    });   
186    buttonPanel.add(cancelButton);
187    buttonPanel.add(Box.createHorizontalStrut(10));
188    JButton addButton = new JButton("Set");
189    addButton.setPreferredSize(new Dimension(100, 50));
190    addButton.addActionListener(new ActionListener()
191    {
192      public void actionPerformed(ActionEvent e)
193      {
194        try
195        {
196          setCursor(Cursor.getPredefinedCursor(Cursor.WAIT_CURSOR));
197          modifyWorkflowSchedulerURLToConfig();
198          setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
199        }
200        catch(Exception ee)
201        {
202          setCursor(Cursor.getPredefinedCursor(Cursor.DEFAULT_CURSOR));
203          JOptionPane.showMessageDialog(null, "Couldn't configure the scheduler url - "+ee.getMessage(), "Error", JOptionPane.ERROR_MESSAGE);
204        }
205      }
206    });  
207    buttonPanel.add(addButton);
208    add(buttonPanel, BorderLayout.SOUTH);
209  }
210  
211  
212  /*
213   * Add the new url or modify the existing url to the configuration file
214   */
215  private void modifyWorkflowSchedulerURLToConfig() throws ConfigurationManagerException, NamespaceException
216  {
217    String newURL = urlTextField.getText();
218    if(openURL(newURL))
219    {
220      ConfigurationProperty rootProperty = Initialize.getCurrentModuleProperty();
221      ConfigurationProperty schedulerProperty = rootProperty.getProperty(Initialize.SCHEDULER);
222      if(schedulerProperty != null)
223      {
224        ConfigurationProperty urlProperty = schedulerProperty.getProperty(Initialize.URL);
225        if(urlProperty != null)
226        {
227          urlProperty.setValue(newURL);
228        }
229        else
230        {
231          //add url property to the eixsting scheduler property
232          urlProperty = new ConfigurationProperty(Initialize.getCurrentModule(), Initialize.URL, newURL);
233          schedulerProperty.addProperty(urlProperty);
234        }
235        
236      }
237      else
238      {
239        //add a new scheduler property
240        schedulerProperty =  new ConfigurationProperty(Initialize.getCurrentModule(), Initialize.SCHEDULER);
241        ConfigurationProperty urlProperty = new ConfigurationProperty(Initialize.getCurrentModule(), Initialize.URL, newURL);
242        schedulerProperty.addProperty(urlProperty);
243        rootProperty.addProperty(schedulerProperty);
244      }
245      //System.out.println("the root property is dirty "+rootProperty.isDirty());
246      //ConfigurationManager.getInstance().saveConfiguration();
247      /*if(completeListener != null)
248      {
249        //System.out.println("calling complete method .....");
250        completeListener.completeConfiguration();
251      }*/
252      NamedObj reference = null;
253      StateChangeEvent event = new StateChangeEvent(this,WorkflowSchedulerConfigEvent.MODIFYCONFIGEVENT, reference);
254      StateChangeMonitor.getInstance().notifyStateChange(event);
255      dispose();
256    }
257  }
258  
259  /*
260   * Check if the specified url openable
261   */
262  public static boolean openURL(String urlStr)
263  {
264    boolean openable = false;
265    String error=".";
266    try
267    {
268      URL url = new URL(urlStr);
269      URLConnection connection = url.openConnection();
270      if(connection != null)
271      {
272        //System.out.println("connection is not null");
273        InputStream input = connection.getInputStream();
274        //System.out.println("after getting connection l");
275        if(input != null)
276        {
277          openable = true;
278          //System.out.println("input is NOT null");
279        }
280        else
281        {
282          //System.out.println("input is null");
283        }
284        //System.out.println("reach the endl");
285      }
286      
287    }
288    catch(Exception e)
289    {
290      error =" \nsince "+ e.getMessage()+".";
291      error = error.replace(WorkflowRunEngineConfigurationDialog.URLAPPENDIX, "");
292    }
293    if(!openable)
294    {
295      String displayURL = urlStr.replace(WorkflowRunEngineConfigurationDialog.URLAPPENDIX, "");
296      int choice = JOptionPane.showConfirmDialog(null,  "Couldn't connect to the server "+
297         displayURL+error+"\nDo you still want to add this url to the configuration file?", TITLE,  JOptionPane.YES_NO_OPTION);
298      if (choice == JOptionPane.YES_OPTION)
299      {
300        openable = true;
301      }
302    }
303    return openable;
304  }
305  
306  /*
307   *Add leading space in each row of a panel 
308   */
309  static void addLeadingSpace(JPanel panel, GridBagLayout layout, GridBagConstraints labelConstraint)
310  {
311    String space = "       ";
312    JLabel leadingLabel = new JLabel(space);
313    Dimension size = leadingLabel.getPreferredSize();
314    size.width = LEADSPACESIZE;
315    leadingLabel.setPreferredSize(size);
316    WorkflowSchedulerPanel.addComponent(panel, leadingLabel, layout, labelConstraint);
317  }
318  
319  /*
320   *Add ending space in each row of a panel 
321   */
322  static void addEndingSpace(JPanel panel, GridBagLayout layout, GridBagConstraints lastConstraint )
323  {
324    String space = "       ";
325    JLabel leadingLabel = new JLabel(space);
326    WorkflowSchedulerPanel.addComponent(panel, leadingLabel, layout, lastConstraint);
327  }
328  
329
330}