MATSIM
ObjectAttributesConverter.java
Go to the documentation of this file.
1 
2 /* *********************************************************************** *
3  * project: org.matsim.*
4  * ObjectAttributesConverter.java
5  * *
6  * *********************************************************************** *
7  * *
8  * copyright : (C) 2019 by the members listed in the COPYING, *
9  * LICENSE and WARRANTY file. *
10  * email : info at matsim dot org *
11  * *
12  * *********************************************************************** *
13  * *
14  * This program is free software; you can redistribute it and/or modify *
15  * it under the terms of the GNU General Public License as published by *
16  * the Free Software Foundation; either version 2 of the License, or *
17  * (at your option) any later version. *
18  * See also COPYING, LICENSE and WARRANTY file *
19  * *
20  * *********************************************************************** */
21 
22  package org.matsim.utils.objectattributes;
23 
24 import com.google.inject.Inject;
25 import org.apache.logging.log4j.LogManager;
26 import org.apache.logging.log4j.Logger;
28 import org.matsim.api.core.v01.Coord;
32 
33 import java.util.*;
34 
41  private static final Logger log = LogManager.getLogger(ObjectAttributesConverter.class);
42  private final Map<String, AttributeConverter<?>> converters = new HashMap<>();
43 
44  private final Set<String> missingConverters = new HashSet<>();
45 
46  @Inject
47  public ObjectAttributesConverter(final Map<Class<?>, AttributeConverter<?>> converters) {
48  this();
49  this.putAttributeConverters(converters);
50  }
51 
53  this.converters.put(String.class.getName(), new StringConverter());
54  this.converters.put(Integer.class.getName(), new IntegerConverter());
55  this.converters.put(Float.class.getName(), new FloatConverter());
56  this.converters.put(Double.class.getName(), new DoubleConverter());
57  this.converters.put(Boolean.class.getName(), new BooleanConverter());
58  this.converters.put(Long.class.getName(), new LongConverter());
59  this.converters.put(double[].class.getName(), new DoubleArrayConverter());
60  this.converters.put(Map.class.getName(), new StringStringMapConverter());
61  this.converters.put(Collection.class.getName(), new StringCollectionConverter());
62  this.converters.put(Coord.class.getName(), new CoordConverter());
63  this.converters.put(Coord[].class.getName(), new CoordArrayConverter());
64  this.converters.put(PersonVehicles.class.getName(), new PersonVehiclesAttributeConverter());
65  this.converters.put(DisallowedNextLinks.class.getName(), new DisallowedNextLinksAttributeConverter());
66  this.converters.put(PersonVehicleTypes.class.getName(), new PersonVehicleTypesAttributeConverter());
67  this.converters.put(StringDoubleMap.class.getName(), new StringDoubleMapConverter());
68  }
69 
70  //this is for reading
71  public Object convert(String className, String value) {
72  AttributeConverter converter = getConverter(className);
73  return converter == null ? null : converter.convert(value);
74  }
75 
76  public Map<String, AttributeConverter<?>> getConverters()
77  {
78  return this.converters;
79  }
80 
81  private AttributeConverter getConverter(String className) {
82  if (converters.containsKey(className)) return converters.get(className);
83  try {
84  Class<?> clazz = Class.forName(className);
85 
86  if (clazz.isEnum()) {
87  AttributeConverter converter = new EnumConverter(clazz);
88  converters.put(className, converter);
89  return converter;
90  }
91 
92  if(Map.class.isAssignableFrom(clazz)) return this.converters.get(Map.class.getName());
93  if(Collection.class.isAssignableFrom(clazz)) return this.converters.get(Collection.class.getName());
94 
95  if (missingConverters.add(className)) {
96  log.warn("No AttributeConverter found for class " + className + ". Not all attribute values can be converted.");
97  }
98  }
99  catch (ClassNotFoundException e) {
100  if (missingConverters.add(className)) {
101  log.warn("No AttributeConverter found for class " + className + ", and class is not on classpath. Not all attribute values can be converted.");
102  }
103  }
104 
105  return null;
106  }
107 
108  public String convertToString(Object o) {
109 
110  AttributeConverter converter = getConverter(o.getClass().getName());
111 
112  //handle map and collection converter - check for string elements
113  //we pass in a lot of maps here that we can and (maybe) do not want to write
114  {
115  if(converter instanceof StringStringMapConverter){
116  Map<Object, Object> map = ((Map<Object, Object>) o);
117  if (! map.isEmpty()){
118  Map.Entry firstEntry = map.entrySet().iterator().next();
119  if(! (firstEntry.getKey() instanceof String && firstEntry.getValue() instanceof String) ) return null;
120  }
121  }
122  if(converter instanceof StringCollectionConverter){
123  Collection collection = ((Collection) o);
124  if(! collection.isEmpty()){
125  if(! ( collection.iterator().next() instanceof String) ) return null;
126  }
127  }
128  }
129 
130  // is returning null the right approach there?
131  return converter == null ? null : converter.convertToString(o);
132  }
133 
141  public AttributeConverter putAttributeConverter(final Class<?> clazz, final AttributeConverter converter) {
142  return this.converters.put(clazz.getName(), converter);
143  }
144 
145  public void putAttributeConverters( final Map<Class<?>, AttributeConverter<?>> converters ) {
146  for ( Map.Entry<Class<?>, AttributeConverter<?>> e : converters.entrySet() ) {
147  putAttributeConverter( e.getKey() , e.getValue() );
148  }
149  }
150 
157  public AttributeConverter removeAttributeConverter(final Class<?> clazz) {
158  return this.converters.remove(clazz.getName());
159  }
160 
161 }
ObjectAttributesConverter(final Map< Class<?>, AttributeConverter<?>> converters)
void putAttributeConverters(final Map< Class<?>, AttributeConverter<?>> converters)
AttributeConverter putAttributeConverter(final Class<?> clazz, final AttributeConverter converter)