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