View Javadoc
1   /*
2    *    Copyright 2009-2023 the original author or authors.
3    *
4    *    Licensed under the Apache License, Version 2.0 (the "License");
5    *    you may not use this file except in compliance with the License.
6    *    You may obtain a copy of the License at
7    *
8    *       https://www.apache.org/licenses/LICENSE-2.0
9    *
10   *    Unless required by applicable law or agreed to in writing, software
11   *    distributed under the License is distributed on an "AS IS" BASIS,
12   *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   *    See the License for the specific language governing permissions and
14   *    limitations under the License.
15   */
16  package org.apache.ibatis.reflection.wrapper;
17  
18  import java.util.HashMap;
19  import java.util.List;
20  import java.util.Map;
21  
22  import org.apache.ibatis.reflection.MetaObject;
23  import org.apache.ibatis.reflection.SystemMetaObject;
24  import org.apache.ibatis.reflection.factory.ObjectFactory;
25  import org.apache.ibatis.reflection.property.PropertyTokenizer;
26  
27  /**
28   * @author Clinton Begin
29   */
30  public class MapWrapper extends BaseWrapper {
31  
32    private final Map<String, Object> map;
33  
34    public MapWrapper(MetaObject metaObject, Map<String, Object> map) {
35      super(metaObject);
36      this.map = map;
37    }
38  
39    @Override
40    public Object get(PropertyTokenizer prop) {
41      if (prop.getIndex() != null) {
42        Object collection = resolveCollection(prop, map);
43        return getCollectionValue(prop, collection);
44      }
45      return map.get(prop.getName());
46    }
47  
48    @Override
49    public void set(PropertyTokenizer prop, Object value) {
50      if (prop.getIndex() != null) {
51        Object collection = resolveCollection(prop, map);
52        setCollectionValue(prop, collection, value);
53      } else {
54        map.put(prop.getName(), value);
55      }
56    }
57  
58    @Override
59    public String findProperty(String name, boolean useCamelCaseMapping) {
60      return name;
61    }
62  
63    @Override
64    public String[] getGetterNames() {
65      return map.keySet().toArray(new String[0]);
66    }
67  
68    @Override
69    public String[] getSetterNames() {
70      return map.keySet().toArray(new String[0]);
71    }
72  
73    @Override
74    public Class<?> getSetterType(String name) {
75      PropertyTokenizer prop = new PropertyTokenizer(name);
76      if (prop.hasNext()) {
77        MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
78        if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
79          return Object.class;
80        } else {
81          return metaValue.getSetterType(prop.getChildren());
82        }
83      }
84      if (map.get(name) != null) {
85        return map.get(name).getClass();
86      } else {
87        return Object.class;
88      }
89    }
90  
91    @Override
92    public Class<?> getGetterType(String name) {
93      PropertyTokenizer prop = new PropertyTokenizer(name);
94      if (prop.hasNext()) {
95        MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
96        if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
97          return Object.class;
98        } else {
99          return metaValue.getGetterType(prop.getChildren());
100       }
101     }
102     if (map.get(name) != null) {
103       return map.get(name).getClass();
104     } else {
105       return Object.class;
106     }
107   }
108 
109   @Override
110   public boolean hasSetter(String name) {
111     return true;
112   }
113 
114   @Override
115   public boolean hasGetter(String name) {
116     PropertyTokenizer prop = new PropertyTokenizer(name);
117     if (!prop.hasNext()) {
118       return map.containsKey(prop.getName());
119     }
120     if (map.containsKey(prop.getIndexedName())) {
121       MetaObject metaValue = metaObject.metaObjectForProperty(prop.getIndexedName());
122       if (metaValue == SystemMetaObject.NULL_META_OBJECT) {
123         return true;
124       } else {
125         return metaValue.hasGetter(prop.getChildren());
126       }
127     } else {
128       return false;
129     }
130   }
131 
132   @Override
133   public MetaObject instantiatePropertyValue(String name, PropertyTokenizer prop, ObjectFactory objectFactory) {
134     HashMap<String, Object> map = new HashMap<>();
135     set(prop, map);
136     return MetaObject.forObject(map, metaObject.getObjectFactory(), metaObject.getObjectWrapperFactory(),
137         metaObject.getReflectorFactory());
138   }
139 
140   @Override
141   public boolean isCollection() {
142     return false;
143   }
144 
145   @Override
146   public void add(Object element) {
147     throw new UnsupportedOperationException();
148   }
149 
150   @Override
151   public <E> void addAll(List<E> element) {
152     throw new UnsupportedOperationException();
153   }
154 
155 }