/******************************************************************************
* Copyright (c) 2008-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.sa.wizards;
import java.io.File;
import java.net.URI;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.resources.IResource;
import org.eclipse.core.resources.ResourcesPlugin;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.layout.GridDataFactory;
import org.eclipse.jface.layout.GridLayoutFactory;
import org.eclipse.jface.viewers.ArrayContentProvider;
import org.eclipse.jface.window.Window;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.osgi.util.NLS;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.ModifyEvent;
import org.eclipse.swt.events.ModifyListener;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Event;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Shell;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.dialogs.ListDialog;
import org.eclipse.ui.dialogs.PreferencesUtil;
import org.eclipse.ui.forms.events.HyperlinkAdapter;
import org.eclipse.ui.forms.events.HyperlinkEvent;
import org.eclipse.ui.forms.widgets.FormText;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import com.ebmwebsourcing.petals.common.generation.JbiUtils;
import com.ebmwebsourcing.petals.common.internal.provisional.preferences.PreferencesManager;
import com.ebmwebsourcing.petals.common.internal.provisional.swt.DefaultSelectionListener;
import com.ebmwebsourcing.petals.common.internal.provisional.swt.TextWithButtonComposite;
import com.ebmwebsourcing.petals.common.internal.provisional.ui.FixedShellTooltip;
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.SwtFactory;
import com.ebmwebsourcing.petals.services.PetalsServicesPlugin;
import com.ebmwebsourcing.petals.services.su.Messages;
import com.ebmwebsourcing.petals.services.utils.ServiceProjectRelationUtils;
/**
* The wizard page asking for generic information about a Maven project.
* @author Vincent Zurczak - EBM WebSourcing
*/
public class PetalsSaNewWizardPage extends WizardPage {
private Text nameText, versionText, descriptionText, artifactIdText, groupIdText, projectLocationText;
private String name, version, description, artifactId, groupId;
private URI projectLocationURI;
private boolean isAtDefaultLocation = true;
private FixedShellTooltip helpTooltip;
/**
* The constructor.
* @param pageName
*/
public PetalsSaNewWizardPage( String pageName ) {
super( pageName );
this.version = PetalsConstants.DEFAULT_ARTIFACT_VERSION;
this.groupId = PreferencesManager.getMavenGroupId();
if( StringUtils.isEmpty( this.groupId ))
this.groupId = PetalsConstants.DEFAULT_GROUP_ID;
}
/*
* (non-Javadoc)
* @see org.eclipse.jface.dialogs.IDialogPage
* #createControl(org.eclipse.swt.widgets.Composite)
*/
@Override
public void createControl( Composite parent ) {
// Add a tool tip to display in case of problem
this.helpTooltip = new FixedShellTooltip( getShell(), true, 90 ) {
@Override
public void populateTooltip( Composite parent ) {
parent.setLayout( new GridLayout());
parent.setLayoutData( new GridData( GridData.FILL_BOTH ));
parent.setBackground( getShell().getDisplay().getSystemColor( SWT.COLOR_LIST_BACKGROUND ));
StringBuilder sb = new StringBuilder();
sb.append( "<form><p><b>What does this error mean?</b></p><p>");
sb.append( "This wizard will generate, among other things, Maven artifacts.<br />" );
sb.append( "Unfortunately, there is a problem with the <A>the Petals Maven preferences</A>.</p>" );
sb.append( "<p>Please, make them correct.</p></form>");
FormText formText = new FormText( parent, SWT.WRAP | SWT.NO_FOCUS );
formText.setBackground( getShell().getDisplay().getSystemColor( SWT.COLOR_LIST_BACKGROUND ));
formText.setText( sb.toString(), true, false );
formText.addHyperlinkListener( new HyperlinkAdapter() {
@Override
public void linkActivated( HyperlinkEvent e ) {
try {
Dialog dlg = PreferencesUtil.createPreferenceDialogOn(
new Shell(),
"com.ebmwebsourcing.petals.services.prefs.maven",
null, null );
if( dlg.open() == Window.OK )
validate();
} catch( Exception e1 ) {
PetalsServicesPlugin.log( e1, IStatus.ERROR );
}
}
});
}
};
this.helpTooltip.hide();
// Basic fields
Composite container = new Composite( parent, SWT.NONE );
GridLayoutFactory.swtDefaults().numColumns( 2 ).extendedMargins( 15, 15, 20, 0 ).spacing( 15, 5 ).applyTo( container );
container.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ));
SwtFactory.createLabel( container, "Name:", "The service assembly name to put into the jbi.xml and pom.xml files" );
TextWithButtonComposite twc = new TextWithButtonComposite( container );
twc.setLayoutData( new GridData( GridData.FILL_HORIZONTAL ));
twc.getText().setLayoutData( new GridData( GridData.FILL_HORIZONTAL ));
final List<IProject> suProjects = new ArrayList<IProject> ();
for( IProject p : ResourcesPlugin.getWorkspace().getRoot().getProjects()) {
if( ServiceProjectRelationUtils.isSuProject( p ))
suProjects.add( p );
}
twc.getButton().setText( "Name Helper..." );
if( suProjects.isEmpty()) {
twc.getButton().setEnabled( false );
twc.getButton().setToolTipText( "No Service Unit project was found in the workspace" );
} else {
twc.getButton().setToolTipText( "Generate the SA name from a SU name" );
}
twc.getButton().addSelectionListener( new DefaultSelectionListener() {
@Override
public void widgetSelected( SelectionEvent e ) {
ListDialog dlg = new ListDialog( getShell());
dlg.setContentProvider( new ArrayContentProvider());
dlg.setLabelProvider( new WorkbenchLabelProvider());
dlg.setInput( suProjects );
if( dlg.open() != Window.OK )
return;
String suName = ((IProject) dlg.getResult()[ 0 ]).getName();
String saName = JbiUtils.createSaName( suName );
PetalsSaNewWizardPage.this.nameText.setText( saName );
}
});
this.nameText = twc.getText();
this.nameText.addModifyListener( new ModifyListener () {
@Override
public void modifyText( ModifyEvent e ) {
String aid = PetalsSaNewWizardPage.this.artifactIdText.getText();
String n = PetalsSaNewWizardPage.this.nameText.getText();
if( aid.trim().length() != 0 && ! n.startsWith( aid ))
validate();
else
PetalsSaNewWizardPage.this.artifactIdText.setText( n );
}
});
ModifyListener validationListener = new ModifyListener () {
@Override
public void modifyText( ModifyEvent e ) {
validate();
}
};
SwtFactory.createLabel( container, "Artifact ID:", "The service assembly description to put into the jbi.xml and pom.xml files" );
this.artifactIdText = SwtFactory.createSimpleTextField( container, true );
this.artifactIdText.addModifyListener( validationListener );
new Label( container, SWT.NONE ).setText( "Group ID:" );
this.groupIdText = SwtFactory.createSimpleTextField( container, true );
this.groupIdText.setText( this.groupId );
this.groupIdText.addModifyListener( validationListener );
new Label( container, SWT.NONE ).setText( "Version:" );
this.versionText = SwtFactory.createSimpleTextField( container, true );
this.versionText.setText( this.version );
this.versionText.addModifyListener( validationListener );
new Label( container, SWT.NONE ).setText( "Description:" );
this.descriptionText = SwtFactory.createSimpleTextField( container, true );
this.descriptionText.addModifyListener( validationListener );
// Project location
final Button useDefaultLocButton = new Button( container, SWT.CHECK );
useDefaultLocButton.setText( "Create the project in the default location" );
GridDataFactory.swtDefaults().indent( 0, 17 ).span( 2, 1 ).applyTo( useDefaultLocButton );
Composite locContainer = new Composite( container, SWT.NONE );
GridLayoutFactory.swtDefaults().numColumns( 2 ).margins( 0, 0 ).applyTo( locContainer );
GridDataFactory.swtDefaults().span( 2, 1 ).applyTo( locContainer );
final Label locLabel = new Label( locContainer, SWT.NONE );
locLabel.setText( "Project location:" );
final TextWithButtonComposite twbc = SwtFactory.createDirectoryBrowser( locContainer );
this.projectLocationText = twbc.getText();
this.projectLocationText.setText( ResourcesPlugin.getWorkspace().getRoot().getLocation().toOSString());
this.projectLocationText.addModifyListener( validationListener );
useDefaultLocButton.setSelection( this.isAtDefaultLocation );
useDefaultLocButton.addSelectionListener( new SelectionAdapter () {
@Override
public void widgetSelected( SelectionEvent e ) {
PetalsSaNewWizardPage.this.isAtDefaultLocation =
useDefaultLocButton.getSelection();
boolean use = ! PetalsSaNewWizardPage.this.isAtDefaultLocation;
locLabel.setEnabled( use );
PetalsSaNewWizardPage.this.projectLocationText.setEnabled( use );
twbc.getButton().setEnabled( use );
PetalsSaNewWizardPage.this.projectLocationText.setFocus();
}
});
// Last steps in the UI definition
useDefaultLocButton.notifyListeners( SWT.Selection, new Event());
setControl( container );
validate();
String msg = getErrorMessage();
setErrorMessage( null );
setMessage( msg, INFORMATION );
this.nameText.setFocus();
}
/**
* Display the error message provided as parameter and prevent the user from going further in the wizard.
* @param message the error message to display, or null to display nothing.
*/
protected final void updateStatus( String message ) {
setErrorMessage( message );
setPageComplete( message == null );
}
/**
* Validate the page fields.
* @return true if all the elements are valid, false otherwise.
*/
protected boolean validate() {
setMessage( null, INFORMATION );
// Handle problems with the Maven configuration at the beginning of the wizard
if( ! PreferencesManager.isMavenTemplateConfigurationValid()) {
updateStatus( "There is an error in your preferences about custom POM templates." );
this.helpTooltip.show();
return false;
}
else {
this.helpTooltip.hide();
}
try {
for( IResource resource : ResourcesPlugin.getWorkspace().getRoot().members()) {
if( resource.getName().equalsIgnoreCase( this.nameText.getText())) {
updateStatus( NLS.bind( Messages.ProvideJbiPage_40, this.nameText.getText()));
return false;
}
}
} catch( CoreException e ) {
PetalsServicesPlugin.log( e, IStatus.ERROR );
}
// Other fields
if( this.nameText.getText().length() == 0 ) {
updateStatus( "The name cannot be empty." );
return false;
}
if( this.groupIdText.getText().length() == 0 ) {
updateStatus( "The group ID cannot be empty." );
return false;
}
// Project location
if( ! this.isAtDefaultLocation ) {
if( this.projectLocationText.getText().trim().length() == 0 ) {
updateStatus( "You have to specify the project location." );
return false;
}
try {
this.projectLocationURI = new File(
this.projectLocationText.getText(),
this.nameText.getText()).toURI();
} catch( Exception e ) {
updateStatus( "The specified location is not a valid file location." );
return false;
}
IProject p = ResourcesPlugin.getWorkspace().getRoot().getProject( this.nameText.getText());
IStatus status = ResourcesPlugin.getWorkspace().validateProjectLocationURI( p, this.projectLocationURI );
if( status.getCode() != IStatus.OK ) {
updateStatus( status.getMessage());
return false;
}
}
// Store the result
updateStatus( null );
this.name = this.nameText.getText();
this.description = this.descriptionText.getText();
this.artifactId = this.artifactIdText.getText();
this.groupId = this.groupIdText.getText();
this.version = this.versionText.getText();
return true;
}
/**
* @return the SA name
*/
public String getSaName () {
return this.name;
}
/**
* @return the SA description
*/
public String getSaDescription () {
return this.description;
}
/**
* @return the artifact Id
*/
public String getArtifactId () {
return this.artifactId;
}
/**
* @return the group Id
*/
public String getGroupId () {
return this.groupId;
}
/**
* @return the model version
*/
public String getVersion () {
return this.version;
}
/**
* @return the projectLocationURI
*/
public URI getProjectLocationURI() {
return this.projectLocationURI;
}
}