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 com.sun.data.provider.DataProviderException;
045: import com.sun.data.provider.FieldKey;
046: import java.util.ResourceBundle;
047:
048: /**
049: * <p>This {@link com.sun.data.provider.DataProvider} wraps access to a single
050: * Java Object. The {@link FieldKey}s correspond to the JavaBean properties and
051: * optionally the public member fields of the Java Object.</p>
052: *
053: * <p>NOTE about Serializable: This class wraps access to any Java Object. The
054: * Object can be swapped out using the <code>setObject(Object)</code> method.
055: * For this class to remain Serializable, the contained Object must also be
056: * Serializable.</p>
057: *
058: * @author Joe Nuxoll
059: * Winston Prakash (bug fixes)
060: */
061: public class ObjectDataProvider extends AbstractDataProvider {
062:
063: // ------------------------------------------------------ Instance Variables
064:
065: /**
066: * <p>Resource bundle containing our localized messages.</p>
067: */
068: private transient ResourceBundle bundle = null;
069:
070: /**
071: * Storage for the includeFields property. By default, this is true.
072: */
073: private boolean includeFields = true;
074:
075: /**
076: * <p>The object being wrapped by this
077: * {@link com.sun.data.provider.DataProvider}.</p>
078: *
079: * <p>NOTE about Serializable: This class wraps access to any Java Object.
080: * The Object can be swapped out using the <code>setObject(Object)</code>
081: * method. For this class to remain Serializable, the contained Object
082: * must also be Serializable.</p>
083: */
084: private Object object;
085:
086: // ----------------------------------------------------------- Constructors
087:
088: /**
089: * Constructs a new ObjectDataProvider with default settings, and no
090: * contained Object. Use setObject to set the contained Object.
091: */
092: public ObjectDataProvider() {
093:
094: this (null, false);
095:
096: }
097:
098: /**
099: * Constructs a new ObjectDataProvider to wrap the specified Object.
100: *
101: * @param object The Object to wrap as a DataProvider
102: */
103: public ObjectDataProvider(Object object) {
104:
105: this (object, false);
106:
107: }
108:
109: /**
110: * Creates a new ObjectDataProvider to wrap the specified Object. The
111: * public fields will be included if 'includeFields' is set to true.
112: *
113: * @param object The Object to wrap as a DataProvider
114: * @param includeFields true to include the public fields, false to only
115: * surface the public properties as FieldKeys.
116: */
117: public ObjectDataProvider(Object object, boolean includeFields) {
118:
119: this .includeFields = includeFields;
120: setObject(object);
121:
122: }
123:
124: // ------------------------------------------------------------- Properties
125:
126: /**
127: * @return The Object being represented by this DataProvider
128: */
129: public Object getObject() {
130: return object;
131: }
132:
133: /**
134: * Sets the Object to be wrapped by this DataProvider. Calling this method
135: * will result in the passed object being introspected to populate the list
136: * of public properties and fields to make up the list of FieldKeys.
137: *
138: * @param object The Object to be wrapped by this DataProvider
139: */
140: public void setObject(Object object) {
141: this .object = object;
142: this .support = null;
143:
144: }
145:
146: /**
147: * @return The boolean state of the includeFields property
148: */
149: public boolean isIncludeFields() {
150:
151: return includeFields;
152:
153: }
154:
155: /**
156: * <p>Sets the includeFields property. This affects the set of {@link
157: * FieldKey}s that this {@link com.sun.data.provider.DataProvider} emits.
158: * If includeFields is set to true (the default), then public fields will
159: * be included in the list of available keys (intermixed with the public
160: * properties). If it is set to false, then only the public properties
161: * will be available.</p>
162: *
163: * @param includeFields <code>true</code> to include the public fields, or
164: * <code>false</code> to exclude them (and only show public
165: * properties)
166: */
167: public void setIncludeFields(boolean includeFields) {
168:
169: this .includeFields = includeFields;
170: this .support = null;
171:
172: }
173:
174: // ---------------------------------------------------- DataProvider Methods
175:
176: /** {@inheritDoc} */
177: public FieldKey getFieldKey(String fieldId)
178: throws DataProviderException {
179: FieldKey fieldKey = null;
180: if (getSupport() != null) {
181: fieldKey = getSupport().getFieldKey(fieldId);
182: }
183: if (fieldKey != null) {
184: return fieldKey;
185: } else {
186: throw new IllegalArgumentException(fieldId);
187: }
188:
189: }
190:
191: /** {@inheritDoc} */
192: public FieldKey[] getFieldKeys() throws DataProviderException {
193:
194: if (getSupport() != null) {
195: return getSupport().getFieldKeys();
196: }
197: return FieldKey.EMPTY_ARRAY;
198:
199: }
200:
201: /** {@inheritDoc} */
202: public Class getType(FieldKey fieldKey)
203: throws DataProviderException {
204: if ((getSupport() == null)
205: || (getSupport().getFieldKey(fieldKey.getFieldId()) == null)) {
206: throw new IllegalArgumentException(fieldKey.toString());
207: } else {
208: return getSupport().getType(fieldKey);
209: }
210: }
211:
212: /** {@inheritDoc} */
213: public Object getValue(FieldKey fieldKey)
214: throws DataProviderException {
215:
216: if ((getSupport() == null)
217: || (getSupport().getFieldKey(fieldKey.getFieldId()) == null)) {
218: throw new IllegalArgumentException(fieldKey.toString());
219: }
220:
221: if (java.beans.Beans.isDesignTime() && object == null) {
222: // Fill the object with design time fake data
223: object = AbstractDataProvider
224: .getFakeData(object.getClass());
225: }
226:
227: return getSupport().getValue(fieldKey, object);
228: }
229:
230: /** {@inheritDoc} */
231: public void setValue(FieldKey fieldKey, Object value)
232: throws DataProviderException {
233:
234: if ((getSupport() == null)
235: || (getSupport().getFieldKey(fieldKey.getFieldId()) == null)) {
236: throw new IllegalArgumentException(fieldKey.toString());
237: }
238: if (getSupport().isReadOnly(fieldKey)) {
239: throw new IllegalStateException(fieldKey.toString() + " "
240: + getBundle().getString("IS_READ_ONLY"));
241: }
242: Object previous = getSupport().getValue(fieldKey, object);
243: getSupport().setValue(fieldKey, object, value);
244: fireValueChanged(fieldKey, previous, value);
245:
246: }
247:
248: /** {@inheritDoc} */
249: public boolean isReadOnly(FieldKey fieldKey)
250: throws DataProviderException {
251: if ((getSupport() == null)
252: || (getSupport().getFieldKey(fieldKey.getFieldId()) == null)) {
253: throw new IllegalArgumentException(fieldKey.toString());
254: }
255: return getSupport().isReadOnly(fieldKey);
256:
257: }
258:
259: // --------------------------------------------------------- Private Methods
260:
261: /**
262: * <p>Return the resource bundle containing our localized messages.</p>
263: */
264: private ResourceBundle getBundle() {
265:
266: if (bundle == null) {
267: bundle = ResourceBundle
268: .getBundle("com/sun/data/provider/impl/Bundle");
269: }
270: return bundle;
271:
272: }
273:
274: /**
275: * <p>The cached support object for field key manipulation. Must be
276: * transient because its content is not Serializable.</p>
277: */
278: private transient ObjectFieldKeySupport support = null;
279:
280: /**
281: * <p>Return the {@link ObjectFieldKeySupport} instance for the
282: * object class we are wrapping.</p>
283: */
284: private ObjectFieldKeySupport getSupport() {
285:
286: if ((support == null) && (object != null)) {
287: support = new ObjectFieldKeySupport(object.getClass(),
288: includeFields);
289: }
290: return support;
291:
292: }
293:
294: }
|