Open Source Repository

Home /hibernate/hibernate-3.2.7.ga | Repository Home


org/hibernate/collection/PersistentIndexedElementHolder.java
//$Id: PersistentIndexedElementHolder.java 10086 2006-07-05 18:17:27Z [email protected] $
package org.hibernate.collection;

import java.io.Serializable;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import org.dom4j.Element;
import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
import org.hibernate.loader.CollectionAliases;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.persister.collection.CollectionPersister;
import org.hibernate.type.NullableType;
import org.hibernate.type.Type;
import org.hibernate.util.CollectionHelper;

/**
 * A persistent wrapper for an XML element
 *
 @author Gavin King
 */
public abstract class PersistentIndexedElementHolder extends AbstractPersistentCollection {
  protected Element element;
  
  public PersistentIndexedElementHolder(SessionImplementor session, Element element) {
    super(session);
    this.element = element;
    setInitialized();
  }
  
  public static final class IndexedValue {
    String index;
    Object value;
    IndexedValue(String index, Object value) {
      this.index = index;
      this.value = value;
    }
  }
  
  protected static String getIndex(Element element, String indexNodeName, int i) {
    if (indexNodeName!=null) {
      return element.attributeValue(indexNodeName);
    }
    else {
      return Integer.toString(i);
    }
  }
  
  protected static void setIndex(Element element, String indexNodeName, String index) {
    if (indexNodeName!=nullelement.addAttribute(indexNodeName, index);
  }
  
  protected static String getIndexAttributeName(CollectionPersister persister) {
    String node = persister.getIndexNodeName();
    return node==null null : node.substring(1);
  }
  
  public Serializable getSnapshot(CollectionPersister persister
  throws HibernateException {
    
    final Type elementType = persister.getElementType();
    String indexNode = getIndexAttributeName(persister);    
    List elements = element.elementspersister.getElementNodeName() );
    HashMap snapshot = new HashMapelements.size() );
    for int i=0; i<elements.size(); i++ ) {
      Element elem = (Elementelements.get(i);
      Object value = elementType.fromXMLNodeelem, persister.getFactory() );
      Object copy = elementType.deepCopyvalue, getSession().getEntityMode(), persister.getFactory() );
      snapshot.putgetIndex(elem, indexNode, i), copy );
    }
    return snapshot;
    
  }

  public Collection getOrphans(Serializable snapshot, String entityName
  throws HibernateException {
    //orphan delete not supported for EntityMode.DOM4J
    return CollectionHelper.EMPTY_COLLECTION; 
  }

  public PersistentIndexedElementHolder(SessionImplementor session, CollectionPersister persister, Serializable key
  throws HibernateException {
    super(session);
    Element owner = (Elementsession.getPersistenceContext().getCollectionOwner(key, persister);
    if (owner==nullthrow new AssertionFailure("null owner");
    //element = XMLHelper.generateDom4jElement( persister.getNodeName() );
    final String nodeName = persister.getNodeName();
    if ".".equals(nodeName) ) {
      element = owner;
    }
    else {
      element = owner.elementnodeName );
      if (element==nullelement = owner.addElementnodeName );
    }
  }

  public boolean isWrapper(Object collection) {
    return element==collection;
  }

  public boolean equalsSnapshot(CollectionPersister persisterthrows HibernateException {
    Type elementType = persister.getElementType();
    String indexNode = getIndexAttributeName(persister);    
    HashMap snapshot = (HashMapgetSnapshot();
    List elements = element.elementspersister.getElementNodeName() );
    if snapshot.size()!= elements.size() ) return false;
    for int i=0; i<snapshot.size(); i++ ) {
      Element elem = (Elementelements.get(i);
      Object old = snapshot.getgetIndex(elem, indexNode, i) );
      Object current = elementType.fromXMLNodeelem, persister.getFactory() );
      if elementType.isDirtyold, current, getSession() ) ) return false;
    }
    return true;
  }

  public boolean isSnapshotEmpty(Serializable snapshot) {
    return ( (HashMapsnapshot ).isEmpty();
  }
  
  public boolean empty() {
    return !element.elementIterator().hasNext();
  }

  public Object readFrom(ResultSet rs, CollectionPersister persister, CollectionAliases descriptor, Object owner)
  throws HibernateException, SQLException {
    Object object = persister.readElementrs, owner, descriptor.getSuffixedElementAliases(), getSession() );
    final Type elementType = persister.getElementType();
    final SessionFactoryImplementor factory = persister.getFactory();
    String indexNode = getIndexAttributeName(persister);

    Element elem = element.addElementpersister.getElementNodeName() );
    elementType.setToXMLNodeelem, object, factory )
    
    final Type indexType = persister.getIndexType();
    final Object indexValue = persister.readIndexrs, descriptor.getSuffixedIndexAliases(), getSession() );
    final String index = ( (NullableTypeindexType ).toXMLStringindexValue, factory );
    setIndex(elem, indexNode, index);
    return object;
  }

  public Iterator entries(CollectionPersister persister) {
    
    final Type elementType = persister.getElementType();
    String indexNode = getIndexAttributeName(persister);
    List elements =  element.elementspersister.getElementNodeName() );
    int length = elements.size();
    List result = new ArrayList(length);
    for int i=0; i<length; i++ ) {
      Element elem = (Elementelements.get(i);
      Object object = elementType.fromXMLNodeelem, persister.getFactory() );
      result.addnew IndexedValuegetIndex(elem, indexNode, i), object ) );
    }
    return result.iterator();
  }

  public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {}

  public boolean isDirectlyAccessible() {
    return true;
  }

  public Object getValue() {
    return element;
  }

  public Iterator getDeletes(CollectionPersister persister, boolean indexIsFormula
  throws HibernateException {
    
    final Type indexType = persister.getIndexType();
    HashMap snapshot = (HashMapgetSnapshot();
    HashMap deletes = (HashMapsnapshot.clone();
    deletes.keySet().removeAll( ( (HashMapgetSnapshot(persister) ).keySet() );
    ArrayList deleteList = new ArrayListdeletes.size() );
    Iterator iter = deletes.entrySet().iterator();
    while iter.hasNext() ) {
      Map.Entry me = (Map.Entryiter.next();
      final Object object = indexIsFormula ?
        me.getValue() :
        ( (NullableTypeindexType ).fromXMLString( (Stringme.getKey(), persister.getFactory() );
      if (object!=nulldeleteList.add(object);
    }
    
    return deleteList.iterator();
    
  }

  public boolean needsInserting(Object entry, int i, Type elementType
  throws HibernateException {
    HashMap snapshot = (HashMapgetSnapshot();
    IndexedValue iv = (IndexedValueentry;
    return iv.value!=null && snapshot.getiv.index )==null;
  }

  public boolean needsUpdating(Object entry, int i, Type elementType
  throws HibernateException {
    HashMap snapshot = (HashMapgetSnapshot();
    IndexedValue iv = (IndexedValueentry;
    Object old = snapshot.getiv.index );
    return old!=null && elementType.isDirtyold, iv.value, getSession() );
  }

  public Object getIndex(Object entry, int i, CollectionPersister persister) {
    String index = ( (IndexedValueentry ).index;
    final Type indexType = persister.getIndexType();
    return ( (NullableTypeindexType ).fromXMLStringindex, persister.getFactory() );
  }

  public Object getElement(Object entry) {
    return ( (IndexedValueentry ).value;
  }

  public Object getSnapshotElement(Object entry, int i) {
    return ( (HashMapgetSnapshot() ).get( ( (IndexedValueentry ).index );
  }

  public boolean entryExists(Object entry, int i) {
    return entry!=null;
  }

}