src/core/net/sf/basedb/util/formatter/MultiFormatter.java

Code
Comments
Other
Rev Date Author Line
2942 22 Nov 06 nicklas 1 /**
2942 22 Nov 06 nicklas 2   $Id$
2942 22 Nov 06 nicklas 3
3675 16 Aug 07 jari 4   Copyright (C) 2006 Nicklas Nordborg
2942 22 Nov 06 nicklas 5
2942 22 Nov 06 nicklas 6   This file is part of BASE - BioArray Software Environment.
2942 22 Nov 06 nicklas 7   Available at http://base.thep.lu.se/
2942 22 Nov 06 nicklas 8
2942 22 Nov 06 nicklas 9   BASE is free software; you can redistribute it and/or
2942 22 Nov 06 nicklas 10   modify it under the terms of the GNU General Public License
4479 05 Sep 08 jari 11   as published by the Free Software Foundation; either version 3
2942 22 Nov 06 nicklas 12   of the License, or (at your option) any later version.
2942 22 Nov 06 nicklas 13
2942 22 Nov 06 nicklas 14   BASE is distributed in the hope that it will be useful,
2942 22 Nov 06 nicklas 15   but WITHOUT ANY WARRANTY; without even the implied warranty of
2942 22 Nov 06 nicklas 16   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
2942 22 Nov 06 nicklas 17   GNU General Public License for more details.
2942 22 Nov 06 nicklas 18
2942 22 Nov 06 nicklas 19   You should have received a copy of the GNU General Public License
4515 11 Sep 08 jari 20   along with BASE. If not, see <http://www.gnu.org/licenses/>.
2942 22 Nov 06 nicklas 21 */
2942 22 Nov 06 nicklas 22 package net.sf.basedb.util.formatter;
2942 22 Nov 06 nicklas 23
2942 22 Nov 06 nicklas 24 import java.util.HashMap;
2942 22 Nov 06 nicklas 25 import java.util.Map;
2942 22 Nov 06 nicklas 26
7649 14 Mar 19 nicklas 27 import net.sf.basedb.util.excel.ExcelFormatter;
7649 14 Mar 19 nicklas 28 import net.sf.basedb.util.excel.ExcelValue;
2942 22 Nov 06 nicklas 29
7649 14 Mar 19 nicklas 30
2942 22 Nov 06 nicklas 31 /**
2942 22 Nov 06 nicklas 32    A generic formatter that can be used to format objects of mixed classes.
2942 22 Nov 06 nicklas 33    To use it you register a formatter for each class you expect to use. 
2942 22 Nov 06 nicklas 34    A default formatter is used for objects with unregistered classes.
2942 22 Nov 06 nicklas 35    <p>
2942 22 Nov 06 nicklas 36    Null values return the empty string.
2942 22 Nov 06 nicklas 37    
2942 22 Nov 06 nicklas 38   @author nicklas
2942 22 Nov 06 nicklas 39   @version 2.0
2942 22 Nov 06 nicklas 40   @base.modified $Date$
2942 22 Nov 06 nicklas 41 */
2942 22 Nov 06 nicklas 42 public class MultiFormatter
7649 14 Mar 19 nicklas 43   implements Formatter<Object>, ExcelFormatter<Object, Object>
2942 22 Nov 06 nicklas 44 {
2942 22 Nov 06 nicklas 45
2942 22 Nov 06 nicklas 46   private final Formatter<Object> defaultFormatter;
2942 22 Nov 06 nicklas 47   private final boolean checkSuperclass;
6875 20 Apr 15 nicklas 48   private final Map<Class<?>, Formatter<Object>> formatters;
4371 03 Jul 08 nicklas 49   private final boolean decideOnFirst;
6875 20 Apr 15 nicklas 50   private Formatter<Object> formatter;
2942 22 Nov 06 nicklas 51   
2942 22 Nov 06 nicklas 52   /**
2942 22 Nov 06 nicklas 53     Create a new multi formatter.
2942 22 Nov 06 nicklas 54     @param defaultFormatter The formatter to use if the object's class
2942 22 Nov 06 nicklas 55       isn't found among the registered formatters
5319 20 Apr 10 nicklas 56     @param checkSuperclass If the superclass and interfaces of the object should be
2942 22 Nov 06 nicklas 57       checked in case there is no exact match
2942 22 Nov 06 nicklas 58   */
2942 22 Nov 06 nicklas 59   public MultiFormatter(Formatter<Object> defaultFormatter, boolean checkSuperclass)
2942 22 Nov 06 nicklas 60   {
4371 03 Jul 08 nicklas 61     this(defaultFormatter, checkSuperclass, false);
4371 03 Jul 08 nicklas 62   }
4371 03 Jul 08 nicklas 63   
4371 03 Jul 08 nicklas 64   /**
4371 03 Jul 08 nicklas 65     Create a new multi formatter.
4371 03 Jul 08 nicklas 66     @param defaultFormatter The formatter to use if the object's class
4371 03 Jul 08 nicklas 67       isn't found among the registered formatters
5319 20 Apr 10 nicklas 68     @param checkSuperclass If the superclass and interfaces of the object should be
4371 03 Jul 08 nicklas 69       checked in case there is no exact match
4371 03 Jul 08 nicklas 70     @param decideOnFirst If TRUE, the first non-null value decides which parent
4371 03 Jul 08 nicklas 71       formatter to use. All subsequent calls to {@link #format(Object)} uses
4371 03 Jul 08 nicklas 72       the same formatetter. This is useful when you know that the formatter will
4371 03 Jul 08 nicklas 73       only use the same class of objects, but not which class.
4371 03 Jul 08 nicklas 74     @since 2.7.2
4371 03 Jul 08 nicklas 75   */
4371 03 Jul 08 nicklas 76   public MultiFormatter(Formatter<Object> defaultFormatter, boolean checkSuperclass, 
4371 03 Jul 08 nicklas 77     boolean decideOnFirst)
4371 03 Jul 08 nicklas 78   {
2942 22 Nov 06 nicklas 79     this.defaultFormatter = defaultFormatter;
6875 20 Apr 15 nicklas 80     this.formatters = new HashMap<Class<?>, Formatter<Object>>();
2942 22 Nov 06 nicklas 81     this.checkSuperclass = checkSuperclass;
4371 03 Jul 08 nicklas 82     this.decideOnFirst = decideOnFirst;
2942 22 Nov 06 nicklas 83   }
2942 22 Nov 06 nicklas 84   
2942 22 Nov 06 nicklas 85   /*
2942 22 Nov 06 nicklas 86     From the Formatter interface
2942 22 Nov 06 nicklas 87     -------------------------------------------
2942 22 Nov 06 nicklas 88   */
6127 14 Sep 12 nicklas 89   @Override
2942 22 Nov 06 nicklas 90   public String format(Object value)
2942 22 Nov 06 nicklas 91   {
2942 22 Nov 06 nicklas 92     if (value == null) return "";
7649 14 Mar 19 nicklas 93     Formatter<Object> f = getFormatter(value);
7649 14 Mar 19 nicklas 94     return f.format(value);
7649 14 Mar 19 nicklas 95   }
7649 14 Mar 19 nicklas 96   @Override
7649 14 Mar 19 nicklas 97   public Number parseString(String value)
7649 14 Mar 19 nicklas 98   {
7649 14 Mar 19 nicklas 99     throw new UnsupportedOperationException("parseString");
7649 14 Mar 19 nicklas 100   }
7649 14 Mar 19 nicklas 101   // -------------------------------------------
7649 14 Mar 19 nicklas 102
7649 14 Mar 19 nicklas 103   private Formatter<Object> getFormatter(Object value)
7649 14 Mar 19 nicklas 104   {
6875 20 Apr 15 nicklas 105     Class<?> c = value.getClass();
6875 20 Apr 15 nicklas 106     Formatter<Object> f = formatter;
4371 03 Jul 08 nicklas 107     if (f == null)
2942 22 Nov 06 nicklas 108     {
4371 03 Jul 08 nicklas 109       f = formatters.get(c);
4371 03 Jul 08 nicklas 110       if (f == null && checkSuperclass)
2942 22 Nov 06 nicklas 111       {
2942 22 Nov 06 nicklas 112         c = c.getSuperclass();
6875 20 Apr 15 nicklas 113         Class<?>[] interfaces = c.getInterfaces();
4371 03 Jul 08 nicklas 114         while (f == null && c != null)
4371 03 Jul 08 nicklas 115         {
4371 03 Jul 08 nicklas 116           f = formatters.get(c);
4371 03 Jul 08 nicklas 117           c = c.getSuperclass();
4371 03 Jul 08 nicklas 118         }
5319 20 Apr 10 nicklas 119         if (f == null)
5319 20 Apr 10 nicklas 120         {
6875 20 Apr 15 nicklas 121           for (Class<?> iface : interfaces)
5319 20 Apr 10 nicklas 122           {
5319 20 Apr 10 nicklas 123             f = formatters.get(iface);
5319 20 Apr 10 nicklas 124             if (f != null) break;
5319 20 Apr 10 nicklas 125           }
5319 20 Apr 10 nicklas 126         }
2942 22 Nov 06 nicklas 127       }
4371 03 Jul 08 nicklas 128       if (f == null) f = defaultFormatter;
4371 03 Jul 08 nicklas 129       if (decideOnFirst) formatter = f;
2942 22 Nov 06 nicklas 130     }
7649 14 Mar 19 nicklas 131     return f;
2942 22 Nov 06 nicklas 132   }
7649 14 Mar 19 nicklas 133   
2942 22 Nov 06 nicklas 134   /**
2942 22 Nov 06 nicklas 135     Register a formatter for the specified class.
2942 22 Nov 06 nicklas 136     @param clazz The class of objects to format with the formatter
2942 22 Nov 06 nicklas 137     @param formatter The formatter
2942 22 Nov 06 nicklas 138   */
6875 20 Apr 15 nicklas 139   @SuppressWarnings({ "unchecked", "rawtypes" })
2942 22 Nov 06 nicklas 140   public <T> void registerFormatter(Class<? extends T> clazz, Formatter<T> formatter)
2942 22 Nov 06 nicklas 141   {
6875 20 Apr 15 nicklas 142     formatters.put((Class)clazz, (Formatter)formatter);
2942 22 Nov 06 nicklas 143   }
7649 14 Mar 19 nicklas 144
7649 14 Mar 19 nicklas 145   @SuppressWarnings({ "rawtypes", "unchecked" })
7649 14 Mar 19 nicklas 146   @Override
7649 14 Mar 19 nicklas 147   public ExcelValue<Object> toExcelValue(Object value) 
7649 14 Mar 19 nicklas 148   {
7649 14 Mar 19 nicklas 149     if (value == null) return null;
7649 14 Mar 19 nicklas 150     Formatter<Object> f = getFormatter(value);
7649 14 Mar 19 nicklas 151     ExcelValue ev = null;
7649 14 Mar 19 nicklas 152     if (f instanceof ExcelFormatter)
7649 14 Mar 19 nicklas 153     {
7649 14 Mar 19 nicklas 154       ExcelFormatter ef = (ExcelFormatter)f;
7649 14 Mar 19 nicklas 155       ev = ef.toExcelValue(value);
7649 14 Mar 19 nicklas 156     }
7649 14 Mar 19 nicklas 157     else
7649 14 Mar 19 nicklas 158     {
7649 14 Mar 19 nicklas 159       ev = ExcelValue.asString(f.format(value));
7649 14 Mar 19 nicklas 160     }
7649 14 Mar 19 nicklas 161     return ev;
7649 14 Mar 19 nicklas 162   }
2942 22 Nov 06 nicklas 163 }