1 package org.hibernate.collection; 3 4 import java.io.Serializable ; 5 import java.sql.ResultSet ; 6 import java.sql.SQLException ; 7 import java.util.ArrayList ; 8 import java.util.Collection ; 9 import java.util.HashMap ; 10 import java.util.Iterator ; 11 import java.util.List ; 12 import java.util.Map ; 13 14 import org.dom4j.Element; 15 import org.hibernate.AssertionFailure; 16 import org.hibernate.HibernateException; 17 import org.hibernate.loader.CollectionAliases; 18 import org.hibernate.engine.SessionFactoryImplementor; 19 import org.hibernate.engine.SessionImplementor; 20 import org.hibernate.persister.collection.CollectionPersister; 21 import org.hibernate.type.NullableType; 22 import org.hibernate.type.Type; 23 import org.hibernate.util.CollectionHelper; 24 25 30 public abstract class PersistentIndexedElementHolder extends AbstractPersistentCollection { 31 protected Element element; 32 33 public PersistentIndexedElementHolder(SessionImplementor session, Element element) { 34 super(session); 35 this.element = element; 36 setInitialized(); 37 } 38 39 public static final class IndexedValue { 40 String index; 41 Object value; 42 IndexedValue(String index, Object value) { 43 this.index = index; 44 this.value = value; 45 } 46 } 47 48 protected static String getIndex(Element element, String indexNodeName, int i) { 49 if (indexNodeName!=null) { 50 return element.attributeValue(indexNodeName); 51 } 52 else { 53 return Integer.toString(i); 54 } 55 } 56 57 protected static void setIndex(Element element, String indexNodeName, String index) { 58 if (indexNodeName!=null) element.addAttribute(indexNodeName, index); 59 } 60 61 protected static String getIndexAttributeName(CollectionPersister persister) { 62 String node = persister.getIndexNodeName(); 63 return node==null ? null : node.substring(1); 64 } 65 66 public Serializable getSnapshot(CollectionPersister persister) 67 throws HibernateException { 68 69 final Type elementType = persister.getElementType(); 70 String indexNode = getIndexAttributeName(persister); 71 List elements = element.elements( persister.getElementNodeName() ); 72 HashMap snapshot = new HashMap ( elements.size() ); 73 for ( int i=0; i<elements.size(); i++ ) { 74 Element elem = (Element) elements.get(i); 75 Object value = elementType.fromXMLNode( elem, persister.getFactory() ); 76 Object copy = elementType.deepCopy( value, getSession().getEntityMode(), persister.getFactory() ); 77 snapshot.put( getIndex(elem, indexNode, i), copy ); 78 } 79 return snapshot; 80 81 } 82 83 public Collection getOrphans(Serializable snapshot, String entityName) 84 throws HibernateException { 85 return CollectionHelper.EMPTY_COLLECTION; 87 } 88 89 public PersistentIndexedElementHolder(SessionImplementor session, CollectionPersister persister, Serializable key) 90 throws HibernateException { 91 super(session); 92 Element owner = (Element) session.getPersistenceContext().getCollectionOwner(key, persister); 93 if (owner==null) throw new AssertionFailure("null owner"); 94 final String nodeName = persister.getNodeName(); 96 if ( ".".equals(nodeName) ) { 97 element = owner; 98 } 99 else { 100 element = owner.element( nodeName ); 101 if (element==null) element = owner.addElement( nodeName ); 102 } 103 } 104 105 public boolean isWrapper(Object collection) { 106 return element==collection; 107 } 108 109 public boolean equalsSnapshot(CollectionPersister persister) throws HibernateException { 110 Type elementType = persister.getElementType(); 111 String indexNode = getIndexAttributeName(persister); 112 HashMap snapshot = (HashMap ) getSnapshot(); 113 List elements = element.elements( persister.getElementNodeName() ); 114 if ( snapshot.size()!= elements.size() ) return false; 115 for ( int i=0; i<snapshot.size(); i++ ) { 116 Element elem = (Element) elements.get(i); 117 Object old = snapshot.get( getIndex(elem, indexNode, i) ); 118 Object current = elementType.fromXMLNode( elem, persister.getFactory() ); 119 if ( elementType.isDirty( old, current, getSession() ) ) return false; 120 } 121 return true; 122 } 123 124 public boolean isSnapshotEmpty(Serializable snapshot) { 125 return ( (HashMap ) snapshot ).isEmpty(); 126 } 127 128 public boolean empty() { 129 return !element.elementIterator().hasNext(); 130 } 131 132 public Object readFrom(ResultSet rs, CollectionPersister persister, CollectionAliases descriptor, Object owner) 133 throws HibernateException, SQLException { 134 Object object = persister.readElement( rs, owner, descriptor.getSuffixedElementAliases(), getSession() ); 135 final Type elementType = persister.getElementType(); 136 final SessionFactoryImplementor factory = persister.getFactory(); 137 String indexNode = getIndexAttributeName(persister); 138 139 Element elem = element.addElement( persister.getElementNodeName() ); 140 elementType.setToXMLNode( elem, object, factory ); 141 142 final Type indexType = persister.getIndexType(); 143 final Object indexValue = persister.readIndex( rs, descriptor.getSuffixedIndexAliases(), getSession() ); 144 final String index = ( (NullableType) indexType ).toXMLString( indexValue, factory ); 145 setIndex(elem, indexNode, index); 146 return object; 147 } 148 149 public Iterator entries(CollectionPersister persister) { 150 151 final Type elementType = persister.getElementType(); 152 String indexNode = getIndexAttributeName(persister); 153 List elements = element.elements( persister.getElementNodeName() ); 154 int length = elements.size(); 155 List result = new ArrayList (length); 156 for ( int i=0; i<length; i++ ) { 157 Element elem = (Element) elements.get(i); 158 Object object = elementType.fromXMLNode( elem, persister.getFactory() ); 159 result.add( new IndexedValue( getIndex(elem, indexNode, i), object ) ); 160 } 161 return result.iterator(); 162 } 163 164 public void beforeInitialize(CollectionPersister persister) {} 165 166 public boolean isDirectlyAccessible() { 167 return true; 168 } 169 170 public Object getValue() { 171 return element; 172 } 173 174 public Iterator getDeletes(CollectionPersister persister, boolean indexIsFormula) 175 throws HibernateException { 176 177 final Type indexType = persister.getIndexType(); 178 HashMap snapshot = (HashMap ) getSnapshot(); 179 HashMap deletes = (HashMap ) snapshot.clone(); 180 deletes.keySet().removeAll( ( (HashMap ) getSnapshot(persister) ).keySet() ); 181 ArrayList deleteList = new ArrayList ( deletes.size() ); 182 Iterator iter = deletes.entrySet().iterator(); 183 while ( iter.hasNext() ) { 184 Map.Entry me = (Map.Entry ) iter.next(); 185 final Object object = indexIsFormula ? 186 me.getValue() : 187 ( (NullableType) indexType ).fromXMLString( (String ) me.getKey(), persister.getFactory() ); 188 if (object!=null) deleteList.add(object); 189 } 190 191 return deleteList.iterator(); 192 193 } 194 195 public boolean needsInserting(Object entry, int i, Type elementType) 196 throws HibernateException { 197 HashMap snapshot = (HashMap ) getSnapshot(); 198 IndexedValue iv = (IndexedValue) entry; 199 return iv.value!=null && snapshot.get( iv.index )==null; 200 } 201 202 public boolean needsUpdating(Object entry, int i, Type elementType) 203 throws HibernateException { 204 HashMap snapshot = (HashMap ) getSnapshot(); 205 IndexedValue iv = (IndexedValue) entry; 206 Object old = snapshot.get( iv.index ); 207 return old!=null && elementType.isDirty( old, iv.value, getSession() ); 208 } 209 210 public Object getIndex(Object entry, int i, CollectionPersister persister) { 211 String index = ( (IndexedValue) entry ).index; 212 final Type indexType = persister.getIndexType(); 213 return ( (NullableType) indexType ).fromXMLString( index, persister.getFactory() ); 214 } 215 216 public Object getElement(Object entry) { 217 return ( (IndexedValue) entry ).value; 218 } 219 220 public Object getSnapshotElement(Object entry, int i) { 221 return ( (HashMap ) getSnapshot() ).get( ( (IndexedValue) entry ).index ); 222 } 223 224 public boolean entryExists(Object entry, int i) { 225 return entry!=null; 226 } 227 228 } 229 | Popular Tags |