Initial commit from SVN.

This commit is contained in:
wcrisman
2014-05-30 10:31:51 -07:00
commit b45e56b890
1968 changed files with 370949 additions and 0 deletions

View File

@@ -0,0 +1,309 @@
/*
* Copyright (c) 2005,2008 Declarative Engineering LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Declarative Engineering LLC
* verson 1 which accompanies this distribution, and is available at
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
*/
package com.foundation.common;
import com.foundation.event.*;
import com.foundation.event.model.Binding;
import com.foundation.event.model.IModelListenerAttributeHandler;
import com.foundation.event.model.IModelListenerCollectionHandler;
import com.foundation.event.model.ModelListener;
import com.foundation.metadata.Attribute;
/*
* The binding's results (the attribute values) are provided to the listener as input to other bindings.
* <p>
* Note: Attributes whose values have not yet been assigned will not be loaded (if lazy loadable). The value IModelListenerAttributeHandler.NOT_SET will be used instead.
* </p>
*/
public class AttributeBinding extends Binding {
/** This value is used in place of an attribute value if the attribute has not yet been initialized. @see IModelListenerAttributeHandler.NOT_SET */
protected static final Object NOT_SET = IModelListenerAttributeHandler.NOT_SET;
/** This flag may be passed in the constructor to indicate that the binding should force the attribute to be lazy loaded if there isn't yet a value and it is lazy loadable. */
public static final int FLAG_LAZY_LOAD_ATTRIBUTE = 0x02;
/** The attribute that this binding is using for events and values. */
private int attribute;
/** The optional handler which is notified when the attribute value changes, a new attribute value is discovered, or a previous attribute value is removed. The attribute value is discovered or removed if the object that has the attribute is added or removed to/from the model listener. */
private IModelListenerAttributeHandler attributeHandler = null;
/** The optional handlers which are notified when the attribute's value is a collection and the collection adds or removes a value. The handler is called for every value in the collection when the collection is first discovered or removed. Multiple handlers are allowed since a collection can contain other collections (in which case the first level collection calls the first level handler, etc). */
private IModelListenerCollectionHandler[] collectionHandlers = null;
protected static class AttributeEntityMetadata extends Binding.Metadata implements IEventHandler {
/** The last known value for the entity's attribute. */
private Object value = null;
/**
* AttributeEntityMetadata constructor.
* @param binding The binding that created this metadata.
* @param source The source binding that generated the entity this binding references. This may be null if the entity is a root of the listener.
* @param entity The entity the metadata describes.
*/
public AttributeEntityMetadata(Binding binding, Binding.Metadata source, IEntity entity) {
super(binding, source, entity);
}//AttributeEntityMetadata()//
/* (non-Javadoc)
* @see com.foundation.common.Binding.Metadata#getCollectionModelListener(int)
*/
protected IModelListenerCollectionHandler getCollectionModelListener(int collectionDepth) {
return null; //TODO:
}//getCollectionModelListener()//
public Object getValue() {
return value;
}//getValue()//
public void setValue(Object value) {
this.value = value;
}//setValue()//
/* (non-Javadoc)
* @see com.foundation.event.IHandler#evaluate(int, java.lang.Object[], int)
*/
public void evaluate(int eventNumber, Object[] eventParameters, int flags) {
//Never called.//
}//evaluate()//
/* (non-Javadoc)
* @see com.foundation.event.IEventHandler#evaluate(com.foundation.event.IEventEmitter, int, java.lang.Object[], int)
*/
public void evaluate(IEventEmitter eventEmitter, int eventNumber, Object[] eventParameters, int flags) {
if(EventSupport.isStandardEvent(flags) || EventSupport.isTrustedChangeEvent(flags)) {
AttributeBinding binding = (AttributeBinding) getBinding();
IEntity entity = (IEntity) getObject();
IModelListenerAttributeHandler handler = binding.getAttributeHandler();
Object newValue = entity.getAttributeSupport().getAttributeValue(binding.getAttribute());
Object oldValue = getValue();
binding.changeStarted();
//TODO: The entity (eventEmitter) has fired an event we were listening for. The attribute's value has changed.
if(handler != null) {
if((oldValue == NOT_SET) && (EventSupport.isTrustedChangeEvent(flags))) {
handler.run(getObject(handler.getReferenceType(), true), IModelListenerAttributeHandler.TYPE_INITIALIZED, 0, null, newValue);
}//if//
else {
handler.run(getObject(handler.getReferenceType(), true), IModelListenerAttributeHandler.TYPE_CHANGED, 0, oldValue, newValue);
}//else//
}//if//
//Notify the model listener of the value that is no longer in its scope.//
if((oldValue != null) && (oldValue != NOT_SET)) {
((AttributeBinding) getBinding()).valueRemoved(this, oldValue, 0);
}//if//
//Save the attribute's value so we know what the old value was when we are notified of a change.//
setValue(newValue);
//Notify the model listener of the value that is in its scope.//
if((newValue != null) && (newValue != NOT_SET)) {
((AttributeBinding) getBinding()).valueAdded(this, newValue, EventSupport.isTrustedChangeEvent(flags) ? ModelListener.INTERNAL_FLAG_INITIALIZING : 0);
}//if//
binding.changeStopped();
}//if//
}//evaluate()//
}//AttributeEntityMetadata//
/**
* Determines whether the attribute has not yet been initialized based on the flags.
* @param flags The flags from the IModelListenerAttributeHandler.
* @return Whether the attribute is not yet initialized.
*/
public static boolean isAttributeUninitialized(int flags) {
return (flags & IModelListenerAttributeHandler.FLAG_ATTRIBUTE_UNINITIALIZED) > 0;
}//isAttributeUninitialized()//
/**
* Determines whether the event is occuring while the model listener is in the process of initializing.
* @param flags The flags from the IModelListenerAttributeHandler.
* @return Whether the listener is initializing.
*/
public static boolean isListenerInitializing(int flags) {
return (flags & IModelListenerAttributeHandler.FLAG_LISTENER_INITIALIZING) > 0;
}//isListenerInitializing()//
/**
* Determines whether the event is occuring while the model listener is in the process of releasing.
* @param flags The flags from the IModelListenerAttributeHandler.
* @return Whether the listener is releasing.
*/
public static boolean isListenerReleasing(int flags) {
return (flags & IModelListenerAttributeHandler.FLAG_LISTENER_RELEASING) > 0;
}//isListenerReleasing()//
/**
* AttributeBinding constructor.
* @param entityType The type of entity that this binding applies to.
* @param attribute The attribute used by the binding.
*/
public AttributeBinding(Class entityType, int attribute) {
super(entityType, 0);
this.attribute = attribute;
}//AttributeBinding()//
/**
* AttributeBinding constructor.
* @param entityType The type of entity that this binding applies to.
* @param flags The applicable flags for this binding, or zero.
* @param attribute The attribute used by the binding.
*/
public AttributeBinding(Class entityType, int attribute, int flags) {
super(entityType, flags);
this.attribute = attribute;
}//AttributeBinding()//
/**
* AttributeBinding constructor.
* @param entityType The type of entity that this binding applies to.
* @param flags The applicable flags for this binding, or zero.
* @param attribute The attribute used by the binding.
* @param attributeHandler The optional handler which is notified when the attribute value changes, a new attribute value is discovered, or a previous attribute value is removed. The attribute value is discovered or removed if the object that has the attribute is added or removed to/from the model listener.
* @param collectionHandler The optional handlers which are notified when the attribute's value is a collection and the collection adds or removes a value. The handler is called for every value in the collection when the collection is first discovered or removed. Multiple handlers are allowed since a collection can contain other collections (in which case the first level collection calls the first level handler, etc).
*/
public AttributeBinding(Class entityType, int attribute, int flags, IModelListenerAttributeHandler attributeHandler, IModelListenerCollectionHandler[] collectionHandlers) {
super(entityType, flags);
this.attribute = attribute;
this.attributeHandler = attributeHandler;
this.collectionHandlers = collectionHandlers;
}//AttributeBinding()//
/**
* AttributeBinding constructor.
* @param entityType The type of entity that this binding applies to.
* @param attribute The attribute used by the binding.
*/
public AttributeBinding(Class entityType, Attribute attribute) {
super(entityType, 0);
this.attribute = attribute.getNumber();
}//AttributeBinding()//
/**
* AttributeBinding constructor.
* @param entityType The type of entity that this binding applies to.
* @param flags The applicable flags for this binding, or zero.
* @param attribute The attribute used by the binding.
*/
public AttributeBinding(Class entityType, Attribute attribute, int flags) {
super(entityType, flags);
this.attribute = attribute.getNumber();
}//AttributeBinding()//
/**
* AttributeBinding constructor.
* @param entityType The type of entity that this binding applies to.
* @param flags The applicable flags for this binding, or zero.
* @param attribute The attribute used by the binding.
* @param attributeHandler The optional handler which is notified when the attribute value changes, a new attribute value is discovered, or a previous attribute value is removed. The attribute value is discovered or removed if the object that has the attribute is added or removed to/from the model listener.
* @param collectionHandler The optional handlers which are notified when the attribute's value is a collection and the collection adds or removes a value. The handler is called for every value in the collection when the collection is first discovered or removed. Multiple handlers are allowed since a collection can contain other collections (in which case the first level collection calls the first level handler, etc).
*/
public AttributeBinding(Class entityType, Attribute attribute, int flags, IModelListenerAttributeHandler attributeHandler, IModelListenerCollectionHandler[] collectionHandlers) {
super(entityType, flags);
this.attribute = attribute.getNumber();
this.attributeHandler = attributeHandler;
this.collectionHandlers = collectionHandlers;
}//AttributeBinding()//
/**
* Determines whether this binding should force the lazy load to be called if the attribute is not yet initialized.
* @return Whether the lazy load should be called for the attribute if a value is not yet set.
*/
public boolean lazyLoadAttribute() {
return (getFlags() & FLAG_LAZY_LOAD_ATTRIBUTE) > 0;
}//lazyLoadAttribute()//
/**
* Gets the attribute number that this binding uses.
* @return The attribute bound by this binding.
*/
protected int getAttribute() {
return attribute;
}//getAttribute()//
/**
* Gets the optional handler that is to be called when the attribute values are changed.
* @return The handler called when an attribute's value changes, or when an object reference containing the attributes is added or removed.
*/
protected IModelListenerAttributeHandler getAttributeHandler() {
return attributeHandler;
}//getAttributeHandler()//
/**
* Gets the optional handlers called when the attribute value is a collection whose values are changed.
* @return Array of collection changed handlers used to notify if the attribute's value is a collection (or collection of collections, etc). The depth of the collection that changed is the index into this array.
*/
protected IModelListenerCollectionHandler[] getCollectionHandlers() {
return collectionHandlers;
}//getCollectionHandlers()//
/* (non-Javadoc)
* @see com.foundation.common.Binding#internalCreateMetadata(com.foundation.common.Binding.Metadata, java.lang.Object)
*/
protected Binding.Metadata internalCreateMetadata(Binding.Metadata source, Object object) {
return new AttributeEntityMetadata(this, source, (IEntity) object);
}//internalCreateMetadata()//
/* (non-Javadoc)
* @see com.foundation.event.model.Binding#internalInitialize(com.foundation.event.model.Binding.Metadata, int)
*/
protected void internalInitialize(Binding.Metadata metadata, int flags) {
AttributeEntityMetadata attributeMetadata = (AttributeEntityMetadata) metadata;
IEntity entity = (IEntity) metadata.getObject();
//Save the attribute's value so we know what the old value was when we are notified of a change.//
attributeMetadata.setValue(lazyLoadAttribute() || entity.getAttributeSupport().getIsAttributeRealized(attribute) ? entity.getAttributeSupport().getAttributeValue(attribute) : NOT_SET);
//Register the listener to the entity for its attribute's value.//
getEventSupport().register(entity, attribute, attributeMetadata, true);
//Notify the event handler that the value has been added.//
if(getAttributeHandler() != null) {
int handlerFlags = ((flags & ModelListener.INTERNAL_FLAG_INITIALIZING) > 0) ? IModelListenerAttributeHandler.FLAG_LISTENER_INITIALIZING : 0;
if(attributeMetadata.getValue() == NOT_SET) {
handlerFlags |= IModelListenerAttributeHandler.FLAG_ATTRIBUTE_UNINITIALIZED;
}//if//
getAttributeHandler().run(attributeMetadata.getObject(getAttributeHandler().getReferenceType(), true), IModelListenerAttributeHandler.TYPE_ADDED, handlerFlags, null, attributeMetadata.getValue() == NOT_SET ? null : attributeMetadata.getValue());
}//if//
//Notify the model listener of the value that is now in its scope.//
if((attributeMetadata.getValue() != null) && (attributeMetadata.getValue() != NOT_SET)) {
valueAdded(metadata, attributeMetadata.getValue(), flags);
}//if//
}//internalInitialize()//
/* (non-Javadoc)
* @see com.foundation.common.Binding#internalRelease(com.foundation.common.Binding.Metadata, int)
*/
protected void internalRelease(Binding.Metadata metadata, int flags) {
AttributeEntityMetadata attributeMetadata = (AttributeEntityMetadata) metadata;
//Unregister the listener to the entity for its attribute's value.//
getEventSupport().unregister((IEntity) metadata.getObject(), attribute, attributeMetadata);
//Notify the model listener of the value that is no longer in its scope.//
if((attributeMetadata.getValue() != null) && (attributeMetadata.getValue() != NOT_SET)) {
valueRemoved(metadata, attributeMetadata.getValue(), flags);
}//if//
//Notify the event handler that the value has been removed.//
if(getAttributeHandler() != null) {
int handlerFlags = ((flags & ModelListener.INTERNAL_FLAG_RELEASING) > 0) ? IModelListenerAttributeHandler.FLAG_LISTENER_RELEASING : 0;
if(attributeMetadata.getValue() == NOT_SET) {
handlerFlags |= IModelListenerAttributeHandler.FLAG_ATTRIBUTE_UNINITIALIZED;
}//if//
getAttributeHandler().run(attributeMetadata.getObject(getAttributeHandler().getReferenceType(), true), IModelListenerAttributeHandler.TYPE_REMOVED, handlerFlags, attributeMetadata.getValue() == NOT_SET ? null : attributeMetadata.getValue(), null);
}//if//
}//internalRelease()//
/* (non-Javadoc)
* @see com.foundation.event.model.Binding#getMetadata(java.lang.Object, com.foundation.event.model.Binding)
*/
protected Metadata getMetadata(Object value, Metadata source) {
return getMetadata(new AttributeEntityMetadata(this, source, (IEntity) value));
}//getMetadata()//
/* (non-Javadoc)
* @see com.foundation.event.model.Binding#debug(java.lang.StringBuffer, com.foundation.event.model.Binding.Metadata, int, com.foundation.event.model.ModelListener.DebugHandler)
*/
protected void debug(StringBuffer buffer, Binding.Metadata metadata, int tabDepth, ModelListener.DebugHandler handler) {
AttributeEntityMetadata attributeMetadata = (AttributeEntityMetadata) metadata;
IEntity entity = (IEntity) metadata.getObject();
for(int index = 0; index < tabDepth; index++) {
buffer.append('\t');
}//for//
buffer.append("(.");
buffer.append(entity.getAttributeName(attribute));
buffer.append(")\r\n");
//Navigate to the value's bindings.//
debug(buffer, attributeMetadata, attributeMetadata.getValue(), tabDepth + 1, handler);
}//debug()//
}//AttributeBinding//

