public List<String> getMatchedURIs(boolean decode) { if (stack != null) { List<String> objects = new ArrayList<String>(); List<String> uris = new LinkedList<String>(); String sum = ""; for (MethodInvocationInfo invocation : stack) { OperationResourceInfo ori = invocation.getMethodInfo(); URITemplate[] paths = {ori.getClassResourceInfo().getURITemplate(), ori.getURITemplate()}; for (URITemplate t : paths) { if (t != null) { String v = t.getValue(); sum += "/" + (decode ? HttpUtils.pathDecode(v) : v); } } UriBuilder ub = UriBuilder.fromPath(sum); objects.addAll(invocation.getTemplateValues()); uris.add(0, ub.build(objects.toArray()).normalize().getPath()); } return uris; } LOG.fine("No resource stack information, returning empty list"); return Collections.emptyList(); }
private List<Object> getPathParamValues( Method m, Object[] params, MultivaluedMap<ParameterType, Parameter> map, List<Parameter> beanParams, OperationResourceInfo ori, int bodyIndex) { List<Object> list = new LinkedList<Object>(); List<String> methodVars = ori.getURITemplate().getVariables(); List<Parameter> paramsList = getParameters(map, ParameterType.PATH); Map<String, BeanPair> beanParamValues = new HashMap<String, BeanPair>(beanParams.size()); for (Parameter p : beanParams) { beanParamValues.putAll(getValuesFromBeanParam(params[p.getIndex()], PathParam.class)); } if (!beanParamValues.isEmpty() && !methodVars.containsAll(beanParamValues.keySet())) { List<String> classVars = ori.getClassResourceInfo().getURITemplate().getVariables(); for (String classVar : classVars) { BeanPair pair = beanParamValues.get(classVar); if (pair != null) { Object paramValue = convertParamValue(pair.getValue(), pair.getAnns()); if (isRoot) { valuesMap.put(classVar, paramValue); } else { list.add(paramValue); } } } } if (isRoot) { list.addAll(valuesMap.values()); } Map<String, Parameter> paramsMap = new LinkedHashMap<String, Parameter>(); for (Parameter p : paramsList) { if (p.getName().length() == 0) { MultivaluedMap<String, Object> values = InjectionUtils.extractValuesFromBean(params[p.getIndex()], ""); for (String var : methodVars) { list.addAll(values.get(var)); } } else { paramsMap.put(p.getName(), p); } } Object requestBody = bodyIndex == -1 ? null : params[bodyIndex]; for (String varName : methodVars) { Parameter p = paramsMap.remove(varName); if (p != null) { list.add(convertParamValue(params[p.getIndex()], getParamAnnotations(m, p))); } else if (beanParamValues.containsKey(varName)) { BeanPair pair = beanParamValues.get(varName); list.add(convertParamValue(pair.getValue(), pair.getAnns())); } else if (requestBody != null) { try { Method getter = requestBody .getClass() .getMethod("get" + StringUtils.capitalize(varName), new Class<?>[] {}); list.add(getter.invoke(requestBody, new Object[] {})); } catch (Exception ex) { // continue } } } for (Parameter p : paramsMap.values()) { if (valuesMap.containsKey(p.getName())) { int index = 0; for (Iterator<String> it = valuesMap.keySet().iterator(); it.hasNext(); index++) { if (it.next().equals(p.getName()) && index < list.size()) { list.remove(index); list.add(index, convertParamValue(params[p.getIndex()], null)); break; } } } } return list; }
/** * Updates the current state if Client method is invoked, otherwise does the remote invocation or * returns a new proxy if subresource method is invoked. Can throw an expected exception if * ResponseExceptionMapper is registered */ public Object invoke(Object o, Method m, Object[] params) throws Throwable { Class<?> declaringClass = m.getDeclaringClass(); if (Client.class == declaringClass || InvocationHandlerAware.class == declaringClass || Object.class == declaringClass) { return m.invoke(this, params); } resetResponse(); OperationResourceInfo ori = cri.getMethodDispatcher().getOperationResourceInfo(m); if (ori == null) { reportInvalidResourceMethod(m, "INVALID_RESOURCE_METHOD"); } MultivaluedMap<ParameterType, Parameter> types = getParametersInfo(m, params, ori); List<Parameter> beanParamsList = getParameters(types, ParameterType.BEAN); int bodyIndex = getBodyIndex(types, ori); List<Object> pathParams = getPathParamValues(m, params, types, beanParamsList, ori, bodyIndex); UriBuilder builder = getCurrentBuilder().clone(); if (isRoot) { addNonEmptyPath(builder, ori.getClassResourceInfo().getURITemplate().getValue()); } addNonEmptyPath(builder, ori.getURITemplate().getValue()); handleMatrixes(m, params, types, beanParamsList, builder); handleQueries(m, params, types, beanParamsList, builder); URI uri = builder.buildFromEncoded(pathParams.toArray()).normalize(); MultivaluedMap<String, String> headers = getHeaders(); MultivaluedMap<String, String> paramHeaders = new MetadataMap<String, String>(); handleHeaders(m, params, paramHeaders, beanParamsList, types); handleCookies(m, params, paramHeaders, beanParamsList, types); if (ori.isSubResourceLocator()) { ClassResourceInfo subCri = cri.getSubResource(m.getReturnType(), m.getReturnType()); if (subCri == null) { reportInvalidResourceMethod(m, "INVALID_SUBRESOURCE"); } MultivaluedMap<String, String> subHeaders = paramHeaders; if (inheritHeaders) { subHeaders.putAll(headers); } ClientState newState = getState() .newState( uri, subHeaders, getTemplateParametersMap(ori.getURITemplate(), pathParams)); ClientProxyImpl proxyImpl = new ClientProxyImpl(newState, proxyLoader, subCri, false, inheritHeaders); proxyImpl.setConfiguration(getConfiguration()); return JAXRSClientFactory.createProxy(m.getReturnType(), proxyLoader, proxyImpl); } headers.putAll(paramHeaders); getState().setTemplates(getTemplateParametersMap(ori.getURITemplate(), pathParams)); Object body = null; if (bodyIndex != -1) { body = params[bodyIndex]; if (body == null) { bodyIndex = -1; } } else if (types.containsKey(ParameterType.FORM)) { body = handleForm(m, params, types, beanParamsList); } else if (types.containsKey(ParameterType.REQUEST_BODY)) { body = handleMultipart(types, ori, params); } setRequestHeaders( headers, ori, types.containsKey(ParameterType.FORM), body == null ? null : body.getClass(), m.getReturnType()); return doChainedInvocation(uri, headers, ori, body, bodyIndex, null, null); }