View Javadoc

1   package org.weda.converter.impl;
2   
3   import java.util.HashMap;
4   import java.util.List;
5   import java.util.Map;
6   import org.weda.message.Messages;
7   import org.weda.converter.ValueTypeConverter;
8   import org.weda.converter.ValueTypeConverterException;
9   import org.weda.message.MessagesRegistry;
10  import org.weda.message.impl.MessagesSubset;
11  
12  /**
13   *
14   * @author tim
15   */
16  public class ConverterRegistryImpl implements ValueTypeConverter{
17      private final static Map<Class, Class> PRIMITIVS_TYPES = 
18                  new HashMap<Class, Class>();
19      private List<ValueTypeConverterInfo> converterInfos;
20      private MessagesRegistry messagesRegistry;
21      private Map<Class/*fromClass*/, Map<Class/*toClass*/, ValueTypeConverter>>
22                  converters = new HashMap//new IdentityHashMap
23                      <Class, Map<Class, ValueTypeConverter>>();
24      private Map<Class, Map<Class, ValueTypeConverter>>
25                  subclassConverters = 
26                      new HashMap<Class, Map<Class, ValueTypeConverter>>();
27      private Messages serviceMessages;
28      private String messageCategory;
29      
30      static {
31          PRIMITIVS_TYPES.put(Byte.TYPE, Byte.class);
32          PRIMITIVS_TYPES.put(Short.TYPE, Short.class);
33          PRIMITIVS_TYPES.put(Integer.TYPE, Integer.class);
34          PRIMITIVS_TYPES.put(Long.TYPE, Long.class);
35          PRIMITIVS_TYPES.put(Float.TYPE, Float.class);
36          PRIMITIVS_TYPES.put(Double.TYPE, Double.class);
37      }
38      
39      public void init() throws ConverterRegistryException {
40          Map<Class, ValueTypeConverter> instances = 
41              new HashMap<Class, ValueTypeConverter>();
42          serviceMessages = 
43                  new MessagesSubset(messagesRegistry, getMessageCategory());
44          for (ValueTypeConverterInfo info: converterInfos){
45              try{
46                  ValueTypeConverter conv=instances.get(info.getConverterClass());
47                  if (conv==null){
48                      conv = (ValueTypeConverter)
49                          info.getConverterClass().newInstance();                    
50                      instances.put(info.getConverterClass(), conv);
51                      conv.setMessages(
52                          new MessagesSubset(
53                              serviceMessages
54                              , info.getConverterClass().getName()));
55                  }
56                  //converters
57                  if (!converters.containsKey(info.getFromClass()))
58                      converters.put(
59                            info.getFromClass()
60                          , new HashMap<Class, ValueTypeConverter>());
61                  converters.get(
62                          info.getFromClass()).put(info.getToClass(), conv);
63                  //subclass converters
64                  if (info.isConvertSubclasses()){
65                      if (!subclassConverters.containsKey(info.getFromClass())){
66                          subclassConverters.put(
67                                  info.getFromClass()
68                                  , new HashMap<Class, ValueTypeConverter>());
69                      }
70                      subclassConverters.get(
71                          info.getFromClass()).put(info.getToClass(), conv);
72                  }
73              }catch(Exception e){
74                  throw new ConverterRegistryException(
75                      String.format(
76                          "Can't create converter of class (%s)"
77                        , info.getConverterClass().getName())
78                    , e);
79              }
80          }
81      }
82      
83      public Object convert(Class toType, Object value, String pattern) 
84          throws ValueTypeConverterException
85      {
86          if (value==null)
87              return null;
88          //if (toType.equals(value.getClass()))
89          if (toType.isAssignableFrom(value.getClass()))
90              return value;
91          Class convertToType = toType;
92          ValueTypeConverter converter = 
93                  getConverter(value.getClass(), toType, converters);
94          if (converter==null) {            
95              Class toTypeNew = PRIMITIVS_TYPES.get(toType);
96              if (toTypeNew != null){
97                  convertToType = toTypeNew;
98                  converter = getConverter(
99                          value.getClass(), convertToType, converters);
100             }
101             if (converter==null){
102                 Class fromClass = value.getClass().getSuperclass();
103                 while (fromClass!=null){
104                     converter = getConverter(
105                             fromClass, convertToType, subclassConverters);
106                     if (converter!=null)
107                         break;
108                     fromClass = fromClass.getSuperclass();
109                 }                
110             }
111             if (converter == null){
112                 Class fromClass = null;
113                 for (Class clazz: subclassConverters.keySet())
114                     if (clazz.isAssignableFrom(value.getClass())){
115                         fromClass = clazz;
116                         converter = getConverter(
117                                 fromClass, convertToType, subclassConverters);
118                         if (converter!=null)
119                             break;
120                     }
121             }
122         }
123         if (converter!=null)
124             return converter.convert(convertToType, value, pattern);
125         else
126             throw new ValueTypeConverterException(
127                 String.format(
128                     "Registry doesn't have converter to convert value " +
129                     "of type (%s) to type (%s)"
130                     , value.getClass().getName(), toType.getName()));
131     }
132     
133     private final ValueTypeConverter getConverter(
134             Class fromClass, Class toClass
135             , Map<Class, Map<Class, ValueTypeConverter>> convs)
136         throws ValueTypeConverterException 
137     {
138         ValueTypeConverter converter = null;
139         Map<Class, ValueTypeConverter> map = convs.get(fromClass);
140         if (map!=null)
141             converter = map.get(toClass);
142         return converter;
143     }
144     
145     public void setConverterInfos(List<ValueTypeConverterInfo> converterInfos){
146         this.converterInfos=converterInfos;
147     }
148 
149     public String getMessageCategory() {
150         return messageCategory;
151     }
152 
153     public void setMessageCategory(String messageCategory) {
154         this.messageCategory = messageCategory;
155     }
156 
157     public void setMessagesRegistry(MessagesRegistry messages) {
158         this.messagesRegistry = messages;
159     }
160     
161     public void setMessages(Messages messages){ }
162     
163 }