/** * Set HUD size. If not the HUD view will use WRAP_CONTENT instead * * @param width in dp * @param height in dp * @return Current HUD */ public KProgressHUD setSize(int width, int height) { mProgressDialog.setSize(width, height); return this; }
/** * 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; }