import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
-import org.vamsas.objects.core.ApplicationData;
-import org.vamsas.objects.core.User;
-import org.vamsas.objects.core.VAMSAS;
-import org.vamsas.objects.core.VamsasDocument;
-import org.vamsas.objects.utils.AppDataReference;
-import org.vamsas.test.objects.Core;
import uk.ac.vamsas.client.ClientHandle;
import uk.ac.vamsas.client.IClientAppdata;
import uk.ac.vamsas.client.UserHandle;
import uk.ac.vamsas.client.Vobject;
import uk.ac.vamsas.client.VorbaId;
+import uk.ac.vamsas.objects.core.ApplicationData;
+import uk.ac.vamsas.objects.core.User;
+import uk.ac.vamsas.objects.core.VAMSAS;
+import uk.ac.vamsas.objects.core.VamsasDocument;
+import uk.ac.vamsas.objects.utils.AppDataReference;
+import uk.ac.vamsas.test.objects.Core;
/**
- * Maintains a collection of vamsas objects, appdatas and states, and provides api for a SimpleClient's client.
+ * Maintains a collection of vamsas objects, appdatas and states,
+ * and provides api for a SimpleClient's client.
+ * TODO: test and migrate ArchiveClient.getAppData methods to here and retest in ExampleApplication
* @author jimp
*/
public class ClientDocument extends uk.ac.vamsas.client.ClientDocument implements IClientDocument {
private static Log log = LogFactory.getLog(ClientDocument.class);
private VamsasDocument doc;
protected SimpleClient sclient;
- protected VamsasArchive archive = null;
+ protected VamsasArchive iohandler = null;
/**
* indicate if new data has been incorporated
*/
public boolean isModified() {
return isModified;
}
- private Vector updatedObjects=null;
/**
*
- * prepare Application-side dataset from the vamsas Document archive
+ * prepare Application-side dataset from the vamsas Document iohandler
* @param doc - the dataset
* @param docHandler - the sessionFile IO handler
* @param Factory - the source of current and new vorbaIds
/**
- * prepare Application-side dataset from the vamsas Document archive
+ * prepare Application-side dataset from the vamsas Document iohandler
*/
this.sclient = sclient;
- archive = docHandler;
+ iohandler = docHandler;
this.doc = doc;
- updatedObjects=null; /// TODO: correct this line
+ _VamsasRoots=doc.getVAMSAS();
}
/*
* internal reference to single copy of Document Roots array
*/
private VAMSAS[] _VamsasRoots=null;
- /*
+
+ protected void updateDocumentRoots() {
+ if (doc==null) {
+ log.error("updateDocumentRoots called on null document. Probably an implementation error.");
+ return;
+ }
+ if (isModified) {
+ if (_VamsasRoots!=null) {
+ doc.setVAMSAS(_VamsasRoots);
+ _VamsasRoots=null;
+ }
+ }
+ }
+/*
* (non-Javadoc)
* LATER: currently there is only one Vector of roots ever passed to client - decide if this is correct (means this is not thread safe and may behave unexpectedly)
* @see uk.ac.vamsas.client.IClientDocument#getVamsasRoots()
log.debug("Null document for getVamsasRoots(), returning null");
return null;
}
- if (archive==null) {
+ if (iohandler==null) {
// LATER: decide on read-only status of ClientDocument object
log.warn("getVamsasRoots() called on possibly read-only document.");
}
if (roots == null) {
// Make a new one to return to client to get filled.
_VamsasRoots = new VAMSAS[] { new VAMSAS() };
+ registerObject(_VamsasRoots[0]);
// Do provenance now. just in case.
doc.getProvenance().addEntry(sclient.getProvenanceEntry("Created new document root [id="+_VamsasRoots[0].getId()+"]"));
doc.addVAMSAS(_VamsasRoots[0]);
return -1;
if (docRoots==null || docRoots.length==0)
return -1;
- String r_id = root.getId();
+ VorbaId d_id=null,r_id = root.getVorbaId();
for (int i=0,j=docRoots.length; i<j; i++)
- if (docRoots[i]==root || (docRoots[i]!=null && docRoots[i].getId().equals(r_id)))
+ if (docRoots[i]==root || (docRoots[i]!=null && (d_id=docRoots[i].getVorbaId())!=null) && d_id.equals(r_id))
return i;
return -1;
}
+
/**
* verify that newr version is really an intact version of the
* @param newVersion (may be modified)
if (oldVersion==newVersion) {
// may be a virgin root element.
if (!newVersion.isRegistered())
- _registerObject(newVersion);
+ _registerObject(newVersion); // TODO: check - this call hasn't been tested.
// Should retrieve original version and compare - unless local hashes can be used to determine if resultSet has been truncated.
// just do internal validation for moment.
- if (newVersion.isValid())
+ try {
+ if (SimpleClientConfig.validateUpdatedRoots())
+ newVersion.validate();
return true;
+ }
+ catch (Exception e)
+ {
+ log.error("Validation Exception for new vamsas root :"+newVersion.getVorbaId(),e);
+ }
return false;
} else {
// redundant ? if (oldVersion.is__stored_in_document())
if (!newVersion.isRegistered())
_registerObject(newVersion);
- if (newVersion.isValid())
+ try {
+ if (SimpleClientConfig.validateMergedRoots())
+ newVersion.validate();
return true;
+ }
+ catch (Exception e)
+ {
+ log.error("Validation Exception for new vamsas root :"+newVersion.getVorbaId(),e);
+ }
}
return false;
/**
- * LATER isValidUpdate : Ideally. we efficiently walk down, comparing hashes, to deal with merging and verifying provenance for objects
+ * LATER: MUCH LATER! - not needed for simple case and this routine shouldn't live in this class anymore
+ * isValidUpdate : Ideally. we efficiently walk down, comparing hashes, to deal with merging and verifying provenance for objects
// extract root objects
if (newroots != null) {
/* (non-Javadoc)
* LATER: decide: this affects the next call to getVamsasRoots()
- * @see uk.ac.vamsas.client.IClientDocument#addVamsasRoot(org.vamsas.objects.core.VAMSAS)
+ * @see uk.ac.vamsas.client.IClientDocument#addVamsasRoot(uk.ac.vamsas.objects.core.VAMSAS)
*/
public void addVamsasRoot(VAMSAS newroot) {
if (doc==null) {
log.debug("addVamsasRoots called on null document.");
return;
}
- VAMSAS[] newroots = _combineRoots(new VAMSAS[] {newroot}, _VamsasRoots, this);
+ VAMSAS[] newroots = _combineRoots(new VAMSAS[] {newroot}, getVamsasRoots(), this);
_VamsasRoots = newroots;
}
log.warn("registerObjects called for null vamsasObjects hasharray.");
return null;
}
+ if (iohandler==null) {
+ log.warn("registerObjects called for read only document.");
+ return null;
+ }
+
if (unregistered!=null) {
VorbaId id = _registerObject(unregistered);
log.debug("Registered object - total of "+vamsasObjects.size()+" ids.");
* @see uk.ac.vamsas.client.IClientDocument#getClientAppdata()
*/
public IClientAppdata getClientAppdata() {
+ // TODO: getClientAppdata not tested in ArchiveClient mockup
+ log.error("TODO: TEST Client Appdata access methods");
if (doc==null) {
log.warn("getClientAppdata called on null document.");
return null;
* @return
*/
protected VamsasArchiveReader getVamsasArchiveReader() {
+ if (iohandler==null) {
+ log.error("Near fatal. Null VamsasArchive iohandler so can't get VamsasArchiveReader");
+ return null;
+ }
try {
- return archive.getOriginalArchiveReader();
+ log.info("TODO: test getVamsasArchiveReader");
+ return iohandler.getOriginalArchiveReader();
} catch (Exception e) {
log.warn("Unable to create OriginalArchiveReader!", e);
}
return null;
}
+ /**
+ * called by vamsas api to write updated document to session
+ * @return true if update was successful
+ * @throws java.io.IOException
+ */
protected boolean updateSessionDocument() throws java.io.IOException {
boolean docupdate = true; // 'non-serious' problems below set this false
if (doc==null) {
log.warn("updateSessionDocument called on null document.");
throw new java.io.IOException("Document is closed.");
}
- if (archive==null) {
- log.warn("updateSessionDocument called document archive handler.");
+ if (iohandler==null) {
+ log.warn("updateSessionDocument called document iohandler handler.");
throw new java.io.IOException("Document is closed.");
}
// update the VamsasDocument structure with any new appData's.
// try to update the sessionFile
log.debug("Attempting to update session "+sclient.session.getSessionUrn());
- if (scappd.isModified()) {
+ if (scappd!=null && scappd.isModified()) {
ClientHandle client = sclient.client;
UserHandle user = sclient.user;
scappd.closeForWriting();
scappd.appsGlobal.setDataReference(AppDataReference.uniqueAppDataReference(doc, sclient.client.getClientUrn()));
}
// LATER: use a switch to decide if the data should be written as a reference or as an embedded data chunk
- scappd.updateAnAppdataEntry(archive, scappd.appsGlobal, scappd.newAppData);
+ scappd.updateAnAppdataEntry(iohandler, scappd.appsGlobal, scappd.newAppData);
log.debug("...Successfully updated Global Appdata Entry.");
}
if (scappd.newUserData!=null && scappd.newUserData.sessionFile.exists()) {
}
appd.setDataReference(AppDataReference.uniqueAppDataReference(doc, sclient.client.getClientUrn()+safe_username));
}
- scappd.updateAnAppdataEntry(archive, scappd.usersData, scappd.newUserData);
+ scappd.updateAnAppdataEntry(iohandler, scappd.usersData, scappd.newUserData);
log.debug("...Successfully updated user AppData entry.");
}
}
+ try {
+ if (iohandler.transferRemainingAppDatas())
+ log.debug("Remaining appdatas were transferred.");
+ else
+ log.debug("No remaining appdatas were transferred. (Correct?)");
+ } catch (Exception e) {
+ log.error("While transferring remaining AppDatas", e);
+ }
log.debug("Updating Document...");
- // now update the document.
+ // now update the document. - this was basically the doUpdate method in test.ArchiveClient
+ updateDocumentRoots();
try {
- archive.putVamsasDocument(doc);
+ iohandler.putVamsasDocument(doc);
log.debug("Successfully written document entry.");
}
catch (Exception e) {
log.error("Marshalling error for vamsas document.",e);
docupdate = false; // pass on the (probable) object validation error
}
- if (archive.transferRemainingAppDatas())
- log.debug("Remaining appdatas were transferred.");
- else
- log.debug("No remaining appdatas were transferred. (Correct?)");
- archive.closeArchive();
+ iohandler.closeArchive();
+ iohandler=null; // so this method cannot be called again for this instance
log.debug("...successully finished and closed.");
return docupdate; // no errors ?
}
super.finalize();
}
public Vector getUpdatedObjects() {
- return updatedObjects;
+ // TODO: WALK through the document objects calling the update mechanism for each one, or just pass this vector back to client ?return updatedObjects;
+ return null;
}
}