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: package com.sun.rave.web.ui.faces;
042:
043: import java.io.IOException;
044: import java.io.ObjectInputStream;
045: import java.io.ObjectOutputStream;
046: import java.util.Map;
047: import javax.faces.context.FacesContext;
048: import javax.faces.el.ValueBinding;
049: import com.sun.data.provider.RowKey;
050: import com.sun.data.provider.SortCriteria;
051: import com.sun.data.provider.TableDataProvider;
052: import com.sun.data.provider.impl.TableRowDataProvider;
053:
054: /**
055: * <p>The ValueBindingSortCriteria class is an implementation of SortCriteria
056: * that simply retrieves the sort value from the {@link ValueBinding}.</p>
057: *
058: * @author Joe Nuxoll
059: */
060: public class ValueBindingSortCriteria extends SortCriteria {
061:
062: /**
063: * Constructs a ValueBindingSortCriteria with no associated {@link ValueBinding}.
064: */
065: public ValueBindingSortCriteria() {
066: }
067:
068: /**
069: * Constructs a ValueBindingSortCriteria with the specified {@link ValueBinding}.
070: *
071: * @param valueBinding The desired ValueBinding
072: */
073: public ValueBindingSortCriteria(ValueBinding valueBinding) {
074: this .valueBinding = valueBinding;
075: }
076:
077: /**
078: * Constructs a ValueBindingSortCriteria with the specified {@link ValueBinding} and
079: * ascending state.
080: *
081: * @param valueBinding The desired ValueBinding
082: * @param ascending The desired boolean state for the ascending property
083: */
084: public ValueBindingSortCriteria(ValueBinding valueBinding,
085: boolean ascending) {
086: this .valueBinding = valueBinding;
087: this .setAscending(ascending);
088: }
089:
090: /**
091: * Returns the ValueBinding to use for this sort criteria.
092: *
093: * @return The currently set ValueBinding for this sort criteria
094: */
095: public ValueBinding getValueBinding() {
096: return valueBinding;
097: }
098:
099: /**
100: * Sets the ValueBinding for this sort criteria.
101: *
102: * @param valueBinding The desired ValueBinding for this sort criteria
103: */
104: public void setValueBinding(ValueBinding valueBinding) {
105: this .valueBinding = valueBinding;
106: }
107:
108: /**
109: * Returns the request map variable key that will be used to store the
110: * {@link TableRowDataProvider} for the current row being sorted. This
111: * allows value expressions to refer to the "current" row during the sort
112: * operation.
113: *
114: * @return String key to use for the {@link TableRowDataProvider}
115: */
116: public String getRequestMapKey() {
117: return requestMapKey;
118: }
119:
120: /**
121: * Sets the request map variable key that will be used to store the
122: * {@link TableRowDataProvider} for the current row being sorted. This
123: * allows value expressions to refer to the "current" row during the sort
124: * operation.
125: *
126: * @param requestMapKey String key to use for the {@link TableRowDataProvider}
127: */
128: public void setRequestMapKey(String requestMapKey) {
129: this .requestMapKey = requestMapKey;
130: }
131:
132: /**
133: * <p>If no display name is set, this returns the {@link ValueBinding}'s
134: * display name.</p>
135: *
136: * {@inheritDoc}
137: */
138: public String getDisplayName() {
139: String name = super .getDisplayName();
140: if ((name == null || "".equals(name)) && valueBinding != null) {
141: return valueBinding.getExpressionString();
142: }
143: return name;
144: }
145:
146: /**
147: * Returns the ValueBinding's value expresssion string.
148: *
149: * {@inheritDoc}
150: */
151: public String getCriteriaKey() {
152: return valueBinding != null ? valueBinding
153: .getExpressionString() : ""; // NOI18N
154: }
155:
156: /**
157: * <p>Returns the value from the {@link ValueBinding} ignoring the arguments.</p>
158: *
159: * {@inheritDoc}
160: */
161: public Object getSortValue(TableDataProvider provider, RowKey row) {
162:
163: if (valueBinding == null) {
164: return null;
165: }
166:
167: FacesContext facesContext = FacesContext.getCurrentInstance();
168: Map requestMap = facesContext.getExternalContext()
169: .getRequestMap();
170: Object value = null;
171:
172: synchronized (rowProviderLock) {
173:
174: Object storedRequestMapValue = null;
175: if (requestMapKey != null && !"".equals(requestMapKey)) {
176: storedRequestMapValue = requestMap.get(requestMapKey);
177: if (rowProvider == null) {
178: rowProvider = new TableRowDataProvider();
179: }
180: rowProvider.setTableDataProvider(provider);
181: rowProvider.setTableRow(row);
182: requestMap.put(requestMapKey, rowProvider);
183: }
184:
185: value = valueBinding.getValue(facesContext);
186:
187: if (requestMapKey != null && !"".equals(requestMapKey)) {
188: if (rowProvider != null) {
189: rowProvider.setTableDataProvider(null);
190: rowProvider.setTableRow(null);
191: }
192: requestMap.put(requestMapKey, storedRequestMapValue);
193: }
194: }
195:
196: return value;
197: }
198:
199: private transient ValueBinding valueBinding;
200: private String requestMapKey = "currentRow"; // NOI18N
201: private transient TableRowDataProvider rowProvider;
202: private String rowProviderLock = "rowProviderLock"; // this is a monitor lock for rowProvider
203:
204: private void writeObject(ObjectOutputStream out) throws IOException {
205:
206: // Serialize simple objects first
207: out.writeObject(requestMapKey);
208: out.writeObject(rowProviderLock);
209:
210: // Serialize valueBinding specially
211: if (valueBinding != null) {
212: out.writeObject(valueBinding.getExpressionString());
213: } else {
214: out.writeObject((String) null);
215: }
216:
217: // NOTE - rowProvider is reconstituted on demand,
218: // so we don't need to serialize it
219:
220: }
221:
222: private void readObject(ObjectInputStream in) throws IOException,
223: ClassNotFoundException {
224:
225: // Deserialize simple objects first
226: requestMapKey = (String) in.readObject();
227: rowProviderLock = (String) in.readObject();
228:
229: // Deserialize valueBinding specially
230: String s = (String) in.readObject();
231: if (s != null) {
232: FacesContext facesContext = FacesContext
233: .getCurrentInstance();
234: valueBinding = facesContext.getApplication()
235: .createValueBinding(s);
236: } else {
237: valueBinding = null;
238: }
239: }
240:
241: }
|