1package com.xtremelabs.robolectric.shadows;
2
3import java.util.HashMap;
4import java.util.Map;
5
6import android.content.ContentResolver;
7import android.database.AbstractCursor;
8import android.database.CursorWindow;
9import android.net.Uri;
10
11import com.xtremelabs.robolectric.internal.Implementation;
12import com.xtremelabs.robolectric.internal.Implements;
13import com.xtremelabs.robolectric.internal.RealObject;
14
15
16@Implements(AbstractCursor.class)
17public 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
31    public int getCount() {
32        return rowCount;
33    }
34
35    @Implementation
36    public boolean moveToFirst() {
37        setPosition(0);
38        return realAbstractCursor.getCount() > 0;
39    }
40
41    @Implementation
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
51    public int getPosition() {
52        return currentRowNumber;
53    }
54
55
56    @Implementation
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     */
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
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
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
100    public CursorWindow getWindow() {
101        return null;
102    }
103
104    @Implementation
105    public String[] getColumnNames() {
106        return columnNameArray;
107    }
108
109    @Implementation
110    public String getColumnName(int column) {
111        return columnNameArray[column];
112    }
113
114    @Implementation
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
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
129    public int getColumnCount() {
130        return getColumnNames().length;
131    }
132
133    @Implementation
134    public boolean isFirst() {
135        return currentRowNumber == 0;
136    }
137
138    @Implementation
139    public boolean isLast() {
140        return currentRowNumber == realAbstractCursor.getCount() - 1;
141    }
142
143    @Implementation
144    public boolean isBeforeFirst() {
145        return currentRowNumber < 0;
146    }
147
148    @Implementation
149    public boolean isAfterLast() {
150        return currentRowNumber >= realAbstractCursor.getCount();
151    }
152
153    @Implementation
154    public void setNotificationUri(ContentResolver cr, Uri notifyUri) {
155        notificationUri = notifyUri;
156    }
157
158	@Implementation
159	public boolean isClosed() {
160		return mClosed;
161	}
162
163	@Implementation
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     */
172    public Uri getNotificationUri_Compatibility() {
173        return notificationUri;
174    }
175
176
177}