001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2007 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041:
042: package com.sun.data.provider.impl;
043:
044: import java.io.Serializable;
045: import java.util.ArrayList;
046: import java.util.HashMap;
047: import java.util.Iterator;
048: import com.sun.data.provider.DataProvider;
049: import com.sun.data.provider.DataProviderException;
050: import com.sun.data.provider.FieldKey;
051: import com.sun.data.provider.RowKey;
052: import com.sun.data.provider.TableCursorListener;
053: import com.sun.data.provider.TableCursorVetoException;
054: import com.sun.data.provider.TableDataListener;
055: import com.sun.data.provider.TableDataProvider;
056: import com.sun.data.provider.TransactionalDataListener;
057: import com.sun.data.provider.TransactionalDataProvider;
058: import java.util.ResourceBundle;
059:
060: /**
061: *
062: * @author Joe Nuxoll
063: * Winston Prakash (Buf Fixes and clean up)
064: */
065: public class BasicTransactionalTableDataProvider extends
066: AbstractTableDataProvider implements TransactionalDataProvider {
067: private transient ResourceBundle bundle = null;
068: /**
069: *
070: */
071: protected TableDataProvider provider;
072:
073: /**
074: *
075: * @param provider TableDataProvider
076: */
077: public void setTableDataProvider(TableDataProvider provider) {
078: if (this .provider != null) {
079: this .provider.removeTableDataListener(dataEars);
080: this .provider.removeTableCursorListener(cursorEars);
081: }
082: this .provider = provider;
083: this .provider.addTableDataListener(dataEars);
084: this .provider.addTableCursorListener(cursorEars);
085: changedRowMap.clear();
086: fireProviderChanged();
087: }
088:
089: /**
090: * <p>Return the resource bundle containing our localized messages.</p>
091: */
092: private ResourceBundle getBundle() {
093:
094: if (bundle == null) {
095: bundle = ResourceBundle
096: .getBundle("com/sun/data/provider/impl/Bundle");
097: }
098: return bundle;
099:
100: }
101:
102: /**
103: *
104: * @return TableDataProvider
105: */
106: public TableDataProvider getTableDataProvider() {
107: return provider;
108: }
109:
110: /**
111: *
112: * @return FieldKey[]
113: */
114: public FieldKey[] getFieldKeys() throws DataProviderException {
115: if (provider == null) {
116: return FieldKey.EMPTY_ARRAY;
117: }
118: return provider.getFieldKeys();
119: }
120:
121: /**
122: *
123: * @param fieldId String
124: * @return FieldKey
125: */
126: public FieldKey getFieldKey(String fieldId)
127: throws DataProviderException {
128: if (provider == null) {
129: return null;
130: }
131: return provider.getFieldKey(fieldId);
132: }
133:
134: /** {@inheritDoc} */
135: public Class getType(FieldKey fieldKey)
136: throws DataProviderException {
137: if (provider == null) {
138: return null;
139: }
140: return provider.getType(fieldKey);
141: }
142:
143: /** {@inheritDoc} */
144: public boolean isReadOnly(FieldKey fieldKey)
145: throws DataProviderException {
146: if (provider == null) {
147: return true;
148: }
149: return provider.isReadOnly(fieldKey);
150: }
151:
152: /** {@inheritDoc} */
153: public int getRowCount() throws DataProviderException {
154: if (provider == null) {
155: return -1;
156: }
157: return provider.getRowCount();
158: }
159:
160: /** {@inheritDoc} */
161: public RowKey[] getRowKeys(int count, RowKey afterRow)
162: throws DataProviderException {
163: if (provider == null) {
164: return RowKey.EMPTY_ARRAY;
165: }
166: return provider.getRowKeys(count, afterRow);
167: }
168:
169: /** {@inheritDoc} */
170: public RowKey getRowKey(String rowId) throws DataProviderException {
171: if (provider == null) {
172: return null;
173: }
174: return provider.getRowKey(rowId);
175: }
176:
177: /** {@inheritDoc} */
178: public boolean isRowAvailable(RowKey row)
179: throws DataProviderException {
180: if (provider == null) {
181: return false;
182: }
183: return provider.isRowAvailable(row);
184: }
185:
186: /** {@inheritDoc} */
187: public Object getValue(FieldKey fieldKey, RowKey row)
188: throws DataProviderException {
189: if (provider == null) {
190: return null;
191: }
192: if (changedRowMap.containsKey(row)) {
193: HashMap changeMap = (HashMap) changedRowMap.get(row);
194: if (changeMap.containsKey(fieldKey)) {
195: return changeMap.get(fieldKey);
196: }
197: }
198: return provider.getValue(fieldKey, row);
199: }
200:
201: /** {@inheritDoc} */
202: public void setValue(FieldKey fieldKey, RowKey row, Object value)
203: throws DataProviderException {
204: if (provider == null) {
205: return;
206: }
207: if (isReadOnly(fieldKey)) {
208: throw new DataProviderException(getBundle().getString(
209: "FK_READ_ONLY"));
210: }
211: HashMap changeMap = null;
212: if (changedRowMap.containsKey(row)) {
213: changeMap = (HashMap) changedRowMap.get(row);
214: } else {
215: changeMap = new HashMap();
216: changedRowMap.put(row, changeMap);
217: }
218: Object oldValue = getValue(fieldKey, row);
219: changeMap.put(fieldKey, value);
220: fireValueChanged(fieldKey, row, oldValue, value);
221: if (getCursorRow() == row) {
222: fireValueChanged(fieldKey, oldValue, value);
223: }
224: }
225:
226: /** {@inheritDoc} */
227: public boolean canInsertRow(RowKey beforeRow)
228: throws DataProviderException {
229: if (provider == null) {
230: return false;
231: }
232: return provider.canInsertRow(beforeRow);
233: }
234:
235: /** {@inheritDoc} */
236: public RowKey insertRow(RowKey beforeRow)
237: throws DataProviderException {
238: if (provider == null) {
239: return null;
240: }
241: return provider.insertRow(beforeRow);
242: }
243:
244: /** {@inheritDoc} */
245: public boolean canAppendRow() throws DataProviderException {
246: if (provider == null) {
247: return false;
248: }
249: return provider.canAppendRow();
250: }
251:
252: /** {@inheritDoc} */
253: public RowKey appendRow() throws DataProviderException {
254: if (provider == null) {
255: return null;
256: }
257: return provider.appendRow();
258: }
259:
260: /** {@inheritDoc} */
261: public boolean canRemoveRow(RowKey row)
262: throws DataProviderException {
263: if (provider == null) {
264: return false;
265: }
266: return provider.canRemoveRow(row);
267: }
268:
269: /** {@inheritDoc} */
270: public void removeRow(RowKey row) throws DataProviderException {
271: if (provider != null) {
272: provider.removeRow(row);
273: }
274: }
275:
276: /**
277: *
278: */
279: protected HashMap changedRowMap = new HashMap();
280:
281: /**
282: *
283: */
284: public void commitChanges() throws DataProviderException {
285: Iterator rowKeys = changedRowMap.keySet().iterator();
286: while (rowKeys.hasNext()) {
287: RowKey rowKey = (RowKey) rowKeys.next();
288: HashMap changeMap = (HashMap) changedRowMap.get(rowKey);
289: Iterator changeKeys = changeMap.keySet().iterator();
290: while (changeKeys.hasNext()) {
291: FieldKey fieldKey = (FieldKey) changeKeys.next();
292: provider.setValue(fieldKey, rowKey, changeMap
293: .get(fieldKey));
294: }
295: }
296: changedRowMap.clear();
297: fireChangesCommitted();
298: }
299:
300: /**
301: *
302: */
303: public void revertChanges() throws DataProviderException {
304: changedRowMap.clear();
305: fireChangesReverted();
306: fireProviderChanged();
307: }
308:
309: // ----------------------------------------------------------- Event Methods
310:
311: /** {@inheritDoc} */
312: public void addTransactionalDataListener(TransactionalDataListener l) {
313: super .addDataListener(l);
314: }
315:
316: /** {@inheritDoc} */
317: public void removeTransactionalDataListener(
318: TransactionalDataListener l) {
319: super .removeDataListener(l);
320: }
321:
322: /** {@inheritDoc} */
323: public TransactionalDataListener[] getTransactionalDataListeners() {
324: if (dpListeners == null) {
325: return new TransactionalDataListener[0];
326: } else {
327: ArrayList cdpList = new ArrayList();
328: for (int i = 0; i < dpListeners.length; i++) {
329: if (dpListeners[i] instanceof TransactionalDataListener) {
330: cdpList.add(dpListeners[i]);
331: }
332: }
333: return (TransactionalDataListener[]) cdpList
334: .toArray(new TransactionalDataListener[cdpList
335: .size()]);
336: }
337: }
338:
339: /**
340: * Fires a changesCommtted event to each registered {@link
341: * TransactionalDataListener}
342: *
343: * @see TransactionalDataListener#changesCommitted(TransactionalDataProvider)
344: */
345: protected void fireChangesCommitted() {
346: TransactionalDataListener[] cdpls = getTransactionalDataListeners();
347: for (int i = 0; i < cdpls.length; i++) {
348: cdpls[i].changesCommitted(this );
349: }
350: }
351:
352: /**
353: * Fires a changesReverted event to each registered {@link
354: * TransactionalDataListener}
355: *
356: * @see TransactionalDataListener#changesReverted(TransactionalDataProvider)
357: */
358: protected void fireChangesReverted() {
359: TransactionalDataListener[] cdpls = getTransactionalDataListeners();
360: for (int i = 0; i < cdpls.length; i++) {
361: cdpls[i].changesReverted(this );
362: }
363: }
364:
365: /**
366: *
367: */
368: private class DataEars implements TableDataListener, Serializable {
369: public void valueChanged(TableDataProvider provider,
370: FieldKey fieldKey, RowKey row, Object oldValue,
371: Object newValue) {
372: fireValueChanged(fieldKey, row, oldValue, newValue);
373: }
374:
375: public void rowAdded(TableDataProvider provider, RowKey row) {
376: fireRowAdded(row);
377: }
378:
379: public void rowRemoved(TableDataProvider provider, RowKey row) {
380: fireRowRemoved(row);
381: }
382:
383: public void valueChanged(DataProvider provider,
384: FieldKey fieldKey, Object oldValue, Object newValue) {
385: fireValueChanged(fieldKey, oldValue, newValue);
386: }
387:
388: public void providerChanged(DataProvider provider) {
389: fireProviderChanged();
390: }
391: };
392:
393: private class CursorEars implements TableCursorListener,
394: Serializable {
395: public void cursorChanging(TableDataProvider provider,
396: RowKey oldRow, RowKey newRow)
397: throws TableCursorVetoException {
398: fireCursorChanging(oldRow, newRow);
399: }
400:
401: public void cursorChanged(TableDataProvider provider,
402: RowKey oldRow, RowKey newRow) {
403: fireCursorChanged(oldRow, newRow);
404: }
405: };
406:
407: private DataEars dataEars = new DataEars();
408: private CursorEars cursorEars = new CursorEars();
409: }
|