blob: 5b3b489849d9260350bdb43ae50db9fa6056375e [file] [log] [blame]
/***********************************************************************
* Copyright (c) 2008, 2010 by SAP AG, Walldorf.
* 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:
* SAP AG - initial API and implementation
* Dimiter Dimitrov, d.dimitrov@sap.com - initial API and implementation
***********************************************************************/
package org.eclipse.jpt.ui.internal.wizards.entity;
import java.io.File;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.resources.IFolder;
import org.eclipse.core.resources.IProject;
import org.eclipse.core.runtime.IPath;
import org.eclipse.core.runtime.IStatus;
import org.eclipse.core.runtime.Path;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IPackageFragmentRoot;
import org.eclipse.jdt.core.JavaCore;
import org.eclipse.jem.util.emf.workbench.ProjectUtilities;
import org.eclipse.jface.viewers.ILabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.StructuredSelection;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.viewers.ViewerFilter;
import org.eclipse.jface.window.Window;
import org.eclipse.jpt.core.JpaFacet;
import org.eclipse.jpt.core.JpaProject;
import org.eclipse.jpt.core.JptCorePlugin;
import org.eclipse.jpt.core.internal.utility.jdt.JDTTools;
import org.eclipse.jpt.core.resource.xml.JpaXmlResource;
import org.eclipse.jpt.ui.internal.JpaHelpContextIds;
import org.eclipse.jpt.ui.internal.jface.XmlMappingFileViewerFilter;
import org.eclipse.jpt.ui.internal.wizards.SelectJpaOrmMappingFileDialog;
import org.eclipse.jpt.ui.internal.wizards.entity.data.model.IEntityDataModelProperties;
import org.eclipse.jpt.ui.internal.wizards.orm.MappingFileWizard;
import org.eclipse.jpt.utility.internal.ArrayTools;
import org.eclipse.jst.j2ee.internal.common.operations.INewJavaClassDataModelProperties;
import org.eclipse.jst.j2ee.internal.plugin.J2EEUIMessages;
import org.eclipse.jst.j2ee.internal.wizard.NewJavaClassWizardPage;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
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.Combo;
import org.eclipse.swt.widgets.Composite;
import org.eclipse.swt.widgets.Group;
import org.eclipse.swt.widgets.Link;
import org.eclipse.swt.widgets.Text;
import org.eclipse.ui.PlatformUI;
import org.eclipse.ui.dialogs.ISelectionStatusValidator;
import org.eclipse.ui.help.IWorkbenchHelpSystem;
import org.eclipse.ui.model.WorkbenchContentProvider;
import org.eclipse.ui.model.WorkbenchLabelProvider;
import org.eclipse.wst.common.frameworks.datamodel.IDataModel;
import org.eclipse.wst.common.frameworks.internal.plugin.WTPCommonPlugin;
public class EntityClassWizardPage
extends NewJavaClassWizardPage {
private static final String EMPTY = "";//$NON-NLS-1$
private static final String SINGLE_TABLE = "SINGLE_TABLE";//$NON-NLS-1$
private static final String TABLE_PER_CLASS = "TABLE_PER_CLASS";//$NON-NLS-1$
private static final String JOINED = "JOINED";//$NON-NLS-1$
private static final String[] INHERITANCE_STRATEGIES =
new String[] {EMPTY, SINGLE_TABLE, TABLE_PER_CLASS, JOINED };
private Combo inheritanceStrategyCombo;
private Button entityButton;
private Button mapedAsSuperclassButton;
private Button inheritanceButton;
private Link displayNameLink;
private Button xmlSupportButton;
private boolean isFirstCheck = true;
private Text ormXmlName;
private Button browseButton;
public EntityClassWizardPage(
IDataModel model, String pageName, String pageDesc, String pageTitle) {
super(model, pageName, pageDesc, pageTitle, null);
}
@Override
protected String[] getValidationPropertyNames() {
return ArrayTools.addAll(
super.getValidationPropertyNames(),
new String[] {IEntityDataModelProperties.XML_NAME, IEntityDataModelProperties.XML_SUPPORT});
}
private IProject getProject() {
return (IProject) getDataModel().getProperty(INewJavaClassDataModelProperties.PROJECT);
}
/* Create top level composite (class properties) and add the entity's specific inheritance group
* @see org.eclipse.jst.j2ee.internal.wizard.NewJavaClassWizardPage#createTopLevelComposite(org.eclipse.swt.widgets.Composite)
*/
@Override
protected Composite createTopLevelComposite(Composite parent) {
Composite composite = super.createTopLevelComposite(parent);
this.getHelpSystem().setHelp(composite, JpaHelpContextIds.NEW_JPA_ENTITY_ENTITY_CLASS);
createInheritanceControl(composite);
this.inheritanceButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
boolean isChecked = inheritanceButton.getSelection();
if (isChecked) {
entityButton.setSelection(true);
mapedAsSuperclassButton.setSelection(false);
}
inheritanceStrategyCombo.setEnabled(isChecked);
model.setBooleanProperty(IEntityDataModelProperties.ENTITY, true);
model.setBooleanProperty(IEntityDataModelProperties.MAPPED_AS_SUPERCLASS, false);
entityButton.setEnabled(!isChecked);
mapedAsSuperclassButton.setEnabled(!isChecked);
}
});
createXMLstorageControl(composite);
this.xmlSupportButton.addSelectionListener(new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
boolean isChecked = xmlSupportButton.getSelection();
enableMappingXMLChooseGroup(isChecked);
if (isFirstCheck) {
ormXmlName.setText(JptCorePlugin.DEFAULT_ORM_XML_RUNTIME_PATH.toString());
isFirstCheck = false;
}
}
});
return composite;
}
@Override
protected ISelectionStatusValidator getContainerDialogSelectionValidator() {
return new ISelectionStatusValidator() {
public IStatus validate(Object[] selection) {
if (selection != null && selection[0] != null) {
if (selection[0] instanceof IProject) {
IProject project = (IProject) selection[0];
IJavaProject javaProject = JavaCore.create(project);
for (IPackageFragmentRoot root : JDTTools.getJavaSourceFolders(javaProject)) {
if (project.equals(root.getResource())) {
return WTPCommonPlugin.OK_STATUS;
}
}
}
else {
return WTPCommonPlugin.OK_STATUS;
}
}
return WTPCommonPlugin.createErrorStatus(J2EEUIMessages.CONTAINER_SELECTION_DIALOG_VALIDATOR_MESG);
}
};
}
@Override
protected ViewerFilter getContainerDialogViewerFilter() {
return new ViewerFilter() {
@Override
public boolean select(Viewer viewer, Object parent, Object element) {
String projectName = (String) model.getProperty(IEntityDataModelProperties.PROJECT_NAME);
if (element instanceof IProject) {
IProject project = (IProject) element;
return project.getName().equals(projectName);
}
else if (element instanceof IFolder) {
IFolder folder = (IFolder) element;
// only show source folders
IProject project = ProjectUtilities.getProject(projectName);
IJavaProject javaProject = JavaCore.create(project);
for (IPackageFragmentRoot root : JDTTools.getJavaSourceFolders(javaProject)) {
if (folder.equals(root.getResource()))
return true;
}
}
return false;
}
};
}
/**
* Create the inheritance group
* @param parent the main composite
*/
private void createInheritanceControl(Composite parent) {
Group group = createGroup(parent, EntityWizardMsg.INHERITANCE_GROUP);
this.entityButton = createRadioButton(group, EntityWizardMsg.ENTITY, IEntityDataModelProperties.ENTITY);
this.mapedAsSuperclassButton = createRadioButton(group, EntityWizardMsg.MAPPED_AS_SUPERCLASS, IEntityDataModelProperties.MAPPED_AS_SUPERCLASS);
this.inheritanceButton = createCheckButton(group, GridData.HORIZONTAL_ALIGN_FILL, 1/*horizontal span*/, EntityWizardMsg.INHERITANCE_CHECK_BOX, IEntityDataModelProperties.INHERITANCE);
createComboBox(group, IEntityDataModelProperties.INHERITANCE_STRATEGY);
}
/**
* Create the group, which manage entity mapping registration
* @param parent the main composite
*/
private void createXMLstorageControl(Composite parent) {
Group group = createGroup(parent, EntityWizardMsg.XML_STORAGE_GROUP);
this.xmlSupportButton = createCheckButton(group, GridData.FILL_HORIZONTAL, 3/*horizontal span*/, EntityWizardMsg.XML_SUPPORT, IEntityDataModelProperties.XML_SUPPORT);
createBrowseGroup(group, EntityWizardMsg.CHOOSE_XML, IEntityDataModelProperties.XML_NAME);
this.ormXmlName.setEnabled(false);
this.browseButton.setEnabled(false);
}
/**
* @param parent the main composite
* @param text the name/title of the group
* @return the created group
*/
private Group createGroup(Composite parent, String text) {
Group group = new Group(parent, SWT.NONE);
GridData groupGridData = new GridData(GridData.FILL_HORIZONTAL);
groupGridData.horizontalSpan = 3;
group.setLayoutData(groupGridData);
group.setLayout(new GridLayout(3, false));
group.setText(text);
return group;
}
/**
* Create radio button
* @param parent the main composite - inheritance group
* @param text the label of the button
* @param property the related property to which this button will be synchronized
* @return the created button
*/
private Button createRadioButton(Composite parent, String text, String property) {
Button button = new Button(parent, SWT.RADIO);
GridData groupGridData = new GridData(GridData.FILL_HORIZONTAL);
groupGridData.horizontalSpan = 3;
button.setLayoutData(groupGridData);
button.setText(text);
this.synchHelper.synchRadio(button, property, /*dependentControls*/ null);
return button;
}
/**
* Create check button
* @param parent the main composite - inheritance group
* @param text the label of the button
* @param property the related property to which this button will be synchronized
* @return the created button
*/
private Button createCheckButton(Composite parent, int fillStrategy, int horizontalSpan, String text, String property) {
final Button button = new Button(parent, SWT.CHECK);
GridData groupGridData = new GridData(fillStrategy);
groupGridData.horizontalSpan = horizontalSpan;
button.setLayoutData(groupGridData);
button.setText(text);
this.synchHelper.synchCheckbox(button, property, /*dependentControls*/ null);
return button;
}
/**
* Create combo box, which presents the set of possible inheritance strategies
* @param parent the main composite - inheritance group
* @param property the related property to which this button will be synchronized
* @return
*/
private Combo createComboBox(Composite parent, String property) {
this.inheritanceStrategyCombo = new Combo(parent, SWT.BORDER | SWT.READ_ONLY);
GridData groupGridData = new GridData(GridData.FILL_HORIZONTAL);
groupGridData.horizontalSpan = 2;
this.inheritanceStrategyCombo.setLayoutData(groupGridData);
this.inheritanceStrategyCombo.setItems(INHERITANCE_STRATEGIES);
this.synchHelper.synchCombo(this.inheritanceStrategyCombo, property, /*dependentControls*/ null);
this.inheritanceStrategyCombo.setEnabled(false);
return this.inheritanceStrategyCombo;
}
/**
* Create XML group
* @param parent the main composite
* @param label the name of the group
* @param property the related property to which this group will be synchronized
* @return the created group
*/
private void createBrowseGroup(Composite parent, String label, String property) {
Composite composite = new Composite(parent, SWT.NULL);
composite.setLayout(new GridLayout(3, false));
composite.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
this.displayNameLink = new Link(composite, SWT.LEFT);
this.displayNameLink.setText(label);
this.displayNameLink.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_BEGINNING));
this.displayNameLink.addSelectionListener(
new SelectionAdapter() {
@Override
public void widgetSelected(SelectionEvent e) {
openNewMappingFileWizard();
}
}
);
this.ormXmlName = new Text(composite, SWT.SINGLE | SWT.BORDER);
this.ormXmlName.setLayoutData(new GridData(GridData.FILL_HORIZONTAL));
this.browseButton = new Button(composite, SWT.PUSH);
this.browseButton.setText(EntityWizardMsg.BROWSE_BUTTON_LABEL);
GridData browseButtonData = new GridData(GridData.HORIZONTAL_ALIGN_FILL);
browseButtonData.horizontalSpan = 1;
this.browseButton.setLayoutData(browseButtonData);
this.browseButton.addSelectionListener(new SelectionListener() {
public void widgetSelected(SelectionEvent e) {
handleChooseXmlButtonPressed();
}
public void widgetDefaultSelected(SelectionEvent e) {
widgetSelected(e);
}
});
this.synchHelper.synchText(this.ormXmlName, property, /*dependentControls*/null);
enableMappingXMLChooseGroup(false);
}
private void openNewMappingFileWizard() {
IProject project = getProject();
IPath path = MappingFileWizard.createNewMappingFile(new StructuredSelection(project), getMappingFileName());
if (path != null) {
this.model.setProperty(IEntityDataModelProperties.XML_NAME, path.toString());
//have to validate in case the file name did not actually change, but the xml file was created
validatePage();
}
}
protected String getMappingFileName() {
String mappingFileLocation = this.model.getStringProperty(IEntityDataModelProperties.XML_NAME);
return new File(mappingFileLocation).getName();
}
/**
* Process browsing when the Browse... button have been pressed. Allow choosing of
* XML for entity mapping registration
*
*/
private void handleChooseXmlButtonPressed() {
IProject project = getProject();
if (project == null) {
return;
}
JpaProject jpaProject = JptCorePlugin.getJpaProject(project);
ViewerFilter filter = getDialogViewerFilter(jpaProject);
ITreeContentProvider contentProvider = new WorkbenchContentProvider();
ILabelProvider labelProvider = new WorkbenchLabelProvider();
SelectJpaOrmMappingFileDialog dialog = new SelectJpaOrmMappingFileDialog(getShell(), project, labelProvider, contentProvider);
dialog.setTitle(EntityWizardMsg.MAPPING_XML_TITLE);
dialog.setMessage(EntityWizardMsg.CHOOSE_MAPPING_XML_MESSAGE);
dialog.addFilter(filter);
String ormFileName = this.ormXmlName.getText();
JpaXmlResource resource = jpaProject.getMappingFileXmlResource(new Path(ormFileName));
IFile initialSelection = (resource != null) ? resource.getFile() : null;
dialog.setInput(project);
if (initialSelection != null) {
dialog.setInitialSelection(initialSelection);
}
if (dialog.open() == Window.OK) {
this.model.setProperty(IEntityDataModelProperties.XML_NAME, dialog.getChosenName());
}
}
/**
* This method create filter for the browse/add alternative mapping XML
* @return new instance of viewer filter for the SelectMappingXMLDialog
*/
protected ViewerFilter getDialogViewerFilter(JpaProject jpaProject) {
return new XmlMappingFileViewerFilter(jpaProject);
}
private void enableMappingXMLChooseGroup(boolean enabled) {
this.displayNameLink.setEnabled(enabled);
this.ormXmlName.setEnabled(enabled);
this.browseButton.setEnabled(enabled);
}
/**
* This method is used by the project list initializer. The method checks
* if the specified project is valid to include it in the project list.
*
* <p>Subclasses of this wizard page should override this method to
* adjust filtering of the projects to their needs. </p>
*
* @param project reference to the project to be checked
*
* @return <code>true</code> if the project is valid to be included in
* the project list, <code>false</code> - otherwise.
*/
@Override
protected boolean isProjectValid(IProject project) {
return (project.isAccessible() && JpaFacet.isInstalled(project));
}
protected final IWorkbenchHelpSystem getHelpSystem() {
return PlatformUI.getWorkbench().getHelpSystem();
}
}