View Javadoc
1   package net.technearts;
2   
3   import java.util.ArrayList;
4   import java.util.Arrays;
5   import java.util.Collection;
6   import java.util.Deque;
7   import java.util.LinkedList;
8   import java.util.List;
9   import java.util.Map;
10  import java.util.Map.Entry;
11  import java.util.NavigableSet;
12  import java.util.Optional;
13  import java.util.Queue;
14  import java.util.Set;
15  import java.util.SortedSet;
16  import java.util.TreeSet;
17  import java.util.function.Predicate;
18  
19  import org.apache.commons.beanutils.PropertyUtils;
20  import org.apache.commons.lang3.StringUtils;
21  import org.slf4j.Logger;
22  import org.slf4j.LoggerFactory;
23  
24  import com.google.common.collect.HashBasedTable;
25  import com.google.common.collect.Table;
26  
27  public class Repository {
28    private static final Logger LOG = LoggerFactory.getLogger("Marshaller");
29    private Table<Mapping, Integer, Object> table = HashBasedTable.create();
30    private Table<Member, Integer, String> nonMappedMembers = HashBasedTable.create();
31    private List<Predicate<Object>> entityPredicates = new ArrayList<>();
32  
33    public void put(Mapping mapping, int line, Object value) {
34      if (entityPredicates.stream().allMatch(predicate -> predicate.test(value))) {
35        table.put(mapping, line, value);
36      }
37    }
38  
39    public Object get(String name, int line) {
40      if (name == null) {
41        throw new IllegalArgumentException("Nome não pode ser nulo");
42      }
43      return table.column(line).entrySet().stream()
44          .filter(entry -> name.equals(entry.getKey().getName())).findFirst().orElse(null);
45    }
46  
47    public Map<Integer, Object> get(String name) {
48      for (Entry<Mapping, Map<Integer, Object>> entry : table.rowMap().entrySet()) {
49        if (name.equals(entry.getKey().getName())) {
50          return entry.getValue();
51        }
52      }
53      return null;
54    }
55  
56    public Map<Integer, Object> get(Class<?> klazz) {
57      for (Entry<Mapping, Map<Integer, Object>> entry : table.rowMap().entrySet()) {
58        if (klazz.getName().equals(entry.getKey().getClassName())) {
59          return entry.getValue();
60        }
61      }
62      return null;
63    }
64  
65    public void addFilter(Predicate<Object> predicate) {
66      entityPredicates.add(predicate);
67    }
68  
69    @SuppressWarnings("unchecked")
70    public final <T, V> void set(final T bean, final Member member, final V value, String separator,
71        List<Mapping> mappings) {
72      final String name = member.getProperty();
73      final String mappedBy = member.getMappedBy();
74      final String converter = member.getConverter();
75      try {
76        Class<T> klass = (Class<T>) PropertyUtils.getPropertyType(bean, name);
77        if (Arrays.asList(klass.getInterfaces()).contains(Collection.class)) {
78          Collection<V> c = (Collection<V>) PropertyUtils.getProperty(bean, name);
79          if (c == null) {
80            c = (Collection<V>) newCollectionInstance(klass);
81            PropertyUtils.setProperty(bean, name, c);
82          }
83          if (value == null) {
84            return;
85          }
86          // embedded
87          if (!member.isReferenceBased()) {
88            c.add(value);
89            return;
90          }
91          // multivalued reference
92          for (String o : value.toString().split(separator)) {
93            if (StringUtils.isBlank(mappedBy)) {
94              c.add((V) o);
95            } else {
96              for (Object v : this.get(converter).values()) {
97                try {
98                  String property = mappedBy;
99                  Optional<Mapping> optionalMapping = mappings.stream()
100                     .filter(mapping -> mapping.getName().equals(converter)).findFirst();
101                 if (optionalMapping.isPresent()) {
102                   Member m = optionalMapping.get().getMember(mappedBy);
103                   if (m != null) {
104                     property = m.getProperty();
105                   } else {
106                     // TODO ?
107                   }
108                 } else {
109                   // TODO ?
110                 }
111                 String element = PropertyUtils.getProperty(v, property).toString().trim();
112                 if (o.trim().equals(element)) {
113                   c.add((V) v);
114                 }
115               } catch (NullPointerException e) {
116                 throw new IllegalArgumentException(
117                     "Mapeamento " + mappedBy + " da classe " + converter + " não encontrado.");
118               }
119             }
120           }
121         }
122       } else {
123         PropertyUtils.setProperty(bean, name, value);
124       }
125     } catch (ReflectiveOperationException e) {
126       LOG.error(
127           "A propriedade " + name + " não foi encontrada em " + bean.getClass().getSimpleName());
128     }
129   }
130 
131   @SuppressWarnings("unchecked")
132   private <T> T newCollectionInstance(Class<T> klass) {
133     T t = null;
134     try {
135       t = (T) klass.newInstance();
136     } catch (NullPointerException | InstantiationException | IllegalAccessException e) {
137       if (NavigableSet.class.equals(klass) || Set.class.equals(klass)
138           || SortedSet.class.equals(klass)
139           || Arrays.asList(klass.getInterfaces()).contains(NavigableSet.class)
140           || Arrays.asList(klass.getInterfaces()).contains(Set.class)
141           || Arrays.asList(klass.getInterfaces()).contains(SortedSet.class)) {
142         t = (T) newCollectionInstance(TreeSet.class);
143       } else if (List.class.equals(klass) || Queue.class.equals(klass) || Deque.class.equals(klass)
144           || Arrays.asList(klass.getInterfaces()).contains(List.class)
145           || Arrays.asList(klass.getInterfaces()).contains(Queue.class)
146           || Arrays.asList(klass.getInterfaces()).contains(Deque.class)) {
147         t = (T) newCollectionInstance(LinkedList.class);
148       }
149     }
150     return t;
151   }
152 
153   public <T, V> void set(Member member, int line, V value) {
154     nonMappedMembers.put(member, line, value.toString());
155   }
156 }