/* * @(#) ObjectGrouperManager.java * * Copyright 2002 - 2003 JIDE Software. All rights reserved. */ package com.jidesoft.grouper; import com.jidesoft.grouper.date.DateMonthGrouper; import com.jidesoft.grouper.date.DateYearGrouper; import com.jidesoft.utils.CacheMap; import com.jidesoft.utils.RegistrationListener; import java.util.Calendar; import java.util.Date; /** * A global object that can register Object Grouper with a type and a GrouperContext. */ public class ObjectGrouperManager { private static CacheMap<ObjectGrouper, GrouperContext> _cache = new CacheMap<ObjectGrouper, GrouperContext>(GrouperContext.DEFAULT_CONTEXT); private static ObjectGrouper _defaultGrouper = null; /** * Registers a grouper with the type specified as class and a grouper context specified as context. * * @param clazz type * @param grouper group to be registered * @param context the grouper context. */ public static void registerGrouper(Class<?> clazz, ObjectGrouper grouper, GrouperContext context) { if (clazz == null) { throw new IllegalArgumentException("Parameter class cannot be null"); } if (context == null) { context = GrouperContext.DEFAULT_CONTEXT; } if (isAutoInit() && !_inited && !_initing) { initDefaultGrouper(); } _cache.register(clazz, grouper, context); } /** * Registers a grouper with type specified as clazz. * * @param clazz the data type. * @param grouper the grouper to be registered */ public static void registerGrouper(Class<?> clazz, ObjectGrouper grouper) { registerGrouper(clazz, grouper, GrouperContext.DEFAULT_CONTEXT); } /** * Unregisters grouper associated with clazz and context. * * @param clazz the data type. * @param context the grouper context. */ public static void unregisterGrouper(Class<?> clazz, GrouperContext context) { if (context == null) { context = GrouperContext.DEFAULT_CONTEXT; } if (isAutoInit() && !_inited && !_initing) { initDefaultGrouper(); } _cache.unregister(clazz, context); } /** * Unregisters grouper associated with clazz. * * @param clazz the data type. */ public static void unregisterGrouper(Class<?> clazz) { unregisterGrouper(clazz, GrouperContext.DEFAULT_CONTEXT); } /** * Unregisters all groupers associated with clazz. * * @param clazz the data type. */ public static void unregisterAllGroupers(Class<?> clazz) { _cache.remove(clazz); } /** * Unregisters all the groupers which registered before. */ public static void unregisterAllGroupers() { _cache.clear(); } /** * Gets the registered grouper associated with class and context. * * @param clazz the data type. * @param context the grouper context. * * @return the registered grouper. It could return null if there is no grouper for the type and the context. */ public static ObjectGrouper getGrouper(Class<?> clazz, GrouperContext context) { if (isAutoInit() && !_inited && !_initing) { initDefaultGrouper(); } if (context == null) { context = GrouperContext.DEFAULT_CONTEXT; } ObjectGrouper object = _cache.getRegisteredObject(clazz, context); if (object != null) { return object; } else { return _defaultGrouper; } } /** * Gets the grouper associated with the type. * * @param clazz the data type. * * @return the grouper. It could return null if there is no grouper for the type. */ public static ObjectGrouper getGrouper(Class<?> clazz) { return getGrouper(clazz, GrouperContext.DEFAULT_CONTEXT); } /** * Converts an object to string using default grouper context. * * @param object object to be converted. * * @return the string */ public static Object getGroupValue(Object object) { if (object != null) return getGroupValue(object, object.getClass(), GrouperContext.DEFAULT_CONTEXT); else return null; } /** * Converts an object to string using default grouper context. * * @param object object to be converted. * @param clazz type of the object * * @return the string */ public static Object getGroupValue(Object object, Class<?> clazz) { return getGroupValue(object, clazz, GrouperContext.DEFAULT_CONTEXT); } /** * Converts an object to string using grouper context specified. * * @param object object to be converted. * @param clazz type of the object * @param context group context * * @return the string converted from object */ public static Object getGroupValue(Object object, Class<?> clazz, GrouperContext context) { ObjectGrouper grouper = getGrouper(clazz, context); if (grouper != null) { return grouper.getValue(object); } return null; } private static boolean _inited = false; private static boolean _initing = false; private static boolean _autoInit = true; /** * Checks the value of autoInit. * * @return true or false. * * @see #setAutoInit(boolean) */ public static boolean isAutoInit() { return _autoInit; } /** * Sets autoInit to true or false. If autoInit is true, whenever someone tries to call methods getValue, {@link * #initDefaultGrouper()} will be called if it has never be called. By default, autoInit is true. * <p/> * This might affect the behavior if users provide their own groupers and want to overwrite default groupers. In * this case, instead of depending on autoInit to initialize default groupers, you should call {@link * #initDefaultGrouper()} first, then call registerGrouper to add your own groupers. * * @param autoInit false if you want to disable autoInit which means you either don't want those default comparators * registered or you will call {@link #initDefaultGrouper()} yourself. */ public static void setAutoInit(boolean autoInit) { _autoInit = autoInit; } /** * Adds a listener to the list that's notified each time a change to the manager occurs. * * @param l the RegistrationListener */ public static void addRegistrationListener(RegistrationListener l) { _cache.addRegistrationListener(l); } /** * Removes a listener from the list that's notified each time a change to the manager occurs. * * @param l the RegistrationListener */ public static void removeRegistrationListener(RegistrationListener l) { _cache.removeRegistrationListener(l); } /** * Returns an array of all the registration listeners registered on this manager. * * @return all of this registration's <code>RegistrationListener</code>s or an empty array if no registration * listeners are currently registered * * @see #addRegistrationListener * @see #removeRegistrationListener */ public static RegistrationListener[] getRegistrationListeners() { return _cache.getRegistrationListeners(); } /** * Gets the available GrouperContexts registered with the class. * * @param clazz the class. * * @return the available GrouperContexts. */ public static GrouperContext[] getGrouperContexts(Class<?> clazz) { return _cache.getKeys(clazz, new GrouperContext[0]); } /** * Initialize default groupers. Please make sure you call this method before you use any group related classes. By * default we register following groupers. * <code><pre> * DateYearGrouper dateYearGrouper = new DateYearGrouper(); * registerGrouper(Date.class, dateYearGrouper, DateYearGrouper.CONTEXT); * registerGrouper(Calendar.class, dateYearGrouper, DateYearGrouper.CONTEXT); * registerGrouper(Long.class, dateYearGrouper, DateYearGrouper.CONTEXT); * DateMonthGrouper dateMonthGrouper = new DateMonthGrouper(); * registerGrouper(Date.class, dateMonthGrouper, DateMonthGrouper.CONTEXT); * registerGrouper(Calendar.class, dateMonthGrouper, DateMonthGrouper.CONTEXT); * registerGrouper(Long.class, dateMonthGrouper, DateMonthGrouper.CONTEXT); * </pre></code> */ public static void initDefaultGrouper() { if (_inited) { return; } _initing = true; try { DateYearGrouper dateYearGrouper = new DateYearGrouper(); registerGrouper(Date.class, dateYearGrouper, DateYearGrouper.CONTEXT); registerGrouper(Calendar.class, dateYearGrouper, DateYearGrouper.CONTEXT); registerGrouper(Long.class, dateYearGrouper, DateYearGrouper.CONTEXT); DateMonthGrouper dateMonthGrouper = new DateMonthGrouper(); registerGrouper(Date.class, dateMonthGrouper, DateMonthGrouper.CONTEXT); registerGrouper(Calendar.class, dateMonthGrouper, DateMonthGrouper.CONTEXT); registerGrouper(Long.class, dateMonthGrouper, DateMonthGrouper.CONTEXT); } finally { _initing = false; _inited = true; } } /** * If {@link #initDefaultGrouper()} is called once, calling it again will have no effect because an internal flag is * set. This method will reset the internal flag so that you can call {@link #initDefaultGrouper()} in case you * unregister all groupers using {@link #unregisterAllGroupers()}. */ public static void resetInit() { _inited = false; } public static void clear() { resetInit(); _cache.clear(); } }