blob: bffd37d4d66d91ff809e2d8ec9d98153d8f757fd [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2013 Oracle. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License 2.0, which accompanies this distribution
* and is available at https://www.eclipse.org/legal/epl-2.0/.
*
* Contributors:
* Oracle - initial API and implementation
******************************************************************************/
package org.eclipse.jpt.jpa.ui.internal.wizards.makepersistent;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.jdt.ui.JavaElementLabelProvider;
import org.eclipse.jface.dialogs.Dialog;
import org.eclipse.jface.resource.ResourceManager;
import org.eclipse.jface.viewers.ILabelProviderListener;
import org.eclipse.jface.viewers.ITableLabelProvider;
import org.eclipse.jface.viewers.ITreeContentProvider;
import org.eclipse.jface.viewers.TreeSelection;
import org.eclipse.jface.viewers.TreeViewer;
import org.eclipse.jface.viewers.Viewer;
import org.eclipse.jface.wizard.WizardDialog;
import org.eclipse.jface.wizard.WizardPage;
import org.eclipse.jpt.common.ui.JptCommonUiImages;
import org.eclipse.jpt.jpa.annotate.mapping.AnnotationAttributeNames;
import org.eclipse.jpt.jpa.annotate.mapping.BasicEntityPropertyElem;
import org.eclipse.jpt.jpa.annotate.mapping.ColumnAttributes;
import org.eclipse.jpt.jpa.annotate.mapping.EntityPropertyElem;
import org.eclipse.jpt.jpa.annotate.mapping.EntityRefPropertyElem;
import org.eclipse.jpt.jpa.annotate.mapping.IdEntityPropertyElement;
import org.eclipse.jpt.jpa.annotate.mapping.JavaMapper;
import org.eclipse.jpt.jpa.annotate.mapping.JoinStrategy;
import org.eclipse.jpt.jpa.annotate.util.AnnotateMappingUtil;
import org.eclipse.jpt.jpa.core.JpaProject;
import org.eclipse.jpt.jpa.core.MappingKeys;
import org.eclipse.jpt.jpa.core.context.persistence.PersistenceUnit;
import org.eclipse.jpt.jpa.core.resource.orm.JPA;
import org.eclipse.jpt.jpa.db.Schema;
import org.eclipse.jpt.jpa.ui.JptJpaUiImages;
import org.eclipse.jpt.jpa.ui.internal.wizards.makepersistent.JpaMakePersistentWizard.TypeComparator;
import org.eclipse.swt.SWT;
import org.eclipse.swt.events.SelectionAdapter;
import org.eclipse.swt.events.SelectionEvent;
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.Display;
import org.eclipse.swt.widgets.Label;
import org.eclipse.swt.widgets.Tree;
import org.eclipse.swt.widgets.TreeColumn;
import org.eclipse.ui.ISharedImages;
import org.eclipse.ui.PlatformUI;
public class PropsMappingPage extends WizardPage
{
/* CU private */ final JpaProject jpaProject;
/* CU private */ final ResourceManager resourceManager;
private JavaClassMapping[] javaClassMappings;
private ClassMappingPage classMappingPage;
private TreeViewer mappingTreeViewer;
private Button editBtn;
private Button removeBtn;
private static final int JAVA_CLASS_COLUMN_WIDTH = 130;
private static final int PROPERTY_NAME_COLUMN_WIDTH = 110;
private static final int PROPERTY_TYPE_COLUMN_WIDTH = 130;
private static final int PROPERTY_DATABASE_COLUMN_WIDTH = 140;
private static final int PROPERTY_COLUMN_TYPE_WIDTH = 100;
private static final int MAPPING_TABLE_HEIGHT = 80;
private static final int JAVA_CLASS_COLUMN_INDEX = 0;
private static final int NAME_COLUMN_INDEX = 1;
private static final int TYPE_COLUMN_INDEX = 2;
private static final int DATABASE_COLUMN_INDEX = 3;
private static final int COLUMN_TYPE_INDEX = 4;
public PropsMappingPage(JpaProject proj, JavaClassMapping[] javaClassMappings,
ResourceManager resourceManager, ClassMappingPage classMappingPage)
{
super("Class Mapping Properties"); //$NON-NLS-1$
this.resourceManager = resourceManager;
this.jpaProject = proj;
this.javaClassMappings = javaClassMappings;
this.classMappingPage = classMappingPage;
setTitle(JptJpaUiMakePersistentMessages.PROPS_MAPPING_PAGE_TITLE);
setMessage(JptJpaUiMakePersistentMessages.PROPS_MAPPING_PAGE_DESC);
this.classMappingPage.addListener(new ClassMappingPage.Listener()
{
public void classMappingChanged(JavaClassMapping javaClassMapping)
{
handleClassMappingChange(javaClassMapping);
}
});
}
public void createControl(Composite parent)
{
initializeDialogUnits(parent);
Composite composite = new Composite(parent, SWT.NULL);
composite.setLayout(new GridLayout(2, false));
Label label = new Label(composite, SWT.NONE);
label.setText(JptJpaUiMakePersistentMessages.PROPS_MAPPING_PAGE_LABEL);
GridData gd = new GridData();
gd.horizontalSpan = 2;
label.setLayoutData(gd);
createMappingTable(composite);
createMappingButtons(composite);
updateMappingButtons();
setControl(composite);
}
private void createMappingTable(Composite parent)
{
Tree mappingTree = new Tree(parent, SWT.BORDER | SWT.H_SCROLL | SWT.V_SCROLL | SWT.FULL_SELECTION | SWT.SINGLE);
mappingTree.setHeaderVisible(true);
mappingTree.setLinesVisible(true);
this.mappingTreeViewer = new TreeViewer(mappingTree);
TreeColumn column1 = new TreeColumn(mappingTree, SWT.LEFT);
column1.setAlignment(SWT.LEFT);
column1.setText(JptJpaUiMakePersistentMessages.PROPS_MAPPING_PAGE_JAVA_CLASS_LABEL);
column1.setWidth(JAVA_CLASS_COLUMN_WIDTH);
TreeColumn column2 = new TreeColumn(mappingTree, SWT.RIGHT);
column2.setAlignment(SWT.LEFT);
column2.setText(JptJpaUiMakePersistentMessages.PROPS_MAPPING_PAGE_PROPERTY_NAME_LABEL);
column2.setWidth(PROPERTY_NAME_COLUMN_WIDTH);
TreeColumn column3 = new TreeColumn(mappingTree, SWT.RIGHT);
column3.setAlignment(SWT.LEFT);
column3.setText(JptJpaUiMakePersistentMessages.PROPS_MAPPING_PAGE_PROPERTY_TYPE_LABEL);
column3.setWidth(PROPERTY_TYPE_COLUMN_WIDTH);
TreeColumn column4 = new TreeColumn(mappingTree, SWT.RIGHT);
column4.setAlignment(SWT.LEFT);
column4.setText(JptJpaUiMakePersistentMessages.PROPS_MAPPING_PAGE_DATABASE_COLUMN);
column4.setWidth(PROPERTY_DATABASE_COLUMN_WIDTH);
TreeColumn column5 = new TreeColumn(mappingTree, SWT.RIGHT);
column5.setAlignment(SWT.LEFT);
column5.setText(JptJpaUiMakePersistentMessages.PROPS_MAPPING_PAGE_COLUMN_TYPE);
column5.setWidth(PROPERTY_COLUMN_TYPE_WIDTH);
GridData gd = new GridData(GridData.FILL_BOTH);
gd.widthHint = JAVA_CLASS_COLUMN_WIDTH + PROPERTY_NAME_COLUMN_WIDTH
+ PROPERTY_TYPE_COLUMN_WIDTH + PROPERTY_DATABASE_COLUMN_WIDTH
+ PROPERTY_COLUMN_TYPE_WIDTH;
gd.heightHint = MAPPING_TABLE_HEIGHT;
mappingTree.setLayoutData(gd);
this.mappingTreeViewer.setContentProvider(new PropertiesMappingContentProvider());
this.mappingTreeViewer.setComparator(new TypeComparator());
this.mappingTreeViewer.setLabelProvider(new PropertiesMappingLabelProvider());
this.mappingTreeViewer.setInput(this.javaClassMappings);
this.mappingTreeViewer.expandAll();
mappingTree.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
updateMappingButtons();
}
});
}
private void createMappingButtons(Composite parent)
{
Composite buttons = new Composite(parent, SWT.NULL);
GridLayout gridLayout = new GridLayout(1, false);
gridLayout.marginHeight = 0;
buttons.setLayout(gridLayout);
buttons.setLayoutData(new GridData(GridData.VERTICAL_ALIGN_BEGINNING));
editBtn = new Button(buttons, SWT.NULL);
editBtn.setImage(this.resourceManager.createImage(JptCommonUiImages.EDIT_BUTTON));
editBtn.setToolTipText(JptJpaUiMakePersistentMessages.PROPS_MAPPING_PAGE_EDIT);
editBtn.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
editBtn.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
editMapping();
}
});
removeBtn = new Button(buttons, SWT.NULL);
removeBtn.setImage(PlatformUI.getWorkbench().getSharedImages().getImage(ISharedImages.IMG_TOOL_DELETE));
removeBtn.setToolTipText(JptJpaUiMakePersistentMessages.PROPS_MAPPING_PAGE_REMOVE);
removeBtn.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_FILL));
removeBtn.addSelectionListener(new SelectionAdapter()
{
@Override
public void widgetSelected(SelectionEvent e)
{
removeMapping();
}
});
}
private void updateMappingButtons()
{
TreeSelection sel = (TreeSelection)this.mappingTreeViewer.getSelection();
if (sel.getFirstElement() instanceof EntityPropertyElem)
{
editBtn.setEnabled(true);
removeBtn.setEnabled(true);
}
else
{
editBtn.setEnabled(false);
removeBtn.setEnabled(false);
}
}
private void editMapping()
{
Object selectedObj = ((TreeSelection)this.mappingTreeViewer.getSelection()).getFirstElement();
EntityPropertyElem entityProp = (EntityPropertyElem)selectedObj;
Schema schema = this.classMappingPage.getSchema();
JavaClassMapping classMapping = getClassMapping(entityProp.getClassName());
int index = classMapping != null ? classMapping.getPropertyMappings().indexOf(entityProp) : -1;
if (entityProp.getTagName().equals(JPA.ID))
{
assert entityProp instanceof IdEntityPropertyElement;
IdEntityPropertyElement idEntityProp = (IdEntityPropertyElement)entityProp;
IdEntityPropertyElement idEntityPropCopy = new IdEntityPropertyElement(idEntityProp);
IdAnnotationDialog dlg = new IdAnnotationDialog(
Display.getDefault().getActiveShell(), this.resourceManager,
idEntityProp.getDBTable(), idEntityPropCopy, this.jpaProject.getProject());
if (dlg.open() == Dialog.OK && index != -1)
{
classMapping.getPropertyMappings().remove(index);
idEntityPropCopy.setUnmapped(false);
classMapping.getPropertyMappings().add(index, idEntityPropCopy);
this.mappingTreeViewer.update(idEntityPropCopy, null);
}
}
else if (entityProp.getTagName().equals(JPA.BASIC))
{
assert entityProp instanceof BasicEntityPropertyElem;
BasicEntityPropertyElem basicEntityProp = (BasicEntityPropertyElem)entityProp;
BasicEntityPropertyElem basicEntityPropCopy = new BasicEntityPropertyElem(basicEntityProp);
BasicAnnotationDialog dlg = new BasicAnnotationDialog(
Display.getDefault().getActiveShell(), this.resourceManager,
this.jpaProject.getProject(), entityProp.getDBTable(), basicEntityPropCopy);
if (dlg.open() == Dialog.OK && index != -1)
{
classMapping.getPropertyMappings().remove(index);
basicEntityPropCopy.setUnmapped(false);
classMapping.getPropertyMappings().add(index, basicEntityPropCopy);
this.mappingTreeViewer.update(basicEntityPropCopy, null);
}
}
else if (entityProp.getTagName().equals(JPA.ONE_TO_MANY) ||
entityProp.getTagName().equals(JPA.MANY_TO_MANY) ||
entityProp.getTagName().equals(JPA.MANY_TO_ONE) ||
entityProp.getTagName().equals(JPA.ONE_TO_ONE))
{
assert entityProp instanceof EntityRefPropertyElem;
EntityRefPropertyElem refElem = (EntityRefPropertyElem)entityProp;
EntityRefPropertyElem refElemCopy = new EntityRefPropertyElem(refElem);
PersistenceUnit persistenceUnit = ((JpaMakePersistentWizard)this.getWizard()).getPersistenceUnit();
AssociationAnnotationWizard wizard = new AssociationAnnotationWizard(persistenceUnit, this.resourceManager,
this.jpaProject.getProject(), classMapping.getFullyQualifiedName(), schema,
entityProp.getDBTable(), refElemCopy);
WizardDialog dialog = new WizardDialog(Display.getCurrent().getActiveShell(), wizard);
dialog.create();
if (dialog.open() == Dialog.OK && index != -1)
{
classMapping.getPropertyMappings().remove(index);
refElemCopy.setUnmapped(false);
classMapping.getPropertyMappings().add(index, refElemCopy);
this.mappingTreeViewer.update(refElemCopy, null);
}
}
}
private void removeMapping()
{
Object selectedObj = ((TreeSelection)this.mappingTreeViewer.getSelection()).getFirstElement();
EntityPropertyElem entityProp = (EntityPropertyElem)selectedObj;
entityProp.setUnmapped(true);
this.mappingTreeViewer.update(entityProp, null);
}
private void handleClassMappingChange(JavaClassMapping javaClassMapping)
{
javaClassMapping.clearPropertyMappings();
Schema schema = this.classMappingPage.getSchema();
if (schema != null && javaClassMapping.getDBTable() != null)
{
org.eclipse.jpt.jpa.db.Table dbTable = schema.getTableNamed(javaClassMapping.getDBTable());
JavaMapper javaMapper = new JavaMapper(this.jpaProject.getProject(), javaClassMapping.getFullyQualifiedName(),
dbTable, javaClassMapping.getPrimaryKeyProperty());
javaMapper.map();
javaClassMapping.setPropertyMappings(javaMapper.getEntityProperties());
}
if (this.mappingTreeViewer != null)
{
this.mappingTreeViewer.getTree().removeAll();
this.mappingTreeViewer.refresh(true);
this.mappingTreeViewer.expandAll();
}
}
private String getDBColumnDisplayStr(EntityPropertyElem propElem)
{
String colText = null;
String tagName = propElem.getTagName();
if (tagName.equals(JPA.ID) || tagName.equals(JPA.BASIC))
{
ColumnAttributes colAttrs = propElem.getColumnAnnotationAttrs();
if (colAttrs != null)
{
colText = colAttrs.getAnnotationAttribute(AnnotationAttributeNames.NAME).attrValue;
}
// else
// {
// // no mapped db column: just display property name
// colText = propElem.getPropertyName();
// }
}
else if (propElem instanceof EntityRefPropertyElem)
{
EntityRefPropertyElem refElem = (EntityRefPropertyElem)propElem;
if (refElem.getMappedBy() != null)
colText = JptJpaUiMakePersistentMessages.MAPPED_BY_DESC
+ refElem.getMappedBy();
else if (refElem.getJoinTable() != null &&
refElem.getJoinTable().getTableName() != null)
{
colText = refElem.getJoinTable().getTableName() + " "
+ JptJpaUiMakePersistentMessages.JOIN_TABLE_DESC;
}
else if (refElem.getJoinColumns().size() > 0)
{
ColumnAttributes joinCol = refElem.getJoinColumns().get(0);
String colName = joinCol.getName();
String refColName = joinCol.getReferencedColumnName();
if (colName != null && refColName != null)
colText = String.format(JptJpaUiMakePersistentMessages.PROPS_MAPPING_PAGE_JOIN_AND,
colName, refColName);
else if (colName != null)
colText = colName;
}
else if (refElem.getJoinStrategy() == JoinStrategy.PRIMARY_KEY_JOIN_COLUMNS)
{
colText = JptJpaUiMakePersistentMessages.PK_JOIN_COLUMN_DESC;
}
}
return colText;
}
private JavaClassMapping getClassMapping(String fqClassName)
{
for (JavaClassMapping classMapping : this.javaClassMappings)
{
if (classMapping.getFullyQualifiedName().equals(fqClassName))
{
return classMapping;
}
}
return null;
}
private class PropertiesMappingContentProvider implements ITreeContentProvider
{
public Object[] getElements(Object inputElement)
{
JavaClassMapping[] javaClassMappings = (JavaClassMapping[])inputElement;
List<JavaClassMapping> entityMappings = new ArrayList<JavaClassMapping>();
for (JavaClassMapping javaClassMapping : javaClassMappings)
{
if (javaClassMapping.getMappingKey().equals(MappingKeys.ENTITY_TYPE_MAPPING_KEY))
{
entityMappings.add(javaClassMapping);
}
}
return entityMappings.toArray();
}
public void dispose()
{
}
public void inputChanged(Viewer viewer, Object oldInput, Object newInput)
{
}
public Object[] getChildren(Object parentElement)
{
if (parentElement instanceof JavaClassMapping)
{
return ((JavaClassMapping)parentElement).getPropertyMappings().toArray();
}
return new Object[0];
}
public Object getParent(Object element)
{
return null;
}
public boolean hasChildren(Object element)
{
if (element instanceof JavaClassMapping)
return true;
return false;
}
}
private class PropertiesMappingLabelProvider implements ITableLabelProvider
{
private final JavaElementLabelProvider javaElementLabelProvider =
new JavaElementLabelProvider(JavaElementLabelProvider.SHOW_POST_QUALIFIED
| JavaElementLabelProvider.SHOW_SMALL_ICONS
| JavaElementLabelProvider.SHOW_OVERLAY_ICONS);
public Image getColumnImage(Object element, int columnIndex)
{
switch (columnIndex)
{
case JAVA_CLASS_COLUMN_INDEX:
{
if (element instanceof JavaClassMapping)
{
return this.javaElementLabelProvider.getImage(((JavaClassMapping)element).getJDTType());
}
break;
}
case NAME_COLUMN_INDEX:
{
if (element instanceof EntityPropertyElem)
{
EntityPropertyElem propElem = (EntityPropertyElem)element;
Image image = null;
if (propElem.getTagName().equals(JPA.ID))
image = resourceManager.createImage(JptJpaUiImages.ID);
else if (propElem.getTagName().equals(JPA.BASIC))
image = resourceManager.createImage(JptJpaUiImages.BASIC);
else if (propElem.getTagName().equals(JPA.ONE_TO_MANY))
image = resourceManager.createImage(JptJpaUiImages.ONE_TO_MANY);
else if (propElem.getTagName().equals(JPA.MANY_TO_MANY))
image = resourceManager.createImage(JptJpaUiImages.MANY_TO_MANY);
else if (propElem.getTagName().equals(JPA.MANY_TO_ONE))
image = resourceManager.createImage(JptJpaUiImages.MANY_TO_ONE);
else if (propElem.getTagName().equals(JPA.ONE_TO_ONE))
image = resourceManager.createImage(JptJpaUiImages.ONE_TO_ONE);
return image;
}
break;
}
case TYPE_COLUMN_INDEX:
{
if (element instanceof EntityRefPropertyElem)
{
EntityRefPropertyElem refElem = (EntityRefPropertyElem)element;
if (refElem.isEntityCollection() && refElem.getRefEntityClassName() == null)
{
return resourceManager.createImage(JptCommonUiImages.WARNING);
}
}
break;
}
case DATABASE_COLUMN_INDEX:
{
if (element instanceof EntityPropertyElem)
{
EntityPropertyElem propElem = (EntityPropertyElem)element;
if (!propElem.isUnmapped())
{
String colDispStr = getDBColumnDisplayStr(propElem);
if (colDispStr == null)
return resourceManager.createImage(JptCommonUiImages.WARNING);
}
}
break;
}
}
return null;
}
public String getColumnText(Object element, int columnIndex)
{
switch (columnIndex)
{
case JAVA_CLASS_COLUMN_INDEX:
{
if (element instanceof JavaClassMapping)
{
return ((JavaClassMapping)element).getJDTType().getElementName();
}
break;
}
case NAME_COLUMN_INDEX:
{
if (element instanceof EntityPropertyElem)
{
EntityPropertyElem propElem = (EntityPropertyElem)element;
return propElem.getPropertyName();
}
break;
}
case TYPE_COLUMN_INDEX:
{
if (element instanceof EntityPropertyElem)
{
EntityPropertyElem propElem = (EntityPropertyElem)element;
String label = AnnotateMappingUtil.getClassName(propElem.getPropertyType());
if (propElem instanceof EntityRefPropertyElem)
{
EntityRefPropertyElem refElem = (EntityRefPropertyElem)propElem;
if (refElem.isEntityCollection())
{
if (refElem.getRefEntityClassName() == null)
{
label += '<' + JptJpaUiMakePersistentMessages.PROPS_MAPPING_PAGE_UNSPECIFIED + '>';
}
}
}
return label;
}
break;
}
case DATABASE_COLUMN_INDEX:
{
if (element instanceof EntityPropertyElem)
{
String colText = null;
EntityPropertyElem propElem = (EntityPropertyElem)element;
if (propElem.isUnmapped())
{
colText = "-";
}
else
{
colText = getDBColumnDisplayStr(propElem);
if (colText == null)
{
colText = JptJpaUiMakePersistentMessages.PROPS_MAPPING_PAGE_UNSPECIFIED;
}
}
return colText;
}
break;
}
case COLUMN_TYPE_INDEX:
{
if (element instanceof EntityPropertyElem)
{
EntityPropertyElem propElem = (EntityPropertyElem)element;
String colText = null;
if (propElem.isUnmapped())
{
colText = "-";
}
else
{
ColumnAttributes colAttrs = propElem.getColumnAnnotationAttrs();
if (colAttrs != null)
{
String colName = colAttrs.getAnnotationAttribute(AnnotationAttributeNames.NAME).attrValue;
if (colName != null)
{
Schema schema = classMappingPage.getSchema();
if (schema != null && propElem.getDBColumn() != null)
{
colText = propElem.getDBColumn().getDataTypeName();
}
}
}
else
colText = JptJpaUiMakePersistentMessages.PROPS_MAPPING_PAGE_COLUMN_TYPE_NA;
}
return colText;
}
break;
}
}
return null;
}
public void addListener(ILabelProviderListener listener){}
public void dispose(){}
public boolean isLabelProperty(Object element, String property)
{
return false;
}
public void removeListener(ILabelProviderListener listener){}
}
}