/*************************************************** * * cismet GmbH, Saarbruecken, Germany * * ... and it just works. * ****************************************************/ /* * To change this template, choose Tools | Templates * and open the template in the editor. */ package de.cismet.cids.editors; import Sirius.navigator.connection.SessionManager; import Sirius.server.middleware.types.AbstractAttributeRepresentationFormater; import Sirius.server.middleware.types.LightweightMetaObject; import Sirius.server.middleware.types.MetaClass; import Sirius.server.middleware.types.MetaClassStore; import Sirius.server.middleware.types.MetaObject; import org.jdesktop.beansbinding.Converter; import org.jdesktop.beansbinding.Validator; import java.awt.Component; import java.io.Serializable; import java.util.Arrays; import java.util.Collection; import java.util.Comparator; import java.util.Vector; import javax.swing.ComboBoxModel; import javax.swing.DefaultComboBoxModel; import javax.swing.DefaultListCellRenderer; import javax.swing.JComboBox; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.ListCellRenderer; import de.cismet.cids.dynamics.CidsBean; import de.cismet.cids.navigator.utils.ClassCacheMultiple; import de.cismet.cidsx.server.search.builtin.legacy.LightweightMetaObjectsByQuerySearch; import de.cismet.cidsx.server.search.builtin.legacy.LightweightMetaObjectsSearch; /** * DOCUMENT ME! * * @author srichter * @version $Revision$, $Date$ */ public class FastBindableReferenceCombo extends JComboBox implements Bindable, MetaClassStore, Serializable { //~ Static fields/initializers --------------------------------------------- private static final Comparator<MetaObject> LWMO_COMP = new Comparator<MetaObject>() { @Override public final int compare(final MetaObject o1, final MetaObject o2) { return String.CASE_INSENSITIVE_ORDER.compare((o1 != null) ? o1.toString() : "", (o2 != null) ? o2.toString() : ""); // NOI18N } }; private static final org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger( FastBindableReferenceCombo.class); //~ Instance fields -------------------------------------------------------- private final AbstractAttributeRepresentationFormater representationFormater; private final String representation; @Deprecated private final String query; private final LightweightMetaObjectsSearch lwmoSearch; private boolean nullable = true; private boolean sorted = false; private String[] representationFields; private CidsBean cidsBean = null; private MetaClass metaClass = null; private String nullValueRepresentation = "-"; // NOI18N //~ Constructors ----------------------------------------------------------- /** * Creates a new FastBindableReferenceCombo object. */ public FastBindableReferenceCombo() { this("%1$2s", new String[] { "NAME" }); } /** * Creates a new FastBindableReferenceCombo object. * * @param representation DOCUMENT ME! * @param representationFields DOCUMENT ME! */ public FastBindableReferenceCombo(final String representation, final String[] representationFields) { this((LightweightMetaObjectsSearch)null, representation, representationFields); // NOI18N } /** * Creates a new FastBindableReferenceCombo object. * * @param query DOCUMENT ME! * @param representation DOCUMENT ME! * @param representationFields DOCUMENT ME! */ @Deprecated public FastBindableReferenceCombo(final String query, final String representation, final String[] representationFields) { this(query, representation, null, representationFields); } /** * Creates a new FastBindableReferenceCombo object. * * @param lwmoSearch DOCUMENT ME! * @param representation DOCUMENT ME! * @param representationFields DOCUMENT ME! */ public FastBindableReferenceCombo(final LightweightMetaObjectsSearch lwmoSearch, final String representation, final String[] representationFields) { this(lwmoSearch, representation, null, representationFields); } /** * Creates a new FastBindableReferenceCombo object. * * @param query DOCUMENT ME! * @param formater DOCUMENT ME! * @param representationFields DOCUMENT ME! */ @Deprecated public FastBindableReferenceCombo(final String query, final AbstractAttributeRepresentationFormater formater, final String[] representationFields) { this(query, null, formater, representationFields); } /** * Creates a new FastBindableReferenceCombo object. * * @param lwmoSearch DOCUMENT ME! * @param formater DOCUMENT ME! * @param representationFields DOCUMENT ME! */ public FastBindableReferenceCombo(final LightweightMetaObjectsSearch lwmoSearch, final AbstractAttributeRepresentationFormater formater, final String[] representationFields) { this(lwmoSearch, null, formater, representationFields); } /** * Creates a new FastBindableReferenceCombo object. * * @param query DOCUMENT ME! * @param representation DOCUMENT ME! * @param formater DOCUMENT ME! * @param representationFields DOCUMENT ME! */ @Deprecated private FastBindableReferenceCombo(final String query, final String representation, final AbstractAttributeRepresentationFormater formater, final String[] representationFields) { this(null, query, representation, formater, representationFields); } /** * Creates a new FastBindableReferenceCombo object. * * @param lwmoSearch DOCUMENT ME! * @param representation DOCUMENT ME! * @param formater DOCUMENT ME! * @param representationFields DOCUMENT ME! */ private FastBindableReferenceCombo(final LightweightMetaObjectsSearch lwmoSearch, final String representation, final AbstractAttributeRepresentationFormater formater, final String[] representationFields) { this(lwmoSearch, null, representation, formater, representationFields); } /** * Creates a new FastBindableReferenceCombo object. * * @param lwmoSearch DOCUMENT ME! * @param query DOCUMENT ME! * @param representation DOCUMENT ME! * @param formater DOCUMENT ME! * @param representationFields DOCUMENT ME! */ @Deprecated private FastBindableReferenceCombo(final LightweightMetaObjectsSearch lwmoSearch, final String query, final String representation, final AbstractAttributeRepresentationFormater formater, final String[] representationFields) { final String[] s = new String[] { null }; this.lwmoSearch = lwmoSearch; this.query = query; this.metaClass = null; this.representation = representation; this.representationFormater = formater; this.representationFields = representationFields; setModel(new DefaultComboBoxModel(s)); final DefaultListCellRenderer dlcr = new DefaultListCellRenderer(); setRenderer(new ListCellRenderer() { @Override public Component getListCellRendererComponent(final JList list, final Object value, final int index, final boolean isSelected, final boolean cellHasFocus) { final Component ret = dlcr.getListCellRendererComponent( list, value, index, isSelected, cellHasFocus); if (value == null) { ((JLabel)ret).setText(getNullValueRepresentation()); } return ret; } }); } //~ Methods ---------------------------------------------------------------- /** * DOCUMENT ME! */ private void init() { try { final DefaultComboBoxModel mod = createModelForMetaClass(nullable); setModel(mod); setSelectedItem(cidsBean); } catch (Exception ex) { LOG.error(ex, ex); } } /** * DOCUMENT ME! * * @param o DOCUMENT ME! * * @return DOCUMENT ME! */ public int getIndexOf(final Object o) { final ComboBoxModel m = getModel(); if (m instanceof DefaultComboBoxModel) { return ((DefaultComboBoxModel)m).getIndexOf(o); } else if (m != null) { for (int i = 0; i < m.getSize(); ++i) { final Object cur = m.getElementAt(i); if ((o == cur) || ((cur != null) && cur.equals(o))) { return i; } } } return -1; } @Override public String getBindingProperty() { return "selectedItem"; // NOI18N } @Override public Validator getValidator() { return null; } @Override public Converter getConverter() { return null; } @Override public Object getNullSourceValue() { return null; } @Override public Object getErrorSourceValue() { return null; } /** * DANGER: could be buggy :( * * @return DOCUMENT ME! */ @Override public Object getSelectedItem() { return cidsBean; } /** * DANGER: could be buggy :( * * @param anObject DOCUMENT ME! */ @Override public void setSelectedItem(final Object anObject) { if (anObject != null) { if (anObject instanceof CidsBean) { cidsBean = (CidsBean)anObject; } else if (anObject instanceof MetaObject) { try { cidsBean = ((MetaObject)anObject).getBean(); } catch (Exception ex) { cidsBean = null; LOG.error(ex, ex); } } } else { cidsBean = null; } // just to notify listeners super.setSelectedItem(anObject); } /** * DANGER: could be buggy :( * * @return DOCUMENT ME! */ @Override public int getSelectedIndex() { return getIndexOf(cidsBean); } @Override public MetaClass getMetaClass() { return metaClass; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public String getNullValueRepresentation() { return nullValueRepresentation; } /** * DOCUMENT ME! * * @param nullValueRepresentation DOCUMENT ME! */ public void setNullValueRepresentation(final String nullValueRepresentation) { this.nullValueRepresentation = nullValueRepresentation; } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public boolean isNullable() { return nullable; } /** * DOCUMENT ME! * * @param nullable DOCUMENT ME! */ public void setNullable(final boolean nullable) { this.nullable = nullable; } /** * DOCUMENT ME! */ public void refreshModel() { // if (EventQueue.isDispatchThread()) { // init(); // } else { // EventQueue.invokeLater(new Runnable() { // // @Override // public void run() { init(); // } // }); // } } /** * DOCUMENT ME! * * @return DOCUMENT ME! * * @throws Exception DOCUMENT ME! */ public final MetaObject[] receiveLightweightMetaObjects() throws Exception { final MetaClass mc = metaClass; if (mc == null) { LOG.error("MetaClass is null!", new Exception()); // NOI18N return new MetaObject[0]; } MetaObject[] lwmos; final LightweightMetaObjectsSearch search; if ((query != null) && (query.trim().length() > 1)) { search = new LightweightMetaObjectsByQuerySearch(); ((LightweightMetaObjectsByQuerySearch)search).setDomain(mc.getDomain()); ((LightweightMetaObjectsByQuerySearch)search).setClassId(mc.getID()); ((LightweightMetaObjectsByQuerySearch)search).setQuery(query); } else { search = this.lwmoSearch; } if (search != null) { search.setRepresentationFields(getRepresentationFields()); if (representationFormater == null) { search.setRepresentationPattern(getRepresentation()); } final Collection<LightweightMetaObject> results = SessionManager.getProxy() .customServerSearch(SessionManager.getSession().getUser(), search); if (representationFormater != null) { for (final LightweightMetaObject result : results) { result.setFormater(representationFormater); } } lwmos = results.toArray(new MetaObject[0]); } else { if (representationFormater != null) { lwmos = SessionManager.getProxy() .getAllLightweightMetaObjectsForClass(mc.getID(), SessionManager.getSession().getUser(), getRepresentationFields(), representationFormater); } else { lwmos = SessionManager.getProxy() .getAllLightweightMetaObjectsForClass(mc.getID(), SessionManager.getSession().getUser(), getRepresentationFields(), getRepresentation()); } } if (sorted) { Arrays.sort(lwmos, LWMO_COMP); } if (nullable) { final MetaObject[] withNull = new MetaObject[lwmos.length + 1]; System.arraycopy(lwmos, 0, withNull, 1, lwmos.length); lwmos = withNull; } return lwmos; } /** * DOCUMENT ME! * * @param nullable DOCUMENT ME! * * @return DOCUMENT ME! * * @throws Exception DOCUMENT ME! */ public DefaultComboBoxModel createModelForMetaClass(final boolean nullable) throws Exception { final MetaObject[] lwmos = receiveLightweightMetaObjects(); // final DefaultComboBoxModel model = new DefaultComboBoxModel(lwmos); final DefaultComboBoxModel model = new MetaObjectComboBoxModel(lwmos); return model; } /** * DOCUMENT ME! * * @return the sorted */ public boolean isSorted() { return sorted; } /** * DOCUMENT ME! * * @param sorted the sorted to set */ public void setSorted(final boolean sorted) { this.sorted = sorted; } /** * DOCUMENT ME! * * @return the query */ @Deprecated public String getQuery() { return query; } /** * DOCUMENT ME! * * @return the representation */ public String getRepresentation() { return representation; } /** * DOCUMENT ME! * * @return the representationFields */ public String[] getRepresentationFields() { return representationFields; } /** * DOCUMENT ME! * * @param representationFields the representationFields to set */ public void setRepresentationFields(final String[] representationFields) { this.representationFields = representationFields; } /** * DOCUMENT ME! * * @param domain DOCUMENT ME! * @param tabname DOCUMENT ME! */ public void setMetaClassFromTableName(final String domain, final String tabname) { // if (EventQueue.isDispatchThread()) { setMetaClassFromTableNameImpl(domain, tabname); // } else { // EventQueue.invokeLater(new Runnable() { // // @Override // public void run() { // setMetaClassFromTableNameImpl(domain, tabname); // } // }); // } } /** * DOCUMENT ME! * * @param domain DOCUMENT ME! * @param tabname DOCUMENT ME! */ private void setMetaClassFromTableNameImpl(final String domain, final String tabname) { if ((tabname != null) && (tabname.length() > 0)) { this.metaClass = ClassCacheMultiple.getMetaClass(domain, tabname); if (metaClass == null) { LOG.error("Could not find MetaClass for Table " + tabname + " in domain " + domain); // NOI18N } init(); } } /** * DOCUMENT ME! * * @return DOCUMENT ME! */ public MetaClass getCurrentMetaClass() { return metaClass; } @Override public void setMetaClass(final MetaClass metaClass) { // if (EventQueue.isDispatchThread()) { setMetaClassImpl(metaClass); // } else { // EventQueue.invokeLater(new Runnable() { // // @Override // public void run() { // setMetaClassImpl(metaClass); // // } // }); // } } /** * DOCUMENT ME! * * @param metaClass DOCUMENT ME! */ private void setMetaClassImpl(final MetaClass metaClass) { this.metaClass = metaClass; init(); } } /** * DOCUMENT ME! * * @version $Revision$, $Date$ */ final class MetaObjectComboBoxModel extends DefaultComboBoxModel { //~ Static fields/initializers --------------------------------------------- private static final org.apache.log4j.Logger log = org.apache.log4j.Logger.getLogger(MetaObjectComboBoxModel.class); //~ Constructors ----------------------------------------------------------- /** * Creates a new MetaObjectComboBoxModel object. */ public MetaObjectComboBoxModel() { super(); } /** * Creates a new MetaObjectComboBoxModel object. * * @param v DOCUMENT ME! */ public MetaObjectComboBoxModel(final Vector<?> v) { super(checkTypes(v.toArray())); } /** * Creates a new MetaObjectComboBoxModel object. * * @param items DOCUMENT ME! */ public MetaObjectComboBoxModel(final Object[] items) { super(checkTypes(items)); } //~ Methods ---------------------------------------------------------------- /** * DOCUMENT ME! * * @param items DOCUMENT ME! * * @return DOCUMENT ME! */ private static Object[] checkTypes(final Object[] items) { for (final Object item : items) { checkType(item); } return items; } /** * DOCUMENT ME! * * @param item DOCUMENT ME! * * @return DOCUMENT ME! */ private static Object checkType(final Object item) { // if (!(item instanceof MetaObject || item == null)) { // log.fatal("!", new Exception()); // throw new IllegalStateException("Can not fill CidsBeanComboBoxModel with item " + item + " of class " + item.getClass() + // "!. Model supports only instances of CidsBean and MetaObject!"); // } // if(item != null) { // log.fatal("type: "+item.getClass()); // } else { // log.fatal("type is null"); // } return item; } @Override public void addElement(final Object anObject) { super.addElement(checkType(anObject)); } @Override public void setSelectedItem(Object anObject) { // log.fatal("setSelectedItem: " + anObject, new Exception()); if (anObject instanceof CidsBean) { anObject = ((CidsBean)anObject).getMetaObject(); } super.setSelectedItem(checkType(anObject)); } @Override public Object getSelectedItem() { final Object o = super.getSelectedItem(); // if (o instanceof MetaObject) { // o = ((MetaObject) o).getBean(); // } // log.fatal("getSelectedItem: " + o, new Exception()); return o; } @Override public int getIndexOf(final Object anObject) { if (anObject instanceof MetaObject) { return findIndexForMetaObject((MetaObject)anObject); } else if (anObject instanceof CidsBean) { return findIndexForCidsBean((CidsBean)anObject); } // log.fatal("getIndexOf: " + anObject +" as "+super.getIndexOf(anObject), new Exception()); return super.getIndexOf(anObject); } /** * DOCUMENT ME! * * @param mo DOCUMENT ME! * * @return DOCUMENT ME! */ int findIndexForMetaObject(final MetaObject mo) { if (mo != null) { final int objID = mo.getID(); final int classID = mo.getClassID(); // search for MO for (int i = 0; i < getSize(); ++i) { final Object item = getElementAt(i); if (item instanceof MetaObject) { final MetaObject curMo = (MetaObject)item; if ((curMo.getID() == objID) && (curMo.getClassID() == classID)) { return i; } } } } else { // search for null for (int i = 0; i < getSize(); ++i) { final Object item = getElementAt(i); if (item == null) { return i; } } } // nothing found return -1; } /** * DOCUMENT ME! * * @param bean DOCUMENT ME! * * @return DOCUMENT ME! */ int findIndexForCidsBean(final CidsBean bean) { if (bean != null) { return findIndexForMetaObject(bean.getMetaObject()); } else { return findIndexForMetaObject(null); } } }