Save This Page
Home » hibernate-distribution-3.3.1.GA-dist » org.hibernate » collection » [javadoc | source]
    1   /*
    2    * Hibernate, Relational Persistence for Idiomatic Java
    3    *
    4    * Copyright (c) 2008, Red Hat Middleware LLC or third-party contributors as
    5    * indicated by the @author tags or express copyright attribution
    6    * statements applied by the authors.  All third-party contributions are
    7    * distributed under license by Red Hat Middleware LLC.
    8    *
    9    * This copyrighted material is made available to anyone wishing to use, modify,
   10    * copy, or redistribute it subject to the terms and conditions of the GNU
   11    * Lesser General Public License, as published by the Free Software Foundation.
   12    *
   13    * This program is distributed in the hope that it will be useful,
   14    * but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
   15    * or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License
   16    * for more details.
   17    *
   18    * You should have received a copy of the GNU Lesser General Public License
   19    * along with this distribution; if not, write to:
   20    * Free Software Foundation, Inc.
   21    * 51 Franklin Street, Fifth Floor
   22    * Boston, MA  02110-1301  USA
   23    *
   24    */
   25   package org.hibernate.collection;
   26   
   27   import java.io.Serializable;
   28   import java.sql.ResultSet;
   29   import java.sql.SQLException;
   30   import java.util.ArrayList;
   31   import java.util.Collection;
   32   import java.util.Iterator;
   33   import java.util.List;
   34   import java.util.ListIterator;
   35   
   36   import org.hibernate.EntityMode;
   37   import org.hibernate.HibernateException;
   38   import org.hibernate.engine.SessionImplementor;
   39   import org.hibernate.loader.CollectionAliases;
   40   import org.hibernate.persister.collection.CollectionPersister;
   41   import org.hibernate.type.Type;
   42   
   43   /**
   44    * A persistent wrapper for a <tt>java.util.List</tt>. Underlying
   45    * collection is an <tt>ArrayList</tt>.
   46    *
   47    * @see java.util.ArrayList
   48    * @author Gavin King
   49    */
   50   public class PersistentList extends AbstractPersistentCollection implements List {
   51   
   52   	protected List list;
   53   
   54   	public Serializable getSnapshot(CollectionPersister persister) throws HibernateException {
   55   
   56   		EntityMode entityMode = getSession().getEntityMode();
   57   
   58   		ArrayList clonedList = new ArrayList( list.size() );
   59   		Iterator iter = list.iterator();
   60   		while ( iter.hasNext() ) {
   61   			Object deepCopy = persister.getElementType()
   62   					.deepCopy( iter.next(), entityMode, persister.getFactory() );
   63   			clonedList.add( deepCopy );
   64   		}
   65   		return clonedList;
   66   	}
   67   
   68   	public Collection getOrphans(Serializable snapshot, String entityName) throws HibernateException {
   69   		List sn = (List) snapshot;
   70   	    return getOrphans( sn, list, entityName, getSession() );
   71   	}
   72   
   73   	public boolean equalsSnapshot(CollectionPersister persister) throws HibernateException {
   74   		Type elementType = persister.getElementType();
   75   		List sn = (List) getSnapshot();
   76   		if ( sn.size()!=this.list.size() ) return false;
   77   		Iterator iter = list.iterator();
   78   		Iterator sniter = sn.iterator();
   79   		while ( iter.hasNext() ) {
   80   			if ( elementType.isDirty( iter.next(), sniter.next(), getSession() ) ) return false;
   81   		}
   82   		return true;
   83   	}
   84   
   85   	public boolean isSnapshotEmpty(Serializable snapshot) {
   86   		return ( (Collection) snapshot ).isEmpty();
   87   	}
   88   
   89   	public PersistentList(SessionImplementor session) {
   90   		super(session);
   91   	}
   92   
   93   	public PersistentList(SessionImplementor session, List list) {
   94   		super(session);
   95   		this.list = list;
   96   		setInitialized();
   97   		setDirectlyAccessible(true);
   98   	}
   99   
  100   	public void beforeInitialize(CollectionPersister persister, int anticipatedSize) {
  101   		this.list = ( List ) persister.getCollectionType().instantiate( anticipatedSize );
  102   	}
  103   
  104   	public boolean isWrapper(Object collection) {
  105   		return list==collection;
  106   	}
  107   
  108   	public PersistentList() {} //needed for SOAP libraries, etc
  109   
  110   	/**
  111   	 * @see java.util.List#size()
  112   	 */
  113   	public int size() {
  114   		return readSize() ? getCachedSize() : list.size();
  115   	}
  116   
  117   	/**
  118   	 * @see java.util.List#isEmpty()
  119   	 */
  120   	public boolean isEmpty() {
  121   		return readSize() ? getCachedSize()==0 : list.isEmpty();
  122   	}
  123   
  124   	/**
  125   	 * @see java.util.List#contains(Object)
  126   	 */
  127   	public boolean contains(Object object) {
  128   		Boolean exists = readElementExistence(object);
  129   		return exists==null ?
  130   				list.contains(object) :
  131   				exists.booleanValue();
  132   	}
  133   
  134   	/**
  135   	 * @see java.util.List#iterator()
  136   	 */
  137   	public Iterator iterator() {
  138   		read();
  139   		return new IteratorProxy( list.iterator() );
  140   	}
  141   
  142   	/**
  143   	 * @see java.util.List#toArray()
  144   	 */
  145   	public Object[] toArray() {
  146   		read();
  147   		return list.toArray();
  148   	}
  149   
  150   	/**
  151   	 * @see java.util.List#toArray(Object[])
  152   	 */
  153   	public Object[] toArray(Object[] array) {
  154   		read();
  155   		return list.toArray(array);
  156   	}
  157   
  158   	/**
  159   	 * @see java.util.List#add(Object)
  160   	 */
  161   	public boolean add(Object object) {
  162   		if ( !isOperationQueueEnabled() ) {
  163   			write();
  164   			return list.add(object);
  165   		}
  166   		else {
  167   			queueOperation( new SimpleAdd(object) );
  168   			return true;
  169   		}
  170   	}
  171   
  172   	/**
  173   	 * @see java.util.List#remove(Object)
  174   	 */
  175   	public boolean remove(Object value) {
  176   		Boolean exists = isPutQueueEnabled() ? readElementExistence(value) : null;
  177   		if ( exists == null ) {
  178   			initialize( true );
  179   			if ( list.remove( value ) ) {
  180   				dirty();
  181   				return true;
  182   			}
  183   			else {
  184   				return false;
  185   			}
  186   		}
  187   		else if ( exists.booleanValue() ) {
  188   			queueOperation( new SimpleRemove(value) );
  189   			return true;
  190   		}
  191   		else {
  192   			return false;
  193   		}
  194   	}
  195   
  196   	/**
  197   	 * @see java.util.List#containsAll(Collection)
  198   	 */
  199   	public boolean containsAll(Collection coll) {
  200   		read();
  201   		return list.containsAll(coll);
  202   	}
  203   
  204   	/**
  205   	 * @see java.util.List#addAll(Collection)
  206   	 */
  207   	public boolean addAll(Collection values) {
  208   		if ( values.size()==0 ) {
  209   			return false;
  210   		}
  211   		if ( !isOperationQueueEnabled() ) {
  212   			write();
  213   			return list.addAll(values);
  214   		}
  215   		else {
  216   			Iterator iter = values.iterator();
  217   			while ( iter.hasNext() ) {
  218   				queueOperation( new SimpleAdd( iter.next() ) );
  219   			}
  220   			return values.size()>0;
  221   		}
  222   	}
  223   
  224   	/**
  225   	 * @see java.util.List#addAll(int, Collection)
  226   	 */
  227   	public boolean addAll(int index, Collection coll) {
  228   		if ( coll.size()>0 ) {
  229   			write();
  230   			return list.addAll(index,  coll);
  231   		}
  232   		else {
  233   			return false;
  234   		}
  235   	}
  236   
  237   	/**
  238   	 * @see java.util.List#removeAll(Collection)
  239   	 */
  240   	public boolean removeAll(Collection coll) {
  241   		if ( coll.size()>0 ) {
  242   			initialize( true );
  243   			if ( list.removeAll( coll ) ) {
  244   				dirty();
  245   				return true;
  246   			}
  247   			else {
  248   				return false;
  249   			}
  250   		}
  251   		else {
  252   			return false;
  253   		}
  254   	}
  255   
  256   	/**
  257   	 * @see java.util.List#retainAll(Collection)
  258   	 */
  259   	public boolean retainAll(Collection coll) {
  260   		initialize( true );
  261   		if ( list.retainAll( coll ) ) {
  262   			dirty();
  263   			return true;
  264   		}
  265   		else {
  266   			return false;
  267   		}
  268   	}
  269   
  270   	/**
  271   	 * @see java.util.List#clear()
  272   	 */
  273   	public void clear() {
  274   		if ( isClearQueueEnabled() ) {
  275   			queueOperation( new Clear() );
  276   		}
  277   		else {
  278   			initialize( true );
  279   			if ( ! list.isEmpty() ) {
  280   				list.clear();
  281   				dirty();
  282   			}
  283   		}
  284   	}
  285   
  286   	/**
  287   	 * @see java.util.List#get(int)
  288   	 */
  289   	public Object get(int index) {
  290   		if (index<0) {
  291   			throw new ArrayIndexOutOfBoundsException("negative index");
  292   		}
  293   		Object result = readElementByIndex( new Integer(index) );
  294   		return result==UNKNOWN ? list.get(index) : result;
  295   	}
  296   
  297   	/**
  298   	 * @see java.util.List#set(int, Object)
  299   	 */
  300   	public Object set(int index, Object value) {
  301   		if (index<0) {
  302   			throw new ArrayIndexOutOfBoundsException("negative index");
  303   		}
  304   		Object old = isPutQueueEnabled() ? readElementByIndex( new Integer(index) ) : UNKNOWN;
  305   		if ( old==UNKNOWN ) {
  306   			write();
  307   			return list.set(index, value);
  308   		}
  309   		else {
  310   			queueOperation( new Set(index, value, old) );
  311   			return old;
  312   		}
  313   	}
  314   
  315   	/**
  316   	 * @see java.util.List#add(int, Object)
  317   	 */
  318   	public void add(int index, Object value) {
  319   		if (index<0) {
  320   			throw new ArrayIndexOutOfBoundsException("negative index");
  321   		}
  322   		if ( !isOperationQueueEnabled() ) {
  323   			write();
  324   			list.add(index, value);
  325   		}
  326   		else {
  327   			queueOperation( new Add(index, value) );
  328   		}
  329   	}
  330   
  331   	/**
  332   	 * @see java.util.List#remove(int)
  333   	 */
  334   	public Object remove(int index) {
  335   		if (index<0) {
  336   			throw new ArrayIndexOutOfBoundsException("negative index");
  337   		}
  338   		Object old = isPutQueueEnabled() ?
  339   				readElementByIndex( new Integer(index) ) : UNKNOWN;
  340   		if ( old==UNKNOWN ) {
  341   			write();
  342   			return list.remove(index);
  343   		}
  344   		else {
  345   			queueOperation( new Remove(index, old) );
  346   			return old;
  347   		}
  348   	}
  349   
  350   	/**
  351   	 * @see java.util.List#indexOf(Object)
  352   	 */
  353   	public int indexOf(Object value) {
  354   		read();
  355   		return list.indexOf(value);
  356   	}
  357   
  358   	/**
  359   	 * @see java.util.List#lastIndexOf(Object)
  360   	 */
  361   	public int lastIndexOf(Object value) {
  362   		read();
  363   		return list.lastIndexOf(value);
  364   	}
  365   
  366   	/**
  367   	 * @see java.util.List#listIterator()
  368   	 */
  369   	public ListIterator listIterator() {
  370   		read();
  371   		return new ListIteratorProxy( list.listIterator() );
  372   	}
  373   
  374   	/**
  375   	 * @see java.util.List#listIterator(int)
  376   	 */
  377   	public ListIterator listIterator(int index) {
  378   		read();
  379   		return new ListIteratorProxy( list.listIterator(index) );
  380   	}
  381   
  382   	/**
  383   	 * @see java.util.List#subList(int, int)
  384   	 */
  385   	public java.util.List subList(int from, int to) {
  386   		read();
  387   		return new ListProxy( list.subList(from, to) );
  388   	}
  389   
  390   	public boolean empty() {
  391   		return list.isEmpty();
  392   	}
  393   
  394   	public String toString() {
  395   		read();
  396   		return list.toString();
  397   	}
  398   
  399   	public Object readFrom(ResultSet rs, CollectionPersister persister, CollectionAliases descriptor, Object owner)
  400   	throws HibernateException, SQLException {
  401   		Object element = persister.readElement( rs, owner, descriptor.getSuffixedElementAliases(), getSession() ) ;
  402   		int index = ( (Integer) persister.readIndex( rs, descriptor.getSuffixedIndexAliases(), getSession() ) ).intValue();
  403   
  404   		//pad with nulls from the current last element up to the new index
  405   		for ( int i = list.size(); i<=index; i++) {
  406   			list.add(i, null);
  407   		}
  408   
  409   		list.set(index, element);
  410   		return element;
  411   	}
  412   
  413   	public Iterator entries(CollectionPersister persister) {
  414   		return list.iterator();
  415   	}
  416   
  417   	public void initializeFromCache(CollectionPersister persister, Serializable disassembled, Object owner)
  418   	throws HibernateException {
  419   		Serializable[] array = ( Serializable[] ) disassembled;
  420   		int size = array.length;
  421   		beforeInitialize( persister, size );
  422   		for ( int i = 0; i < size; i++ ) {
  423   			list.add( persister.getElementType().assemble( array[i], getSession(), owner ) );
  424   		}
  425   	}
  426   
  427   	public Serializable disassemble(CollectionPersister persister)
  428   	throws HibernateException {
  429   
  430   		int length = list.size();
  431   		Serializable[] result = new Serializable[length];
  432   		for ( int i=0; i<length; i++ ) {
  433   			result[i] = persister.getElementType().disassemble( list.get(i), getSession(), null );
  434   		}
  435   		return result;
  436   	}
  437   
  438   
  439   	public Iterator getDeletes(CollectionPersister persister, boolean indexIsFormula) throws HibernateException {
  440   		List deletes = new ArrayList();
  441   		List sn = (List) getSnapshot();
  442   		int end;
  443   		if ( sn.size() > list.size() ) {
  444   			for ( int i=list.size(); i<sn.size(); i++ ) {
  445   				deletes.add( indexIsFormula ? sn.get(i) : new Integer(i) );
  446   			}
  447   			end = list.size();
  448   		}
  449   		else {
  450   			end = sn.size();
  451   		}
  452   		for ( int i=0; i<end; i++ ) {
  453   			if ( list.get(i)==null && sn.get(i)!=null ) {
  454   				deletes.add( indexIsFormula ? sn.get(i) : new Integer(i) );
  455   			}
  456   		}
  457   		return deletes.iterator();
  458   	}
  459   
  460   	public boolean needsInserting(Object entry, int i, Type elemType) throws HibernateException {
  461   		final List sn = (List) getSnapshot();
  462   		return list.get(i)!=null && ( i >= sn.size() || sn.get(i)==null );
  463   	}
  464   
  465   	public boolean needsUpdating(Object entry, int i, Type elemType) throws HibernateException {
  466   		final List sn = (List) getSnapshot();
  467   		return i<sn.size() && sn.get(i)!=null && list.get(i)!=null &&
  468   			elemType.isDirty( list.get(i), sn.get(i), getSession() );
  469   	}
  470   
  471   	public Object getIndex(Object entry, int i, CollectionPersister persister) {
  472   		return new Integer(i);
  473   	}
  474   
  475   	public Object getElement(Object entry) {
  476   		return entry;
  477   	}
  478   
  479   	public Object getSnapshotElement(Object entry, int i) {
  480   		final List sn = (List) getSnapshot();
  481   		return sn.get(i);
  482   	}
  483   
  484   	public boolean equals(Object other) {
  485   		read();
  486   		return list.equals(other);
  487   	}
  488   
  489   	public int hashCode() {
  490   		read();
  491   		return list.hashCode();
  492   	}
  493   
  494   	public boolean entryExists(Object entry, int i) {
  495   		return entry!=null;
  496   	}
  497   
  498   	final class Clear implements DelayedOperation {
  499   		public void operate() {
  500   			list.clear();
  501   		}
  502   		public Object getAddedInstance() {
  503   			return null;
  504   		}
  505   		public Object getOrphan() {
  506   			throw new UnsupportedOperationException("queued clear cannot be used with orphan delete");
  507   		}
  508   	}
  509   
  510   	final class SimpleAdd implements DelayedOperation {
  511   		private Object value;
  512   
  513   		public SimpleAdd(Object value) {
  514   			this.value = value;
  515   		}
  516   		public void operate() {
  517   			list.add(value);
  518   		}
  519   		public Object getAddedInstance() {
  520   			return value;
  521   		}
  522   		public Object getOrphan() {
  523   			return null;
  524   		}
  525   	}
  526   
  527   	final class Add implements DelayedOperation {
  528   		private int index;
  529   		private Object value;
  530   
  531   		public Add(int index, Object value) {
  532   			this.index = index;
  533   			this.value = value;
  534   		}
  535   		public void operate() {
  536   			list.add(index, value);
  537   		}
  538   		public Object getAddedInstance() {
  539   			return value;
  540   		}
  541   		public Object getOrphan() {
  542   			return null;
  543   		}
  544   	}
  545   
  546   	final class Set implements DelayedOperation {
  547   		private int index;
  548   		private Object value;
  549   		private Object old;
  550   
  551   		public Set(int index, Object value, Object old) {
  552   			this.index = index;
  553   			this.value = value;
  554   			this.old = old;
  555   		}
  556   		public void operate() {
  557   			list.set(index, value);
  558   		}
  559   		public Object getAddedInstance() {
  560   			return value;
  561   		}
  562   		public Object getOrphan() {
  563   			return old;
  564   		}
  565   	}
  566   
  567   	final class Remove implements DelayedOperation {
  568   		private int index;
  569   		private Object old;
  570   
  571   		public Remove(int index, Object old) {
  572   			this.index = index;
  573   			this.old = old;
  574   		}
  575   		public void operate() {
  576   			list.remove(index);
  577   		}
  578   		public Object getAddedInstance() {
  579   			return null;
  580   		}
  581   		public Object getOrphan() {
  582   			return old;
  583   		}
  584   	}
  585   
  586   	final class SimpleRemove implements DelayedOperation {
  587   		private Object value;
  588   
  589   		public SimpleRemove(Object value) {
  590   			this.value = value;
  591   		}
  592   		public void operate() {
  593   			list.remove(value);
  594   		}
  595   		public Object getAddedInstance() {
  596   			return null;
  597   		}
  598   		public Object getOrphan() {
  599   			return value;
  600   		}
  601   	}
  602   }

Save This Page
Home » hibernate-distribution-3.3.1.GA-dist » org.hibernate » collection » [javadoc | source]