private void doPopup(MouseEvent e) {
   // Check if there is any thing is selected
   boolean isSelected = false;
   if (changedList != null) {
     if (changedList.getSelection().size() > 0) isSelected = true;
   }
   if (!isSelected && newList != null) {
     if (newList.getSelection().size() > 0) isSelected = true;
   }
   if (!isSelected && deleteInDBList != null) {
     if (deleteInDBList.getSelection().size() > 0) isSelected = true;
   }
   if (!isSelected && deleteList != null)
     if (deleteList.getSelection().size() > 0) isSelected = true;
   if (!isSelected && localHasMoreIEList != null) {
     if (localHasMoreIEList.getSelection().size() > 0) isSelected = true;
   }
   if (!isSelected) return;
   JPopupMenu popup = new JPopupMenu();
   popup.add(updateFromDBAction);
   popup.add(commitToDBAction);
   popup.add(showComparisonAction);
   popup.add(clearRecordAction);
   JComponent comp = (JComponent) e.getSource();
   popup.show(comp, e.getX(), e.getY());
 }
 private void commitToDB() {
   // Find which InstanceListPane should be used
   InstanceListPane instanceList = null;
   InstanceListPane[] panes =
       new InstanceListPane[] {
         changedList, newList, deleteInDBList, localHasMoreIEList, deleteList
       };
   for (int i = 0; i < panes.length; i++) {
     if (panes[i] == null) continue;
     if (panes[i].getSelection().size() > 0) {
       instanceList = panes[i];
       break;
     }
   }
   if (instanceList == null) return;
   List selection = instanceList.getSelection();
   List commitList = null;
   if (instanceList != deleteList) {
     // Make sure any user changes have been saved before doing
     // a commit
     saveChanges(fileAdaptor);
     // Now do the commit
     commitList =
         SynchronizationManager.getManager()
             .commitToDB(selection, fileAdaptor, dbAdaptor, false, this);
   } else {
     commitList =
         SynchronizationManager.getManager()
             .deleteInstancesInDB(dbAdaptor, fileAdaptor, selection, this);
   }
   if (commitList != null && commitList.size() > 0) {
     instanceList.deleteInstances(commitList);
   }
   updateInstanceList(instanceList);
 }
 private void clearDeleteRecord() {
   if (deleteList != null) {
     java.util.List list = deleteList.getSelection();
     if (list.size() > 0) {
       try {
         java.util.List dbIDs = new ArrayList(list.size());
         for (Iterator it = list.iterator(); it.hasNext(); ) {
           GKInstance instance = (GKInstance) it.next();
           dbIDs.add(instance.getDBID());
         }
         fileAdaptor.clearDeleteRecord(dbIDs);
       } catch (IOException e) {
         System.err.println("SynchronizationDialog.clearDeleteRecord(): " + e);
         e.printStackTrace();
       }
       deleteList.deleteInstances(list);
       // Check if deleteList needs to be removed
       if (deleteList.getDisplayedInstances().size() == 0) {
         centerPane.remove(deleteList);
         centerPane.validate();
         centerPane.repaint();
       }
     }
   }
 }
 /**
  * A helper method to update GUIs related the passed InstanceListPane: delete, or update the
  * assoicated title.
  *
  * @param instanceList
  */
 private void updateInstanceList(InstanceListPane instanceList) {
   if (instanceList == null) return; // Just in case
   if (instanceList.getDisplayedInstances().size() == 0) {
     removeInstanceList(instanceList);
     // Have to null the original reference
     if (instanceList == changedList) changedList = null;
     else if (instanceList == newList) newList = null;
     else if (instanceList == deleteInDBList) deleteInDBList = null;
     else if (instanceList == localHasMoreIEList) localHasMoreIEList = null;
     else if (instanceList == deleteList) deleteList = null;
   } else {
     // Update label
     SectionTitlePane titlePane = (SectionTitlePane) listToTitle.get(instanceList);
     String title = titlePane.getTitle();
     int index = title.lastIndexOf(":");
     title = title.substring(0, index) + ": " + instanceList.getDisplayedInstances().size();
     titlePane.setTitle(title);
   }
 }
 private void handleMergeResult(
     GKInstance localCopy, GKInstance dbCopy, InstanceComparisonPane comparisonPane) {
   if (comparisonPane.getSaveMergeOption() == InstanceComparisonPane.OVERWRITE_FIRST) {
     // Need to refresh the selected instance
     InstanceComparer comparer = new InstanceComparer();
     try {
       int result = comparer.compare(localCopy, dbCopy);
       if (result != InstanceComparer.IS_IDENTICAL) {
         typeMap.put(localCopy, mapCompareResultToString(result));
       } else {
         typeMap.remove(localCopy);
         changedList.deleteInstance(localCopy);
       }
       changedList.repaint();
     } catch (Exception e1) {
       System.err.println("SynchronizationDialog.handleMergeResult(): " + e1);
       e1.printStackTrace();
     }
   } else if (comparisonPane.getSaveMergeOption() == InstanceComparisonPane.SAVE_AS_NEW) {
     // Need to add a new instance to the local new instance
     GKInstance newInstance = comparisonPane.getMerged();
     List newInstances = (List) syncMap.get(NEW_KEY);
     if (newInstances == null) {
       newInstances = new ArrayList();
       syncMap.put(NEW_KEY, newInstances);
     }
     newInstances.add(newInstance);
     typeMap.put(newInstance, NEW_KEY);
     if (newList == null) {
       // Get some information from changed
       newList =
           initInstanceListPane(newInstances, "Instances created locally: " + newInstances.size());
       centerPane.validate();
     } else {
       // Cannot call this method because it is used for one schema class only
       // newList.addInstance(newInstance);
       newList.setTitle("Instances created locally: " + newInstances.size());
       newList.setDisplayedInstances(newInstances);
       newList.repaint();
     }
   }
 }
 private void validateActions() {
   boolean isChangedSelected = false;
   if (changedList != null && changedList.getSelection().size() > 0) isChangedSelected = true;
   boolean isNewSelected = false;
   if (newList != null && newList.getSelection().size() > 0) isNewSelected = true;
   boolean isDeleteInDBSelected = false;
   if (deleteInDBList != null && deleteInDBList.getSelection().size() > 0)
     isDeleteInDBSelected = true;
   boolean isDeleteSelected = false;
   if (deleteList != null && deleteList.getSelection().size() > 0) isDeleteSelected = true;
   boolean isLocalHasUnExpSelected = false;
   if (localHasMoreIEList != null && localHasMoreIEList.getSelection().size() > 0)
     isLocalHasUnExpSelected = true;
   if (!isChangedSelected
       && !isNewSelected
       && !isDeleteInDBSelected
       && !isDeleteSelected
       && !isLocalHasUnExpSelected) {
     updateFromDBAction.setEnabled(false);
     commitToDBAction.setEnabled(false);
     showComparisonAction.setEnabled(false);
     clearRecordAction.setEnabled(false);
     return;
   }
   // UpdateFromDBAction
   if (!isNewSelected) updateFromDBAction.setEnabled(true);
   else updateFromDBAction.setEnabled(false);
   // CommitToDBAction
   if (isChangedSelected) {
     // detailed cases
     List changed = changedList.getSelection();
     boolean isLocalChangeSelected = false;
     boolean isDBChangeSelected = false;
     boolean isConflictSelected = false;
     for (Iterator it = changed.iterator(); it.hasNext(); ) {
       GKInstance instance = (GKInstance) it.next();
       String type = (String) typeMap.get(instance);
       if (type == NEW_CHANGE_IN_LOCAL_KEY) isLocalChangeSelected = true;
       else if (type == NEW_CHANGE_IN_DB_KEY) isDBChangeSelected = true;
       else if (type == CONFLICT_CHANGE_KEY || type == LOCAL_HAS_MORE_IE_KEY)
         isConflictSelected = true;
     }
     if (isDBChangeSelected || isConflictSelected) commitToDBAction.setEnabled(false);
     else commitToDBAction.setEnabled(true);
   } else if (isLocalHasUnExpSelected) {
     // Add a key in the config so that only some people can
     // commit this strange InstanceEdit
     if (isLocalHasUnexpIECommitAllowed) commitToDBAction.setEnabled(true);
     else commitToDBAction.setEnabled(false);
   } else commitToDBAction.setEnabled(true);
   // showComparisonAction
   if (isChangedSelected || isLocalHasUnExpSelected) showComparisonAction.setEnabled(true);
   else showComparisonAction.setEnabled(false);
   // ClearRecordAction
   if (isDeleteSelected) // Single selection enforced
   clearRecordAction.setEnabled(true);
   else clearRecordAction.setEnabled(false);
 }
  private InstanceListPane initInstanceListPane(List instances, String title) {
    InstanceListPane instanceList = new InstanceListPane();
    instanceList.getInstanceList().addListSelectionListener(selectionListener);
    instanceList.setIsViewable(false);
    if (mouseAdaptor == null) {
      // To view instances
      mouseAdaptor =
          new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
              if (e.isPopupTrigger()) doPopup(e);
            }

            public void mouseReleased(MouseEvent e) {
              if (e.isPopupTrigger()) doPopup(e);
            }

            // Use mouseClicked method. See InstanceListPane.init().
            public void mouseClicked(MouseEvent e) {
              if (e.getButton() == MouseEvent.BUTTON1 && e.getClickCount() == 2) {
                JList list = (JList) e.getSource();
                if (list.getSelectedValues().length != 1) return;
                InstanceListPane instanceList = figureOutInstanceListPane(list);
                if (instanceList == changedList || instanceList == localHasMoreIEList) {
                  showComparison();
                } else {
                  GKInstance instance = (GKInstance) list.getSelectedValue();
                  JDialog parentDialog =
                      (JDialog) SwingUtilities.getAncestorOfClass(JDialog.class, centerPane);
                  FrameManager.getManager().showInstance(instance, parentDialog);
                }
              }
            }
          };
    }
    instanceList.getInstanceList().addMouseListener(mouseAdaptor);
    InstanceUtilities.sortInstances(instances);
    instanceList.setDisplayedInstances(instances);
    // instanceList.setTitle(title);
    instanceList.setListCellRenderer(cellRenderer);
    instanceList.hideTitle();
    SectionTitlePane titlePane = new SectionTitlePane(title);
    titlePane.setSectionPane(instanceList);
    centerPane.add(titlePane);
    centerPane.add(instanceList);
    listToTitle.put(instanceList, titlePane);
    return instanceList;
  }
  private void showComparison() {
    // Find the instance that can be used for comparision. This instance
    // should be chosen from changedList or localHasUnexpInstance
    GKInstance instance = null;
    if (changedList != null) { // Check changedList first
      List selection = changedList.getSelection();
      if (selection.size() > 0) instance = (GKInstance) selection.get(0);
    }
    if (instance == null && localHasMoreIEList != null) {
      List selection = localHasMoreIEList.getSelection();
      if (selection.size() > 0) instance = (GKInstance) selection.get(0);
    }
    if (instance == null) return;
    final InstanceComparisonPane comparisonPane = new InstanceComparisonPane();
    // Fine tune comparison pane for making comparisons with
    // database
    comparisonPane.setSaveDialogHideUnusedButtons(true);
    comparisonPane.setSaveDialogSaveAsNewBtnFirst(false);
    comparisonPane.setSaveDialogSaveAsNewBtnTitle(
        "Create new local instance and put merge into that");
    comparisonPane.setSaveDialogReplaceFirstBtnTitle(
        "Overwrite existing instance with merge (recommended)");
    comparisonPane.setCloseAfterSaving(true);
    try {
      String clsName = instance.getSchemClass().getName();
      Long instanceId = instance.getDBID();
      final GKInstance localCopy = fileAdaptor.fetchInstance(clsName, instanceId);
      dbAdaptor.setUseCache(false);
      // final GKInstance dbCopy = dbAdaptor.fetchInstance(clsName, instanceId);
      // The class type might be changed locally or remotely. So not clsName should be used
      // to fetch database instance. Otherwise, null exception will be thrown. The same thing
      // is done also in creating synchronization result.
      final GKInstance dbCopy = dbAdaptor.fetchInstance(instanceId);
      dbAdaptor.setUseCache(true);
      comparisonPane.setInstances(localCopy, dbCopy);
      String title =
          "Comparing Instances \""
              + instance.getDisplayName()
              + "\" in the local and DB repositories";
      JDialog parentDialog = (JDialog) SwingUtilities.getAncestorOfClass(JDialog.class, centerPane);
      final JDialog dialog = new JDialog(parentDialog, title);
      // Try to update the list automatically
      dialog.addWindowListener(
          new WindowAdapter() {
            public void windowClosed(WindowEvent e) {
              handleMergeResult(localCopy, dbCopy, comparisonPane);
              // To prevent double calling. It is called again when parentDialog is closed.
              dialog.removeWindowListener(this);
            }
          });
      dialog.getContentPane().add(comparisonPane, BorderLayout.CENTER);
      dialog.setModal(true);
      dialog.setSize(800, 600);
      GKApplicationUtilities.center(dialog);
      dialog.setVisible(true);

      // Update synchronization dialog panels depending on user
      // choice.
      if (comparisonPane.getSaveMergeOption() == InstanceComparisonPane.SAVE_AS_NEW) {
        GKInstance merged = comparisonPane.getMerged();

        if (newList == null) {
          List list = new ArrayList();
          list.add(merged);
          newList = initInstanceListPane(list, "Instances created locally: " + list.size());
        } else newList.addInstance(merged);
      } else if (comparisonPane.getSaveMergeOption() == InstanceComparisonPane.OVERWRITE_FIRST) {
        dbAdaptor.setUseCache(false);
        GKInstance remoteCopy = dbAdaptor.fetchInstance(instance.getDBID());
        dbAdaptor.setUseCache(true);
        if (remoteCopy != null) {
          InstanceComparer comparer = new InstanceComparer();
          int reply = comparer.compare(instance, remoteCopy);
          if (reply == InstanceComparer.LOCAL_HAS_MORE_IE) {
            if (localHasMoreIEList == null) {
              List list = new ArrayList();
              list.add(instance);
              localHasMoreIEList =
                  initInstanceListPane(
                      list, "Local instances having unexpected InstanceEdits: " + list.size());
            } else localHasMoreIEList.addInstance(instance);
          } else if (reply == InstanceComparer.IS_IDENTICAL) {
            // Merge has made local and database copies
            // identical - don't need to check in anymore
            changedList.deleteInstance(instance);
          } else if (reply != InstanceComparer.NEW_CHANGE_IN_LOCAL) {
            // Merge has produced a conflict
            typeMap.put(mapCompareResultToString(reply), instance);
          } else
            // The user should now be allowed to commit this
            // instance, because it will now have changed.
            commitToDBAction.setEnabled(true);

          JOptionPane.showMessageDialog(
              parentDialog,
              "Merge successful, you will need to check the merged instance into the database.\n\n",
              "Merge OK",
              JOptionPane.INFORMATION_MESSAGE);
        }
      }

    } catch (Exception e1) {
      System.err.println("Synchronization.createDisplayMapPane(): " + e1);
      e1.printStackTrace();
      JOptionPane.showMessageDialog(
          this,
          "Error in comparing: " + instance.toString(),
          "Error in Comparing",
          JOptionPane.ERROR_MESSAGE);
    }
  }
 private void updateFromDB() {
   InstanceListPane touchedList = null;
   // Find out which instances have been selected in all relevant lists
   // Update the attribute values for changed list.
   try {
     if (changedList != null) {
       java.util.List list = new ArrayList(changedList.getSelection()); // To support it.remove()
       // Use a new ArrayList.
       if (list != null && list.size() > 0) {
         for (Iterator it = list.iterator(); it.hasNext(); ) {
           GKInstance instance = (GKInstance) it.next();
           // Fetch GKInstance based on its DB_ID since SchemaClass might be changed.
           GKInstance localCopy = fileAdaptor.fetchInstance(instance.getDBID());
           dbAdaptor.setUseCache(false);
           GKInstance dbCopy = dbAdaptor.fetchInstance(instance.getDBID());
           dbAdaptor.setUseCache(true);
           if (SynchronizationManager.getManager().updateFromDB(localCopy, dbCopy, this)) {
             AttributeEditManager.getManager().attributeEdit(localCopy);
             fileAdaptor.removeDirtyFlag(localCopy);
           } else it.remove(); // Remove from the list
         }
         // Remove all selected instances
         changedList.deleteInstances(list);
         touchedList = changedList;
       }
     }
     if (localHasMoreIEList != null && localHasMoreIEList.getSelection().size() > 0) {
       List list = new ArrayList(localHasMoreIEList.getSelection());
       for (Iterator it = list.iterator(); it.hasNext(); ) {
         GKInstance localCopy = (GKInstance) it.next();
         dbAdaptor.setUseCache(false);
         GKInstance dbCopy = dbAdaptor.fetchInstance(localCopy.getDBID());
         dbAdaptor.setUseCache(true);
         if (SynchronizationManager.getManager().updateFromDB(localCopy, dbCopy, this)) {
           AttributeEditManager.getManager().attributeEdit(localCopy);
           fileAdaptor.removeDirtyFlag(localCopy);
         } else it.remove(); // Remove from the list, if it it cancelled by the user.
       }
       localHasMoreIEList.deleteInstances(list);
       touchedList = localHasMoreIEList;
     }
     // Delete the local copy for deleteInDBList.
     if (deleteInDBList != null) {
       java.util.List list = deleteInDBList.getSelection();
       if (list != null && list.size() > 0) {
         for (Iterator it = list.iterator(); it.hasNext(); ) {
           GKInstance instance = (GKInstance) it.next();
           fileAdaptor.deleteInstance(instance);
         }
       }
       deleteInDBList.deleteInstances(list);
       touchedList = deleteInDBList;
     }
     // Get another copy for the local repository
     if (deleteList != null) {
       java.util.List<?> list = deleteList.getSelection();
       if (list != null && list.size() > 0) {
         Map<SchemaClass, Set<GKInstance>> checkOutMap =
             new HashMap<SchemaClass, Set<GKInstance>>(); // All checked out Instances
         for (Iterator<?> it = list.iterator(); it.hasNext(); ) {
           GKInstance instance = (GKInstance) it.next();
           Map<SchemaClass, List<GKInstance>> schemaMap =
               InstanceUtilities.listDownloadableInstances(instance);
           // Have to merge schemaMap to checkOutMap
           for (SchemaClass key : schemaMap.keySet()) {
             List<GKInstance> list1 = schemaMap.get(key);
             if (list1 != null && list1.size() > 0) {
               Set<GKInstance> list2 = checkOutMap.get(key);
               if (list2 == null) {
                 list2 = new HashSet<GKInstance>();
                 checkOutMap.put(key, list2);
               }
               // Remove first to avoid any duplication
               list2.addAll(list1);
             }
           }
         }
         fileAdaptor.store(checkOutMap);
         InstanceUtilities.clearShellFlags(checkOutMap);
         // There are maybe more than selected instances after checking out
         List<GKInstance> checkedOut = new ArrayList<GKInstance>();
         for (Set<GKInstance> set : checkOutMap.values()) {
           checkedOut.addAll(set);
         }
         deleteList.deleteInstances(checkedOut);
         // deleteList.deleteInstances(list);
         // Need to clear out these deletion records
         List<Long> dbIds = new ArrayList<Long>();
         for (GKInstance inst : checkedOut) dbIds.add(inst.getDBID());
         fileAdaptor.clearDeleteRecord(dbIds);
         touchedList = deleteList;
       }
     }
   } catch (Exception e) {
     System.err.println("SynchronizationDialog.updateFromDB(): " + e);
     e.printStackTrace();
   }
   updateInstanceList(touchedList);
 }