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); }