/** * A helper method to save changes * * @param fileAdaptor * @param curatorFrame * @return true for saving the changes, while false for an unsuccessful saving. An unsuccessful * saving might result from cancelling or throwing an exception. */ private boolean saveChanges(XMLFileAdaptor fileAdaptor) { // Make sure everything is changed if (fileAdaptor.isDirty()) { int reply = JOptionPane.showConfirmDialog( this, "You have to save changes first before doing synchronization.\n" + "Do you want to save changes and then do synchronization?", "Save Changes?", JOptionPane.OK_CANCEL_OPTION); if (reply == JOptionPane.CANCEL_OPTION) return false; try { fileAdaptor.save(); return true; } catch (Exception e) { JOptionPane.showMessageDialog( this, "Cannot save changes:" + e.getMessage(), "Error in Saving", JOptionPane.ERROR_MESSAGE); System.err.println("SynchronizationDialog.saveChanges(): " + e); e.printStackTrace(); return false; } } return true; }
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(); } } } }
protected List getSynchronizingClassList(XMLFileAdaptor fileAdaptor) { GKSchemaClass topCls = selectedCls; if (topCls == null) topCls = (GKSchemaClass) ((GKSchema) fileAdaptor.getSchema()).getRootClass(); List clsList = new ArrayList(); InstanceUtilities.getDescendentClasses(clsList, topCls); return clsList; }
private SchemaClass getDisplayedPESubclass(SchemaClass cls) { SchemaClass displayedCls = cls; // Only the first level of PE is displayed. Need to map it to one of // these subclasses XMLFileAdaptor fileAdaptor = PersistenceManager.getManager().getActiveFileAdaptor(); GKSchemaClass pe = (GKSchemaClass) fileAdaptor.getSchema().getClassByName(ReactomeJavaConstants.PhysicalEntity); for (Iterator it = pe.getSubClasses().iterator(); it.hasNext(); ) { GKSchemaClass sub = (GKSchemaClass) it.next(); if (cls.isa(sub)) { displayedCls = sub; break; } } return displayedCls; }
@Override public void mapClass( OWLIndividual bpInstance, BioPAXFactory bpFactory, XMLFileAdaptor fileAdaptor, Map<OWLIndividual, GKInstance> bpToRInstancesMap) throws Exception { RDFSClass cls = bpInstance.getRDFType(); if (cls != bpFactory.getpathwayClass()) return; // this method will work for pathway only GKInstance instance = fileAdaptor.createNewInstance(ReactomeJavaConstants.Pathway); bpToRInstancesMap.put(bpInstance, instance); }
/** * Set the list of SchemaClasses to be displayed in this EntityInstanceListPane. * * @param classes * @throws Exception */ public void setSchemaClasses(List<GKSchemaClass> classes, XMLFileAdaptor fileAdaptor) throws Exception { DefaultTreeModel model = (DefaultTreeModel) tree.getModel(); DefaultMutableTreeNode root = (DefaultMutableTreeNode) model.getRoot(); root.removeAllChildren(); for (GKSchemaClass cls : classes) { Collection instances = fileAdaptor.fetchInstancesByClass(cls.getName()); // Don't add an empty class node to save space if (instances == null || instances.size() == 0) continue; DefaultMutableTreeNode clsNode = new DefaultMutableTreeNode(cls); root.add(clsNode); buildTree(instances, clsNode); } model.nodeStructureChanged(root); }
private Map getLocalDeleteMap(XMLFileAdaptor fileAdaptor, List synClassList) { Map rtnMap = new HashMap(); Map deleteMap = fileAdaptor.getDeleteMap(); if (deleteMap != null && deleteMap.size() > 0) { List synClassName = new ArrayList(synClassList.size()); for (Iterator it = synClassList.iterator(); it.hasNext(); ) { GKSchemaClass cls = (GKSchemaClass) it.next(); synClassName.add(cls.getName()); } for (Iterator it = deleteMap.keySet().iterator(); it.hasNext(); ) { Long dbID = (Long) it.next(); String className = (String) deleteMap.get(dbID); if (synClassName.contains(className)) rtnMap.put(dbID, className); } } return rtnMap; }
/** * Synchronize a local instance repository to the db repository. Calling this method may modify * deleteMap Map in the FileAdaptor object. * * @param fileAdaptor the PersistenceAdaptor for the local instance repository. * @param dbAdaptor the PersistenceAdaptor for the database instance repository. * @return Key: delete, deleteInDB, new and/or changed; Values: A list of instances * <p>Sideeffect: changes typeMap. */ private Map synchronize(final XMLFileAdaptor fileAdaptor, final MySQLAdaptor dbAdaptor) { // Need another thread to display the progress final ProgressDialog progDialog = new ProgressDialog((JFrame) getOwner()); progDialog.setSize(300, 180); // GKApplicationUtilities.center(progDialog); progDialog.setLocationRelativeTo(progDialog.getOwner()); progDialog.setModal(true); final List syncClassList = getSynchronizingClassList(fileAdaptor); // Get the total instance counter Schema schema = fileAdaptor.getSchema(); SchemaClass cls = null; long total = 0; try { total = getTotalInstanceCount(fileAdaptor); } catch (Exception e) { System.err.println("SyncrhonizationEngine.synchronize(): " + e); e.printStackTrace(); } progDialog.totalBar.setMaximum((int) total); progDialog.totalBar.setMinimum(0); // Let the synchronizing work in another thread. final Map map = new HashMap(); Thread t = new Thread() { public void run() { java.util.List newInstances = new ArrayList(); java.util.List changedInstances = new ArrayList(); java.util.List deletedInDBInstances = new ArrayList(); java.util.List localHasMoreIEInstances = new ArrayList(); Schema schema = fileAdaptor.getSchema(); SchemaClass schemaClass = null; Collection instances = null; GKInstance instance = null; GKInstance dbCopy = null; int index = 0; int total = 0; // For comparsing InstanceComparer comparer = new InstanceComparer(); try { for (Iterator it = syncClassList.iterator(); it.hasNext(); ) { if (isCancelled) break; schemaClass = (SchemaClass) it.next(); instances = fileAdaptor.fetchInstancesByClass(schemaClass, false); if (instances == null || instances.size() == 0) continue; progDialog.clsLabel.setText("Scan class " + schemaClass.getName() + "..."); progDialog.clsBar.setMinimum(0); progDialog.clsBar.setMaximum(instances.size()); List existedIDs = new ArrayList(instances.size()); for (Iterator it1 = instances.iterator(); it1.hasNext(); ) { instance = (GKInstance) it1.next(); if (instance.getDBID().longValue() < 0) { newInstances.add(instance); typeMap.put(instance, NEW_KEY); } else // Shell instances should not be skipped since a shell instance can still // be deleted locally so existence checking is needed. existedIDs.add(instance.getDBID()); } if (existedIDs.size() == 0) continue; Collection existences = dbAdaptor.fetchInstances(schemaClass.getName(), existedIDs); if (existences.size() > 0) { // Load all modified attribute SchemaAttribute att = schemaClass.getAttribute("modified"); // Load all atributes in a batch dbAdaptor.loadInstanceAttributeValues(existences, att); } index = 0; for (Iterator it1 = instances.iterator(); it1.hasNext(); ) { if (isCancelled) break; instance = (GKInstance) it1.next(); if (instance.getDBID().longValue() < 0) { // Handled by the previous loop continue; } // The schema class might be changed. Use the // top-leve class to fetch instance dbCopy = dbAdaptor.fetchInstance(instance.getDBID()); if (dbCopy == null) { deletedInDBInstances.add(instance); typeMap.put(instance, DELETE_IN_DB_KEY); } // Don't care a shell instance else { if (!instance.isShell()) { int tmp = comparer.compare(instance, dbCopy); String typeKey = mapCompareResultToString(tmp); if (typeKey == LOCAL_HAS_MORE_IE_KEY) { localHasMoreIEInstances.add(instance); typeMap.put(instance, typeKey); } else if (typeKey != IS_IDENTICAL_KEY) { changedInstances.add(instance); typeMap.put(instance, typeKey); } } } index++; total++; progDialog.clsBar.setValue(index); progDialog.totalBar.setValue(total); } } if (deletedInDBInstances.size() > 0) map.put(DELETE_IN_DB_KEY, deletedInDBInstances); if (newInstances.size() > 0) map.put(NEW_KEY, newInstances); if (changedInstances.size() > 0) map.put(CHANGED_KEY, changedInstances); if (localHasMoreIEInstances.size() > 0) map.put(LOCAL_HAS_MORE_IE_KEY, localHasMoreIEInstances); // Check the delete instances Map deleteMap = getLocalDeleteMap(fileAdaptor, syncClassList); if (deleteMap != null && deleteMap.size() > 0) { java.util.List deleteInstances = new ArrayList(); List clearingIDs = new ArrayList(); for (Iterator it = deleteMap.keySet().iterator(); it.hasNext(); ) { Long dbID = (Long) it.next(); String className = (String) deleteMap.get(dbID); dbCopy = dbAdaptor.fetchInstance(className, dbID); if (dbCopy != null) { deleteInstances.add(dbCopy); typeMap.put(dbCopy, DELETE_KEY); } else clearingIDs.add(dbID); } if (deleteInstances.size() > 0) map.put(DELETE_KEY, deleteInstances); fileAdaptor.clearDeleteRecord(clearingIDs); } progDialog.dispose(); } catch (Exception e) { System.err.println("SynchronizationEngine.synchronize() 1: " + e); e.printStackTrace(); JOptionPane.showMessageDialog( progDialog, "Error in synchronizing: \n" + e, "Error in Synchronizing", JOptionPane.ERROR_MESSAGE); // Have to set this first to behavior correctly since thread issue. isCancelled = true; progDialog.dispose(); } } }; t.start(); progDialog.setVisible(true); return map; }
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); }
protected long getTotalInstanceCount(XMLFileAdaptor fileAdaptor) throws Exception { GKSchemaClass topCls = selectedCls; if (topCls == null) topCls = (GKSchemaClass) ((GKSchema) fileAdaptor.getSchema()).getRootClass(); return fileAdaptor.getClassInstanceCount(topCls); }