View Javadoc

1   package org.sourceforge.jemm.collections;
2   
3   import java.util.Arrays;
4   import java.util.Collection;
5   import java.util.HashSet;
6   import java.util.Iterator;
7   import java.util.Set;
8   
9   import org.sourceforge.jemm.collections.internal.ClearRequest;
10  import org.sourceforge.jemm.collections.internal.ContainsRequest;
11  import org.sourceforge.jemm.collections.internal.ContainsResponse;
12  import org.sourceforge.jemm.collections.internal.RemoveRequest;
13  import org.sourceforge.jemm.collections.internal.RemoveResponse;
14  import org.sourceforge.jemm.collections.internal.SizeRequest;
15  import org.sourceforge.jemm.collections.internal.SizeResponse;
16  import org.sourceforge.jemm.collections.internal.StoredValue;
17  import org.sourceforge.jemm.collections.internal.ToArrayRequest;
18  import org.sourceforge.jemm.collections.internal.ToArrayResponse;
19  import org.sourceforge.jemm.collections.internal.set.SetAddRequest;
20  import org.sourceforge.jemm.collections.internal.set.SetAddResponse;
21  import org.sourceforge.jemm.lifecycle.ShadowTypeObject;
22  import org.sourceforge.jemm.util.JEMMType;
23  
24  /**
25   * Persistent set implementation.  
26   * 
27   *<P>
28   *<B> Note: Nulls are not allowed as values. </B>
29   * 
30   * @author Rory Graves
31   * 
32   * @see java.util.Set
33   * @param <E> The type of the set.  
34   *
35   */
36  public final class JemmSet<E> extends JEMMType implements Set<E> {
37      /**
38       * Creates a JemmSet.
39       */
40      public JemmSet() {
41          super();
42      }
43      
44      /** Internally JEMM used constructor
45       * @param jemmOIF The underlying shadow object 
46       */
47      protected JemmSet(ShadowTypeObject jemmOIF) {
48          super(jemmOIF);
49      }
50   
51      public boolean add(E uValue) {
52          StoredValue sValue = new StoredValue(uValue);
53          
54          SetAddRequest req = new SetAddRequest(sValue,null);
55          while(true) {
56              SetAddResponse resp = (SetAddResponse) jemmOIF.processRequest(req);
57              if(resp.wasAdded())
58              	return true;
59              else {
60              	if(resp.getConflicts() == null)
61              		return false;
62              	
63          		// the object already .equals something in the collection, return false
64              	for (StoredValue conflict : resp.getConflicts())
65              		if(sValue.equals(conflict))
66              			return false;
67  
68              	// none of the values match, so call add again, with the results marked as 
69              	// seen and not equals            	
70              	req = new SetAddRequest(sValue,resp.getConflicts());
71              }
72          }
73      }
74  
75      public boolean addAll(Collection<? extends E> uCollection) {
76      	throw new UnsupportedOperationException("JemmSet does not currently support containsAll()");
77      }
78  
79      public void clear() {
80          jemmOIF.processRequest(new ClearRequest());
81      }
82  
83      public boolean contains(Object uValue) {
84          ContainsResponse result = (ContainsResponse) jemmOIF.processRequest(new ContainsRequest(uValue));
85          if(result.isFound())
86          	return true;
87          else
88          	if(result.getPossibles() != null)
89          		for (Object possible : result.getPossibles())
90          			if(uValue.equals(possible))
91          				return true;        				
92  		return false;
93      }
94  
95      public boolean containsAll(Collection<?> uCollection) {
96      	throw new UnsupportedOperationException("JemmSet does not currently support containsAll()");
97      }
98  
99      public boolean isEmpty() {
100     	return size() == 0;
101     }
102 
103     @SuppressWarnings("unchecked")
104 	public Iterator<E> iterator() {
105     	Object[] arr = toArray();
106         Set<E> set = new HashSet<E>();
107         for(Object obj : arr)
108         	set.add((E) obj);
109         
110         return set.iterator();
111     }
112 
113     public boolean remove(Object uValue) {
114     	RemoveRequest req = new RemoveRequest(uValue);
115     	while(true) {
116     		RemoveResponse resp = (RemoveResponse) jemmOIF.processRequest(req);
117     		if(resp.wasRemoved())
118     			return true;
119     		else {
120     			if(resp.getPotentialMatches() == null)
121     				return false;
122     			
123     			Object match = null;
124     			for(int i=0; i<resp.getPotentialMatches().length && match == null; i++)
125     				if(uValue.equals(resp.getPotentialMatches()[i]))
126     					match = resp.getPotentialMatches()[i];
127     					
128     			if(match == null)
129     				return false; 
130     			
131     			req = new RemoveRequest(match);
132     		}
133     	}
134     }
135 
136     public boolean removeAll(Collection<?> uCollection) {
137     	throw new UnsupportedOperationException("JemmSet does not currently support containsAll()");
138     }
139 
140     public boolean retainAll(Collection<?> uCollection) {
141     	throw new UnsupportedOperationException("JemmSet does not currently support retainAll()");
142     }
143 
144     public int size() {
145     	return ((SizeResponse) jemmOIF.processRequest(new SizeRequest())).getSize();
146     }
147 
148     public Object[] toArray() {        
149     	return ((ToArrayResponse) jemmOIF.processRequest(new ToArrayRequest())).getArray();
150     }
151 
152     @SuppressWarnings("unchecked")
153 	public <T> T[] toArray(T[] a) {    	
154     	Object[] curValues = toArray();
155     	int size = curValues.length;
156         if (a.length < size) { 
157         	// target array is not large enough
158             // Make a new array of a's runtime type, but my contents:
159             return (T[]) Arrays.copyOf(curValues, size, a.getClass());
160         }
161         
162         System.arraycopy(curValues, 0, a, 0, size);
163         if (a.length > size)
164             a[size] = null;
165         return a;
166     }
167 }