1 package com.xtremelabs.robolectric.shadows;
2 
3 import java.util.HashMap;
4 import java.util.Map;
5 
6 import android.content.ContentResolver;
7 import android.database.AbstractCursor;
8 import android.database.CursorWindow;
9 import android.net.Uri;
10 
11 import com.xtremelabs.robolectric.internal.Implementation;
12 import com.xtremelabs.robolectric.internal.Implements;
13 import com.xtremelabs.robolectric.internal.RealObject;
14 
15 
16 @Implements(AbstractCursor.class)
17 public class ShadowAbstractCursor {
18     @RealObject
19     private AbstractCursor realAbstractCursor;
20 
21     protected Map<String, Object> currentRow;
22     protected int currentRowNumber = -1;
23     protected Map<String, Integer> columnNames = new HashMap<String, Integer>();
24     protected String[] columnNameArray;
25     protected Map<Integer, Map<String, Object>> rows = new HashMap<Integer, Map<String, Object>>();
26     protected int rowCount;
27     protected Uri notificationUri;
28 	protected boolean mClosed;
29 
30     @Implementation
getCount()31     public int getCount() {
32         return rowCount;
33     }
34 
35     @Implementation
moveToFirst()36     public boolean moveToFirst() {
37         setPosition(0);
38         return realAbstractCursor.getCount() > 0;
39     }
40 
41     @Implementation
moveToLast()42     public boolean moveToLast() {
43     	if( realAbstractCursor.getCount() == 0 ) {
44     		return false;
45     	}
46     	setPosition( realAbstractCursor.getCount() - 1 );
47     	return true;
48     }
49 
50     @Implementation
getPosition()51     public int getPosition() {
52         return currentRowNumber;
53     }
54 
55 
56     @Implementation
moveToPosition(int pos)57     public boolean moveToPosition(int pos) {
58         if (pos >= realAbstractCursor.getCount()) {
59             return false;
60         }
61 
62         setPosition(pos);
63         return true;
64     }
65 
66     /**
67      * Set currentRowNumber(Int) and currentRow (Map)
68      *
69      * @param pos = the position to set
70      */
setPosition(int pos)71     private void setPosition(int pos) {
72         currentRowNumber = pos;
73         if ((-1 == currentRowNumber) || (rowCount == currentRowNumber)) {
74             currentRow = null;
75         } else {
76             currentRow = rows.get(currentRowNumber);
77         }
78     }
79 
80     @Implementation
moveToNext()81     public boolean moveToNext() {
82         if (currentRowNumber + 1 >= realAbstractCursor.getCount()) {
83             currentRowNumber = realAbstractCursor.getCount();
84             return false;
85         }
86         setPosition(++currentRowNumber);
87         return true;
88     }
89 
90     @Implementation
moveToPrevious()91     public boolean moveToPrevious() {
92         if (currentRowNumber < 0 || realAbstractCursor.getCount() == 0) {
93             return false;
94         }
95         setPosition(--currentRowNumber);
96         return true;
97     }
98 
99     @Implementation
getWindow()100     public CursorWindow getWindow() {
101         return null;
102     }
103 
104     @Implementation
getColumnNames()105     public String[] getColumnNames() {
106         return columnNameArray;
107     }
108 
109     @Implementation
getColumnName(int column)110     public String getColumnName(int column) {
111         return columnNameArray[column];
112     }
113 
114     @Implementation
getColumnIndex(String columnName)115     public int getColumnIndex(String columnName) {
116         for (int i=0; i<columnNameArray.length; i++) {
117             if (columnName.equals(columnNameArray[i])) return i;
118         }
119         return -1;
120     }
121 
122     @Implementation
getColumnIndexOrThrow(String columnName)123     public int getColumnIndexOrThrow(String columnName) {
124         int idx = getColumnIndex(columnName);
125         if (idx >= 0) return idx; else throw new IllegalArgumentException("column does not exist");
126     }
127 
128     @Implementation
getColumnCount()129     public int getColumnCount() {
130         return getColumnNames().length;
131     }
132 
133     @Implementation
isFirst()134     public boolean isFirst() {
135         return currentRowNumber == 0;
136     }
137 
138     @Implementation
isLast()139     public boolean isLast() {
140         return currentRowNumber == realAbstractCursor.getCount() - 1;
141     }
142 
143     @Implementation
isBeforeFirst()144     public boolean isBeforeFirst() {
145         return currentRowNumber < 0;
146     }
147 
148     @Implementation
isAfterLast()149     public boolean isAfterLast() {
150         return currentRowNumber >= realAbstractCursor.getCount();
151     }
152 
153     @Implementation
setNotificationUri(ContentResolver cr, Uri notifyUri)154     public void setNotificationUri(ContentResolver cr, Uri notifyUri) {
155         notificationUri = notifyUri;
156     }
157 
158 	@Implementation
isClosed()159 	public boolean isClosed() {
160 		return mClosed;
161 	}
162 
163 	@Implementation
close()164 	public void close() {
165 		mClosed = true;
166 	}
167 
168 	/**
169      * Returns the Uri set by {@code setNotificationUri()}.  Method included for testing
170      * pre-API 11 projects.
171      */
getNotificationUri_Compatibility()172     public Uri getNotificationUri_Compatibility() {
173         return notificationUri;
174     }
175 
176 
177 }