001
014
015 package com.liferay.portal.json;
016
017 import com.liferay.portal.kernel.json.JSON;
018 import com.liferay.portal.kernel.json.JSONIncludesManager;
019 import com.liferay.portal.kernel.util.StringPool;
020 import com.liferay.portal.kernel.util.StringUtil;
021
022 import java.lang.reflect.Field;
023 import java.lang.reflect.Method;
024
025 import java.util.ArrayList;
026 import java.util.HashMap;
027 import java.util.List;
028 import java.util.Map;
029
030
033 public class JSONIncludesManagerImpl implements JSONIncludesManager {
034
035 @Override
036 public String[] lookupExcludes(Class<?> type) {
037 String[] excludes = _excludesMap.get(type);
038
039 if (excludes != null) {
040 return excludes;
041 }
042
043 Class<?> originalType = type;
044
045 List<String> list = new ArrayList<String>();
046
047 while (type != null) {
048 JSON jsonAnnotation = type.getAnnotation(JSON.class);
049
050 if ((jsonAnnotation != null) && jsonAnnotation.strict()) {
051 list.add(_EXCLUDE_ALL);
052
053 break;
054 }
055 else {
056 _scanFieldsAndMethods(list, type, false);
057 }
058
059 type = type.getSuperclass();
060 }
061
062 excludes = _listToArray(list);
063
064 _excludesMap.put(originalType, excludes);
065
066 return excludes;
067 }
068
069 @Override
070 public String[] lookupIncludes(Class<?> type) {
071 String[] includes = _includesMap.get(type);
072
073 if (includes != null) {
074 return includes;
075 }
076
077 Class<?> originalType = type;
078
079 List<String> list = new ArrayList<String>();
080
081 while (type != null) {
082 _scanFieldsAndMethods(list, type, true);
083
084 type = type.getSuperclass();
085 }
086
087 includes = _listToArray(list);
088
089 _includesMap.put(originalType, includes);
090
091 return includes;
092 }
093
094 private String _getPropertyName(Method method) {
095 Class<?>[] parameterTypes = method.getParameterTypes();
096
097 if (parameterTypes.length != 0) {
098 return null;
099 }
100
101 String propertyName = null;
102
103 String methodName = method.getName();
104
105 if (methodName.startsWith("get")) {
106 propertyName = methodName.substring(3);
107 }
108 else if (methodName.startsWith("is")) {
109 propertyName = methodName.substring(2);
110 }
111 else {
112 return null;
113 }
114
115 if (propertyName.length() < 2 ) {
116 return StringUtil.toLowerCase(propertyName);
117 }
118 else if (Character.isUpperCase(propertyName.charAt(0)) &&
119 Character.isUpperCase(propertyName.charAt(1)) ) {
120
121 return propertyName;
122 }
123 else {
124 return Character.toLowerCase(propertyName.charAt(0)) +
125 propertyName.substring(1);
126 }
127 }
128
129 private String[] _listToArray(List<String> list) {
130 if (list.isEmpty()) {
131 return _EMPTY_LIST;
132 }
133 else {
134 return list.toArray(new String[list.size()]);
135 }
136 }
137
138 private void _scanFieldsAndMethods(
139 List<String> list, Class<?> type, boolean include) {
140
141 Field[] fields = type.getDeclaredFields();
142
143 for (Field field : fields) {
144 JSON jsonAnnotation = field.getAnnotation(JSON.class);
145
146 if ((jsonAnnotation != null) &&
147 (jsonAnnotation.include() == include)) {
148
149 String name = field.getName();
150
151 if (name.startsWith(StringPool.UNDERLINE)) {
152 name = name.substring(1);
153 }
154
155 if (!list.contains(name)) {
156 list.add(name);
157 }
158 }
159 }
160
161 Method[] methods = type.getDeclaredMethods();
162
163 for (Method method : methods) {
164 JSON jsonAnnotation = method.getAnnotation(JSON.class);
165
166 if ((jsonAnnotation != null) &&
167 (jsonAnnotation.include() == include)) {
168
169 String name = _getPropertyName(method);
170
171 if (name != null) {
172 if (!list.contains(name)) {
173 list.add(name);
174 }
175 }
176 }
177 }
178 }
179
180 private static final String[] _EMPTY_LIST = new String[0];
181
182 private static final String _EXCLUDE_ALL = "*";
183
184 private Map<Class<?>, String[]> _excludesMap =
185 new HashMap<Class<?>, String[]>();
186 private Map<Class<?>, String[]> _includesMap =
187 new HashMap<Class<?>, String[]>();
188
189 }