private static ClassResourceInfo getAncestorWithSameServiceClass( ClassResourceInfo parent, Class<?> subClass) { if (parent == null) { return null; } if (parent.getServiceClass() == subClass) { return parent; } return getAncestorWithSameServiceClass(parent.getParent(), subClass); }
private static boolean checkMethodDispatcher(ClassResourceInfo cr) { if (cr.getMethodDispatcher().getOperationResourceInfos().isEmpty()) { LOG.warning( new org.apache.cxf.common.i18n.Message( "NO_RESOURCE_OP_EXC", BUNDLE, cr.getServiceClass().getName()) .toString()); return false; } return true; }
private static void getAllTypesForResource( ClassResourceInfo resource, ResourceTypes types, boolean jaxbOnly, MessageBodyWriter<?> jaxbWriter) { for (OperationResourceInfo ori : resource.getMethodDispatcher().getOperationResourceInfos()) { Method method = ori.getMethodToInvoke(); Class<?> realReturnType = method.getReturnType(); Class<?> cls = realReturnType; if (cls == Response.class) { cls = getActualJaxbType(cls, method, false); } Type type = method.getGenericReturnType(); if (jaxbOnly) { checkJaxbType( resource.getServiceClass(), cls, realReturnType == Response.class ? cls : type, types, method.getAnnotations(), jaxbWriter); } else { types.getAllTypes().put(cls, type); } for (Parameter pm : ori.getParameters()) { if (pm.getType() == ParameterType.REQUEST_BODY) { Class<?> inType = method.getParameterTypes()[pm.getIndex()]; Type paramType = method.getGenericParameterTypes()[pm.getIndex()]; if (jaxbOnly) { checkJaxbType( resource.getServiceClass(), inType, paramType, types, method.getParameterAnnotations()[pm.getIndex()], jaxbWriter); } else { types.getAllTypes().put(inType, paramType); } } } } for (ClassResourceInfo sub : resource.getSubResources()) { if (!isRecursiveSubResource(resource, sub)) { getAllTypesForResource(sub, types, jaxbOnly, jaxbWriter); } } }
private static boolean isRecursiveSubResource(ClassResourceInfo parent, ClassResourceInfo sub) { if (parent == null) { return false; } if (parent == sub) { return true; } return isRecursiveSubResource(parent.getParent(), sub); }
public static ClassResourceInfo createClassResourceInfo( final Class<?> rClass, final Class<?> sClass, ClassResourceInfo parent, boolean root, boolean enableStatic, Bus bus) { ClassResourceInfo cri = new ClassResourceInfo(rClass, sClass, root, enableStatic, bus); cri.setParent(parent); if (root) { URITemplate t = URITemplate.createTemplate(cri.getPath()); cri.setURITemplate(t); } evaluateResourceClass(cri, enableStatic); return checkMethodDispatcher(cri) ? cri : null; }
private static void evaluateResourceClass(ClassResourceInfo cri, boolean enableStatic) { MethodDispatcher md = new MethodDispatcher(); Class<?> serviceClass = cri.getServiceClass(); boolean isFineLevelLoggable = LOG.isLoggable(Level.FINE); for (Method m : serviceClass.getMethods()) { Method annotatedMethod = AnnotationUtils.getAnnotatedMethod(serviceClass, m); String httpMethod = AnnotationUtils.getHttpMethodValue(annotatedMethod); Path path = AnnotationUtils.getMethodAnnotation(annotatedMethod, Path.class); if (httpMethod != null || path != null) { md.bind(createOperationInfo(m, annotatedMethod, cri, path, httpMethod), m); if (httpMethod == null) { // subresource locator Class<?> subClass = m.getReturnType(); if (enableStatic) { ClassResourceInfo subCri = cri.findResource(subClass, subClass); if (subCri == null) { ClassResourceInfo ancestor = getAncestorWithSameServiceClass(cri, subClass); subCri = ancestor != null ? ancestor : createClassResourceInfo( subClass, subClass, cri, false, enableStatic, cri.getBus()); } if (subCri != null) { cri.addSubClassResourceInfo(subCri); } } } } else if (isFineLevelLoggable) { LOG.fine( new org.apache.cxf.common.i18n.Message( "NOT_RESOURCE_METHOD", BUNDLE, m.getDeclaringClass().getName(), m.getName()) .toString()); } } cri.setMethodDispatcher(md); }
private void initValuesMap(Object... varValues) { if (isRoot) { List<String> vars = cri.getURITemplate().getVariables(); valuesMap = new LinkedHashMap<String, Object>(); for (int i = 0; i < vars.size(); i++) { if (varValues.length > 0) { if (i < varValues.length) { valuesMap.put(vars.get(i), varValues[i]); } else { org.apache.cxf.common.i18n.Message msg = new org.apache.cxf.common.i18n.Message( "ROOT_VARS_MISMATCH", BUNDLE, vars.size(), varValues.length); LOG.info(msg.toString()); break; } } else { valuesMap.put(vars.get(i), ""); } } } }
public static ClassResourceInfo createServiceClassResourceInfo( Map<String, UserResource> resources, UserResource model, Class<?> sClass, boolean isRoot, boolean enableStatic, Bus bus) { if (model == null) { throw new RuntimeException("Resource class " + sClass.getName() + " has no model info"); } ClassResourceInfo cri = new ClassResourceInfo( sClass, sClass, isRoot, enableStatic, true, model.getConsumes(), model.getProduces(), bus); URITemplate t = URITemplate.createTemplate(model.getPath()); cri.setURITemplate(t); MethodDispatcher md = new MethodDispatcher(); Map<String, UserOperation> ops = model.getOperationsAsMap(); Method defaultMethod = null; Map<String, Method> methodNames = new HashMap<String, Method>(); for (Method m : cri.getServiceClass().getMethods()) { if (m.getAnnotation(DefaultMethod.class) != null) { // if needed we can also support multiple default methods defaultMethod = m; } methodNames.put(m.getName(), m); } for (Map.Entry<String, UserOperation> entry : ops.entrySet()) { UserOperation op = entry.getValue(); Method actualMethod = methodNames.get(op.getName()); if (actualMethod == null) { actualMethod = defaultMethod; } if (actualMethod == null) { continue; } OperationResourceInfo ori = new OperationResourceInfo( actualMethod, cri, URITemplate.createTemplate(op.getPath()), op.getVerb(), op.getConsumes(), op.getProduces(), op.getParameters(), op.isOneway()); String rClassName = actualMethod.getReturnType().getName(); if (op.getVerb() == null) { if (resources.containsKey(rClassName)) { ClassResourceInfo subCri = rClassName.equals(model.getName()) ? cri : createServiceClassResourceInfo( resources, resources.get(rClassName), actualMethod.getReturnType(), false, enableStatic, bus); if (subCri != null) { cri.addSubClassResourceInfo(subCri); md.bind(ori, actualMethod); } } } else { md.bind(ori, actualMethod); } } cri.setMethodDispatcher(md); return checkMethodDispatcher(cri) ? cri : null; }
/** * 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); }