| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.apache.struts2.json.smd; |
| |
| import com.opensymphony.xwork2.ActionContext; |
| import com.opensymphony.xwork2.ActionInvocation; |
| import org.apache.logging.log4j.LogManager; |
| import org.apache.logging.log4j.Logger; |
| import org.apache.struts2.json.JSONUtil; |
| import org.apache.struts2.json.annotations.SMD; |
| import org.apache.struts2.json.annotations.SMDMethod; |
| import org.apache.struts2.json.annotations.SMDMethodParameter; |
| |
| import javax.servlet.http.HttpServletRequest; |
| import java.lang.annotation.Annotation; |
| import java.lang.reflect.Method; |
| import java.util.List; |
| import java.util.regex.Pattern; |
| |
| public class SMDGenerator { |
| |
| private static final Logger LOG = LogManager.getLogger(SMDGenerator.class); |
| |
| // rootObject is based on OGNL expression (action by default) |
| private Object rootObject; |
| private List<Pattern> excludeProperties; |
| private boolean ignoreInterfaces; |
| |
| public SMDGenerator(Object root, List<Pattern> excludeProperties, boolean ignoreInterfaces) { |
| this.rootObject = root; |
| this.excludeProperties = excludeProperties; |
| this.ignoreInterfaces = ignoreInterfaces; |
| } |
| |
| public org.apache.struts2.json.smd.SMD generate(ActionInvocation actionInvocation) { |
| ActionContext actionContext = actionInvocation.getInvocationContext(); |
| HttpServletRequest request = actionContext.getServletRequest(); |
| |
| Class<?> clazz = rootObject.getClass(); |
| org.apache.struts2.json.smd.SMD smd = new org.apache.struts2.json.smd.SMD(); |
| // URL |
| smd.setServiceUrl(request.getRequestURI()); |
| |
| // customize SMD |
| org.apache.struts2.json.annotations.SMD smdAnnotation = clazz.getAnnotation(SMD.class); |
| if (smdAnnotation != null) { |
| smd.setObjectName(smdAnnotation.objectName()); |
| smd.setServiceType(smdAnnotation.serviceType()); |
| smd.setVersion(smdAnnotation.version()); |
| } |
| |
| // get public methods |
| Method[] methods = JSONUtil.listSMDMethods(clazz, ignoreInterfaces); |
| |
| for (Method method : methods) { |
| processAnnotatedMethod(smd, method); |
| } |
| return smd; |
| |
| } |
| |
| private void processAnnotatedMethod(org.apache.struts2.json.smd.SMD smd, Method method) { |
| SMDMethod smdMethodAnnotation = method.getAnnotation(SMDMethod.class); |
| // SMDMethod annotation is required |
| if (shouldProcessMethod(method, smdMethodAnnotation)) { |
| String methodName = readMethodName(method, smdMethodAnnotation); |
| org.apache.struts2.json.smd.SMDMethod smdMethod = new org.apache.struts2.json.smd.SMDMethod(methodName); |
| smd.addSMDMethod(smdMethod); |
| |
| // find params for this method |
| processMethodsParameters(method, smdMethod); |
| |
| } else if (LOG.isDebugEnabled()) { |
| LOG.debug("Ignoring property " + method.getName()); |
| } |
| } |
| |
| private void processMethodsParameters(Method method, org.apache.struts2.json.smd.SMDMethod smdMethod) { |
| int parametersCount = method.getParameterTypes().length; |
| if (parametersCount > 0) { |
| |
| Annotation[][] parameterAnnotations = method.getParameterAnnotations(); |
| |
| for (int i = 0; i < parametersCount; i++) { |
| processParameter(smdMethod, parameterAnnotations[i], i); |
| } |
| } |
| } |
| |
| private void processParameter(org.apache.struts2.json.smd.SMDMethod smdMethod, Annotation[] parameterAnnotation, int i) { |
| // are you ever going to pick shorter names? nope |
| SMDMethodParameter smdMethodParameterAnnotation = getSMDMethodParameterAnnotation(parameterAnnotation); |
| String paramName = buildParamName(i, smdMethodParameterAnnotation); |
| smdMethod.addSMDMethodParameter(new org.apache.struts2.json.smd.SMDMethodParameter(paramName)); |
| } |
| |
| private String buildParamName(int i, SMDMethodParameter smdMethodParameterAnnotation) { |
| return smdMethodParameterAnnotation != null ? smdMethodParameterAnnotation.name() : "p" + i; |
| } |
| |
| private String readMethodName(Method method, SMDMethod smdMethodAnnotation) { |
| return smdMethodAnnotation.name().length() == 0 ? method.getName() : smdMethodAnnotation.name(); |
| } |
| |
| private boolean shouldProcessMethod(Method method, SMDMethod smdMethodAnnotation) { |
| return ((smdMethodAnnotation != null) && !this.shouldExcludeProperty(method.getName())); |
| } |
| |
| private boolean shouldExcludeProperty(String expr) { |
| if (this.excludeProperties != null) { |
| for (Pattern pattern : this.excludeProperties) { |
| if (pattern.matcher(expr).matches()) |
| return true; |
| } |
| } |
| return false; |
| } |
| |
| /** |
| * Find an SMDethodParameter annotation on this array |
| */ |
| private org.apache.struts2.json.annotations.SMDMethodParameter getSMDMethodParameterAnnotation( |
| Annotation[] annotations) { |
| for (Annotation annotation : annotations) { |
| if (annotation instanceof org.apache.struts2.json.annotations.SMDMethodParameter) |
| return (org.apache.struts2.json.annotations.SMDMethodParameter) annotation; |
| } |
| |
| return null; |
| } |
| |
| } |