/** Generate the panel */
 public ResultSearchPrincipalPanel() {
   try {
     init();
   } catch (Exception e) {
     Log.error(Bundle.getMessage(Bundle.ERROR_CREATING) + getClass().getName(), e);
   }
 }
  /**
   * Invoked when an action occurs.
   *
   * @param e the ActionEvent
   */
  public void actionPerformed(ActionEvent event) {
    Object o = event.getSource();

    if ((o == null) || !(o instanceof ManagementObjectPanel)) {
      Log.error(Bundle.getMessage(Bundle.ERROR_INVALID_ACTION_EVENT));
      return;
    }

    ConnectorManagementPanel p = (ConnectorManagementPanel) o;
    ConnectorManagementObject mo = (ConnectorManagementObject) p.getManagementObject();

    try {
      if (event.getID() == p.ACTION_EVENT_UPDATE) {
        saveConfiguration(mo);
      }
    } catch (AdminException e) {
      p.notifyError(e);
    }
  }
  /**
   * Create the model of the table. The fields associated to a princiapl (princiaplID, user,
   * deviceID) are managed in the model
   */
  public class MyTableModel extends AbstractTableModel {

    // -------------------------------------------------------- Private data
    /** princiapls to display in table */
    private Sync4jPrincipal[] principals = null;

    /** properties of the table, contains the column names */
    private String[] columnNames =
        new String[] {
          Bundle.getMessage(Bundle.PRINCIPAL_PANEL_PRINCIPALID),
          Bundle.getMessage(Bundle.PRINCIPAL_PANEL_USERNAME),
          Bundle.getMessage(Bundle.PRINCIPAL_PANEL_DEVICEID)
        };

    /** container of datas in the table */
    private Object[][] rowData = null;

    // -------------------------------------------------------- Constructors
    /** void constructor */
    public MyTableModel() {}

    // ------------------------------------------------------ Public methods
    /**
     * Returns rows number
     *
     * @return rows number
     */
    public int getRowCount() {
      if (rowData == null) {
        return 0;
      } else {
        return rowData.length;
      }
    }

    /**
     * Returns number of columns
     *
     * @return columns number
     */
    public int getColumnCount() {
      return columnNames.length;
    }

    /**
     * Delete a row from the table.
     *
     * @param row target to delete
     */
    public void deleteRow(int row) {
      int col = getColumnCount();
      int rows = getRowCount() - 1;
      boolean deleted = false;
      Object[][] oldRowData = rowData;
      rowData = new Object[rows][columnNames.length];

      Sync4jPrincipal[] oldPrincipalArray = principals;
      principals = new Sync4jPrincipal[rows];

      for (int i = 0; i < rows; i++) {
        if (i == row) {
          deleted = true;
        }
        for (int y = 0; y < col; y++) {
          if (deleted) {
            rowData[i][y] = oldRowData[i + 1][y];
            model.fireTableCellUpdated(i, y);
          } else {
            rowData[i][y] = oldRowData[i][y];
            model.fireTableCellUpdated(i, y);
          }
        }

        if (!deleted) {
          principals[i] = oldPrincipalArray[i];
        } else {
          principals[i] = oldPrincipalArray[i + 1];
        }
      }
      model.fireTableDataChanged();
    }

    /**
     * Returns value in the table
     *
     * @param row origin row
     * @param column origin column
     * @return value in the table
     */
    public Object getValueAt(int row, int column) {
      return rowData[row][column];
    }

    // -------------------------------------------------------
    // Overrides javax.swing.table.AbstractTableModel methods
    // -------------------------------------------------------
    /**
     * Returns the name of the column
     *
     * @param column origin column
     * @return name of the column
     */
    public String getColumnName(int column) {
      return columnNames[column];
    }

    // -------------------------------------------------------
    // Overrides javax.swing.table.AbstractTableModel methods
    // -------------------------------------------------------
    /**
     * Returns classname of the value in the table
     *
     * @param column
     * @return Classname of the value in the table
     */
    public Class getColumnClass(int column) {
      return String.class;
    }

    // -------------------------------------------------------
    // Overrides javax.swing.table.AbstractTableModel methods
    // -------------------------------------------------------
    /**
     * Set if cell in the table is editable. First column is not editable, other are editable
     *
     * @param row selected row
     * @param col selected column
     * @return true if cell is editable
     */
    public boolean isCellEditable(int row, int col) {
      return false;
    }

    // -------------------------------------------------------
    // Overrides javax.swing.table.AbstractTableModel methods
    // -------------------------------------------------------
    /**
     * Set value of the principal in the table and save a copy of the old values if edited
     *
     * @param value princiapl value to insert in the table
     * @param row selected row
     * @param col selected column
     */
    public void setValueAt(Object value, int row, int col) {
      rowData[row][col] = value;
      Sync4jPrincipal principal = principals[row];
      if (col == 0) {
        principal.setId(Long.parseLong((String) value));
      }
      if (col == 1) {
        principal.setUsername((String) value);
      }
      if (col == 2) {
        principal.setDeviceId((String) value);
      }
    }

    /**
     * Load values of recived principals into table
     *
     * @param devices
     */
    public void loadPrincipals(Sync4jPrincipal[] principals) {

      int size = principals.length;
      this.principals = principals;
      rowData = new Object[size][columnNames.length];
      for (int i = 0; i < size; i++) {
        rowData[i][0] = String.valueOf(principals[i].getId());
        rowData[i][1] = (principals[i].getUsername());
        rowData[i][2] = (principals[i].getDeviceId());
      }
    }
  }
  /**
   * Starts the process to create a new SyncSouce
   *
   * @param node SyncTypeNode involved in the process
   * @throws AdminException if a error occurs during the process
   */
  public void editConnector(ConnectorNode node) throws AdminException {
    Sync4jModule module = node.getModule();
    Sync4jConnector connector = node.getConnector();

    Log.debug("node:" + node);

    final String panelName = module.getModuleName() + " - " + connector.getConnectorName();

    ConnectorManagementPanel panel = (ConnectorManagementPanel) PanelManager.getPanel(panelName);

    ConnectorManagementObject mo =
        new ConnectorManagementObject(
            null, module.getModuleId(), connector.getConnectorId(), connector.getConnectorName());

    if (panel != null) {
      //
      // Management object loading and setting
      //
      readConfiguration(mo);

      panel.setManagementObject(mo);
      panel.updateForm();
      PanelManager.showPanel(panelName);
    } else {
      String adminClassName = connector.getAdminClass();

      Log.debug("admin class name: " + adminClassName);

      if ((adminClassName == null) || (adminClassName.trim().length() == 0)) {
        //
        // There is no configuration panel for this connector... just
        // do nothing
        //
        return;
      }

      //
      // Admin class loading
      //

      Class adminClass = null;

      SyncAdminController adminController = ExplorerUtil.getSyncAdminController();

      ClassLoader cl = adminController.getSync4jClassLoader();

      try {
        adminClass = cl.loadClass(adminClassName);
        panel = (ConnectorManagementPanel) adminClass.newInstance();
      } catch (Exception e) {
        String errorMessage = Bundle.getMessage(Bundle.ERROR_LOADING_CONNECTOR_CONFIG_PANEL);
        Log.error(errorMessage + " (class name: " + adminClassName + ")");
        Log.error(e);
        NotifyDescriptor desc = new NotifyDescriptor.Message(errorMessage);
        DialogDisplayer.getDefault().notify(desc);
        return;
      }

      //
      // Management object loading and setting
      //
      readConfiguration(mo);

      panel.setName(panelName);
      panel.setManagementObject(mo);
      panel.addActionListener(this);

      //
      // Tell the panel to rewrite its content
      //
      panel.updateForm();

      panel.validate();

      PanelManager.addPanel(panel);
    }
  }