001/*
002 * The contents of this file are subject to the terms of the Common Development and
003 * Distribution License (the License). You may not use this file except in compliance with the
004 * License.
005 *
006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the
007 * specific language governing permission and limitations under the License.
008 *
009 * When distributing Covered Software, include this CDDL Header Notice in each file and include
010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL
011 * Header, with the fields enclosed by brackets [] replaced by your own identifying
012 * information: "Portions Copyright [year] [name of copyright owner]".
013 *
014 * Copyright 2008 Sun Microsystems, Inc.
015 * Portions Copyright 2015 ForgeRock AS.
016 */
017
018package org.opends.guitools.controlpanel.ui.renderer;
019
020import java.awt.Component;
021import java.awt.event.ActionEvent;
022import java.awt.event.ActionListener;
023
024import javax.swing.AbstractCellEditor;
025import javax.swing.DefaultCellEditor;
026import javax.swing.JPasswordField;
027import javax.swing.JTable;
028import javax.swing.JTextField;
029import javax.swing.event.DocumentEvent;
030import javax.swing.event.DocumentListener;
031import javax.swing.table.TableCellEditor;
032
033import org.opends.guitools.controlpanel.datamodel.BinaryValue;
034import org.opends.guitools.controlpanel.datamodel.ControlPanelInfo;
035import org.opends.guitools.controlpanel.datamodel.ObjectClassValue;
036import org.opends.guitools.controlpanel.ui.BinaryAttributeEditorPanel;
037import org.opends.guitools.controlpanel.ui.ObjectClassEditorPanel;
038import org.opends.guitools.controlpanel.ui.GenericDialog;
039import org.opends.guitools.controlpanel.ui.components.BinaryCellPanel;
040import org.opends.guitools.controlpanel.ui.components.ObjectClassCellPanel;
041import org.opends.guitools.controlpanel.util.Utilities;
042
043/**
044 * The cell editor used in the 'Attribute' View of the entries in the LDAP
045 * entry browser.
046 *
047 */
048public class AttributeCellEditor extends AbstractCellEditor
049implements TableCellEditor
050{
051  private static final long serialVersionUID = 1979354208925355746L;
052
053  private BinaryCellPanel binaryPanel;
054
055  private ObjectClassCellPanel ocPanel;
056
057  private ObjectClassValue ocValue;
058  private byte[] value;
059  private BinaryValue binaryValue;
060
061  private TableCellEditor defaultEditor;
062  private TableCellEditor passwordEditor;
063
064  private GenericDialog editBinaryDlg;
065  private BinaryAttributeEditorPanel editBinaryPanel;
066
067  private GenericDialog editOcDlg;
068  private ObjectClassEditorPanel editOcPanel;
069
070  private JTable table;
071
072  private JTextField textField;
073
074  private JPasswordField passwordField;
075
076  private ControlPanelInfo info;
077
078  private String attrName;
079
080
081  /**
082   * Default constructor.
083   *
084   */
085  public AttributeCellEditor()
086  {
087    textField = Utilities.createTextField();
088    textField.getDocument().addDocumentListener(new DocumentListener()
089    {
090      /** {@inheritDoc} */
091      public void changedUpdate(DocumentEvent ev)
092      {
093        if (!textField.hasFocus())
094        {
095          textField.requestFocusInWindow();
096        }
097      }
098
099      /** {@inheritDoc} */
100      public void insertUpdate(DocumentEvent ev)
101      {
102        changedUpdate(ev);
103      }
104
105      /** {@inheritDoc} */
106      public void removeUpdate(DocumentEvent ev)
107      {
108        changedUpdate(ev);
109      }
110    });
111    passwordField = Utilities.createPasswordField();
112    passwordField.getDocument().addDocumentListener(new DocumentListener()
113    {
114      /** {@inheritDoc} */
115      public void changedUpdate(DocumentEvent ev)
116      {
117        if (!passwordField.hasFocus())
118        {
119          passwordField.requestFocusInWindow();
120        }
121      }
122
123      /** {@inheritDoc} */
124      public void insertUpdate(DocumentEvent ev)
125      {
126        changedUpdate(ev);
127      }
128
129      /** {@inheritDoc} */
130      public void removeUpdate(DocumentEvent ev)
131      {
132        changedUpdate(ev);
133      }
134    });
135    this.defaultEditor = new DefaultCellEditor(textField);
136    this.passwordEditor = new DefaultCellEditor(passwordField);
137    binaryPanel = new BinaryCellPanel();
138    binaryPanel.addEditActionListener(new ActionListener()
139    {
140      /** {@inheritDoc} */
141      public void actionPerformed(ActionEvent e)
142      {
143        if (editBinaryDlg == null)
144        {
145          editBinaryPanel = new BinaryAttributeEditorPanel();
146          editBinaryPanel.setInfo(getInfo());
147          editBinaryDlg = new GenericDialog(Utilities.getFrame(table),
148              editBinaryPanel);
149          editBinaryDlg.setModal(true);
150          Utilities.centerGoldenMean(editBinaryDlg,
151              Utilities.getParentDialog(table));
152        }
153        if (binaryValue != null)
154        {
155          editBinaryPanel.setValue(attrName, binaryValue);
156        }
157        else if (value != null)
158        {
159          if (value.length > 0)
160          {
161            editBinaryPanel.setValue(attrName,
162                BinaryValue.createBase64(value));
163          }
164          else
165          {
166            editBinaryPanel.setValue(attrName, null);
167          }
168        }
169        else
170        {
171          editBinaryPanel.setValue(attrName, null);
172        }
173        editBinaryDlg.setVisible(true);
174        if (editBinaryPanel.valueChanged())
175        {
176          BinaryValue changedValue = editBinaryPanel.getBinaryValue();
177          binaryValue = changedValue;
178          value = null;
179          ocValue = null;
180        }
181        fireEditingStopped();
182      }
183    });
184    ocPanel = new ObjectClassCellPanel();
185    ocPanel.addEditActionListener(new ActionListener()
186    {
187      /** {@inheritDoc} */
188      public void actionPerformed(ActionEvent ev)
189      {
190        if (editOcDlg == null)
191        {
192          editOcPanel = new ObjectClassEditorPanel();
193          editOcPanel.setInfo(getInfo());
194          editOcDlg = new GenericDialog(
195              null,
196              editOcPanel);
197          editOcDlg.setModal(true);
198          Utilities.centerGoldenMean(editOcDlg,
199              Utilities.getParentDialog(table));
200        }
201        if (ocValue != null)
202        {
203          editOcPanel.setValue(ocValue);
204        }
205        editOcDlg.setVisible(true);
206        if (editOcPanel.valueChanged())
207        {
208          binaryValue = null;
209          value = null;
210          ocValue = editOcPanel.getObjectClassValue();
211          fireEditingStopped();
212        }
213      }
214    });
215  }
216
217  /** {@inheritDoc} */
218  public Component getTableCellEditorComponent(JTable table, Object value,
219                   boolean isSelected, int row, int column)
220  {
221    this.table = table;
222    if (isPassword(table, row))
223    {
224      this.value = null;
225      this.binaryValue = null;
226      this.ocValue = null;
227      return passwordEditor.getTableCellEditorComponent(table, value,
228          isSelected, row, column);
229    }
230    else if (value instanceof ObjectClassValue)
231    {
232      this.value = null;
233      this.binaryValue = null;
234      this.ocValue = (ObjectClassValue)value;
235      ocPanel.setValue(ocValue);
236      ocPanel.setBorder(CustomCellRenderer.getDefaultFocusBorder(table,
237          value, isSelected, row, column));
238      return ocPanel;
239    }
240    else if (value instanceof byte[] || value instanceof BinaryValue)
241    {
242      attrName = getAttributeName(table, row);
243      boolean isImage = Utilities.hasImageSyntax(attrName,
244          getInfo().getServerDescriptor().getSchema());
245      if (value instanceof byte[])
246      {
247        this.value = (byte[])value;
248        this.binaryValue = null;
249        this.ocValue = null;
250        if (this.value.length > 0)
251        {
252          binaryPanel.setValue(BinaryValue.createBase64(this.value), isImage);
253        }
254        else
255        {
256          binaryPanel.setValue((byte[])null, isImage);
257        }
258      }
259      else
260      {
261        this.value = null;
262        this.ocValue = null;
263        binaryValue = (BinaryValue)value;
264        binaryPanel.setValue(binaryValue, isImage);
265      }
266      binaryPanel.setBorder(CustomCellRenderer.getDefaultFocusBorder(table,
267          value, isSelected, row, column));
268      return binaryPanel;
269    }
270    else
271    {
272      this.value = null;
273      this.binaryValue = null;
274      this.ocValue = null;
275      return defaultEditor.getTableCellEditorComponent(table, value, isSelected,
276          row, column);
277    }
278  }
279
280  /** {@inheritDoc} */
281  public Object getCellEditorValue()
282  {
283    if (binaryValue != null)
284    {
285      return binaryValue;
286    }
287    else if (value != null)
288    {
289      return value;
290    }
291    else if (ocValue != null)
292    {
293      return ocValue;
294    }
295    else
296    {
297      return defaultEditor.getCellEditorValue();
298    }
299  }
300
301  private boolean isPassword(JTable table, int row)
302  {
303    boolean isPassword = false;
304    Object o = table.getValueAt(row, 0);
305    if (Utilities.hasPasswordSyntax(String.valueOf(o),
306        getInfo().getServerDescriptor().getSchema()))
307    {
308      isPassword = true;
309    }
310    return isPassword;
311  }
312
313  private String getAttributeName(JTable table, int row)
314  {
315    return String.valueOf(table.getValueAt(row, 0));
316  }
317
318  /**
319   * Returns the control panel information.
320   * @return the control panel information.
321   */
322  public ControlPanelInfo getInfo()
323  {
324    return info;
325  }
326
327  /**
328   * Sets the control panel information.
329   * @param info the control panel information.
330   */
331  public void setInfo(ControlPanelInfo info)
332  {
333    this.info = info;
334  }
335}