/******************************************************************************
* Copyright (c) 2010-2013, Linagora
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Linagora - initial API and implementation
*******************************************************************************/
package com.ebmwebsourcing.petals.services.eip.designer.tabbedproperties;
import java.beans.PropertyChangeEvent;
import java.beans.PropertyChangeListener;
import java.io.File;
import java.lang.reflect.InvocationTargetException;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.bpel.common.wsdl.helpers.UriAndUrlHelper;
import org.eclipse.core.filesystem.EFS;
import org.eclipse.core.filesystem.IFileStore;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.gef.commands.Command;
import org.eclipse.gef.commands.CommandStack;
import org.eclipse.jface.dialogs.MessageDialog;
import org.eclipse.jface.viewers.ISelection;
import org.eclipse.jface.viewers.IStructuredSelection;
import org.eclipse.jface.window.Window;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CLabel;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionEvent;
import org.eclipse.swt.events.SelectionListener;
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.FileDialog;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.IEditorPart;
import org.eclipse.ui.IWorkbenchPage;
import org.eclipse.ui.IWorkbenchPart;
import org.eclipse.ui.PartInitException;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.widgets.Hyperlink;
import org.eclipse.ui.ide.IDE;
import org.eclipse.ui.views.properties.tabbed.AbstractPropertySection;
import org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage;
import com.ebmwebsourcing.petals.common.internal.provisional.ui.StyledElementListSelectionDialog;
import com.ebmwebsourcing.petals.common.internal.provisional.utils.PetalsConstants;
import com.ebmwebsourcing.petals.common.internal.provisional.utils.StringUtils;
import com.ebmwebsourcing.petals.common.internal.provisional.utils.WsdlUtils;
import com.ebmwebsourcing.petals.common.internal.provisional.utils.WsdlUtils.JbiBasicBean;
import com.ebmwebsourcing.petals.services.eip.PetalsEipPlugin;
import com.ebmwebsourcing.petals.services.eip.designer.edit.commands.EipNodeSetAttributeCommand;
import com.ebmwebsourcing.petals.services.eip.designer.edit.parts.EipNodeEditPart;
import com.ebmwebsourcing.petals.services.eip.designer.model.AbstractNode;
import com.ebmwebsourcing.petals.services.eip.designer.model.EipNode;
import com.ebmwebsourcing.petals.services.utils.PCStyledLabelProvider;
/**
* The section for the service properties of an EIP.
* @author Vincent Zurczak - EBM WebSourcing
*/
public class EipInterfaceSection extends AbstractPropertySection implements PropertyChangeListener {
private EipNode eip;
private boolean enableListener;
private File wsdlFile;
private Text itfNsText, itfNameText, srvNsText, srvNameText, edptText, wsdlText;
private Hyperlink selectWsdlServiceLink, openWsdlLink;
/**
* Constructor.
*/
public EipInterfaceSection() {
// nothing
}
/*
* (non-Jsdoc)
* @see java.beans.PropertyChangeListener
* #propertyChange(java.beans.PropertyChangeEvent)
*/
public void propertyChange( PropertyChangeEvent evt ) {
if( AbstractNode.PROPERTY_SERVICE_NAME.equals( evt.getPropertyName())
|| AbstractNode.PROPERTY_SERVICE_NAMESPACE.equals( evt.getPropertyName())
|| AbstractNode.PROPERTY_INTERFACE_NAME.equals( evt.getPropertyName())
|| AbstractNode.PROPERTY_INTERFACE_NAMESPACE.equals( evt.getPropertyName())
|| AbstractNode.PROPERTY_ENDPOINT_NAME.equals( evt.getPropertyName())
|| EipNode.PROPERTY_WSDL_URI.equals( evt.getPropertyName()))
refresh();
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection
* #createControls(org.eclipse.swt.widgets.Composite, org.eclipse.ui.views.properties.tabbed.TabbedPropertySheetPage)
*/
@Override
public void createControls( Composite parent, TabbedPropertySheetPage aTabbedPropertySheetPage ) {
// Create the container
super.createControls( parent, aTabbedPropertySheetPage );
Composite container = getWidgetFactory().createPlainComposite( parent, SWT.NONE );
container.setLayout( new GridLayout( 4, false ));
// Create the WSDL part
createWsdlParts( container );
this.wsdlText.addModifyListener( new ModifyListener() {
public void modifyText( ModifyEvent e ) {
if( EipInterfaceSection.this.enableListener ) {
EipNodeSetAttributeCommand cmd =
new EipNodeSetAttributeCommand( EipNode.PROPERTY_WSDL_URI );
cmd.setEipNode( EipInterfaceSection.this.eip );
cmd.setNewValue( EipInterfaceSection.this.wsdlText.getText());
executeCommand( cmd );
}
}
});
// Interface
CLabel label = getWidgetFactory().createCLabel( container, "Interface name:" );
label.setToolTipText( "The local part of the interface name" );
this.itfNameText = getWidgetFactory().createText( container, "" );
this.itfNameText.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ));
this.itfNameText.addModifyListener( new ModifyListener() {
public void modifyText( ModifyEvent e ) {
if( EipInterfaceSection.this.enableListener ) {
EipNodeSetAttributeCommand cmd =
new EipNodeSetAttributeCommand( AbstractNode.PROPERTY_INTERFACE_NAME );
cmd.setEipNode( EipInterfaceSection.this.eip );
cmd.setNewValue( EipInterfaceSection.this.itfNameText.getText());
executeCommand( cmd );
}
}
});
label = getWidgetFactory().createCLabel( container, "Interface namespace:" );
label.setToolTipText( "The name space URI of the interface name" );
this.itfNsText = getWidgetFactory().createText( container, "" );
this.itfNsText.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ));
this.itfNsText.addModifyListener( new ModifyListener() {
public void modifyText( ModifyEvent e ) {
if( EipInterfaceSection.this.enableListener ) {
EipNodeSetAttributeCommand cmd =
new EipNodeSetAttributeCommand( AbstractNode.PROPERTY_INTERFACE_NAMESPACE );
cmd.setEipNode( EipInterfaceSection.this.eip );
cmd.setNewValue( EipInterfaceSection.this.itfNsText.getText());
executeCommand( cmd );
}
}
});
// Service
label = getWidgetFactory().createCLabel( container, "Service name:" );
label.setToolTipText( "The local part of the service name" );
this.srvNameText = getWidgetFactory().createText( container, "" );
this.srvNameText.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ));
this.srvNameText.addModifyListener( new ModifyListener() {
public void modifyText( ModifyEvent e ) {
if( EipInterfaceSection.this.enableListener ) {
EipNodeSetAttributeCommand cmd =
new EipNodeSetAttributeCommand( AbstractNode.PROPERTY_SERVICE_NAME );
cmd.setEipNode( EipInterfaceSection.this.eip );
cmd.setNewValue( EipInterfaceSection.this.srvNameText.getText());
executeCommand( cmd );
}
}
});
label = getWidgetFactory().createCLabel( container, "Service namespace:" );
label.setToolTipText( "The name space URI of the service name" );
this.srvNsText = getWidgetFactory().createText( container, "" );
this.srvNsText.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ));
this.srvNsText.addModifyListener( new ModifyListener() {
public void modifyText( ModifyEvent e ) {
if( EipInterfaceSection.this.enableListener ) {
EipNodeSetAttributeCommand cmd =
new EipNodeSetAttributeCommand( AbstractNode.PROPERTY_SERVICE_NAMESPACE );
cmd.setEipNode( EipInterfaceSection.this.eip );
cmd.setNewValue( EipInterfaceSection.this.srvNsText.getText());
executeCommand( cmd );
}
}
});
// End-point
label = getWidgetFactory().createCLabel( container, "End-point name:" );
label.setToolTipText( "The end-point name (a simple string)" );
this.edptText = getWidgetFactory().createText( container, "" );
this.edptText.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ));
this.edptText.addModifyListener( new ModifyListener() {
public void modifyText( ModifyEvent e ) {
if( EipInterfaceSection.this.enableListener ) {
EipNodeSetAttributeCommand cmd =
new EipNodeSetAttributeCommand( AbstractNode.PROPERTY_ENDPOINT_NAME );
cmd.setEipNode( EipInterfaceSection.this.eip );
cmd.setNewValue( EipInterfaceSection.this.edptText.getText());
executeCommand( cmd );
}
}
});
}
/**
* Executes a command on top of the EIP editor's command stack.
* @param command
*/
private void executeCommand( Command command ) {
IEditorPart part = getPart().getSite().getPage().getActiveEditor();
CommandStack commandStack = (CommandStack) part.getAdapter( CommandStack.class );
if( commandStack != null )
commandStack.execute( command );
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection
* #setInput(org.eclipse.ui.IWorkbenchPart, org.eclipse.jface.viewers.ISelection)
*/
@Override
public void setInput( IWorkbenchPart part, ISelection selection ) {
super.setInput( part, selection );
// Do not listen to model changes from the previous input
if( this.eip != null )
this.eip.removePropertyChangeListener( this );
if( selection instanceof IStructuredSelection ) {
Object input = ((IStructuredSelection) selection).getFirstElement();
if( input instanceof EipNodeEditPart )
this.eip = (EipNode) ((EipNodeEditPart) input).getModel();
}
// Listen to changes in the new model
if( this.eip != null )
this.eip.addPropertyChangeListener( this );
updateHelpersEnablement();
}
/*
* (non-Javadoc)
* @see org.eclipse.ui.views.properties.tabbed.AbstractPropertySection
* #refresh()
*/
@Override
public void refresh() {
this.enableListener = false;
if( this.itfNsText != null
&& ! this.itfNsText.isDisposed()
&& this.eip != null ) {
// Save the caret position
Text focusText = null;
if( this.itfNsText.isFocusControl())
focusText = this.itfNsText;
else if( this.itfNameText.isFocusControl())
focusText = this.itfNameText;
else if( this.srvNameText.isFocusControl())
focusText = this.srvNameText;
else if( this.srvNsText.isFocusControl())
focusText = this.srvNsText;
else if( this.edptText.isFocusControl())
focusText = this.edptText;
else if( this.wsdlText.isFocusControl())
focusText = this.wsdlText;
int caret = focusText != null ? focusText.getCaretPosition() : -1;
// Update values
this.itfNsText.setText( this.eip.getInterfaceNamespace() != null ? this.eip.getInterfaceNamespace() : "" );
this.itfNameText.setText( this.eip.getInterfaceName() != null ? this.eip.getInterfaceName() : "" );
this.srvNsText.setText( this.eip.getServiceNamespace() != null ? this.eip.getServiceNamespace() : "" );
this.srvNameText.setText( this.eip.getServiceName() != null ? this.eip.getServiceName() : "" );
this.edptText.setText( this.eip.getEndpointName() != null ? this.eip.getEndpointName() : "" );
this.wsdlText.setText( this.eip.getWsdlUri() != null ? this.eip.getWsdlUri() : "" );
// Restore the caret
if( focusText != null )
focusText.setSelection( caret );
}
this.enableListener = true;
}
/**
* Creates the WSDL widgets for a JBI binding set on a SCA reference.
* @param container the parent (SWT) composite
*/
private void createWsdlParts( final Composite container ) {
// Add the edition parts
CLabel label = getWidgetFactory().createCLabel( container, "WSDL location:" );
label.setToolTipText( "The URL of a WSDL description file" );
GridData layoutData = new GridData( SWT.DEFAULT, SWT.TOP, false, false );
layoutData.verticalIndent = 7;
label.setLayoutData( layoutData );
Composite subContainer = getWidgetFactory().createPlainComposite( container, SWT.NONE );
GridLayout layout = new GridLayout( 2, true );
layout.marginBottom = 17;
subContainer.setLayout( layout );
layoutData = new GridData( GridData.FILL_HORIZONTAL );
layoutData.horizontalSpan = 3;
subContainer.setLayoutData( layoutData );
// Only use the left half-part
Composite subSubContainer = getWidgetFactory().createPlainComposite( subContainer, SWT.NONE );
layout = new GridLayout( 2, false );
layout.marginHeight = 0;
layout.marginWidth = 0;
subSubContainer.setLayout( layout );
subSubContainer.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ));
// Add the WSDL browser
this.wsdlText = getWidgetFactory().createText( subSubContainer, "", SWT.READ_ONLY );
this.wsdlText.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ));
Button browseButton = getWidgetFactory().createButton( subSubContainer, "Browse...", SWT.PUSH );
browseButton.addSelectionListener( new SelectionListener() {
public void widgetDefaultSelected( SelectionEvent e ) {
widgetSelected( e );
}
public void widgetSelected( SelectionEvent e ) {
FileDialog dlg = new FileDialog( container.getShell());
dlg.setText( "WSDL Selection" );
dlg.setOverwrite( true );
dlg.setFilterNames( new String[] { "WSDL Files (*.wsdl)" });
dlg.setFilterExtensions( new String[] { "*.wsdl" });
String path = dlg.open();
if( path != null ) {
EipInterfaceSection.this.wsdlText.setText( new File( path ).toURI().toString());
updateHelpersEnablement();
// Parse the WSDL
List<JbiBasicBean> wsdlBeans = parseWsdl();
if( wsdlBeans.size() > 0 )
fillInFields( wsdlBeans.get( 0 ));
}
}
});
// Add the composite for the helpers
Composite helpersComposite = getWidgetFactory().createPlainComposite( subSubContainer, SWT.NONE );
layout = new GridLayout();
layout.marginHeight = 0;
layout.marginWidth = 0;
helpersComposite.setLayout( layout );
layoutData = new GridData( GridData.FILL_HORIZONTAL );
layoutData.horizontalSpan = 2;
helpersComposite.setLayoutData( layoutData );
addHelpers( helpersComposite );
}
/**
* Forces the WSDL parsing.
*/
private List<JbiBasicBean> parseWsdl() {
List<JbiBasicBean> wsdlBeans = new ArrayList<WsdlUtils.JbiBasicBean> ();
if( ! StringUtils.isEmpty( this.wsdlText.getText())) {
try {
wsdlBeans.addAll( WsdlUtils.INSTANCE.parse( this.wsdlText.getText()));
} catch( IllegalArgumentException e ) {
// nothing
} catch( InvocationTargetException e ) {
MessageDialog.openError(
this.wsdlText.getShell(),
"WSDL Parsing Failure",
"The WSDL parsing failed: no service description was found in the referenced WSDL file." );
}
}
return wsdlBeans;
}
/**
* Enables or disables the hyper links in function of the WSDL existence.
*/
private void updateHelpersEnablement() {
boolean hasWsdl = ! StringUtils.isEmpty( this.wsdlText.getText());
if( this.selectWsdlServiceLink != null
&& ! this.selectWsdlServiceLink.isDisposed())
this.selectWsdlServiceLink.setEnabled( hasWsdl );
this.wsdlFile = null;
if( hasWsdl
&& this.openWsdlLink != null
&& ! this.openWsdlLink.isDisposed() ) {
File f = null;
try {
URI uri = UriAndUrlHelper.urlToUri( this.wsdlText.getText());
f = new File( uri );
} catch( Exception e ) {
// nothing
}
if( f != null && f.exists())
this.wsdlFile = f;
}
this.openWsdlLink.setEnabled( this.wsdlFile != null );
}
/**
* Adds the provides helpers.
*/
private void addHelpers( final Composite helpersComposite ) {
// Select a service in a WSDL
this.selectWsdlServiceLink = getWidgetFactory().createHyperlink(
helpersComposite,
"Select a service in the WSDL to fill-in the properties below",
SWT.NONE );
this.selectWsdlServiceLink.setToolTipText( "A WSDL may describe several services instead of just one" );
this.selectWsdlServiceLink.addHyperlinkListener( new HyperlinkAdapter() {
@Override
public void linkActivated( HyperlinkEvent e ) {
PCStyledLabelProvider lp = new PCStyledLabelProvider( EipInterfaceSection.this.wsdlText );
StyledElementListSelectionDialog dlg = new StyledElementListSelectionDialog(
EipInterfaceSection.this.wsdlText.getShell(), lp );
dlg.setFilter( "*" );
dlg.setSize( 120, 20 );
dlg.setMultipleSelection( false );
dlg.setTitle( "Service Selection" );
dlg.setMessage( "Select the service to expose inside Petals." );
List<JbiBasicBean> wsdlBeans = parseWsdl();
if( ! wsdlBeans.isEmpty()) {
dlg.setElements( wsdlBeans.toArray());
if( dlg.open() == Window.OK ) {
JbiBasicBean bean = (JbiBasicBean) dlg.getResult()[ 0 ];
fillInFields( bean );
}
}
lp.dispose();
}
});
// Open the WSDL in the default editor
this.openWsdlLink = getWidgetFactory().createHyperlink( helpersComposite, "Open in the WSDL editor", SWT.NONE );
this.openWsdlLink.setToolTipText( "Open this WSDL in the default WSDL editor" );
this.openWsdlLink.addHyperlinkListener( new HyperlinkAdapter() {
@Override
public void linkActivated( HyperlinkEvent e ) {
if( EipInterfaceSection.this.wsdlFile != null ) {
IFileStore fileStore = EFS.getLocalFileSystem().getStore( new Path( EipInterfaceSection.this.wsdlFile.getAbsolutePath()));
IWorkbenchPage page = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getActivePage();
try {
IDE.openEditorOnFileStore( page, fileStore );
} catch (PartInitException e1 ) {
PetalsEipPlugin.log( e1, IStatus.ERROR );
}
}
}
});
}
/**
* @param bean
*/
private void fillInFields( JbiBasicBean bean ) {
String srvName = bean.getServiceName().getLocalPart();
String srvNs = bean.getServiceName().getNamespaceURI();
EipInterfaceSection.this.srvNameText.setText( srvName != null ? srvName : "" );
EipInterfaceSection.this.srvNsText.setText( srvNs != null ? srvNs : "" );
String itfName = bean.getInterfaceName().getLocalPart();
String itfNs = bean.getInterfaceName().getNamespaceURI();
EipInterfaceSection.this.itfNameText.setText( itfName != null ? itfName : "" );
EipInterfaceSection.this.itfNsText.setText( itfNs != null ? itfNs : "" );
String edptName = bean.getEndpointName() != null ? bean.getEndpointName() : "";
if( PetalsConstants.AUTO_GENERATE.equalsIgnoreCase( edptName )) {
EipInterfaceSection.this.edptText.setEnabled( false );
EipInterfaceSection.this.edptText.setText( "" );
} else {
EipInterfaceSection.this.edptText.setEnabled( true );
EipInterfaceSection.this.edptText.setText( edptName );
}
}
}