/** * The contents of this file are subject to the OpenMRS Public License * Version 1.0 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://license.openmrs.org * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations * under the License. * * Copyright (C) OpenMRS, LLC. All Rights Reserved. */ package org.openmrs.module.sync.ingest; import java.io.Serializable; import java.util.ArrayList; import java.util.Date; import java.util.List; import org.openmrs.module.sync.SyncRecord; import org.openmrs.module.sync.SyncRecordState; import org.openmrs.module.sync.serialization.IItem; import org.openmrs.module.sync.serialization.Item; import org.openmrs.module.sync.serialization.Record; import org.openmrs.module.sync.serialization.TimestampNormalizer; import org.openmrs.module.sync.server.RemoteServer; import org.springframework.util.StringUtils; /** * {@link SyncImportRecord}s are kept on this server for every transactional unit that comes into * the server. <br/> * <br/> * This class is created as soon as information arrives from another server. This table/class is the * first place sync looks to know whether something has already come in or not. <br/> * <br/> {@link SyncImportRecord#uuid} is the {@link SyncRecord#getUuid()} on the remote server for the * record. That remote server can be either a parent or child to this current server. */ public class SyncImportRecord implements Serializable, IItem { public static final long serialVersionUID = 0L; // Fields private Integer importId; private String uuid = null; private String creator = null; private String databaseVersion = null; private Date timestamp = null; private int retryCount; private SyncRecordState state = SyncRecordState.NEW; private String errorMessage; private List<SyncImportItem> items = null; private RemoteServer sourceServer; // convenience string describing the content of this import record private transient String description = null; // Constructors /** default constructor */ public SyncImportRecord() { } public SyncImportRecord(SyncRecord record) { if (record != null) { // the uuid should be set to original uuid - this way all subsequent attempts to execute this change are matched to this import this.uuid = record.getOriginalUuid(); this.creator = record.getCreator(); this.databaseVersion = record.getDatabaseVersion(); this.timestamp = record.getTimestamp(); this.retryCount = record.getRetryCount(); this.state = record.getState(); if (StringUtils.hasLength(record.getContainedClasses())) { this.description = record.getContainedClasses().split(",")[0]; } } } public Integer getImportId() { return importId; } public void setImportId(Integer importId) { this.importId = importId; } // Properties // globally unique id of the record public String getUuid() { return uuid; } public void setUuid(String uuid) { this.uuid = uuid; } // The uuid of the creator of the record public String getCreator() { return creator; } public void setCreator(String creator) { this.creator = creator; } // The database version used when creating this record public String getDatabaseVersion() { return databaseVersion; } public void setDatabaseVersion(String databaseVersion) { this.databaseVersion = databaseVersion; } // timestamp of last operation public Date getTimestamp() { return timestamp; } public void setTimestamp(Date timestamp) { this.timestamp = timestamp; } // retry count public int getRetryCount() { return retryCount; } public void setRetryCount(int retryCount) { this.retryCount = retryCount; } //state public SyncRecordState getState() { return state; } public void setState(SyncRecordState state) { this.state = state; } @Override public boolean equals(Object o) { if (!(o instanceof SyncImportRecord) || o == null) return false; SyncImportRecord oSync = (SyncImportRecord) o; boolean same = ((oSync.getTimestamp() == null) ? (this.getTimestamp() == null) : oSync.getTimestamp().equals( this.getTimestamp())) && ((oSync.getUuid() == null) ? (this.getUuid() == null) : oSync.getUuid().equals(this.getUuid())) && ((oSync.getState() == null) ? (this.getState() == null) : oSync.getState().equals(this.getState())) && (oSync.getRetryCount() == this.getRetryCount()); return same; } public Item save(Record xml, Item parent) throws Exception { Item me = xml.createItem(parent, this.getClass().getName()); //serialize primitives xml.setAttribute(me, "uuid", this.uuid); xml.setAttribute(me, "retryCount", Integer.toString(this.retryCount)); xml.setAttribute(me, "state", this.state.toString()); if (timestamp != null) { xml.setAttribute(me, "timestamp", new TimestampNormalizer().toString(timestamp)); } // serialize error message if (StringUtils.hasText(errorMessage)) { Item errorMessageItem = xml.createItem(me, "errorMessage"); xml.createTextAsCDATA(errorMessageItem, errorMessage); } //serialize items list Item itemsCollection = xml.createItem(me, "items"); if (this.items != null) { me.setAttribute("itemCount", Integer.toString(this.items.size())); for (SyncImportItem importItem : this.items) { importItem.save(xml, itemsCollection); } } return me; } public void load(Record xml, Item me) throws Exception { //deserialize primitives this.uuid = me.getAttribute("uuid"); this.retryCount = Integer.parseInt(me.getAttribute("retryCount")); this.state = SyncRecordState.valueOf(me.getAttribute("state")); if (me.getAttribute("timestamp") == null) this.timestamp = null; else { this.timestamp = (Date) new TimestampNormalizer().fromString(Date.class, me.getAttribute("timestamp")); } Item errorMessageItem = xml.getItem(me, "errorMessage"); if (errorMessageItem != null) this.errorMessage = errorMessageItem.getText(); //now get items Item itemsCollection = xml.getItem(me, "items"); if (itemsCollection.isEmpty()) { this.items = null; } else { this.items = new ArrayList<SyncImportItem>(); List<Item> serItems = xml.getItems(itemsCollection); for (int i = 0; i < serItems.size(); i++) { Item serItem = serItems.get(i); SyncImportItem syncImportItem = new SyncImportItem(); syncImportItem.load(xml, serItem); this.addItem(syncImportItem); } } } public String getErrorMessage() { return errorMessage; } public void setErrorMessage(String errorMessage) { this.errorMessage = errorMessage; } @Override public String toString() { // TODO Auto-generated method stub return "SyncRecord (uuid:" + this.uuid + ") - " + this.state; } public List<SyncImportItem> getItems() { return items; } public void setItems(List<SyncImportItem> items) { this.items = items; } public void addItem(SyncImportItem item) { if (this.items == null) this.items = new ArrayList<SyncImportItem>(); this.items.add(item); } /** * @return the contained type of this import or the first uuid if no description is set */ public String getDescription() { if (description != null) return description; else return uuid; } /** * @return the sourceServer */ public RemoteServer getSourceServer() { return sourceServer; } /** * @param sourceServer the sourceServer to set */ public void setSourceServer(RemoteServer sourceServer) { this.sourceServer = sourceServer; } }