001: /*
002: * @(#) ObjectGrouperManager.java
003: *
004: * Copyright 2002 - 2003 JIDE Software. All rights reserved.
005: */
006: package com.jidesoft.grouper;
007:
008: import com.jidesoft.converter.CacheMap;
009: import com.jidesoft.converter.RegistrationListener;
010: import com.jidesoft.grouper.date.DateMonthGrouper;
011: import com.jidesoft.grouper.date.DateYearGrouper;
012:
013: import java.util.Calendar;
014: import java.util.Date;
015:
016: /**
017: * A global object that can register Object Grouper with a type and a GrouperContext.
018: */
019: public class ObjectGrouperManager {
020:
021: private static CacheMap<ObjectGrouper, GrouperContext> _cache = new CacheMap<ObjectGrouper, GrouperContext>(
022: GrouperContext.DEFAULT_CONTEXT);
023:
024: private static ObjectGrouper _defaultGrouper = null;
025:
026: /**
027: * Registers a grouper with the type specified as class and a grouper context specified as context.
028: *
029: * @param clazz type
030: * @param grouper group to be registered
031: * @param context the grouper context.
032: */
033: public static void registerGrouper(Class<?> clazz,
034: ObjectGrouper grouper, GrouperContext context) {
035: if (clazz == null) {
036: throw new IllegalArgumentException(
037: "Parameter class cannot be null");
038: }
039:
040: if (context == null) {
041: context = GrouperContext.DEFAULT_CONTEXT;
042: }
043: _cache.register(clazz, grouper, context);
044: }
045:
046: /**
047: * Registers a grouper with type specified as clazz.
048: *
049: * @param clazz the data type.
050: * @param grouper the grouper to be registered
051: */
052: public static void registerGrouper(Class<?> clazz,
053: ObjectGrouper grouper) {
054: registerGrouper(clazz, grouper, GrouperContext.DEFAULT_CONTEXT);
055: }
056:
057: /**
058: * Unregisters grouper associated with clazz and context.
059: *
060: * @param clazz the data type.
061: * @param context the grouper context.
062: */
063: public static void unregisterGrouper(Class<?> clazz,
064: GrouperContext context) {
065: if (context == null) {
066: context = GrouperContext.DEFAULT_CONTEXT;
067: }
068: _cache.unregister(clazz, context);
069: }
070:
071: /**
072: * Unregisters grouper associated with clazz.
073: *
074: * @param clazz the data type.
075: */
076: public static void unregisterGrouper(Class<?> clazz) {
077: unregisterGrouper(clazz, GrouperContext.DEFAULT_CONTEXT);
078: }
079:
080: /**
081: * Unregisters all the groupers which registered before.
082: */
083: public static void unregisterAllGroupers() {
084: _cache.clear();
085: }
086:
087: /**
088: * Gets the registered grouper associated with class and context.
089: *
090: * @param clazz the data type.
091: * @param context the grouper context.
092: * @return the registered grouper. It could return null if there is no grouper for the type and the context.
093: */
094: public static ObjectGrouper getGrouper(Class<?> clazz,
095: GrouperContext context) {
096: if (isAutoInit()) {
097: initDefaultGrouper();
098: }
099:
100: if (context == null) {
101: context = GrouperContext.DEFAULT_CONTEXT;
102: }
103: ObjectGrouper object = _cache.getRegisteredObject(clazz,
104: context);
105: if (object != null) {
106: return object;
107: } else {
108: return _defaultGrouper;
109: }
110: }
111:
112: /**
113: * Gets the grouper associated with the type.
114: *
115: * @param clazz the data type.
116: * @return the grouper. It could return null if there is no grouper for the type.
117: */
118: public static ObjectGrouper getGrouper(Class<?> clazz) {
119: return getGrouper(clazz, GrouperContext.DEFAULT_CONTEXT);
120: }
121:
122: /**
123: * Converts an object to string using default grouper context.
124: *
125: * @param object object to be converted.
126: * @return the string
127: */
128: public static Object getGroupValue(Object object) {
129: if (object != null)
130: return getValue(object, object.getClass(),
131: GrouperContext.DEFAULT_CONTEXT);
132: else
133: return null;
134: }
135:
136: /**
137: * Converts an object to string using default grouper context.
138: *
139: * @param object object to be converted.
140: * @param clazz type of the object
141: * @return the string
142: */
143: public static Object getGroupValue(Object object, Class<?> clazz) {
144: return getValue(object, clazz, GrouperContext.DEFAULT_CONTEXT);
145: }
146:
147: /**
148: * Converts an object to string using grouper context sepcified.
149: *
150: * @param object object to be converted.
151: * @param clazz type of the object
152: * @param context group context
153: * @return the string converted from object
154: */
155: public static Object getValue(Object object, Class<?> clazz,
156: GrouperContext context) {
157: ObjectGrouper grouper = getGrouper(clazz, context);
158: if (grouper != null) {
159: return grouper.getValue(object);
160: }
161: return null;
162: }
163:
164: private static boolean _inited = false;
165: private static boolean _autoInit = true;
166:
167: /**
168: * Checks the value of autoInit.
169: *
170: * @return true or false.
171: * @see #setAutoInit(boolean)
172: */
173: public static boolean isAutoInit() {
174: return _autoInit;
175: }
176:
177: /**
178: * Sets autoInit to true or false. If autoInit is true, whenever someone tries to call methods getValue,
179: * {@link #initDefaultGrouper()} will be called if it has never be called. By default, autoInit is true.
180: * <p/>
181: * This might affect the behavior if users provide their own groupers and want to overwrite
182: * default groupers. In this case, instead of depending on autoInit to initialize default groupers,
183: * you should call {@link #initDefaultGrouper()} first, then call registerGrouper to add your own groupers.
184: *
185: * @param autoInit false if you want to disable autoInit which means you either don't
186: * want those default comparators registered or you will call {@link #initDefaultGrouper()} yourself.
187: */
188: public static void setAutoInit(boolean autoInit) {
189: _autoInit = autoInit;
190: }
191:
192: /**
193: * Adds a listener to the list that's notified each time a change
194: * to the manager occurs.
195: *
196: * @param l the RegistrationListener
197: */
198: public static void addRegistrationListener(RegistrationListener l) {
199: _cache.addRegistrationListener(l);
200: }
201:
202: /**
203: * Removes a listener from the list that's notified each time a
204: * change to the manager occurs.
205: *
206: * @param l the RegistrationListener
207: */
208: public static void removeRegistrationListener(RegistrationListener l) {
209: _cache.removeRegistrationListener(l);
210: }
211:
212: /**
213: * Returns an array of all the registration listeners
214: * registered on this manager.
215: *
216: * @return all of this registration's <code>RegistrationListener</code>s
217: * or an empty array if no registration listeners are currently registered
218: * @see #addRegistrationListener
219: * @see #removeRegistrationListener
220: */
221: public static RegistrationListener[] getRegistrationListeners() {
222: return _cache.getRegistrationListeners();
223: }
224:
225: /**
226: * Gets the available GrouperContexts registered with the class.
227: *
228: * @param clazz the class.
229: * @return the available GrouperContexts.
230: */
231: public static GrouperContext[] getGrouperContexts(Class<?> clazz) {
232: return _cache.getKeys(clazz, new GrouperContext[0]);
233: }
234:
235: /**
236: * Initialize default groupers. Please make sure you call this method before you use any
237: * group related classes. By default we register following groupers.
238: * <code><pre>
239: * DateYearGrouper dateYearGrouper = new DateYearGrouper();
240: * registerGrouper(Date.class, dateYearGrouper, DateYearGrouper.CONTEXT);
241: * registerGrouper(Calendar.class, dateYearGrouper, DateYearGrouper.CONTEXT);
242: * registerGrouper(Long.class, dateYearGrouper, DateYearGrouper.CONTEXT);
243: * DateMonthGrouper dateMonthGrouper = new DateMonthGrouper();
244: * registerGrouper(Date.class, dateMonthGrouper, DateMonthGrouper.CONTEXT);
245: * registerGrouper(Calendar.class, dateMonthGrouper, DateMonthGrouper.CONTEXT);
246: * registerGrouper(Long.class, dateMonthGrouper, DateMonthGrouper.CONTEXT);
247: * </pre></code>
248: */
249: public static void initDefaultGrouper() {
250: if (_inited) {
251: return;
252: }
253:
254: DateYearGrouper dateYearGrouper = new DateYearGrouper();
255: registerGrouper(Date.class, dateYearGrouper,
256: DateYearGrouper.CONTEXT);
257: registerGrouper(Calendar.class, dateYearGrouper,
258: DateYearGrouper.CONTEXT);
259: registerGrouper(Long.class, dateYearGrouper,
260: DateYearGrouper.CONTEXT);
261:
262: DateMonthGrouper dateMonthGrouper = new DateMonthGrouper();
263: registerGrouper(Date.class, dateMonthGrouper,
264: DateMonthGrouper.CONTEXT);
265: registerGrouper(Calendar.class, dateMonthGrouper,
266: DateMonthGrouper.CONTEXT);
267: registerGrouper(Long.class, dateMonthGrouper,
268: DateMonthGrouper.CONTEXT);
269:
270: _inited = true;
271: }
272:
273: /**
274: * If {@link #initDefaultGrouper()} is called once, calling it again will have no effect because an internal flag is set.
275: * This method will reset the internal flag so that you can call {@link #initDefaultGrouper()} in case you unresgister all
276: * groupers using {@link #unregisterAllGroupers()}.
277: */
278: public static void resetInit() {
279: _inited = false;
280: }
281: }
|