protected Object handleResponse(Message outMessage, Class<?> serviceCls) throws Throwable { try { Response r = setResponseBuilder(outMessage, outMessage.getExchange()).build(); ((ResponseImpl) r).setOutMessage(outMessage); getState().setResponse(r); Method method = outMessage.getExchange().get(Method.class); checkResponse(method, r, outMessage); if (method.getReturnType() == Void.class || method.getReturnType() == Void.TYPE) { return null; } if (method.getReturnType() == Response.class && (r.getEntity() == null || InputStream.class.isAssignableFrom(r.getEntity().getClass()) && ((InputStream) r.getEntity()).available() == 0)) { return r; } if (PropertyUtils.isTrue( super.getConfiguration().getResponseContext().get(BUFFER_PROXY_RESPONSE))) { r.bufferEntity(); } Class<?> returnType = method.getReturnType(); Type genericType = InjectionUtils.processGenericTypeIfNeeded( serviceCls, returnType, method.getGenericReturnType()); returnType = InjectionUtils.updateParamClassToTypeIfNeeded(returnType, genericType); return readBody(r, outMessage, returnType, genericType, method.getDeclaredAnnotations()); } finally { ClientProviderFactory.getInstance(outMessage).clearThreadLocalProxies(); } }
protected void addMatrixQueryParamsToBuilder( UriBuilder ub, String paramName, ParameterType pt, Annotation[] anns, Object... pValues) { if (pt != ParameterType.MATRIX && pt != ParameterType.QUERY) { throw new IllegalArgumentException( "This method currently deal " + "with matrix and query parameters only"); } if (!"".equals(paramName)) { if (pValues != null && pValues.length > 0) { for (Object pValue : pValues) { if (InjectionUtils.isSupportedCollectionOrArray(pValue.getClass())) { Collection<?> c = pValue.getClass().isArray() ? Arrays.asList((Object[]) pValue) : (Collection<?>) pValue; for (Iterator<?> it = c.iterator(); it.hasNext(); ) { convertMatrixOrQueryToBuilder(ub, paramName, it.next(), pt, anns); } } else { convertMatrixOrQueryToBuilder(ub, paramName, pValue, pt, anns); } } } else { addMatrixOrQueryToBuilder(ub, paramName, pt, pValues); } } else { Object pValue = pValues[0]; MultivaluedMap<String, Object> values = InjectionUtils.extractValuesFromBean(pValue, ""); for (Map.Entry<String, List<Object>> entry : values.entrySet()) { for (Object v : entry.getValue()) { convertMatrixOrQueryToBuilder(ub, entry.getKey(), v, pt, anns); } } } }
public void writeTo( T obj, Class<?> cls, Type genericType, Annotation[] anns, MediaType m, MultivaluedMap<String, Object> headers, OutputStream os) throws IOException { try { String encoding = HttpUtils.getSetEncoding(m, headers, null); if (InjectionUtils.isSupportedCollectionOrArray(cls)) { marshalCollection(cls, obj, genericType, encoding, os, m, anns); } else { Object actualObject = checkAdapter(obj, cls, anns, true); Class<?> actualClass = obj != actualObject || cls.isInterface() ? actualObject.getClass() : cls; marshal(actualObject, actualClass, genericType, encoding, os, m, anns); } } catch (JAXBException e) { handleJAXBException(e, false); } catch (WebApplicationException e) { throw e; } catch (Exception e) { LOG.warning(ExceptionUtils.getStackTrace(e)); throw ExceptionUtils.toInternalServerErrorException(e, null); } }
protected XMLStreamReader getStreamReader(InputStream is, Class<?> type, MediaType mt) { MessageContext mc = getContext(); XMLStreamReader reader = mc != null ? mc.getContent(XMLStreamReader.class) : null; if (reader == null && mc != null) { XMLInputFactory factory = (XMLInputFactory) mc.get(XMLInputFactory.class.getName()); if (factory != null) { try { reader = factory.createXMLStreamReader(is); } catch (XMLStreamException e) { throw ExceptionUtils.toInternalServerErrorException( new RuntimeException("Can not create XMLStreamReader", e), null); } } } if (reader == null && is == null) { reader = getStreamHandlerFromCurrentMessage(XMLStreamReader.class); } reader = createTransformReaderIfNeeded(reader, is); reader = createDepthReaderIfNeeded(reader, is); if (InjectionUtils.isSupportedCollectionOrArray(type)) { return new JAXBCollectionWrapperReader(TransformUtils.createNewReaderIfNeeded(reader, is)); } else { return reader; } }
private static ThreadLocalProxy<?> getFieldThreadLocalProxy(Field f, Object provider) { if (provider != null) { Object proxy = null; synchronized (provider) { try { proxy = InjectionUtils.extractFieldValue(f, provider); } catch (Throwable t) { // continue } if (!(proxy instanceof ThreadLocalProxy)) { proxy = InjectionUtils.createThreadLocalProxy(f.getType()); InjectionUtils.injectFieldValue(f, provider, proxy); } } return (ThreadLocalProxy<?>) proxy; } else { return InjectionUtils.createThreadLocalProxy(f.getType()); } }
protected void doWriteBody( Message outMessage, Object body, Type bodyType, Annotation[] customAnns, OutputStream os) throws Fault { OperationResourceInfo ori = outMessage.getContent(OperationResourceInfo.class); if (ori == null) { return; } Method method = ori.getMethodToInvoke(); int bodyIndex = (Integer) outMessage.get("BODY_INDEX"); Annotation[] anns = customAnns != null ? customAnns : getMethodAnnotations(ori.getAnnotatedMethod(), bodyIndex); try { if (bodyIndex != -1) { Class<?> paramClass = method.getParameterTypes()[bodyIndex]; Class<?> bodyClass = paramClass.isAssignableFrom(body.getClass()) ? paramClass : body.getClass(); Type genericType = method.getGenericParameterTypes()[bodyIndex]; if (bodyType != null) { genericType = bodyType; } genericType = InjectionUtils.processGenericTypeIfNeeded( ori.getClassResourceInfo().getServiceClass(), bodyClass, genericType); bodyClass = InjectionUtils.updateParamClassToTypeIfNeeded(bodyClass, genericType); writeBody(body, outMessage, bodyClass, genericType, anns, os); } else { Type paramType = body.getClass(); if (bodyType != null) { paramType = bodyType; } writeBody(body, outMessage, body.getClass(), paramType, anns, os); } } catch (Exception ex) { throw new Fault(ex); } }
private static ThreadLocalProxy<?> getMethodThreadLocalProxy(Method m, Object provider) { if (provider != null) { Object proxy = null; synchronized (provider) { try { proxy = InjectionUtils.extractFromMethod( provider, InjectionUtils.getGetterFromSetter(m), false); } catch (Throwable t) { // continue } if (!(proxy instanceof ThreadLocalProxy)) { proxy = InjectionUtils.createThreadLocalProxy(m.getParameterTypes()[0]); InjectionUtils.injectThroughMethod(provider, m, proxy); } } return (ThreadLocalProxy<?>) proxy; } else { return InjectionUtils.createThreadLocalProxy(m.getParameterTypes()[0]); } }
private void addFormValue( MultivaluedMap<String, String> form, String name, Object pValue, Annotation[] anns) { if (pValue != null) { if (InjectionUtils.isSupportedCollectionOrArray(pValue.getClass())) { Collection<?> c = pValue.getClass().isArray() ? Arrays.asList((Object[]) pValue) : (Collection<?>) pValue; for (Iterator<?> it = c.iterator(); it.hasNext(); ) { FormUtils.addPropertyToForm(form, name, convertParamValue(it.next(), anns)); } } else { FormUtils.addPropertyToForm( form, name, name.isEmpty() ? pValue : convertParamValue(pValue, anns)); } } }
private Map<String, BeanPair> getValuesFromBeanParam( Object bean, Class<? extends Annotation> annClass, Map<String, BeanPair> values) { for (Method m : bean.getClass().getMethods()) { if (m.getName().startsWith("set")) { try { String propertyName = m.getName().substring(3); Annotation annotation = m.getAnnotation(annClass); boolean beanParam = m.getAnnotation(BeanParam.class) != null; if (annotation != null || beanParam) { Method getter = bean.getClass().getMethod("get" + propertyName, new Class[] {}); Object value = getter.invoke(bean, new Object[] {}); if (value != null) { if (annotation != null) { String annotationValue = AnnotationUtils.getAnnotationValue(annotation); values.put(annotationValue, new BeanPair(value, m.getParameterAnnotations()[0])); } else { getValuesFromBeanParam(value, annClass, values); } } } else { String fieldName = StringUtils.uncapitalize(propertyName); Field f = InjectionUtils.getDeclaredField(bean.getClass(), fieldName); if (f == null) { continue; } annotation = f.getAnnotation(annClass); if (annotation != null) { Object value = ReflectionUtil.accessDeclaredField(f, bean, Object.class); if (value != null) { String annotationValue = AnnotationUtils.getAnnotationValue(annotation); values.put(annotationValue, new BeanPair(value, f.getAnnotations())); } } else if (f.getAnnotation(BeanParam.class) != null) { Object value = ReflectionUtil.accessDeclaredField(f, bean, Object.class); if (value != null) { getValuesFromBeanParam(value, annClass, values); } } } } catch (Throwable t) { // ignore } } } return values; }
private MultivaluedMap<String, String> setRequestHeaders( MultivaluedMap<String, String> headers, OperationResourceInfo ori, boolean formParams, Class<?> bodyClass, Class<?> responseClass) { if (headers.getFirst(HttpHeaders.CONTENT_TYPE) == null) { if (formParams || bodyClass != null && MultivaluedMap.class.isAssignableFrom(bodyClass)) { headers.putSingle(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_FORM_URLENCODED); } else { String ctType = null; List<MediaType> consumeTypes = ori.getConsumeTypes(); if (!consumeTypes.isEmpty() && !consumeTypes.get(0).equals(MediaType.WILDCARD_TYPE)) { ctType = JAXRSUtils.mediaTypeToString(ori.getConsumeTypes().get(0)); } else if (bodyClass != null) { ctType = MediaType.APPLICATION_XML; } if (ctType != null) { headers.putSingle(HttpHeaders.CONTENT_TYPE, ctType); } } } List<MediaType> accepts = getAccept(headers); if (accepts == null) { boolean produceWildcard = ori.getProduceTypes().size() == 0 || ori.getProduceTypes().get(0).equals(MediaType.WILDCARD_TYPE); if (produceWildcard) { accepts = InjectionUtils.isPrimitive(responseClass) ? Collections.singletonList(MediaType.TEXT_PLAIN_TYPE) : Collections.singletonList(MediaType.APPLICATION_XML_TYPE); } else if (responseClass == Void.class || responseClass == Void.TYPE) { accepts = Collections.singletonList(MediaType.WILDCARD_TYPE); } else { accepts = ori.getProduceTypes(); } for (MediaType mt : accepts) { headers.add(HttpHeaders.ACCEPT, JAXRSUtils.mediaTypeToString(mt)); } } return headers; }
@Override public boolean isWriteable(Class<?> type, Type genericType, Annotation[] anns, MediaType mt) { // JAXB support is required if (!super.isWriteable(type, genericType, anns, mt)) { return false; } if (InjectionUtils.isSupportedCollectionOrArray(type)) { return supportJaxbOnly; } // if the user has set the list of out classes and a given class // is in that list then it can only be handled by the template if (outClassCanBeHandled(type.getName()) || outClassesToHandle == null && !supportJaxbOnly) { return outTemplatesAvailable(type, anns, mt); } else { return supportJaxbOnly; } }
private void serializeMessage( ServerProviderFactory providerFactory, Message message, Response theResponse, OperationResourceInfo ori, boolean firstTry) { ResponseImpl response = (ResponseImpl) JAXRSUtils.copyResponseIfNeeded(theResponse); final Exchange exchange = message.getExchange(); boolean headResponse = response.getStatus() == 200 && firstTry && ori != null && HttpMethod.HEAD.equals(ori.getHttpMethod()); Object entity = response.getActualEntity(); if (headResponse && entity != null) { LOG.info(new org.apache.cxf.common.i18n.Message("HEAD_WITHOUT_ENTITY", BUNDLE).toString()); entity = null; } Method invoked = ori == null ? null : ori.getAnnotatedMethod() != null ? ori.getAnnotatedMethod() : ori.getMethodToInvoke(); Annotation[] annotations = null; Annotation[] staticAnns = ori != null ? ori.getOutAnnotations() : new Annotation[] {}; Annotation[] responseAnns = response.getEntityAnnotations(); if (responseAnns != null) { annotations = new Annotation[staticAnns.length + responseAnns.length]; System.arraycopy(staticAnns, 0, annotations, 0, staticAnns.length); System.arraycopy(responseAnns, 0, annotations, staticAnns.length, responseAnns.length); } else { annotations = staticAnns; } response.setStatus(getActualStatus(response.getStatus(), entity)); response.setEntity(entity, annotations); // Prepare the headers MultivaluedMap<String, Object> responseHeaders = prepareResponseHeaders(message, response, entity, firstTry); // Run the filters try { JAXRSUtils.runContainerResponseFilters(providerFactory, response, message, ori, invoked); } catch (Throwable ex) { handleWriteException(providerFactory, message, ex, firstTry); return; } // Write the entity entity = InjectionUtils.getEntity(response.getActualEntity()); setResponseStatus(message, getActualStatus(response.getStatus(), entity)); if (entity == null) { if (!headResponse) { responseHeaders.putSingle(HttpHeaders.CONTENT_LENGTH, "0"); if (MessageUtils.getContextualBoolean( message, "remove.content.type.for.empty.response", false)) { responseHeaders.remove(HttpHeaders.CONTENT_TYPE); message.remove(Message.CONTENT_TYPE); } } HttpUtils.convertHeaderValuesToString(responseHeaders, true); return; } Object ignoreWritersProp = exchange.get(JAXRSUtils.IGNORE_MESSAGE_WRITERS); boolean ignoreWriters = ignoreWritersProp == null ? false : Boolean.valueOf(ignoreWritersProp.toString()); if (ignoreWriters) { writeResponseToStream(message.getContent(OutputStream.class), entity); return; } MediaType responseMediaType = getResponseMediaType(responseHeaders.getFirst(HttpHeaders.CONTENT_TYPE)); Class<?> serviceCls = invoked != null ? ori.getClassResourceInfo().getServiceClass() : null; Class<?> targetType = InjectionUtils.getRawResponseClass(entity); Type genericType = InjectionUtils.getGenericResponseType( invoked, serviceCls, response.getActualEntity(), targetType, exchange); targetType = InjectionUtils.updateParamClassToTypeIfNeeded(targetType, genericType); annotations = response.getEntityAnnotations(); List<WriterInterceptor> writers = providerFactory.createMessageBodyWriterInterceptor( targetType, genericType, annotations, responseMediaType, message, ori == null ? null : ori.getNameBindings()); OutputStream outOriginal = message.getContent(OutputStream.class); if (writers == null || writers.isEmpty()) { writeResponseErrorMessage( message, outOriginal, "NO_MSG_WRITER", targetType, responseMediaType); return; } try { boolean checkWriters = false; if (responseMediaType.isWildcardSubtype()) { Produces pM = AnnotationUtils.getMethodAnnotation( ori == null ? null : ori.getAnnotatedMethod(), Produces.class); Produces pC = AnnotationUtils.getClassAnnotation(serviceCls, Produces.class); checkWriters = pM == null && pC == null; } responseMediaType = checkFinalContentType(responseMediaType, writers, checkWriters); } catch (Throwable ex) { handleWriteException(providerFactory, message, ex, firstTry); return; } String finalResponseContentType = JAXRSUtils.mediaTypeToString(responseMediaType); if (LOG.isLoggable(Level.FINE)) { LOG.fine("Response content type is: " + finalResponseContentType); } responseHeaders.putSingle(HttpHeaders.CONTENT_TYPE, finalResponseContentType); message.put(Message.CONTENT_TYPE, finalResponseContentType); boolean enabled = checkBufferingMode(message, writers, firstTry); try { try { JAXRSUtils.writeMessageBody( writers, entity, targetType, genericType, annotations, responseMediaType, responseHeaders, message); if (isResponseRedirected(message)) { return; } checkCachedStream(message, outOriginal, enabled); } finally { if (enabled) { OutputStream os = message.getContent(OutputStream.class); if (os != outOriginal && os instanceof CachedOutputStream) { os.close(); } message.setContent(OutputStream.class, outOriginal); message.put(XMLStreamWriter.class.getName(), null); } } } catch (Throwable ex) { logWriteError(firstTry, targetType, responseMediaType); handleWriteException(providerFactory, message, ex, firstTry); } }
protected void marshalCollection( Class<?> originalCls, Object collection, Type genericType, String enc, OutputStream os, MediaType m, Annotation[] anns) throws Exception { Class<?> actualClass = InjectionUtils.getActualType(genericType); actualClass = getActualType(actualClass, genericType, anns); Collection<?> c = originalCls.isArray() ? Arrays.asList((Object[]) collection) : (Collection<?>) collection; Iterator<?> it = c.iterator(); Object firstObj = it.hasNext() ? it.next() : null; QName qname = null; if (firstObj instanceof JAXBElement) { JAXBElement<?> el = (JAXBElement<?>) firstObj; qname = el.getName(); actualClass = el.getDeclaredType(); } else { qname = getCollectionWrapperQName(actualClass, genericType, firstObj, true); } if (qname == null) { String message = new org.apache.cxf.common.i18n.Message("NO_COLLECTION_ROOT", BUNDLE).toString(); throw new WebApplicationException(Response.serverError().entity(message).build()); } StringBuilder pi = new StringBuilder(); pi.append(XML_PI_START + (enc == null ? "UTF-8" : enc) + "\"?>"); os.write(pi.toString().getBytes()); String startTag = null; String endTag = null; if (qname.getNamespaceURI().length() > 0) { String prefix = nsPrefixes.get(qname.getNamespaceURI()); if (prefix == null) { prefix = "ns1"; } startTag = "<" + prefix + ":" + qname.getLocalPart() + " xmlns:" + prefix + "=\"" + qname.getNamespaceURI() + "\">"; endTag = "</" + prefix + ":" + qname.getLocalPart() + ">"; } else { startTag = "<" + qname.getLocalPart() + ">"; endTag = "</" + qname.getLocalPart() + ">"; } os.write(startTag.getBytes()); if (firstObj != null) { XmlJavaTypeAdapter adapter = org.apache.cxf.jaxrs.utils.JAXBUtils.getAdapter(firstObj.getClass(), anns); marshalCollectionMember( JAXBUtils.useAdapter(firstObj, adapter, true), actualClass, genericType, enc, os, anns, m, qname.getNamespaceURI()); while (it.hasNext()) { marshalCollectionMember( JAXBUtils.useAdapter(it.next(), adapter, true), actualClass, genericType, enc, os, anns, m, qname.getNamespaceURI()); } } os.write(endTag.getBytes()); }
public T readFrom( Class<T> type, Type genericType, Annotation[] anns, MediaType mt, MultivaluedMap<String, String> headers, InputStream is) throws IOException { if (isPayloadEmpty(headers)) { if (AnnotationUtils.getAnnotation(anns, Nullable.class) != null) { return null; } else { reportEmptyContentLength(); } } XMLStreamReader reader = null; Unmarshaller unmarshaller = null; try { boolean isCollection = InjectionUtils.isSupportedCollectionOrArray(type); Class<?> theGenericType = isCollection ? InjectionUtils.getActualType(genericType) : type; Class<?> theType = getActualType(theGenericType, genericType, anns); unmarshaller = createUnmarshaller(theType, genericType, isCollection); addAttachmentUnmarshaller(unmarshaller); Object response = null; if (JAXBElement.class.isAssignableFrom(type) || !isCollection && (unmarshalAsJaxbElement || jaxbElementClassMap != null && jaxbElementClassMap.containsKey(theType.getName()))) { reader = getStreamReader(is, type, mt); reader = TransformUtils.createNewReaderIfNeeded(reader, is); if (JAXBElement.class.isAssignableFrom(type) && type == theType) { response = unmarshaller.unmarshal(reader); } else { response = unmarshaller.unmarshal(reader, theType); } } else { response = doUnmarshal(unmarshaller, type, is, anns, mt); } if (response instanceof JAXBElement && !JAXBElement.class.isAssignableFrom(type)) { response = ((JAXBElement<?>) response).getValue(); } if (isCollection) { response = ((CollectionWrapper) response) .getCollectionOrArray( unmarshaller, theType, type, genericType, org.apache.cxf.jaxrs.utils.JAXBUtils.getAdapter(theGenericType, anns)); } else { response = checkAdapter(response, type, anns, false); } return type.cast(response); } catch (JAXBException e) { handleJAXBException(e, true); } catch (DepthExceededStaxException e) { throw ExceptionUtils.toWebApplicationException(null, JAXRSUtils.toResponse(413)); } catch (WebApplicationException e) { throw e; } catch (Exception e) { LOG.warning(ExceptionUtils.getStackTrace(e)); throw ExceptionUtils.toBadRequestException(e, null); } finally { try { StaxUtils.close(reader); } catch (XMLStreamException e) { // Ignore } JAXBUtils.closeUnmarshaller(unmarshaller); } // unreachable return null; }
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; }