/** * 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.camel.component.cxf.feature; import java.util.ArrayList; import java.util.Collection; import javax.xml.soap.SOAPMessage; import javax.xml.transform.Source; import org.apache.camel.component.cxf.interceptors.CxfMessageSoapHeaderOutInterceptor; import org.apache.cxf.Bus; import org.apache.cxf.binding.Binding; import org.apache.cxf.binding.soap.SoapBinding; import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor; import org.apache.cxf.binding.soap.saaj.SAAJOutInterceptor; import org.apache.cxf.endpoint.Client; import org.apache.cxf.endpoint.Endpoint; import org.apache.cxf.endpoint.Server; import org.apache.cxf.interceptor.AbstractInDatabindingInterceptor; import org.apache.cxf.jaxws.interceptors.HolderInInterceptor; import org.apache.cxf.jaxws.interceptors.HolderOutInterceptor; import org.apache.cxf.jaxws.interceptors.MessageModeInInterceptor; import org.apache.cxf.jaxws.interceptors.MessageModeOutInterceptor; import org.apache.cxf.jaxws.interceptors.WrapperClassInInterceptor; import org.apache.cxf.jaxws.interceptors.WrapperClassOutInterceptor; import org.apache.cxf.service.model.BindingMessageInfo; import org.apache.cxf.service.model.BindingOperationInfo; import org.apache.cxf.service.model.MessageInfo; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * <p> * MessageDataFormatFeature sets up the CXF endpoint interceptor for handling the * Message in Message data format. * </p> */ public class CXFMessageDataFormatFeature extends AbstractDataFormatFeature { private static final Logger LOG = LoggerFactory.getLogger(CXFMessageDataFormatFeature.class); private static final Collection<Class<?>> REMOVING_IN_INTERCEPTORS; private static final Collection<Class<?>> REMOVING_OUT_INTERCEPTORS; static { REMOVING_IN_INTERCEPTORS = new ArrayList<Class<?>>(); REMOVING_IN_INTERCEPTORS.add(HolderInInterceptor.class); REMOVING_IN_INTERCEPTORS.add(WrapperClassInInterceptor.class); REMOVING_OUT_INTERCEPTORS = new ArrayList<Class<?>>(); REMOVING_OUT_INTERCEPTORS.add(HolderOutInterceptor.class); REMOVING_OUT_INTERCEPTORS.add(WrapperClassOutInterceptor.class); } @Override public void initialize(Client client, Bus bus) { removeFaultInInterceptorFromClient(client); setupEndpoint(client.getEndpoint()); } @Override public void initialize(Server server, Bus bus) { setupEndpoint(server.getEndpoint()); } protected void setupEndpoint(Endpoint ep) { resetPartTypes(ep.getBinding()); Class<?> fmt = Source.class; if (ep.getBinding() instanceof SoapBinding) { ep.getInInterceptors().add(new SAAJInInterceptor()); SAAJOutInterceptor out = new SAAJOutInterceptor(); ep.getOutInterceptors().add(out); ep.getOutInterceptors().add(new CxfMessageSoapHeaderOutInterceptor()); ep.getOutInterceptors().add(new MessageModeOutInterceptor(out, ep.getBinding().getBindingInfo().getName())); fmt = SOAPMessage.class; } else { ep.getOutInterceptors().add(new MessageModeOutInterceptor(Source.class, ep.getBinding().getBindingInfo().getName())); } ep.getInInterceptors().add(new MessageModeInInterceptor(fmt, ep.getBinding().getBindingInfo().getName())); ep.put(AbstractInDatabindingInterceptor.NO_VALIDATE_PARTS, Boolean.TRUE); // need to remove the wrapper class and holder interceptor removeInterceptors(ep.getInInterceptors(), REMOVING_IN_INTERCEPTORS); removeInterceptors(ep.getOutInterceptors(), REMOVING_OUT_INTERCEPTORS); } @Override protected Logger getLogger() { return LOG; } private void resetPartTypes(Binding bop2) { // The HypbridSourceDatabinding, based on JAXB, will possibly set // JAXB types into the parts. Since we need the Source objects, // we'll reset the types to either Source (for streaming), or null // (for non-streaming, defaults to DOMSource. for (BindingOperationInfo bop : bop2.getBindingInfo().getOperations()) { resetPartTypes(bop); } } private void resetPartTypes(BindingOperationInfo bop) { if (bop.isUnwrapped()) { bop = bop.getWrappedOperation(); } if (bop.isUnwrappedCapable()) { resetPartTypeClass(bop.getWrappedOperation().getOperationInfo().getInput()); resetPartTypeClass(bop.getWrappedOperation().getOperationInfo().getOutput()); resetPartTypeClass(bop.getWrappedOperation().getInput()); resetPartTypeClass(bop.getWrappedOperation().getOutput()); } resetPartTypeClass(bop.getOperationInfo().getInput()); resetPartTypeClass(bop.getOperationInfo().getOutput()); resetPartTypeClass(bop.getInput()); resetPartTypeClass(bop.getOutput()); } protected void resetPartTypeClass(BindingMessageInfo bmi) { if (bmi != null) { int size = bmi.getMessageParts().size(); for (int x = 0; x < size; x++) { bmi.getMessageParts().get(x).setTypeClass(Source.class); } } } protected void resetPartTypeClass(MessageInfo msgInfo) { if (msgInfo != null) { int size = msgInfo.getMessageParts().size(); for (int x = 0; x < size; x++) { msgInfo.getMessageParts().get(x).setTypeClass(Source.class); } } } }