*/
protected boolean __stored_in_document = false;
/**
+ * true if Vobject was updated since the vamsas library last read a Vobj with the same VorbaId from a document.
+ */
+ protected boolean __updated_since_last_read = false;
+ /**
* memory of the last doHash() value computed for the Vobject
* @see doHash()
*/
- protected long __last_hash = 0;
+ protected int __last_hash = 0;
/**
* set by testInstanceForIdField() if Vobject should have a VorbaId
*/
protected boolean registerable = false;
-
+ protected boolean __visited = false;
/**
* reference to containing object for this Vobject.
*/
super();
testInstanceForIdField();
}
-
+ java.lang.reflect.Field ___id_field=null; // set to ease pain of reflection
/**
* set the isRegisterable flag based on the presence of a 'private String _id' field in
* the reflected class instance.
*/
private void testInstanceForIdField() {
- // look for the id field (should be an NCName string)
// TODO: decide if 'id' is an appropriate reserved attribute name for the VorbaId
- try {
- java.lang.reflect.Field fd = this.getClass().getDeclaredField("_id");
- if (String.class.isAssignableFrom(fd.getType())) {
- this.setRegisterable(true);
+ // look for the id field in all castor classes (should be an NCName string)
+
+ Class thisclass=this.getClass();
+ setRegisterable(false);
+ while (!thisclass.equals(Vobject.class)) {
+ try {
+ java.lang.reflect.Field fd = thisclass.getDeclaredField("_id");
+ if (String.class.isAssignableFrom(fd.getType())) {
+ ___id_field=fd;
+ this.setRegisterable(true);
+ break;
+ }
+ } catch (SecurityException e) {
+ log.error("Unexpected Security Exception whilst finding id fields to set!",e);
+ } catch (NoSuchFieldException e) {
+ thisclass=thisclass.getSuperclass();
}
- } catch (SecurityException e) {
- e.printStackTrace();
- } catch (NoSuchFieldException e) {
- this.setRegisterable(false);
}
}
-
+ // boolean __testedInstance=false;
/**
* update the Vobject instance's _id field, based on the contents of the
* VorbaId. Only call this if you mean to do it!
*/
protected void setInstanceIdField() {
+ /*if (!registerable && !__testedInstance) {
+ testInstanceForIdField();
+ __testedInstance=true;
+ }*/
if (registerable) {
if (__vorba != null)
try {
+ this.getClass().toString() + " (which cannot be given a vorbaId)");
}
}
+
+ protected String __getInstanceIdField() {
+ /*if (!registerable && !__testedInstance) {
+ testInstanceForIdField();
+ __testedInstance=true;
+ }*/
+ if (registerable) {
+ if (__vorba != null)
+ try {
+ Method fd = this.getClass().getMethod("getId", (Class[]) null);
+ Object idstring = fd.invoke((Object) this, (Object[]) null);
+ log.debug(this.getClass().getName()+" called getInstanceIdField!");
+ if (idstring!=null && idstring instanceof String) {
+ if (((String) idstring).length()>0)
+ return (String) idstring;
+ }
+ } catch (InvocationTargetException e) {
+ log.error("SourceGeneration of "
+ + this.getClass().toString()
+ + "\n has resulted in an inaccessible 'getId' method!\nCannot set ID from the vorbaId Vobject.", e);
+ }
+ catch (IllegalAccessException e) {
+ log.error("SourceGeneration of "
+ + this.getClass().toString()
+ + "\n has resulted in an inaccessible 'getId' method!\nCannot set ID from the vorbaId Vobject.", e);
+ } catch (SecurityException e) {
+ log.error("Security access violation for "+this.getClass().toString(),e);
+ } catch (NoSuchMethodException e) {
+ log.warn(this.getClass().toString()+" was erroneously marked as a Vorba Vobject class (Implementation error?)");
+ this.setRegisterable(false);
+ }
+ } else {
+ System.err.println("Client error. Trying to getInstanceIdField on a "
+ + this.getClass().toString() + " (which cannot be given a vorbaId)");
+ }
+ return null;
+ }
/**
* calculate a hash for the Vobject with all housekeeping fields at standard
VorbaId thisid = vorbaId;
IVorbaIdFactory factory = __vorba;
boolean stored = __stored_in_document;
+ boolean updated = __updated_since_last_read;
+ boolean visited = __visited;
+ java.lang.reflect.Field idfield = ___id_field;
+ ___id_field=null;
+ __updated_since_last_read=false;
vorbaId = null;
__vorba = null;
+ __visited=false;
+ // compute hash
__last_hash = this.hashCode();
+ // reset houseskeeping variables
+ ___id_field=idfield;
vorbaId = thisid;
__vorba = factory;
__stored_in_document = stored;
+ __updated_since_last_read=updated;
V_parent=_V_parent;
+ __visited=visited;
return (__old_hash==0) || (__old_hash == __last_hash);
}
*/
public VorbaId getVorbaId() {
if (registerable && vorbaId == null) {
+ if (this.__stored_in_document) {
+ if (__vorba!=null)
+ vorbaId=org.vamsas.client.VorbaId.newId(this.__getInstanceIdField());
+ }
// Try to use the associated factory.
if (__vorba != null)
if ((vorbaId = __vorba.makeVorbaId(this)) == null)
}
/**
+ * @return true if this object has been updated in the currently stored document since the last time a Vobject with the same ID was read from a Vamsas Document
+ */
+ public boolean is__updated_since_last_read() {
+ return __updated_since_last_read;
+ }
+
+ /**
+ * Set internal flag to indicate this object was updated since the last document read
+ * @param __updated_since_last_read the __updated_since_last_read to set
+ */
+ protected void set__updated_since_last_read(boolean __updated_since_last_read) {
+ this.__updated_since_last_read = __updated_since_last_read;
+ }
+
+ /**
* for use by Vorba agent to reflect state of vamsas Vobject to client
* application.
* Setting stored_in_document on a registerable Vobject without a
*
* @return Returns the __last_hash.
*/
- public long get__last_hash() {
+ public int get__last_hash() {
return __last_hash;
}
* TODO: FIX CYCLIC __ensure+instance_ids
* Implementation note for the todo:
* this works like a depth-first search over all vamsas objects in an vamsasDocument.
- * The doHash() function is used as the 'visited' flag -
+ * __visited is the visited flag, any Vobj who's flag is of a different parity
+ * to the visited argument will be recursed on.
+ * note - the doHash() function used to be used as the 'visited' flag -
* this *is not* a valid heuristic, although it will work "most of the time".
* TODO: LATER? Add another method for setDefaultProvenanceField (in the spirit of setInstanceIdField) using the info from the __vorba.getClient/User/Session methods
*/
protected void __ensure_instance_ids() {
+ __ensure_instance_ids(!__visited);
+ }
+ protected void __ensure_instance_ids(boolean visited) {
if (__vorba==null)
throw new Error("Improperly intialised org.vamsas.client.Vobject - no VorbaFactory given.");
log.debug("doing "+this.getClass()+".__ensure_instance_ids()");
if (!__stored_in_document && registerable)
setInstanceIdField();
- if (!doHash())
- return; // nothing has changed in this Vobject - probably visited it before.
+ if (__visited==visited)
+ return;
+ __visited=visited;
+ __vorba.updateHashValue(this);
+
Class descriptor = null;
XMLClassDescriptorImpl descimpl = null;
try {
vals[k].__vorba = __vorba; // propagate IVorbaIdFactory
if (vals[k].V_parent==null)
vals[k].V_parent=this; // propagate parent reference to this element.
- vals[k].__ensure_instance_ids();
+ vals[k].__ensure_instance_ids(visited);
}
}
}
vals[k].__vorba = __vorba; // propagate IVorbaIdFactory
if (vals[k].V_parent==null)
vals[k].V_parent=this; // propagate parent reference to this field object
- vals[k].__ensure_instance_ids();
+ vals[k].__ensure_instance_ids(visited);
}
}
catch (Exception e) {
rf.__vorba = __vorba; // propagate IVorbaIdFactory
if (rf.V_parent==null)
rf.V_parent=this; // propagate parent reference
- rf.__ensure_instance_ids();
+ rf.__ensure_instance_ids(visited);
}
}
catch (Exception e) {