void exportSyncRecords(PrismsCenter center, DBRecordKeeper keeper, JsonStreamWriter jsw) throws java.io.IOException, PrismsRecordException { jsw.startObject(); jsw.startProperty("id"); jsw.writeNumber(Integer.valueOf(center.getID())); jsw.startProperty("centerID"); jsw.writeNumber(Integer.valueOf(center.getCenterID())); jsw.startProperty("syncRecords"); jsw.startArray(); for (SyncRecord record : keeper.getSyncRecords(center, null)) { jsw.startObject(); jsw.startProperty("id"); jsw.writeNumber(Integer.valueOf(record.getID())); jsw.startProperty("parallelID"); jsw.writeNumber(Integer.valueOf(record.getParallelID())); jsw.startProperty("syncType"); jsw.writeString(record.getSyncType().toString()); jsw.startProperty("time"); jsw.writeNumber(Long.valueOf(record.getSyncTime())); jsw.startProperty("isImport"); jsw.writeBoolean(record.isImport()); jsw.startProperty("syncError"); jsw.writeString(record.getSyncError()); jsw.startProperty("associated"); jsw.startArray(); for (long assoc : keeper.getChangeIDs(null, null, null, null, record, null)) { jsw.startObject(); jsw.startProperty("id"); jsw.writeNumber(Long.valueOf(assoc)); jsw.startProperty("error"); jsw.writeBoolean(!keeper.hasSuccessfulChange(assoc)); jsw.endObject(); } jsw.endArray(); jsw.endObject(); } jsw.endArray(); jsw.endObject(); }
void importData( PrismsApplication app, PrismsSynchronizer sync, String version, JsonSerialReader jsr, StringBuilder message) throws java.io.IOException, SAJParser.ParseException { SyncRecord syncRecord = new SyncRecord( new PrismsCenter("Export"), SyncRecord.Type.AUTOMATIC, System.currentTimeMillis(), false); PrismsSynchronizer.SyncTransaction trans = sync.transact( version, true, syncRecord, false, new prisms.ui.UI.DefaultProgressInformer()); // Items PrismsSynchronizer.PS2ItemReader itemReader = new PrismsSynchronizer.PS2ItemReader(trans); if (!jsr.goToProperty("items")) { message.append("\n\t\tNo items property in sync data"); return; } int items = 0; org.json.simple.JSONObject obj; jsr.startArray(); obj = jsr.parseObject(); while (obj != null) { items++; try { itemReader.read(obj); } catch (PrismsRecordException e) { log.error("Error parsing item", e); } obj = jsr.parseObject(); } jsr.endArray(null); message.append("\n\t\t").append(items).append(" items"); PrismsCenter[] centers; try { centers = sync.getKeeper().getCenters(); } catch (PrismsRecordException e) { message.append("\n\t\t").append("Could not get centers"); log.error("Could not get centers", e); centers = null; } if (centers != null && trans.getImpl().getCentersProperty() != null) { PrismsCenter[] appCenters = centers; for (int i = 0; i < appCenters.length; i++) if (centers[i].getID() == 0) { // Don't include the "Here" center in the UI value appCenters = prisms.util.ArrayUtils.remove(appCenters, i); break; } app.setGlobalProperty( trans.getImpl().getCentersProperty(), appCenters, RecordUtils.TRANSACTION_EVENT_PROP, new prisms.records.RecordsTransaction()); } // Changes PrismsSynchronizer.ChangeReader changeReader = new PrismsSynchronizer.ChangeReader(trans, null, itemReader, 0); if (!jsr.goToProperty("changes")) { message.append("\n\t\tNo changes property in sync data"); return; } int changes = 0; jsr.startArray(); obj = jsr.parseObject(); while (obj != null) { changes++; changeReader.readChange(obj); obj = jsr.parseObject(); } jsr.endArray(null); message.append(", ").append(changes).append(" changes"); changeReader = null; itemReader = null; // Sync records if (centers != null) { if (jsr.goToProperty("syncRecords")) { int syncRecords = 0; jsr.startArray(); while (jsr.getNextItem(true, false) instanceof JsonSerialReader.ObjectItem) { JsonSerialReader.StructState centerState = jsr.save(); try { if (!jsr.goToProperty("id")) { message.append("\n\t\tID missing in sync records group"); break; } int centerID = jsr.parseInt(); PrismsCenter center = null; for (PrismsCenter c : centers) if (c.getID() == centerID) { center = c; break; } if (center == null) { log.warn("No such center with ID " + centerID); continue; } if (!jsr.goToProperty("syncRecords")) { message.append("\n\t\tsyncRecords missing in sync records group"); continue; } jsr.startArray(); while (jsr.getNextItem(true, false) instanceof JsonSerialReader.ObjectItem) { JsonSerialReader.StructState srState = jsr.save(); try { if (!jsr.goToProperty("id")) { log.warn("No id property in sync record"); continue; } int srID = jsr.parseInt(); if (!jsr.goToProperty("parallelID")) { log.warn("No parallelID property in sync record"); continue; } int parallelID = jsr.parseInt(); if (!jsr.goToProperty("syncType")) { log.warn("No syncType property in sync record"); continue; } String typeName = jsr.parseString(); SyncRecord.Type type = SyncRecord.Type.byName(typeName); if (type == null) { log.warn("Unrecognized sync type in sync record: " + typeName); continue; } if (!jsr.goToProperty("time")) { log.warn("No time property in sync record"); continue; } long time = jsr.parseLong(); if (!jsr.goToProperty("isImport")) { log.warn("No isImport property in sync record"); continue; } boolean isImport = jsr.parseBoolean(); if (!jsr.goToProperty("syncError")) { log.warn("No syncError property in sync record"); continue; } Object syncError = jsr.parseNext(false); SyncRecord sr = new SyncRecord(center, type, time, isImport); sr.setID(srID); sr.setParallelID(parallelID); if (syncError instanceof String) sr.setSyncError((String) syncError); else if (syncError == JsonSerialReader.NULL) sr.setSyncError(null); else String.class.cast(syncError); try { sync.getKeeper().putSyncRecord(sr); } catch (PrismsRecordException e) { log.error("Could not persist sync record", e); continue; } syncRecords++; if (!jsr.goToProperty("associated")) { log.warn("No associated property in sync record"); continue; } prisms.util.LongList assocIDs = new prisms.util.LongList(); prisms.util.BooleanList assocErrors = new prisms.util.BooleanList(); jsr.startArray(); while (jsr.getNextItem(true, false) instanceof JsonSerialReader.ObjectItem) { if (!jsr.goToProperty("id")) { log.warn("No id for associated change"); jsr.endObject(null); continue; } assocIDs.add(jsr.parseLong()); if (jsr.goToProperty("error")) assocErrors.add(jsr.parseBoolean()); else assocErrors.add(false); jsr.endObject(null); } jsr.endArray(null); ChangeRecord[] assocChanges; try { assocChanges = sync.getKeeper().getItems(assocIDs.toArray()); } catch (PrismsRecordException e) { log.error("Could not get associated changes", e); continue; } for (int i = 0; i < assocChanges.length; i++) { if (assocChanges[i] != null) try { sync.getKeeper().associate(assocChanges[i], sr, assocErrors.get(i)); } catch (PrismsRecordException e) { log.error("Could not associated change", e); } } } finally { jsr.endObject(srState); } } jsr.endArray(null); } finally { jsr.endObject(centerState); } } jsr.endArray(null); message.append(", ").append(syncRecords).append(" sync records"); } } // Latest changes if (jsr.goToProperty("latestChanges")) { JsonSerialReader.StructState rootState = jsr.startArray(); while (jsr.getNextItem(true, false) instanceof JsonSerialReader.ObjectItem) { JsonSerialReader.StructState lcState = jsr.save(); try { if (!jsr.goToProperty("center")) { log.warn("No center for latest change entry"); continue; } int centerID = jsr.parseInt(); if (!jsr.goToProperty("subjectCenter")) { log.warn("No subjectCenter for latest change entry"); continue; } int subjectCenter = jsr.parseInt(); if (!jsr.goToProperty("latestChange")) { log.warn("No latestChange for latest change entry"); continue; } long changeTime = jsr.parseLong(); try { sync.getKeeper().setLatestChange(centerID, subjectCenter, changeTime); } catch (PrismsRecordException e) { log.error("Could not set latest change", e); } } finally { jsr.endObject(lcState); } } jsr.endArray(rootState); } }
void exportData( prisms.ui.UI ui, PrismsSynchronizer sync, JsonStreamWriter jsw, java.util.HashSet<String> namespaces, prisms.ui.UI.DefaultProgressInformer pi, boolean global) throws java.io.IOException, PrismsRecordException { DBRecordKeeper keeper = (DBRecordKeeper) sync.getKeeper(); String namespace = keeper.getNamespace(); if (namespaces.contains(namespace)) return; namespaces.add(namespace); for (PrismsSynchronizer depend : sync.getDepends()) exportData(ui, depend, jsw, namespaces, pi, global); jsw.startObject(); jsw.startProperty("namespace"); jsw.writeString(namespace); jsw.startProperty("version"); String v = null; SynchronizeImpl impl = null; for (SynchronizeImpl imp : sync.getImpls()) if (prisms.arch.PrismsConfig.compareVersions(imp.getVersion(), v) > 0) { impl = imp; v = impl.getVersion(); } jsw.writeString(v); SyncRecord syncRecord = new SyncRecord( new PrismsCenter("Export"), SyncRecord.Type.AUTOMATIC, System.currentTimeMillis(), false); pi.setProgressText("Exporting " + namespace + " items"); ui.startTimedTask(pi); PrismsSynchronizer.SyncTransaction syncTrans = sync.transact(v, false, syncRecord, false, pi); PrismsSynchronizer.PS2ItemWriter itemWriter = new PrismsSynchronizer.PS2ItemWriter( syncTrans, jsw, new prisms.records.LatestCenterChange[0]); int[] centerIDs = global ? keeper.getAllCenterIDs() : new int[] {keeper.getCenterID()}; SynchronizeImpl.ItemIterator iter = impl.getAllItems(centerIDs, syncRecord.getCenter()); jsw.startProperty("items"); jsw.startArray(); while (iter.hasNext()) itemWriter.writeItem(iter.next()); for (PrismsCenter center : keeper.getCenters()) itemWriter.writeItem(center); if (keeper.getAutoPurger() != null) itemWriter.writeItem(keeper.getAutoPurger()); jsw.endArray(); pi.setProgressText("Exporting " + namespace + " changes"); prisms.util.Sorter<RecordKeeper.ChangeField> sorter; sorter = new prisms.util.Sorter<RecordKeeper.ChangeField>(); sorter.addSort(RecordKeeper.ChangeField.CHANGE_TIME, true); prisms.util.Search changeSearch = global ? null : new prisms.records.ChangeSearch.IDRange( Long.valueOf(IDGenerator.getMinID(keeper.getCenterID())), Long.valueOf(IDGenerator.getMaxID(keeper.getCenterID()))) .and(new prisms.records.ChangeSearch.LocalOnlySearch(null)); prisms.util.LongList changeIDs = new prisms.util.LongList(keeper.search(changeSearch, sorter)); long[] batch = new long[changeIDs.size() < 200 ? changeIDs.size() : 200]; jsw.startProperty("changes"); jsw.startArray(); for (int i = 0; i < changeIDs.size(); i += batch.length) { if (changeIDs.size() - i < batch.length) batch = new long[changeIDs.size() - i]; changeIDs.arrayCopy(i, batch, 0, batch.length); ChangeRecord[] changes = keeper.getItems(batch); for (ChangeRecord change : changes) if (change != null && (change.type.subjectType instanceof PrismsChange || impl.shouldSend(change))) itemWriter.writeChange(change, false); } jsw.endArray(); if (global) { pi.setProgressText("Exporting " + namespace + " sync records"); jsw.startProperty("syncRecords"); jsw.startArray(); for (PrismsCenter center : keeper.getCenters()) exportSyncRecords(center, keeper, jsw); jsw.endArray(); pi.setProgressText("Exporting " + namespace + " metadata"); jsw.startProperty("latestChanges"); jsw.startArray(); prisms.util.IntList allCenterIDs = new prisms.util.IntList(keeper.getAllCenterIDs()); for (int i = 0; i < allCenterIDs.size(); i++) for (int j = 0; j < allCenterIDs.size(); j++) { long changeTime = keeper.getLatestChange(allCenterIDs.get(i), allCenterIDs.get(j)); if (changeTime > 0) { jsw.startObject(); jsw.startProperty("center"); jsw.writeNumber(Integer.valueOf(allCenterIDs.get(i))); jsw.startProperty("subjectCenter"); jsw.writeNumber(Integer.valueOf(allCenterIDs.get(i))); jsw.startProperty("latestChange"); jsw.writeNumber(Long.valueOf(changeTime)); jsw.endObject(); } } jsw.endArray(); } jsw.endObject(); }