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