View File

@@ -0,0 +1,42 @@
/*
* Copyright (c) 2009 Declarative Engineering LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Declarative Engineering LLC
* verson 1 which accompanies this distribution, and is available at
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
*/
package com.foundation.common;
/**
* Used to maintain a linked list of back references within entities and other containment supporting classes (such as ManagedCollection).
* Maintaining weak link back references may require multiple back references if an entity is in multiple collections marked part-of and weak in the same logical object, but the count would rarely go above one and very rarely above two, so a linked list is fairly efficient IMO.
*/
public class BackReferenceNode {
private Object reference;
private BackReferenceNode next = null;
/**
* BackReferenceNode constructor.
* @param reference The object being referenced by the node.
*/
public BackReferenceNode(Object reference) {
this.reference = reference;
}//BackReferenceNode()//
/**
* BackReferenceNode constructor.
* @param reference The object being referenced by the node.
* @param next The next node in the chain.
*/
public BackReferenceNode(Object reference, BackReferenceNode next) {
this.reference = reference;
this.next = next;
}//BackReferenceNode()//
public Object getReference() {
return reference;
}//getReference()//
public BackReferenceNode getNext() {
return next;
}//getNext()//
public void setNext(BackReferenceNode next) {
this.next = next;
}//setNext()//
}//BackReferenceNode//

