/*****************************************************************
* 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.dialog.objentity;
import java.awt.Color;
import java.awt.Component;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.swing.DefaultCellEditor;
import javax.swing.DefaultListCellRenderer;
import javax.swing.JComboBox;
import javax.swing.JLabel;
import javax.swing.JList;
import javax.swing.ListCellRenderer;
import org.apache.cayenne.dba.TypesMapping;
import org.apache.cayenne.map.DbAttribute;
import org.apache.cayenne.map.DbEntity;
import org.apache.cayenne.map.EmbeddableAttribute;
import org.apache.cayenne.map.EmbeddedAttribute;
import org.apache.cayenne.map.ObjAttribute;
import org.apache.cayenne.map.ObjEntity;
import org.apache.cayenne.modeler.Application;
import org.apache.cayenne.modeler.ProjectController;
import org.apache.cayenne.modeler.util.CayenneTable;
import org.apache.cayenne.modeler.util.CayenneTableModel;
import org.apache.cayenne.modeler.util.CellEditorForAttributeTable;
public class OverrideEmbeddableAttributeTableModel extends CayenneTableModel {
private Map<String, String> overrideAttr;
private ObjAttribute attr;
private boolean isAttributeOverrideChange;
private CellEditorForAttributeTable cellEditor;
Collection<String> nameAttr;
private CayenneTable table;
protected List<EmbeddableAttribute> embeddableList;
public List<EmbeddableAttribute> getEmbeddableList() {
return embeddableList;
}
public OverrideEmbeddableAttributeTableModel(ProjectController mediator,
Object eventSource, Collection<EmbeddableAttribute> embAttr, ObjAttribute attr) {
super(mediator, eventSource, new ArrayList<Object>(embAttr));
this.embeddableList = new ArrayList<EmbeddableAttribute>(embAttr);
this.attr = attr;
this.isAttributeOverrideChange = false;
if (attr instanceof EmbeddedAttribute) {
EmbeddedAttribute embeddedAttribute = (EmbeddedAttribute) attr;
this.overrideAttr = embeddedAttribute.getAttributeOverrides();
}
else {
this.overrideAttr = null;
}
Iterator<EmbeddableAttribute> it = embeddableList.iterator();
while (it.hasNext()) {
EmbeddableAttribute emb = it.next();
if (overrideAttr != null) {
if (overrideAttr.get(emb.getName()) != null) {
emb.setDbAttributeName(overrideAttr.get(emb.getName()));
}
}
}
}
public Map<String, String> getOverrideAttr() {
return overrideAttr;
}
// Columns
static final int OBJ_ATTRIBUTE = 0;
static final int OBJ_ATTRIBUTE_TYPE = 1;
static final int DB_ATTRIBUTE = 2;
static final int DB_ATTRIBUTE_TYPE = 3;
protected void orderList() {
// NOOP
}
/**
* Returns ObjAttribute class.
*/
@Override
public Class<?> getElementsClass() {
return ObjAttribute.class;
}
@Override
public void setUpdatedValueAt(Object value, int row, int col) {
EmbeddableAttribute attribute = getEmbeddableAttribute(row);
if (col == DB_ATTRIBUTE) {
attribute.setDbAttributeName(value != null ? value.toString() : null);
fireTableCellUpdated(row, col);
this.isAttributeOverrideChange = true;
((ObjAttributeInfoDialogView) ((ObjAttributeInfoDialog) eventSource)
.getView()).getSaveButton().setEnabled(true);
if (value != null) {
DbEntity currentEnt = ((ObjEntity) attr.getEntity()).getDbEntity();
if (currentEnt != null) {
DbAttribute dbAttr = (DbAttribute) currentEnt.getAttribute(value
.toString());
if (dbAttr != null) {
fireTableCellUpdated(DB_ATTRIBUTE_TYPE, col);
}
}
}
fireTableRowsUpdated(row, row);
}
}
public boolean isAttributeOverrideChange() {
return isAttributeOverrideChange;
}
public CellEditorForAttributeTable setCellEditor(
Collection<String> nameAttr,
CayenneTable table) {
this.table = table;
this.cellEditor = new CellEditorForAttributeTable(table, Application
.getWidgetFactory()
.createComboBox(nameAttr, true));
return cellEditor;
}
public CellEditorForAttributeTable getCellEditor() {
return cellEditor;
}
public boolean isCellEditable(int row, int col) {
return col == DB_ATTRIBUTE;
}
public EmbeddableAttribute getEmbeddableAttribute(int row) {
return (row >= 0 && row < embeddableList.size())
? (EmbeddableAttribute) embeddableList.get(row)
: null;
}
public int getColumnCount() {
return 4;
}
public Object getValueAt(int row, int column) {
EmbeddableAttribute attribute = getEmbeddableAttribute(row);
if (column == OBJ_ATTRIBUTE) {
return attribute.getName();
}
else if (column == OBJ_ATTRIBUTE_TYPE) {
return attribute.getType();
}
else {
String dbAttributeName = attribute.getDbAttributeName();
if (column == DB_ATTRIBUTE) {
return dbAttributeName;
}
else if (column == DB_ATTRIBUTE_TYPE) {
return getDBAttrType(dbAttributeName);
}
else {
return null;
}
}
}
private String getDBAttrType(String dbAttributeName) {
DbEntity currentEnt = ((ObjEntity) attr.getEntity()).getDbEntity();
if (currentEnt != null
&& currentEnt.getAttributes() != null
&& dbAttributeName != null) {
DbAttribute dbAttr = (DbAttribute) currentEnt.getAttribute(dbAttributeName);
if (dbAttr != null) {
return TypesMapping.getSqlNameByType(dbAttr.getType());
}
}
return null;
}
public String getColumnName(int column) {
switch (column) {
case OBJ_ATTRIBUTE:
return "ObjAttribute";
case OBJ_ATTRIBUTE_TYPE:
return "Java Type";
case DB_ATTRIBUTE:
return "DbAttribute";
case DB_ATTRIBUTE_TYPE:
return "DB Type";
default:
return "";
}
}
public void setComboBoxes(Collection<String> nameAttr, int column) {
int count = getRowCount();
for (int i = 0; i < count; i++) {
EmbeddableAttribute embAt = getEmbeddableAttribute(i);
if (!nameAttr.contains(embAt.getDbAttributeName())
&& embAt.getDbAttributeName() != null) {
Collection<String> attributeComboForRow = new ArrayList<String>();
attributeComboForRow.addAll(nameAttr);
attributeComboForRow.add(embAt.getDbAttributeName());
JComboBox comboBoxForRow = Application.getWidgetFactory().createComboBox(
attributeComboForRow,
true);
cellEditor.setEditorAt(new Integer(i), new DefaultCellEditor(
comboBoxForRow));
BoxCellRenderer renderer = new BoxCellRenderer();
renderer.setNotActiveColumn(attributeComboForRow.size() - 1);
comboBoxForRow.setRenderer(renderer);
}
}
table.getColumnModel().getColumn(column).setCellEditor(cellEditor);
}
public ObjAttribute getAttribute() {
return attr;
}
@Override
public boolean isColumnSortable(int sortCol) {
return true;
}
@Override
public void sortByColumn(final int sortCol, boolean isAscent) {
Collections.sort(embeddableList, new Comparator<EmbeddableAttribute>() {
public int compare(EmbeddableAttribute o1, EmbeddableAttribute o2) {
Integer compareObjAttributesVal = compareObjAttributes(o1, o2);
if (compareObjAttributesVal != null) {
return compareObjAttributesVal;
}
String valueToCompare1 = "";
String valueToCompare2 = "";
switch (sortCol) {
case OBJ_ATTRIBUTE:
valueToCompare1 = o1.getName();
valueToCompare2 = o2.getName();
break;
case OBJ_ATTRIBUTE_TYPE:
valueToCompare1 = o1.getType();
valueToCompare2 = o2.getType();
break;
case DB_ATTRIBUTE:
valueToCompare1 = o1.getDbAttributeName();
valueToCompare2 = o2.getDbAttributeName();
break;
case DB_ATTRIBUTE_TYPE:
valueToCompare1 = getDBAttrType(o1.getDbAttributeName());
valueToCompare2 = getDBAttrType(o2.getDbAttributeName());
break;
}
return (valueToCompare1 == null) ? -1 : (valueToCompare2 == null)
? 1
: valueToCompare1.compareTo(valueToCompare2);
}
});
if (!isAscent) {
Collections.reverse(embeddableList);
}
}
private Integer compareObjAttributes(EmbeddableAttribute o1, EmbeddableAttribute o2) {
if ((o1 == null && o2 == null) || o1 == o2) {
return 0;
}
else if (o1 == null && o2 != null) {
return -1;
}
else if (o1 != null && o2 == null) {
return 1;
}
return null;
}
}
class BoxCellRenderer implements ListCellRenderer {
protected DefaultListCellRenderer defaultRenderer = new DefaultListCellRenderer();
private int notActiveColumn;
public Component getListCellRendererComponent(
JList list,
Object value,
int index,
boolean isSelected,
boolean cellHasFocus) {
JLabel renderer = (JLabel) defaultRenderer.getListCellRendererComponent(
list,
value,
index,
isSelected,
cellHasFocus);
if (getNotActiveColumn() != 0 && index == getNotActiveColumn()) {
renderer.setForeground(Color.GRAY);
}
return renderer;
}
public int getNotActiveColumn() {
return notActiveColumn;
}
public void setNotActiveColumn(int notActiveColumn) {
this.notActiveColumn = notActiveColumn;
}
}