gt: 		menuItem.setText( "New Request" );
context: /****************************************************************************
   *
   * Copyright (c) 2012, Linagora
   *
   * This library is free software; you can redistribute it and/or
   * modify it under the terms of the GNU Lesser General Public
   * License as published by the Free Software Foundation; either
   * version 2.1 of the License, or (at your option) any later version.
   *
   * This library is distributed in the hope that it will be useful,
   * but WITHOUT ANY WARRANTY; without even the implied warranty of
   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   * Lesser General Public License for more details.
   *
   * You should have received a copy of the GNU Lesser General Public
   * License along with this library; if not, write to the Free Software
   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
   *
   *****************************************************************************/
  
  package org.ow2.petals.engine.client.swt.tabs;
  
  import java.io.File;
  import java.io.IOException;
  import java.util.ArrayList;
  import java.util.Collection;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Set;
  import java.util.logging.Level;
  
  import javax.jbi.servicedesc.ServiceEndpoint;
  import javax.xml.namespace.QName;
  
  import org.eclipse.core.runtime.IStatus;
  import org.eclipse.jface.dialogs.MessageDialog;
  import org.eclipse.jface.layout.GridDataFactory;
  import org.eclipse.jface.layout.GridLayoutFactory;
  import org.eclipse.jface.resource.JFaceResources;
  import org.eclipse.jface.viewers.ArrayContentProvider;
  import org.eclipse.jface.viewers.ComboViewer;
  import org.eclipse.jface.viewers.ISelection;
  import org.eclipse.jface.viewers.ISelectionChangedListener;
  import org.eclipse.jface.viewers.IStructuredSelection;
  import org.eclipse.jface.viewers.LabelProvider;
  import org.eclipse.jface.viewers.SelectionChangedEvent;
  import org.eclipse.jface.viewers.StructuredSelection;
  import org.eclipse.jface.window.Window;
  import org.eclipse.swt.SWT;
  import org.eclipse.swt.custom.CCombo;
  import org.eclipse.swt.custom.SashForm;
  import org.eclipse.swt.custom.StyleRange;
  import org.eclipse.swt.custom.StyledText;
  import org.eclipse.swt.events.ModifyEvent;
  import org.eclipse.swt.events.ModifyListener;
  import org.eclipse.swt.events.MouseAdapter;
  import org.eclipse.swt.events.MouseEvent;
  import org.eclipse.swt.graphics.Color;
  import org.eclipse.swt.graphics.Image;
  import org.eclipse.swt.layout.GridData;
  import org.eclipse.swt.layout.GridLayout;
  import org.eclipse.swt.widgets.Button;
  import org.eclipse.swt.widgets.Composite;
  import org.eclipse.swt.widgets.DirectoryDialog;
  import org.eclipse.swt.widgets.Display;
  import org.eclipse.swt.widgets.Event;
  import org.eclipse.swt.widgets.FileDialog;
  import org.eclipse.swt.widgets.Group;
  import org.eclipse.swt.widgets.Label;
  import org.eclipse.swt.widgets.Link;
  import org.eclipse.swt.widgets.Listener;
  import org.eclipse.swt.widgets.Menu;
  import org.eclipse.swt.widgets.MenuItem;
  import org.eclipse.swt.widgets.ProgressBar;
  import org.eclipse.swt.widgets.Spinner;
  import org.eclipse.swt.widgets.Text;
  import org.ow2.easywsdl.wsdl.api.Description;
  import org.ow2.easywsdl.wsdl.api.InterfaceType;
  import org.ow2.easywsdl.wsdl.api.WSDLReader;
  import org.ow2.petals.engine.client.misc.PreferencesManager;
  import org.ow2.petals.engine.client.misc.Utils;
  import org.ow2.petals.engine.client.model.OperationBean;
  import org.ow2.petals.engine.client.model.RequestMessageBean;
  import org.ow2.petals.engine.client.model.ResponseMessageBean;
  import org.ow2.petals.engine.client.swt.ClientApplication;
  import org.ow2.petals.engine.client.swt.ImageIds;
  import org.ow2.petals.engine.client.swt.dialogs.NewWsdlOperationDialog;
  import org.ow2.petals.engine.client.swt.dialogs.ServiceRegistryViewerDialog;
  import org.ow2.petals.engine.client.swt.dialogs.ShowWsdlDialog;
  import org.ow2.petals.engine.client.ui.PetalsFacade;
  import org.w3c.dom.Document;
  
  /**
   * The request tab and its management.
   * @author Vincent Zurczak - Linagora
   */
  public class RequestTab extends Composite {
  
  	private static final String DEFAULT_SKELETON = "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n";
  	private static final String COMMENT_NO_WSDL = "<!-- No skeleton could be generated (no WSDL) -->";
  	private static final String COMMENT_INVALID_WSDL = "<!-- No skeleton could be generated (invalid WSDL) -->";
  	private static final String CDATA_SECTION = "<![CDATA[<!-- Insert your mark-ups here -->]]>";
  
  	private final ClientApplication clientApp;
  
  	private MessageComposite requestComposite, responseComposite;
  	private StyledText reportingStyledText;
  	private Label reportingImageLabel;
  	private ProgressBar reportingProgressBar;
  	private Spinner timeoutSpinner;
  	private Text itfText, srvText, edptText;
  	private Button showWsdlButton, sendButton;
  	private ComboViewer operationViewer;
  
  	private Description wsdlDescription;
  	private String wsdlDescriptionAsString;
  	private OperationBean operationBean;
  
  
  
  	/**
  	 * Creates the request tab.
  	 * @param parent
  	 * @param clientApp
  	 */
  	public RequestTab( Composite parent, ClientApplication clientApp ) {
  		super( parent, SWT.NONE );
  		this.clientApp = clientApp;
  
  		setLayout( new GridLayout());
  	    setLayoutData( new GridData( GridData.FILL_BOTH ));
  
  		createTargetServiceSection();
  		createMessageSection();
  		createToolSection();
      }
  
  
  	/**
  	 * Validates the user entries.
  	 */
  	public void validate() {
  
  		String msg = null;
  		if( this.itfText.getData() == null )
  			msg = "No target service was specified.";
  		else if( this.operationBean == null )
  			msg = "You must specify the name of the operation to invoke.";
  		else if( Utils.isEmptyString( this.requestComposite.getPayload()))
  			msg = "You must define a XML payload in the request message.";
  		else {
  			Set<File> attachments = this.requestComposite.getAttachments();
  			if( attachments != null ) {
  				for( File f : attachments ) {
  					if( ! f.exists()) {
  						msg = "The attached file '" + f.getName() + "' does not exist.";
  						break;
  					}
  				}
  			}
  
  			if( msg == null ) {
  				try {
  					Utils.buildDocument( this.requestComposite.getPayload());
  				} catch( Exception e ) {
  					msg = "The request's payload is not a valid XML document.";
  					this.clientApp.log( msg, e, Level.INFO );
  				}
  			}
  		}
  
  		updateMessage( msg, IStatus.ERROR );
  		RequestTab.this.sendButton.setEnabled( msg == null );
  	}
  
  
  	/**
  	 * Clears the tab.
  	 */
  	public void clearTab( ) {
  		this.requestComposite.setInput( null );
  		this.responseComposite.setInput( null );
  		updateMessage( null, IStatus.OK );
  	}
  
  
  	/**
  	 * Displays the response in the user interface.
  	 * @param response
  	 */
  	public void displayResponse( ResponseMessageBean response ) {
  		this.responseComposite.setInput( response );
  	}
  
  
  	/**
  	 * Creates the section for the target service.
  	 */
  	private void createTargetServiceSection() {
  
  		Group targetGroup = new Group( this, SWT.SHADOW_ETCHED_OUT );
  	    targetGroup.setLayout( new GridLayout( 2, false ));
  	    targetGroup.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ));
  	    targetGroup.setText( "Target Service" );
  
  	    Link selectAnotherServiceLink = new Link( targetGroup, SWT.NONE );
  	    selectAnotherServiceLink.setText( "<a>Select another Target Service...</a>" );
  	    selectAnotherServiceLink.setToolTipText( "Select another target service" );
  	    GridDataFactory.swtDefaults().span( 2, 1 ).align( SWT.END, SWT.BEGINNING ).applyTo( selectAnotherServiceLink );
  	    selectAnotherServiceLink.addListener( SWT.Selection, new Listener() {
  	    	@Override
  	    	public void handleEvent( Event e ) {
  	    		retrieveAllServiceEndpoints();
  	    	}
  	    });
  
  	    new Label( targetGroup, SWT.NONE ).setText( "Interface Name:" );
  	    this.itfText = new Text( targetGroup, SWT.BORDER | SWT.READ_ONLY );
  	    this.itfText.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ));
  
  	    new Label( targetGroup, SWT.NONE ).setText( "Service Name:" );
  	    this.srvText = new Text( targetGroup, SWT.BORDER | SWT.READ_ONLY );
  	    this.srvText.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ));
  
  	    new Label( targetGroup, SWT.NONE ).setText( "End-point Name:" );
  	    this.edptText = new Text( targetGroup, SWT.BORDER | SWT.READ_ONLY );
  	    this.edptText.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ));
  
  	    new Label( targetGroup, SWT.NONE ).setText( "Operation Name:" );
  	    Composite lineContainer = new Composite( targetGroup, SWT.NONE );
  	    GridLayoutFactory.swtDefaults().numColumns( 3 ).margins( 0, 0 ).applyTo( lineContainer );
  	    lineContainer.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ));
  
  	    this.operationViewer = new ComboViewer( new CCombo( lineContainer, SWT.BORDER | SWT.DROP_DOWN | SWT.READ_ONLY ));
  	    this.operationViewer.getCCombo().setLayoutData( new GridData( GridData.FILL_HORIZONTAL ));
  	    this.operationViewer.setContentProvider( new ArrayContentProvider());
  	    this.operationViewer.setLabelProvider( new LabelProvider());
  
  	    this.operationViewer.addSelectionChangedListener( new ISelectionChangedListener() {
  			@Override
  			public void selectionChanged( SelectionChangedEvent e ) {
  
  				// Generate a new request? Yes, if empty.
  				boolean validate = true;
  				if( Utils.isEmptyString( RequestTab.this.requestComposite.getPayload()))
  					RequestTab.this.requestComposite.setPayload( generateSkeleton());
  				else {
  					validate = false;
  					updateMessage( "The request may not match the selected service operation.", IStatus.WARNING );
  				}
  
  				// Get data
  				ISelection selection = RequestTab.this.operationViewer.getSelection();
  				if( selection.isEmpty()) {
  					RequestTab.this.operationBean = null;
  				} else {
  					RequestTab.this.operationBean = (OperationBean) ((IStructuredSelection) selection).getFirstElement();
  				}
  
  				// Validate?
  				if( validate )
  					validate();
  			}
  		});
  
  	    Button customOperationButton = new Button( lineContainer, SWT.PUSH );
  	    customOperationButton.setText( "Define a Custom Operation..." );
  	    customOperationButton.addListener( SWT.Selection, new Listener() {
  	    	@Override
  	    	public void handleEvent( Event e ) {
  	    		NewWsdlOperationDialog dlg = new NewWsdlOperationDialog( getShell(), RequestTab.this.operationBean );
  	    		if( dlg.open() == Window.OK )
  	    			updateOperationName( dlg.getOperationBean());
  	    	}
  	    });
  
  	    this.showWsdlButton = new Button( lineContainer, SWT.PUSH );
  	    this.showWsdlButton.setText( "Show WSDL" );
  	    this.showWsdlButton.setEnabled( false );
  	    this.showWsdlButton.addListener( SWT.Selection, new Listener() {
  	    	@Override
  	    	public void handleEvent( Event e ) {
  	    		ShowWsdlDialog.openShowWsdlDialog( getShell(), RequestTab.this.wsdlDescriptionAsString, RequestTab.this.clientApp );
  	    	}
  	    });
  	}
  
  
  	/**
  	 * Creates the section with the message parts.
  	 */
  	private void createMessageSection() {
  
  		// The basics...
  		SashForm sashForm = new SashForm( this, SWT.HORIZONTAL );
  	    GridDataFactory.swtDefaults().align( SWT.FILL, SWT.FILL ).grab( true, true ).indent( 0, 10 ).applyTo( sashForm );
          sashForm.setSashWidth( 20 );
  
          this.requestComposite = new MessageComposite( "Request", sashForm, this.clientApp );
          this.responseComposite = new MessageComposite( "Response", sashForm, this.clientApp );
          sashForm.setWeights( new int[] { 50, 50 });
  
  
          // Add menus items for the request part
          MenuItem menuItem = new MenuItem ( this.requestComposite.getMenu(), SWT.PUSH );
  