001: /**
002: * Copyright 2006 Webmedia Group Ltd.
003: *
004: * Licensed under the Apache License, Version 2.0 (the "License");
005: * you may not use this file except in compliance with the License.
006: * You may obtain a copy of the License at
007: *
008: * http://www.apache.org/licenses/LICENSE-2.0
009: *
010: * Unless required by applicable law or agreed to in writing, software
011: * distributed under the License is distributed on an "AS IS" BASIS,
012: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013: * See the License for the specific language governing permissions and
014: * limitations under the License.
015: **/package org.araneaframework.uilib.list;
016:
017: import java.io.Serializable;
018: import java.util.Comparator;
019: import java.util.HashMap;
020: import java.util.Locale;
021: import java.util.Map;
022: import org.araneaframework.Environment;
023: import org.araneaframework.core.Assert;
024: import org.araneaframework.framework.LocalizationContext;
025: import org.araneaframework.uilib.list.util.ComparatorFactory;
026:
027: /**
028: * List fields types and comparators helper.
029: *
030: * @author <a href="mailto:rein@araneaframework.org">Rein Raudjärv</a>
031: *
032: * @see ListWidget
033: */
034: public class TypeHelper implements Serializable {
035:
036: // Configuration
037: private Locale locale;
038: private boolean ignoreCase = true;
039:
040: // Map<String,Comparator> - custom comparators for fields
041: private Map comparators = new HashMap();
042: // Map<String,Class> - field types
043: private Map types = new HashMap();
044:
045: private boolean initialized = false;
046: private boolean changed = true;
047:
048: public void init(Environment env) throws Exception {
049: if (locale == null) {
050: LocalizationContext l10nCtx = (LocalizationContext) env
051: .getEntry(LocalizationContext.class);
052: if (l10nCtx != null) {
053: locale = l10nCtx.getLocale();
054: }
055: if (locale == null) {
056: locale = Locale.getDefault();
057: }
058: }
059: initialized = true;
060: fireChange();
061: }
062:
063: private boolean isInitialized() {
064: return this .initialized;
065: }
066:
067: public void destroy() throws Exception {
068: }
069:
070: public boolean isIgnoreCase() {
071: return ignoreCase;
072: }
073:
074: public void setIgnoreCase(boolean ignoreCase) {
075: if (this .ignoreCase == ignoreCase)
076: return;
077: this .ignoreCase = ignoreCase;
078: fireChange();
079: }
080:
081: public Locale getLocale() {
082: if (!isInitialized()) {
083: throw new IllegalStateException("Must be initialized first");
084: }
085: return locale;
086: }
087:
088: public void setLocale(Locale locale) {
089: if (locale.equals(this .locale))
090: return;
091:
092: this .locale = locale;
093: fireChange();
094: }
095:
096: // List fields
097:
098: /**
099: * Returns a comparator for the specifeid field.
100: * <p>
101: * First, a custom comparator is returned if found.
102: * <p>
103: * </p>
104: * Otherwise a comparator is tryed to create according to the field type
105: * returned by {@link #getFieldType(String)}.
106: * Also {@link #isIgnoreCase()} and {@link #getLocale()} is considered for
107: * creating the new comparator.
108: *
109: * @param fieldId
110: * field Id.
111: * @return comparator for this field.
112: */
113: public Comparator getFieldComparator(String fieldId) {
114: Comparator result = getCustomComparator(fieldId);
115: if (result == null) {
116: result = buildComparator(getFieldType(fieldId));
117: }
118: return result;
119: }
120:
121: public void addFieldType(String fieldId, Class type) {
122: this .types.put(fieldId, type);
123: fireChange();
124: }
125:
126: /**
127: * Returns the field type.
128: * <p>
129: * Returns <code>null</code> if no type specifeid for this field or no
130: * such field exists.
131: *
132: * @param fieldId
133: * field Id.
134: * @return type of this field.
135: */
136: public Class getFieldType(String fieldId) {
137: return (Class) this .types.get(fieldId);
138: }
139:
140: public Class removeFieldType(String fieldId) {
141: Class result = (Class) this .types.remove(fieldId);
142: fireChange();
143: return result;
144: }
145:
146: public void addCustomComparator(String fieldId, Comparator comp) {
147: this .comparators.put(fieldId, comp);
148: fireChange();
149: }
150:
151: public Comparator getCustomComparator(String fieldId) {
152: return (Comparator) this .comparators.get(fieldId);
153: }
154:
155: public Comparator removeCustomComparator(String fieldId) {
156: Comparator result = (Comparator) this .comparators
157: .remove(fieldId);
158: fireChange();
159: return result;
160: }
161:
162: // Comparator
163:
164: protected Comparator buildComparator(Class type) {
165: Assert.notNullParam(this , type, "type");
166:
167: if (String.class.equals(type)) {
168: return ComparatorFactory.getStringComparator(isNullFirst(),
169: isIgnoreCase(), getLocale());
170: }
171: // Boolean is Comparable since Java 1.5
172: if (Boolean.class.equals(type)
173: && !Boolean.class.isAssignableFrom(Comparable.class)) {
174: return ComparatorFactory.getBooleanComparator(
175: isNullFirst(), isTrueFirst());
176: }
177: return ComparatorFactory.getDefault();
178: }
179:
180: protected boolean isNullFirst() {
181: return ComparatorFactory.NULL_FIRST_BY_DEFAULT;
182: }
183:
184: protected boolean isTrueFirst() {
185: return ComparatorFactory.TRUE_FIRST_BY_DEFAULT;
186: }
187:
188: /**
189: * @since 1.1
190: */
191: protected void fireChange() {
192: changed = true;
193: }
194:
195: /**
196: * Returns whether the basic configuration that specifies which items are
197: * shown has changed since last call to this {@link TypeHelper}'s {@link TypeHelper#checkChanged()}
198: * method.
199: *
200: * @since 1.1
201: */
202: public boolean checkChanged() {
203: boolean result = changed;
204: changed = false;
205: return result;
206: }
207: }
|