001
014
015 package com.liferay.portal.jsonwebservice.action;
016
017 import com.liferay.portal.kernel.exception.PortalException;
018 import com.liferay.portal.kernel.json.JSONFactoryUtil;
019 import com.liferay.portal.kernel.json.JSONSerializable;
020 import com.liferay.portal.kernel.json.JSONSerializer;
021 import com.liferay.portal.kernel.jsonwebservice.JSONWebServiceAction;
022 import com.liferay.portal.kernel.jsonwebservice.JSONWebServiceActionMapping;
023 import com.liferay.portal.kernel.jsonwebservice.JSONWebServiceActionsManagerUtil;
024 import com.liferay.portal.kernel.util.MethodParameter;
025 import com.liferay.portal.kernel.util.StringBundler;
026 import com.liferay.portal.kernel.util.StringPool;
027 import com.liferay.portal.kernel.util.StringUtil;
028
029 import java.io.Serializable;
030
031 import java.lang.reflect.Method;
032
033 import java.util.ArrayList;
034 import java.util.Arrays;
035 import java.util.Date;
036 import java.util.HashMap;
037 import java.util.LinkedHashMap;
038 import java.util.List;
039 import java.util.Locale;
040 import java.util.Map;
041
042 import javax.servlet.http.HttpServletRequest;
043
044 import jodd.util.Wildcard;
045
046
049 public class JSONWebServiceDiscoverAction implements JSONWebServiceAction {
050
051 public JSONWebServiceDiscoverAction(HttpServletRequest request) {
052 _basePath = request.getServletPath();
053 _baseURL = request.getRequestURL().toString();
054 _contextPath = request.getContextPath();
055
056 String discover = request.getParameter("discover");
057
058 _discover = StringUtil.split(discover);
059 }
060
061 @Override
062 public JSONWebServiceActionMapping getJSONWebServiceActionMapping() {
063 return null;
064 }
065
066 @Override
067 public Object invoke() throws Exception {
068 Map<String, Object> resultsMap = new LinkedHashMap<String, Object>();
069
070 Map<String, Object> jsonWebServiceActionMappingMaps =
071 _buildJsonWebServiceActionMappingMaps();
072
073 resultsMap.put("actions", jsonWebServiceActionMappingMaps);
074
075 resultsMap.put("context", _contextPath);
076 resultsMap.put("basePath", _basePath);
077 resultsMap.put("baseURL", _baseURL);
078
079 if (_discover.length > 0) {
080 resultsMap.put("discover", Arrays.toString(_discover));
081 }
082
083 return new DiscoveryContent(resultsMap);
084 }
085
086 public static class DiscoveryContent implements JSONSerializable {
087
088 public DiscoveryContent(Map<String, Object> resultsMap) {
089 _resultsMap = resultsMap;
090 }
091
092 @Override
093 public String toJSONString() {
094 JSONSerializer jsonSerializer =
095 JSONFactoryUtil.createJSONSerializer();
096
097 jsonSerializer.include("*.parameters");
098
099 return jsonSerializer.serialize(_resultsMap);
100 }
101
102 private Map<String, Object> _resultsMap;
103
104 }
105
106 private Map<String, Object> _buildJsonWebServiceActionMappingMaps()
107 throws PortalException {
108
109 List<JSONWebServiceActionMapping> jsonWebServiceActionMappingMaps =
110 JSONWebServiceActionsManagerUtil.getJSONWebServiceActionMappings(
111 _contextPath);
112
113 Map<String, Object> jsonWebServiceActionMappingsMap =
114 new LinkedHashMap<String, Object>(
115 jsonWebServiceActionMappingMaps.size());
116
117 for (JSONWebServiceActionMapping jsonWebServiceActionMapping :
118 jsonWebServiceActionMappingMaps) {
119
120 String path = jsonWebServiceActionMapping.getPath();
121
122 if (!_isAcceptPath(path)) {
123 continue;
124 }
125
126 Map<String, Object> jsonWebServiceActionMappingMap =
127 new LinkedHashMap<String, Object>();
128
129 jsonWebServiceActionMappingMap.put(
130 "method", jsonWebServiceActionMapping.getMethod());
131
132 MethodParameter[] methodParameters =
133 jsonWebServiceActionMapping.getMethodParameters();
134
135 List<Map<String, String>> parametersList =
136 new ArrayList<Map<String, String>>(methodParameters.length);
137
138 for (MethodParameter methodParameter : methodParameters) {
139 Class<?>[] genericTypes = null;
140
141 try {
142 genericTypes = methodParameter.getGenericTypes();
143 }
144 catch (ClassNotFoundException cnfe) {
145 throw new PortalException(cnfe);
146 }
147
148 Map<String, String> parameterMap =
149 new HashMap<String, String>();
150
151 parameterMap.put("name", methodParameter.getName());
152 parameterMap.put(
153 "type",
154 _formatType(methodParameter.getType(), genericTypes));
155
156 parametersList.add(parameterMap);
157 }
158
159 jsonWebServiceActionMappingMap.put("parameters", parametersList);
160
161 jsonWebServiceActionMappingMap.put("path", path);
162
163 Method actionMethod = jsonWebServiceActionMapping.getActionMethod();
164
165 jsonWebServiceActionMappingMap.put(
166 "response", _formatType(actionMethod.getReturnType(), null));
167
168 jsonWebServiceActionMappingsMap.put(
169 path, jsonWebServiceActionMappingMap);
170 }
171
172 return jsonWebServiceActionMappingsMap;
173 }
174
175 private String _formatType(Class<?> type, Class<?>[] genericTypes) {
176 if (type.isArray()) {
177 Class<?> componentType = type.getComponentType();
178
179 return _formatType(componentType, genericTypes) + "[]";
180 }
181
182 if (type.isPrimitive()) {
183 return type.getSimpleName();
184 }
185 else if (type.equals(Date.class)) {
186 return "long";
187 }
188 else if (type.equals(Locale.class) || type.equals(String.class)) {
189 return "string";
190 }
191 else if (type.equals(Object.class) || type.equals(Serializable.class)) {
192 return "object";
193 }
194
195 String typeName = type.getName();
196
197 if (type.equals(List.class)) {
198 typeName = "list";
199 }
200 else if (type.equals(Map.class)) {
201 typeName = "map";
202 }
203 else {
204 _types.add(type);
205 }
206
207 if (genericTypes == null) {
208 return "object<" + typeName + ">";
209 }
210
211 StringBundler sb = new StringBundler(genericTypes.length * 2 + 1);
212
213 sb.append(StringPool.LESS_THAN);
214
215 for (int i = 0; i < genericTypes.length; i++) {
216 Class<?> genericType = genericTypes[i];
217
218 if (i != 0) {
219 sb.append(StringPool.COMMA);
220 }
221
222 sb.append(_formatType(genericType, null));
223 }
224
225 sb.append(StringPool.GREATER_THAN);
226
227 return typeName + sb.toString();
228 }
229
230 private boolean _isAcceptPath(String path) {
231 if (_discover.length == 0) {
232 return true;
233 }
234
235 if (Wildcard.matchOne(path, _discover) != -1) {
236 return true;
237 }
238 else {
239 return false;
240 }
241 }
242
243 private String _basePath;
244 private String _baseURL;
245 private String _contextPath;
246 private String[] _discover;
247 private List<Class<?>> _types = new ArrayList<Class<?>>();
248
249 }