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