package ecologylab.serialization; import java.util.HashMap; import java.util.Stack; import ecologylab.generic.Debug; import ecologylab.serialization.deserializers.ISimplDeserializationIn; import ecologylab.serialization.deserializers.ISimplDeserializationPost; import ecologylab.serialization.deserializers.ISimplDeserializationPre; import ecologylab.serialization.serializers.ISimplSerializationPost; import ecologylab.serialization.serializers.ISimplSerializationPre; public class ElementState<PES extends ElementState> extends Debug implements FieldTypes, XMLTranslationExceptionTypes, ISimplSerializationPre, ISimplSerializationPost, ISimplDeserializationPre, ISimplDeserializationPost, ISimplDeserializationIn { private boolean isRoot = false; /** * Link for a DOM tree. should be removed */ transient PES parent; /** * to handle objects with multiple parents this variable helps keep track of parents in * deserializing graph */ Stack<PES> parents = null; /** * Use for resolving getElementById() */ transient HashMap<String, ElementState> elementByIdMap; transient HashMap<String, ElementState> nestedNameSpaces; static protected final int ESTIMATE_CHARS_PER_FIELD = 80; /** * Just-in time look-up tables to make translation be efficient. Allocated on a per class basis. */ transient private ClassDescriptor classDescriptor; /** * Construct. Create a link to a root optimizations object. */ public ElementState() { } public TranslationContext createGraphContext() throws SIMPLTranslationException { TranslationContext graphContext = new TranslationContext(); graphContext.resolveGraph(this); isRoot = true; return graphContext; } /** * The DOM classic accessor method. * * @return element in the tree rooted from this, whose id attrribute is as in the parameter. * */ public ElementState getElementStateById(String id) { return this.elementByIdMap.get(id); } /** * @return the parent */ public PES parent() { // return (parent != null) ? parent : // (parents != null && !parents.empty()) ? parents.firstElement() : // null; return parent; } /** * Set the parent of this, to create the tree structure. * * @param parent */ public void setParent(PES parent) { this.parent = parent; } public ElementState getRoot() { ElementState parent = parent(); return parent == null ? this : parent.getRoot(); } /** * Perform custom processing on the newly created child node, just before it is added to this. * <p/> * This is part of depth-first traversal during translateFromXML(). * <p/> * This, the default implementation, does nothing. Sub-classes may wish to override. * * @param foo */ protected void createChildHook(ElementState foo) { } /** * Clear data structures and references to enable garbage collecting of resources associated with * this. */ public void recycle() { if (parent == null) { // root state! if (elementByIdMap != null) { elementByIdMap.clear(); elementByIdMap = null; } } else parent = null; elementByIdMap = null; if (nestedNameSpaces != null) { for (ElementState nns : nestedNameSpaces.values()) { if (nns != null) nns.recycle(); } nestedNameSpaces.clear(); nestedNameSpaces = null; } } /** * Set-up referential chains for a newly born child of this. * * @param newParent * @param ourClassDescriptor * TODO */ public void setupInParent(ElementState newParent) { this.elementByIdMap = newParent.elementByIdMap; this.manageParents(newParent); } private void manageParents(ElementState parentES) { PES parentPES = (PES) parentES; if (this.parent == null) { this.parent = parentPES; } else { if (this.parents == null) { this.parents = new Stack<PES>(); this.parents.push(this.parent); this.parents.push(parentPES); } else { this.parents.push(parentPES); } } } /** * @return Returns the optimizations. */ public ClassDescriptor classDescriptor() { ClassDescriptor result = classDescriptor; if (result == null) { result = ClassDescriptor.getClassDescriptor(this); this.classDescriptor = result; } return result; } @Override public void serializationPostHook(TranslationContext translationContext) { // TODO Auto-generated method stub } @Override public void serializationPreHook(TranslationContext translationContext) { // TODO Auto-generated method stub } @Override public void deserializationPreHook(TranslationContext translationContext) { // TODO Auto-generated method stub } @Override public void deserializationPostHook(TranslationContext translationContext, Object object) { // TODO Auto-generated method stub } @Override public void deserializationInHook(TranslationContext translationContext) { // TODO Auto-generated method stub } }