View File

@@ -0,0 +1,93 @@
package com.foundation.common;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import com.common.comparison.Comparator;
import com.common.io.IExternalizable;
import com.common.io.IObjectInputStream;
import com.common.io.IObjectOutputStream;
/**
* Combines multiple attribute values together into a single key value that can be compared and serialized.
*/
public class CompositeEntityKey implements IExternalizable, Externalizable {
private Object[] values;
/**
* CompositeEntityKey constructor.
* @param values The non-null array of values that make up the key. The array must have a length > 1.
*/
public CompositeEntityKey(Object[] values) {
if(values == null || values.length < 2) {
throw new IllegalArgumentException();
}//if//
this.values = values;
}//CompositeEntityKey()//
/**
* Gets the part of the key with the given index.
* @param index The zero based index of the key part.
* @return The key part.
*/
public Object getPart(int index) {
return values[index];
}//getPart()//
/**
* Gets the count of parts in the key.
* @return The part count.
*/
public int getPartCount() {
return values.length;
}//getPartCount()//
/* (non-Javadoc)
* @see java.lang.Object#hashCode()
*/
public int hashCode() {
int result = 0;
for(int index = 0; index < values.length; index++) {
result ^= values[index].hashCode();
}//for//
return result;
}//hashCode()//
/* (non-Javadoc)
* @see java.lang.Object#equals(java.lang.Object)
*/
public boolean equals(Object object) {
boolean result = object instanceof CompositeEntityKey && ((CompositeEntityKey) object).values.length == values.length;
for(int index = 0; result && index < values.length; index++) {
result = Comparator.equals(values[index], ((CompositeEntityKey) object).values[index]);
}//for//
return result;
}//equals()//
/* (non-Javadoc)
* @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
*/
public void writeExternal(ObjectOutput out) throws IOException {
out.writeObject(values);
}//writeExternal()//
/* (non-Javadoc)
* @see java.io.Externalizable#readExternal(java.io.ObjectInput)
*/
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
values = (Object[]) in.readObject();
}//readExternal()//
/* (non-Javadoc)
* @see com.common.io.IExternalizable#writeExternal(com.common.io.IObjectOutputStream)
*/
public void writeExternal(IObjectOutputStream out) throws IOException {
out.writeObject(values);
}//writeExternal()//
/* (non-Javadoc)
* @see com.common.io.IExternalizable#readExternal(com.common.io.IObjectInputStream)
*/
public Object readExternal(IObjectInputStream in) throws IOException, ClassNotFoundException {
values = (Object[]) in.readObject();
return null;
}//readExternal()//
}//CompositeEntityKey//

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,183 @@
/*
* Copyright (c) 2006,2008 Declarative Engineering LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Declarative Engineering LLC
* verson 1 which accompanies this distribution, and is available at
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
*/
package com.foundation.common;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import com.common.io.IObjectInputStream;
import com.common.io.IObjectOutputStream;
import com.common.util.IList;
import com.common.util.optimized.IIntIterator;
import com.common.util.optimized.IntHashSet;
import com.foundation.metadata.Attribute;
import com.foundation.metadata.MetadataService;
import com.foundation.metadata.TypeMetadata;
/*
* This type metadata defines a collection of attributes for a class.
* This metadata may be used in many places, the most common are for defining which attributes of a class to reflect by default, and which attributes to clone when calling IEntity.cloneObject().
* <p><b>This is an immutable object.</b></p>
* <p>TODO: Protect the attribute's int array somehow. We could switch to an IntArray and add an immutable flag to the object.</p>
*/
public class EntityMetadata implements IMetadata {
/** The class of IEntity the metadata applies to. */
private Class type = null;
/** The attributes of the IEntity that are to be included. */
private IntHashSet attributes = null;
/**
* EntityMetadata constructor.
*/
public EntityMetadata() {
super();
}//EntityMetadata()//
/**
* EntityMetadata constructor.
* @param type The entity class that the metadata applies to.
* @param attributes The attributes that will be included or excluded.
* @param inclusive Whether the given attributes are to be included. If false, the metadata user will exclude the attributes passed and include all other attributtes for the type passed, (any attributes not explicitly excluded).
*/
public EntityMetadata(Class type, int[] attributes, boolean inclusive) {
super();
if(!IEntity.class.isAssignableFrom(type) || attributes == null) {
throw new IllegalArgumentException();
}//if//
this.type = type;
//Convert the exclusive attributes array into an inclusive one.//
if(!inclusive) {
TypeMetadata metadata = MetadataService.getSingleton().getTypeMetadata(type);
int totalCount = metadata.getLastAttributeNumber();
IntHashSet attributesSet = new IntHashSet(attributes, false);
this.attributes = new IntHashSet(totalCount - attributes.length);
for(int index = 0; index <= totalCount; index++) {
if(!attributesSet.containsValue(index)) {
this.attributes.add(index);
}//if//
}//for//
}//if//
else {
this.attributes = new IntHashSet(attributes, false);
}//else//
}//EntityMetadata()//
/**
* EntityMetadata constructor.
* @param type The entity class that the metadata applies to.
* @param attributes The attributes that will be included or excluded.
* @param inclusive Whether the given attributes are to be included. If false, the metadata user will exclude the attributes passed and include all other attributtes for the type passed, (any attributes not explicitly excluded).
*/
public EntityMetadata(Class type, Attribute[] attributes, boolean inclusive) {
super();
if(!IEntity.class.isAssignableFrom(type) || attributes == null) {
throw new IllegalArgumentException();
}//if//
this.type = type;
//Convert the exclusive attributes array into an inclusive one.//
if(!inclusive) {
TypeMetadata metadata = MetadataService.getSingleton().getTypeMetadata(type);
int totalCount = metadata.getLastAttributeNumber();
IntHashSet attributesSet = new IntHashSet(Attribute.convert(attributes), false);
this.attributes = new IntHashSet(totalCount - attributes.length);
for(int index = 0; index <= totalCount; index++) {
if(!attributesSet.containsValue(index)) {
this.attributes.add(index);
}//if//
}//for//
}//if//
else {
this.attributes = new IntHashSet(Attribute.convert(attributes), false);
}//else//
}//EntityMetadata()//
/* (non-Javadoc)
* @see com.foundation.common.IMetadata#getType()
*/
public Class getType() {
return type;
}//getType()//
/**
* Gets the attributes of the IEntity that are to be included.
* @return The collection of attributes that make up the metadata.
*/
public IntHashSet getAttributes() {
return attributes;
}//getAttributes()//
/* (non-Javadoc)
* @see com.common.io.IExternalizable#readExternal(com.common.io.IObjectInputStream)
*/
public Object readExternal(IObjectInputStream in) throws IOException, ClassNotFoundException {
TypeMetadata metadata = MetadataService.getSingleton().getTypeMetadata(type);
int count = 0;
/*byte version = */in.readByte();
type = (Class) in.readObject();
count = in.readInt();
attributes = new IntHashSet(count);
for(int index = 0; index < count; index++) {
attributes.add(metadata.getAttributeNumber(in.readUTF()));
}//for//
return null;
}//readExternal()//
/* (non-Javadoc)
* @see java.io.Externalizable#readExternal(java.io.ObjectInput)
*/
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
TypeMetadata metadata = MetadataService.getSingleton().getTypeMetadata(type);
int count = 0;
/*byte version = */in.readByte();
type = (Class) in.readObject();
count = in.readInt();
attributes = new IntHashSet(count);
for(int index = 0; index < count; index++) {
attributes.add(metadata.getAttributeNumber(in.readUTF()));
}//for//
}//readExternal()//
/* (non-Javadoc)
* @see com.common.io.IExternalizable#writeExternal(com.common.io.IObjectOutputStream)
*/
public void writeExternal(IObjectOutputStream out) throws IOException {
IList attributeNames = MetadataService.getSingleton().getTypeMetadata(type).getAttributeNames();
IIntIterator iterator = attributes.iterator();
out.writeByte(0);
out.writeObject(type);
out.writeInt(attributes.getSize());
while(iterator.hasNext()) {
out.writeUTF((String) attributeNames.get(iterator.next()));
}//while//
}//writeExternal()//
/* (non-Javadoc)
* @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
*/
public void writeExternal(ObjectOutput out) throws IOException {
IList attributeNames = MetadataService.getSingleton().getTypeMetadata(type).getAttributeNames();
IIntIterator iterator = attributes.iterator();
out.writeByte(0);
out.writeObject(type);
out.writeInt(attributes.getSize());
while(iterator.hasNext()) {
out.writeUTF((String) attributeNames.get(iterator.next()));
}//while//
}//writeExternal()//
}//TypeMetadata//

View File

@@ -0,0 +1,288 @@
/*
* Copyright (c) 2002,2009 Declarative Engineering LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Declarative Engineering LLC
* verson 1 which accompanies this distribution, and is available at
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
*/
package com.foundation.common;
import java.io.Externalizable;
import com.common.comparison.*;
import com.common.io.IExternalizable;
import com.foundation.attribute.AttributeSupport;
import com.foundation.attribute.IReflectableObject;
import com.foundation.application.IApplication;
import com.foundation.event.*;
import com.foundation.event.model.IModelListenerAttributeHandler;
import com.foundation.event.model.IModelListenerCollectionHandler;
import com.foundation.metadata.Attribute;
import com.foundation.metadata.Event;
import com.foundation.transaction.TransactionContextHolder;
import com.foundation.transaction.TransactionErrorInfo;
import com.foundation.transaction.Transaction;
import com.foundation.transaction.TransactionService;
public interface IEntity extends IReflectableObject, IEventListener, IEventEmitter, IComparable, IExternalizable, Externalizable {
public static final Event VIRTUAL_OBJECT_CHANGED = AttributeSupport.registerEvent(IEntity.class, "virtualObjectChanged");
/**
* This interface is to be passed to the calculatedAttributeRegister method so the framework can capture when calculated attributes require updating.
*/
public static interface ICalculatedAttributeListener extends IModelListenerCollectionHandler, IModelListenerAttributeHandler {
}//ICalculatedAttributeListener//
/** Indicates that no error occured in the model. Check for a transaction error code. */
public static final int MODEL_ERROR_NONE = 0;
/** An unexpected model error occured. */
public static final int MODEL_ERROR_UNKOWN_ERROR = 1;
/** The model version in memory did not match the version of the data in the repository. An update of the in memory model must be performed, and the synchronizing code must wait for updates. */
public static final int MODEL_ERROR_BAD_VERSION = 2;
/** Preparations for the transaction failed. */
public static final int MODEL_ERROR_FAILED_PREPERATIONS = 3;
/** The model's key could not be created. This almost always is due to failing to mark the proper attributes in the entity(s) as key using IEntity.AO_KEY. */
public static final int MODEL_ERROR_KEY_CREATION_FAILED = 4;
/** The identifier for the reusable object returned from a transaction where the entity's repository version didn't match the instance's version (requiring updates from the repository before commiting any changes). */
public static final TransactionErrorInfo ENTITY_TRANSACTION_BAD_VERSION = new TransactionErrorInfo(Transaction.ERROR_NONE, MODEL_ERROR_BAD_VERSION);
/** The identifier for the reusable object returned from a failed transation where failure was due to transaction preparations (not in the actual transaction code). */
public static final TransactionErrorInfo ENTITY_TRANSACTION_FAILED_PREPERATIONS = new TransactionErrorInfo(Transaction.ERROR_NONE, MODEL_ERROR_FAILED_PREPERATIONS);
/** The identifier for the reusable object returned from a failed transation where the failure reason due to a problem commiting the transaction. */
public static final TransactionErrorInfo ENTITY_TRANSACTION_COMMIT_FAILED = new TransactionErrorInfo(Transaction.ERROR_COMMIT_FAILED, MODEL_ERROR_NONE);
/** The identifier for the reusable object returned from a failed transation where the failure reason is unknown. */
public static final TransactionErrorInfo ENTITY_TRANSACTION_UNKOWN_ERROR = new TransactionErrorInfo(Transaction.ERROR_NONE, MODEL_ERROR_UNKOWN_ERROR);
/**
* Gets the application object that this object is running under. The application object provides the object various services that it will need.
* @return The application reference for the application this object is running under.
*/
public IApplication getApplication();
/**
* Gets the support object for the entity's attributes.
* @return The attribute support object for the entity.
*/
public AttributeSupport getAttributeSupport();
/**
* Gets a key object for this entity instance that is serializeable and hashable. It is recommended that this be used infrequently if possible to avoid excessive overhead since keys are not retained by the entity.
* @return The serializable & hashable & comparable (equality only) object that represents this entity.
*/
public Object entityGetKey();
/**
* Sets a key object for this entity instance. This fills in the key attributes. This call will fail if any attributes have been set for the instance.
* @param key The serializable & hashable & comparable (equality only) object that represents this entity.
*/
public void entitySetKey(Object key);
/**
* Gets the number of attributes this entity has declared.
* @return The count of entity attributes.
*/
public int getAttributeCount();
/**
* Gets the name of the attribute associated with the given attribute number.
* <p>This method allows the application easy access to the entity's attribute names using the attribute identifiers.
* <code>
* ((IEntity) object).getAttributeName(MyEntity.MY_ATTRIBUTE);
* </code>
* @param attributeNumber The number that was assigned to the desired attribute.
* @return The name of the attribute.
*/
public String getAttributeName(int attributeNumber);
/**
* Gets the pre-change value for the attribute. This will be null if the attribute has not been changed since last clearing the change flags.
* <p>Note: This method can be perticularly useful when synchronizing changes to a repository. The old value may often need to be explicitly deleted from the repository.</p>
* @param attributeNumber The unique (for this type hierarchy) number that identifies the attribute.
* @return The original value assigned to the attribute, or the value at the time of the last change flag reset.
* @see #getIsAttributeChanged(int)
*/
public Object getOldAttributeValue(Attribute attribute);
/**
* Determines whether the object is bound (via metadata) to a repository.
* @return Whether the object has repository metadata and thus can be stored/retreived to/from a repository.
*/
public boolean isObjectRepositoryBound();
/**
* Determines whether the object is not yet stored in a repository.
* @return Whether the object has not yet been persisted. This is true if the object was created and not read from a repostiory, or if it has not yet been placed in a repository.
*/
public boolean isObjectNew();
/**
* Determines whether any of the object's attributes have been changed since the last time the change flags were reset.
* @return Whether any attribute has been given a new value (including null).
*/
public boolean getIsObjectChanged();
/**
* Determines whether any of the object's attributes or any attributes of any part-of objects (recursive) have been changed since the last time the change flags were reset.
* @return Whether any attribute or any part-of object's attribute has been given a new value (including null).
*/
public boolean getIsVirtualObjectChanged();
/**
* Resets all the change flags.
*/
public void resetObjectChangeFlags();
/**
* Resets all the change flags in this object and all part-of objects.
*/
public void resetVirtualObjectChangeFlags();
/**
* Undoes all changes made to this object since the last time the change flags were reset, or the object was successfully updated in the repository.
*/
public void reverseObjectChanges();
/**
* Undoes all changes made to this object since the last time the change flags were reset, or the object was successfully updated in the repository.
*/
public void reverseVirtualObjectChanges();
/**
* Gets whether the object has been altered in some way.
* <p>
* The altered flag errors on the side of false positives with no possibility of a false negative.
* The intended use of the altered flag is to improve validation efficiency.
* </p>
*/
public boolean getIsAltered();
/**
* Gets whether the virtual object has been altered in some way.
* <p>
* The altered flag errors on the side of false positives with no possibility of a false negative.
* The intended use of the altered flag is to improve validation efficiency.
* </p>
*/
public boolean getIsVirtualObjectAltered();
/**
* Resets the altered flag which is used to identify when the object may have been altered.
* <p>
* The altered flag errors on the side of false positives with no possibility of a false negative.
* The intended use of the altered flag is to improve validation efficiency.
* </p>
*/
public void resetAlteredFlag();
/**
* Resets the virtual object's altered flag which is used to identify when the virtual object may have been altered.
* <p>
* The altered flag errors on the side of false positives with no possibility of a false negative.
* The intended use of the altered flag is to improve validation efficiency.
* </p>
*/
public void resetVirtualObjectAlteredFlags();
/**
* Gets the entity the entity is part of.
* @return The entity that this entity is a part of. This may be null.
*/
public IEntity getPartOfEntity();
/**
* Gets the count of times the part-of entity has been set to the current value.
* @return The counter for setting the part of entity.
*/
public int getPartOfEntityCounter();
/**
* Gets the entities' transaction service servicing the application this entity belongs to.
* @return The transaction service that can field requests by this entity.
*/
public TransactionService getTransactionService();
/**
* Gets the repository identifier used for this entity.
* @return The identifier for the repository the entity was read from, or the default repository for this class.
*/
public Object getRepositoryIdentifier();
/**
* Gets the repository identifier used for this entity.
* @param defaultRepositoryIdentifier The repository identifier to use if the entity isn't already in a repository. If this is null then the application's default repository identifier will be used.
* @return The identifier for the repository the entity was read from, or the default repository for this class.
*/
public Object getRepositoryIdentifier(Object defaultRepositoryIdentifier);
/**
* Updates the default repository with the latest entity data for the entire logical object.
* <p>This method may be called if the entity is not in the repository (it was not read from the repository before being edited), or when the entity was read from the repository and then subsiqently edited.</p>
* <p><b>This method may only be used to perform single instance updates in the repository.</b></p>
* <p><b>It is the caller's responsibility to lock this object's monitor before calling this method.</b></p>
* @return The result of the operation. A null value indicates success. The method will report success if the transaction was unnecessary.
*/
public TransactionErrorInfo entityUpdate();
/**
* Updates the default repository with the latest entity data for the entire logical object.
* <p>This method may be called if the entity is not in the repository (it was not read from the repository before being edited), or when the entity was read from the repository and then subsiqently edited.</p>
* <p><b>This method may only be used to perform single instance updates in the repository.</b></p>
* <p><b>It is the caller's responsibility to lock this object's monitor before calling this method.</b></p>
* @param debugLevel The TransactionService.DEBUG_xxx identifier specifying the level of debugging for the transaction. This may be -1 to use the default value in the TransactionService.
* @return The result of the operation. A null value indicates success. The method will report success if the transaction was unnecessary.
*/
public TransactionErrorInfo entityUpdate(int debugLevel);
/**
* Updates the default repository with the latest entity data for the entire logical object.
* <p>This method may be called if the entity is not in the repository (it was not read from the repository before being edited), or when the entity was read from the repository and then subsiqently edited.</p>
* <p><b>This method may only be used to perform single instance updates in the repository.</b></p>
* <p><b>It is the caller's responsibility to lock this object's monitor before calling this method.</b></p>
* @param updateTask The update task to be run after starting a transaction and validating & locking the version via the repository (if the logical object is bound to a repository that defines version metadata).
* @return The result of the operation. A null value indicates success. The method will report success if the transaction was unnecessary.
*/
public TransactionErrorInfo entityUpdate(Runnable updateTask);
/**
* Updates the default repository with the latest entity data for the entire logical object.
* <p>This method may be called if the entity is not in the repository (it was not read from the repository before being edited), or when the entity was read from the repository and then subsiqently edited.</p>
* <p><b>This method may only be used to perform single instance updates in the repository.</b></p>
* <p><b>It is the caller's responsibility to lock this object's monitor before calling this method.</b></p>
* @param updateTask The update task to be run after starting a transaction and validating & locking the version via the repository (if the logical object is bound to a repository that defines version metadata).
* @param debugLevel The TransactionService.DEBUG_xxx identifier specifying the level of debugging for the transaction. This may be -1 to use the default value in the TransactionService.
* @return The result of the operation. A null value indicates success. The method will report success if the transaction was unnecessary.
*/
public TransactionErrorInfo entityUpdate(Runnable updateTask, int debugLevel);
/**
* Updates the default repository with the latest entity data for the entire logical object.
* <p>Note: This is a method to override for custom processing of repository updates (for example sending the object to a file).</p>
* <p>TODO: Support part of a logical object existing in a different repository from the rest of the logical object.</p>
* <p>This method may be called if the entity is not in the repository (it was not read from the repository before being edited), or when the entity was read from the repository and then subsiqently edited.</p>
* <p><b>This method may only be used to perform single instance updates in the repository.</b></p>
* <p><b>It is the caller's responsibility to lock this object's monitor before calling this method.</b></p>
* @param updateTask The update task to be run after starting a transaction and validating & locking the version via the repository (if the logical object is bound to a repository that defines version metadata).
* @param defaultRepositoryIdentifier The identifier for the repository to use if none of the logical object is in a repository already.
* @return The result of the operation. A null value indicates success. The method will report success if the transaction was unnecessary.
*/
public TransactionErrorInfo entityUpdate(Runnable updateTask, Object defaultRepositoryIdentifier);
/**
* Updates the default repository with the latest entity data for the entire logical object.
* <p>Note: This is a method to override for custom processing of repository updates (for example sending the object to a file).</p>
* <p>TODO: Support part of a logical object existing in a different repository from the rest of the logical object.</p>
* <p>This method may be called if the entity is not in the repository (it was not read from the repository before being edited), or when the entity was read from the repository and then subsiqently edited.</p>
* <p><b>This method may only be used to perform single instance updates in the repository.</b></p>
* <p><b>It is the caller's responsibility to lock this object's monitor before calling this method.</b></p>
* @param updateTask The update task to be run after starting a transaction and validating & locking the version via the repository (if the logical object is bound to a repository that defines version metadata).
* @param defaultRepositoryIdentifier The identifier for the repository to use if none of the logical object is in a repository already.
* @param debugLevel The TransactionService.DEBUG_xxx identifier specifying the level of debugging for the transaction. This may be -1 to use the default value in the TransactionService.
* @return The result of the operation. A null value indicates success. The method will report success if the transaction was unnecessary.
*/
public TransactionErrorInfo entityUpdate(Runnable updateTask, Object defaultRepositoryIdentifier, int debugLevel);
/**
* Updates the default repository with the latest entity data.
* <p>This method may be called if the entity is not in the repository (it was not read from the repository before being edited), or when the entity was read from the repository and then subsiqently edited.</p>
* <p><b>This method may only be used to perform single instance updates in the repository.</b></p>
* @param context The transactional context within which the update is occuring. All repository interactions must be through this context so that they can roll back or commit as one unit.
* @return The result of the operation. A null value indicates success. The method will report success if the transaction was unnecessary.
*/
public TransactionErrorInfo entityUpdate(TransactionContextHolder context);
/**
* Deletes the object in the default repository.
* <p><b>This method may only be used to perform single instance deletions in the repository.</b></p>
* <p><b>It is the caller's responsibility to lock this object's monitor before calling this method.</b></p>
* @return The result of the operation. A null value indicates success. The method will report success if the transaction was unnecessary.
*/
public TransactionErrorInfo entityDelete();
/**
* Deletes the object in the default repository.
* <p><b>This method may only be used to perform single instance deletions in the repository.</b></p>
* <p><b>It is the caller's responsibility to lock this object's monitor before calling this method.</b></p>
* @param debugLevel The TransactionService.DEBUG_xxx identifier specifying the level of debugging for the transaction. This may be -1 to use the default value in the TransactionService.
* @return The result of the operation. A null value indicates success. The method will report success if the transaction was unnecessary.
*/
public TransactionErrorInfo entityDelete(int debugLevel);
/**
* Deletes the object in the default repository.
* <p><b>This method may only be used to perform single instance deletions in the repository.</b></p>
* @param context The transactional context within which the delete is occuring. All repository interactions must be through this context so that they can roll back or commit as one unit.
* @return The result of the operation. A null value indicates success. The method will report success if the transaction was unnecessary.
*/
public TransactionErrorInfo entityDelete(TransactionContextHolder context);
/**
* Determines whether the model should use repository version tracking which allows multiple instances of the same model to exist since the repository will perform the version tracking instead of the model instance.
* @return Whether the model instance defers the version tracking to the repository. This is setup in the repository/model mapping metadata defined by the application.
*/
public boolean useRepositoryVersionTracking();
}//IEntity//

View File

@@ -0,0 +1,22 @@
/*
* Copyright (c) 2006,2009 Declarative Engineering LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Declarative Engineering LLC
* verson 1 which accompanies this distribution, and is available at
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
*/
package com.foundation.common;
import java.io.Externalizable;
import com.common.io.IExternalizable;
/**
* This interface is used by the EntityMetadata and future metadata types that can be passed around to specify what data is required in different situations.
*/
public interface IMetadata extends IExternalizable, Externalizable {
/**
* The class of object for which this metadata can be used.
* @return The metadata type mapping.
*/
public Class getType();
}//IMetadata//

View File

@@ -0,0 +1,100 @@
/*
* Copyright (c) 2006,2009 Declarative Engineering LLC.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Declarative Engineering LLC
* verson 1 which accompanies this distribution, and is available at
* http://declarativeengineering.com/legal/DE_Developer_License_v1.txt
*/
package com.foundation.common;
import java.io.Externalizable;
import java.io.IOException;
import java.io.ObjectInput;
import java.io.ObjectOutput;
import com.common.comparison.Comparator;
import com.common.io.IExternalizable;
import com.common.io.IObjectInputStream;
import com.common.io.IObjectOutputStream;
import com.common.util.LiteHashMap;
/*
* This container is used to pass information about what to include or exclude when performing such operations as cloning models.
*/
public class MetadataContainer implements IExternalizable, Externalizable {
/** Tells the user of the metadata to not include any reflections. */
public static final int FLAG_EXCLUDE_REFLECTIONS = 1;
private LiteHashMap metadataByTypeMap = new LiteHashMap(10, Comparator.getLogicalComparator(), null);
private int flags = 0;
/**
* MetadataContainer constructor.
*/
public MetadataContainer() {
super();
}//MetadataContainer()//
/**
* MetadataContainer constructor.
* @param flags One or more of the flag identifiers defined by this class.
*/
public MetadataContainer(int flags) {
super();
this.flags = flags;
}//MetadataContainer()//
/**
* MetadataContainer constructor.
* @param metadata The set of metadata instances, one for each type for which metadata is provided. The type must match exactly with the object whose metadata is being searched for (ie: type hierarchy is not considered).
*/
public MetadataContainer(IMetadata[] metadata) {
super();
for(int index = 0; index < metadata.length; index++) {
metadataByTypeMap.put(metadata[index].getType(), metadata[index]);
}//for//
}//MetadataContainer()//
/**
* Gets the metadata for the given type.
* @param type The type whose metadata is to be retreived.
* @return The metadata for that exact type, or null if none was specified.
*/
public IMetadata getMetadata(Class type) {
return (IMetadata) metadataByTypeMap.get(type);
}//getMetadata()//
/**
* Determines whether reflections should be excluded based on the flags passed to this metadata container.
* @return Whether reflections should be excluded.
*/
public boolean excludeReflections() {
return (flags & FLAG_EXCLUDE_REFLECTIONS) > 0;
}//excludeReflections()//
/* (non-Javadoc)
* @see com.common.io.IExternalizable#writeExternal(com.common.io.IObjectOutputStream)
*/
public void writeExternal(IObjectOutputStream out) throws IOException {
out.writeByte(0);
out.writeObject(metadataByTypeMap);
}//writeExternal()//
/* (non-Javadoc)
* @see java.io.Externalizable#writeExternal(java.io.ObjectOutput)
*/
public void writeExternal(ObjectOutput out) throws IOException {
out.writeByte(0);
out.writeObject(metadataByTypeMap);
}//writeExternal()//
/* (non-Javadoc)
* @see com.common.io.IExternalizable#readExternal(com.common.io.IObjectInputStream)
*/
public Object readExternal(IObjectInputStream in) throws IOException, ClassNotFoundException {
/*byte version = */in.readByte();
metadataByTypeMap = (LiteHashMap) in.readObject();
return null;
}//readExternal()//
/* (non-Javadoc)
* @see java.io.Externalizable#readExternal(java.io.ObjectInput)
*/
public void readExternal(ObjectInput in) throws IOException, ClassNotFoundException {
/*byte version = */in.readByte();
metadataByTypeMap = (LiteHashMap) in.readObject();
}//readExternal()//
}//MetadataContainer//