
org.apache.cayenne.modeler.editor.ObjEntityTab Maven / Gradle / Ivy
The newest version!
/*****************************************************************
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
****************************************************************/
package org.apache.cayenne.modeler.editor;
import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Insets;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.util.Arrays;
import java.util.EventObject;
import java.util.LinkedList;
import java.util.List;
import javax.swing.DefaultComboBoxModel;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JTextField;
import javax.swing.JToolBar;
import javax.swing.SwingConstants;
import org.apache.cayenne.configuration.DataChannelDescriptor;
import org.apache.cayenne.exp.Expression;
import org.apache.cayenne.map.DataMap;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.EntityResolver;
import org.apache.cayenne.map.ObjAttribute;
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.map.event.EntityEvent;
import org.apache.cayenne.modeler.Application;
import org.apache.cayenne.modeler.ProjectController;
import org.apache.cayenne.modeler.action.ActionManager;
import org.apache.cayenne.modeler.action.CreateAttributeAction;
import org.apache.cayenne.modeler.action.CreateRelationshipAction;
import org.apache.cayenne.modeler.action.ObjEntityCounterpartAction;
import org.apache.cayenne.modeler.action.ObjEntitySyncAction;
import org.apache.cayenne.modeler.dialog.objentity.ClassNameUpdater;
import org.apache.cayenne.modeler.dialog.validator.DuplicatedAttributesDialog;
import org.apache.cayenne.modeler.event.EntityDisplayEvent;
import org.apache.cayenne.modeler.event.ObjEntityDisplayListener;
import org.apache.cayenne.modeler.graph.action.ShowGraphEntityAction;
import org.apache.cayenne.modeler.util.CellRenderers;
import org.apache.cayenne.modeler.util.Comparators;
import org.apache.cayenne.modeler.util.ExpressionConvertor;
import org.apache.cayenne.modeler.util.TextAdapter;
import org.apache.cayenne.modeler.util.combo.AutoCompletion;
import org.apache.cayenne.util.CayenneMapEntry;
import org.apache.cayenne.util.Util;
import org.apache.cayenne.validation.ValidationException;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.Predicate;
import com.jgoodies.forms.builder.DefaultFormBuilder;
import com.jgoodies.forms.layout.FormLayout;
/**
* Detail view of the ObjEntity properties.
*/
public class ObjEntityTab extends JPanel implements ObjEntityDisplayListener,
ExistingSelectionProcessor {
private static final Object noInheritance = new CayenneMapEntry() {
public String getName() {
return "Direct Mapping to Table/View";
}
public Object getParent() {
return null;
}
public void setParent(Object parent) {
}
};
protected ProjectController mediator;
protected TextAdapter name;
protected TextAdapter className;
protected JLabel superclassLabel;
protected TextAdapter superClassName;
protected TextAdapter qualifier;
protected JComboBox dbEntityCombo;
protected JComboBox superEntityCombo;
protected JButton tableLabel;
protected JCheckBox readOnly;
protected JCheckBox optimisticLocking;
protected JCheckBox excludeSuperclassListeners;
protected JCheckBox excludeDefaultListeners;
protected JComponent clientSeparator;
protected JLabel isAbstractLabel;
protected JLabel serverOnlyLabel;
protected JLabel clientClassNameLabel;
protected JLabel clientSuperClassNameLabel;
protected JCheckBox serverOnly;
protected JCheckBox isAbstract;
protected TextAdapter clientClassName;
protected TextAdapter clientSuperClassName;
public ObjEntityTab(ProjectController mediator) {
this.mediator = mediator;
initView();
initController();
}
private void initView() {
this.setLayout(new BorderLayout());
JToolBar toolBar = new JToolBar();
ActionManager actionManager = Application.getInstance().getActionManager();
toolBar.add(actionManager.getAction(ObjEntitySyncAction.class).buildButton());
toolBar.add(actionManager.getAction(CreateAttributeAction.class).buildButton());
toolBar
.add(actionManager
.getAction(CreateRelationshipAction.class)
.buildButton());
toolBar.addSeparator();
toolBar.add(actionManager.getAction(ShowGraphEntityAction.class).buildButton());
toolBar.add(actionManager.getAction(ObjEntityCounterpartAction.class).buildButton());
add(toolBar, BorderLayout.NORTH);
// create widgets
name = new TextAdapter(new JTextField()) {
@Override
protected void updateModel(String text) {
setEntityName(text);
}
};
superClassName = new TextAdapter(new JTextField()) {
@Override
protected void updateModel(String text) {
setSuperClassName(text);
}
};
className = new TextAdapter(new JTextField()) {
@Override
protected void updateModel(String text) {
setClassName(text);
}
};
qualifier = new TextAdapter(new JTextField()) {
@Override
protected void updateModel(String text) {
setQualifier(text);
}
};
dbEntityCombo = Application.getWidgetFactory().createComboBox();
superEntityCombo = Application.getWidgetFactory().createComboBox();
AutoCompletion.enable(dbEntityCombo);
AutoCompletion.enable(superEntityCombo);
readOnly = new JCheckBox();
optimisticLocking = new JCheckBox();
excludeSuperclassListeners = new JCheckBox();
excludeDefaultListeners = new JCheckBox();
// borderless clickable button used as a label
tableLabel = new JButton("Table/View:");
tableLabel.setBorderPainted(false);
tableLabel.setHorizontalAlignment(SwingConstants.LEFT);
tableLabel.setFocusPainted(false);
tableLabel.setMargin(new Insets(0, 0, 0, 0));
tableLabel.setBorder(null);
isAbstract = new JCheckBox();
serverOnly = new JCheckBox();
clientClassName = new TextAdapter(new JTextField()) {
@Override
protected void updateModel(String text) {
setClientClassName(text);
}
};
clientSuperClassName = new TextAdapter(new JTextField()) {
@Override
protected void updateModel(String text) {
setClientSuperClassName(text);
}
};
// assemble
FormLayout layout = new FormLayout("right:pref, 3dlu, fill:200dlu", "");
DefaultFormBuilder builder = new DefaultFormBuilder(layout);
builder.setDefaultDialogBorder();
builder.appendSeparator("ObjEntity Configuration");
builder.append("ObjEntity Name:", name.getComponent());
builder.append("Inheritance:", superEntityCombo);
builder.append(tableLabel, dbEntityCombo);
isAbstractLabel = builder.append("Abstract class:", isAbstract);
builder.appendSeparator();
builder.append("Java Class:", className.getComponent());
superclassLabel = builder.append("Superclass:", superClassName.getComponent());
builder.append("Qualifier:", qualifier.getComponent());
builder.append("Read-Only:", readOnly);
builder.append("Optimistic Locking:", optimisticLocking);
// add callback-related stuff
builder.append("Exclude superclass listeners:", excludeSuperclassListeners);
builder.append("Exclude default listeners:", excludeDefaultListeners);
clientSeparator = builder.appendSeparator("Java Client");
serverOnlyLabel = builder.append("Not for Client Use:", serverOnly);
clientClassNameLabel = builder.append("Client Java Class:", clientClassName
.getComponent());
clientSuperClassNameLabel = builder.append(
"Client Superclass:",
clientSuperClassName.getComponent());
add(builder.getPanel(), BorderLayout.CENTER);
}
private void initController() {
// initialize events processing and tracking of UI updates...
mediator.addObjEntityDisplayListener(this);
dbEntityCombo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Change DbEntity for current ObjEntity
ObjEntity entity = mediator.getCurrentObjEntity();
DbEntity dbEntity = (DbEntity) dbEntityCombo.getSelectedItem();
if (dbEntity != entity.getDbEntity()) {
entity.setDbEntity(dbEntity);
mediator.fireObjEntityEvent(new EntityEvent(this, entity));
}
}
});
superEntityCombo.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Change super-entity
CayenneMapEntry superEntity = (CayenneMapEntry) superEntityCombo
.getSelectedItem();
String name = (superEntity == null || superEntity == noInheritance)
? null
: superEntity.getName();
ObjEntity entity = mediator.getCurrentObjEntity();
if (!Util.nullSafeEquals(name, entity.getSuperEntityName())) {
List duplicateAttributes = null;
if (name != null) {
duplicateAttributes = getDuplicatedAttributes((ObjEntity) superEntity);
}
if (duplicateAttributes != null && duplicateAttributes.size() > 0) {
DuplicatedAttributesDialog.showDialog(
Application.getFrame(),
duplicateAttributes,
(ObjEntity) superEntity,
entity);
if (DuplicatedAttributesDialog.getResult().equals(
DuplicatedAttributesDialog.CANCEL_RESULT)) {
superEntityCombo.setSelectedItem(entity.getSuperEntity());
superClassName.setText(entity.getSuperClassName());
return;
}
}
entity.setSuperEntityName(name);
if (name == null) {
dbEntityCombo.setEnabled(true);
}
else {
dbEntityCombo.setEnabled(false);
dbEntityCombo.getModel().setSelectedItem(null);
}
// if a super-entity selected, disable table selection
// and also update parent DbEntity selection...
toggleEnabled(name == null, !serverOnly.isSelected());
dbEntityCombo.getModel().setSelectedItem(entity.getDbEntity());
superClassName.setText(entity.getSuperClassName());
// fire both EntityEvent and EntityDisplayEvent;
// the later is to update attribute and relationship display
DataChannelDescriptor domain = (DataChannelDescriptor) mediator
.getProject()
.getRootNode();
DataMap map = mediator.getCurrentDataMap();
mediator.fireObjEntityEvent(new EntityEvent(this, entity));
mediator.fireObjEntityDisplayEvent(new EntityDisplayEvent(
this,
entity,
map,
domain));
}
}
});
tableLabel.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
// Jump to DbEntity of the current ObjEntity
DbEntity entity = mediator.getCurrentObjEntity().getDbEntity();
if (entity != null) {
DataChannelDescriptor dom = (DataChannelDescriptor) mediator
.getProject()
.getRootNode();
mediator.fireDbEntityDisplayEvent(new EntityDisplayEvent(
this,
entity,
entity.getDataMap(),
dom));
}
}
});
readOnly.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ObjEntity entity = mediator.getCurrentObjEntity();
if (entity != null) {
entity.setReadOnly(readOnly.isSelected());
mediator.fireObjEntityEvent(new EntityEvent(this, entity));
}
}
});
optimisticLocking.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ObjEntity entity = mediator.getCurrentObjEntity();
if (entity != null) {
entity.setDeclaredLockType(optimisticLocking.isSelected()
? ObjEntity.LOCK_TYPE_OPTIMISTIC
: ObjEntity.LOCK_TYPE_NONE);
mediator.fireObjEntityEvent(new EntityEvent(this, entity));
}
}
});
excludeSuperclassListeners.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ObjEntity entity = mediator.getCurrentObjEntity();
if (entity != null) {
entity.setExcludingSuperclassListeners(excludeSuperclassListeners
.isSelected());
mediator.fireObjEntityEvent(new EntityEvent(this, entity));
}
}
});
excludeDefaultListeners.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ObjEntity entity = mediator.getCurrentObjEntity();
if (entity != null) {
entity.setExcludingDefaultListeners(excludeDefaultListeners
.isSelected());
mediator.fireObjEntityEvent(new EntityEvent(this, entity));
}
}
});
serverOnly.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ObjEntity entity = mediator.getCurrentObjEntity();
if (entity != null) {
entity.setServerOnly(serverOnly.isSelected());
toggleEnabled(dbEntityCombo.isEnabled(), !serverOnly.isSelected());
mediator.fireObjEntityEvent(new EntityEvent(this, entity));
}
}
});
isAbstract.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
ObjEntity entity = mediator.getCurrentObjEntity();
if (entity != null) {
entity.setAbstract(isAbstract.isSelected());
mediator.fireObjEntityEvent(new EntityEvent(this, entity));
}
}
});
}
/**
* Updates the view from the current model state. Invoked when a currently displayed
* ObjEntity is changed.
*
* @param entity current entity
*/
private void initFromModel(final ObjEntity entity) {
// TODO: this is a hack until we implement a real MVC
qualifier.getComponent().setBackground(Color.WHITE);
name.setText(entity.getName());
superClassName.setText(entity.getSuperClassName());
className.setText(entity.getClassName());
readOnly.setSelected(entity.isReadOnly());
isAbstract.setSelected(entity.isAbstract());
serverOnly.setSelected(entity.isServerOnly());
clientClassName.setText(entity.getClientClassName());
clientSuperClassName.setText(entity.getClientSuperClassName());
qualifier.setText(new ExpressionConvertor().valueAsString(entity
.getDeclaredQualifier()));
// TODO: fix inheritance - we should allow to select optimistic
// lock if superclass is not already locked,
// otherwise we must keep this checked in but not editable.
optimisticLocking
.setSelected(entity.getDeclaredLockType() == ObjEntity.LOCK_TYPE_OPTIMISTIC);
excludeSuperclassListeners.setSelected(entity.isExcludingSuperclassListeners());
excludeDefaultListeners.setSelected(entity.isExcludingDefaultListeners());
// init DbEntities
EntityResolver resolver = mediator.getEntityResolver();
DataMap map = mediator.getCurrentDataMap();
Object[] dbEntities = resolver.getDbEntities().toArray();
Arrays.sort(dbEntities, Comparators.getDataMapChildrenComparator());
DefaultComboBoxModel dbModel = new DefaultComboBoxModel(dbEntities);
dbModel.setSelectedItem(entity.getDbEntity());
dbEntityCombo.setRenderer(CellRenderers.entityListRendererWithIcons(map));
dbEntityCombo.setModel(dbModel);
boolean isUsedInheritance = entity.getSuperEntity() != null;
dbEntityCombo.setEnabled(!isUsedInheritance);
// toggle visibilty and editability rules
toggleClientFieldsVisible(map.isClientSupported());
toggleEnabled(entity.getSuperEntityName() == null, !entity.isServerOnly());
// init ObjEntities for inheritance
Predicate inheritanceFilter = new Predicate() {
public boolean evaluate(Object object) {
// do not show this entity or any of the subentities
if (entity == object) {
return false;
}
if (object instanceof ObjEntity) {
return !((ObjEntity) object).isSubentityOf(entity);
}
return false;
}
};
Object[] objEntities = CollectionUtils.select(
map.getObjEntities(),
inheritanceFilter).toArray();
Arrays.sort(objEntities, Comparators.getDataMapChildrenComparator());
Object[] finalObjEntities = new Object[objEntities.length + 1];
finalObjEntities[0] = noInheritance;
System.arraycopy(objEntities, 0, finalObjEntities, 1, objEntities.length);
DefaultComboBoxModel superEntityModel = new DefaultComboBoxModel(finalObjEntities);
superEntityModel.setSelectedItem(entity.getSuperEntity());
superEntityCombo.setRenderer(CellRenderers.entityListRendererWithIcons(map));
superEntityCombo.setModel(superEntityModel);
}
void setClassName(String className) {
if (className != null && className.trim().length() == 0) {
className = null;
}
ObjEntity entity = mediator.getCurrentObjEntity();
// "ent" may be null if we quit editing by changing tree selection
if (entity != null && !Util.nullSafeEquals(entity.getClassName(), className)) {
entity.setClassName(className);
mediator.fireObjEntityEvent(new EntityEvent(this, entity));
}
}
void setSuperClassName(String text) {
if (text != null && text.trim().length() == 0) {
text = null;
}
ObjEntity ent = mediator.getCurrentObjEntity();
if (ent != null && !Util.nullSafeEquals(ent.getSuperClassName(), text)) {
ent.setSuperClassName(text);
mediator.fireObjEntityEvent(new EntityEvent(this, ent));
}
}
void setClientClassName(String className) {
if (className != null && className.trim().length() == 0) {
className = null;
}
ObjEntity entity = mediator.getCurrentObjEntity();
// "ent" may be null if we quit editing by changing tree selection
if (entity != null
&& !Util.nullSafeEquals(entity.getClientClassName(), className)) {
entity.setClientClassName(className);
mediator.fireObjEntityEvent(new EntityEvent(this, entity));
}
}
void setClientSuperClassName(String text) {
if (text != null && text.trim().length() == 0) {
text = null;
}
ObjEntity ent = mediator.getCurrentObjEntity();
if (ent != null && !Util.nullSafeEquals(ent.getClientSuperClassName(), text)) {
ent.setClientSuperClassName(text);
mediator.fireObjEntityEvent(new EntityEvent(this, ent));
}
}
void setQualifier(String text) {
if (text != null && text.trim().length() == 0) {
text = null;
}
ObjEntity entity = mediator.getCurrentObjEntity();
if (entity != null) {
ExpressionConvertor convertor = new ExpressionConvertor();
try {
String oldQualifier = convertor.valueAsString(entity
.getDeclaredQualifier());
if (!Util.nullSafeEquals(oldQualifier, text)) {
Expression exp = (Expression) convertor.stringAsValue(text);
entity.setDeclaredQualifier(exp);
mediator.fireObjEntityEvent(new EntityEvent(this, entity));
}
}
catch (IllegalArgumentException ex) {
// unparsable qualifier
throw new ValidationException(ex.getMessage());
}
}
}
void setEntityName(String newName) {
if (newName != null && newName.trim().length() == 0) {
newName = null;
}
ObjEntity entity = mediator.getCurrentObjEntity();
if (entity == null) {
return;
}
if (Util.nullSafeEquals(newName, entity.getName())) {
return;
}
if (newName == null) {
throw new ValidationException("Entity name is required.");
}
else if (entity.getDataMap().getObjEntity(newName) == null) {
// completely new name, set new name for entity
EntityEvent e = new EntityEvent(this, entity, entity.getName());
entity.setName(newName);
mediator.fireObjEntityEvent(e);
// suggest to update class name
ClassNameUpdater nameUpdater = new ClassNameUpdater(Application
.getInstance()
.getFrameController(), entity);
if (nameUpdater.doNameUpdate()) {
className.setText(entity.getClassName());
clientClassName.setText(entity.getClientClassName());
}
}
else {
// there is an entity with the same name
throw new ValidationException("There is another entity with name '"
+ newName
+ "'.");
}
}
void toggleClientFieldsVisible(boolean visible) {
clientSeparator.setVisible(visible);
clientSuperClassNameLabel.setVisible(visible);
clientClassNameLabel.setVisible(visible);
serverOnlyLabel.setVisible(visible);
clientClassName.getComponent().setVisible(visible);
clientSuperClassName.getComponent().setVisible(visible);
serverOnly.setVisible(visible);
}
void toggleEnabled(boolean directTableMapping, boolean clientFieldsEnabled) {
superClassName.getComponent().setEnabled(directTableMapping);
superclassLabel.setEnabled(directTableMapping);
clientSuperClassName.getComponent().setEnabled(
directTableMapping && clientFieldsEnabled);
clientSuperClassNameLabel.setEnabled(directTableMapping && clientFieldsEnabled);
clientClassNameLabel.setEnabled(clientFieldsEnabled);
clientClassName.getComponent().setEnabled(clientFieldsEnabled);
}
public void processExistingSelection(EventObject e) {
EntityDisplayEvent ede = new EntityDisplayEvent(
this,
mediator.getCurrentObjEntity(),
mediator.getCurrentDataMap(),
(DataChannelDescriptor) mediator.getProject().getRootNode());
mediator.fireObjEntityDisplayEvent(ede);
}
public void currentObjEntityChanged(EntityDisplayEvent e) {
ObjEntity entity = (ObjEntity) e.getEntity();
if (entity == null || !e.isEntityChanged()) {
return;
}
initFromModel(entity);
}
private List getDuplicatedAttributes(ObjEntity superEntity) {
List result = new LinkedList();
ObjEntity entity = mediator.getCurrentObjEntity();
for (ObjAttribute attribute : entity.getAttributes()) {
if (superEntity.getAttribute(attribute.getName()) != null) {
result.add(attribute);
}
}
return result;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy