public class RMCaptureInInterceptor extends AbstractRMInterceptor<Message> { private static final Logger LOG = LogUtils.getLogger(RMCaptureInInterceptor.class); public RMCaptureInInterceptor() { super(Phase.PRE_STREAM); } protected void handle(Message message) throws SequenceFault, RMException { LOG.entering(getClass().getName(), "handleMessage"); // This message capturing mechanism will need to be changed at some point. // Until then, we keep this interceptor here and utilize the robust // option to avoid the unnecessary message capturing/caching. if (!MessageUtils.isTrue(message.getContextualProperty(Message.ROBUST_ONEWAY))) { InputStream is = message.getContent(InputStream.class); if (is != null) { CachedOutputStream saved = new CachedOutputStream(); try { IOUtils.copy(is, saved); saved.flush(); is.close(); saved.lockOutputStream(); LOG.fine("Capturing the original RM message"); RewindableInputStream ris = RewindableInputStream.makeRewindable(saved.getInputStream()); message.setContent(InputStream.class, ris); message.put(RMMessageConstants.SAVED_CONTENT, ris); } catch (Exception e) { throw new Fault(e); } } } } }
@javax.jws.WebService( portName = "SoapPort", serviceName = "SOAPService", targetNamespace = "http://apache.org/hello_world_soap12_http", endpointInterface = "org.apache.hello_world_soap12_http.Greeter", wsdlLocation = "testutils/hello_world_soap12.wsdl") public class GreeterImpl implements Greeter { private static final Logger LOG = LogUtils.getLogger(GreeterImpl.class); /* (non-Javadoc) * @see org.apache.hello_world_soap12_http.Greeter#sayHi() */ public String sayHi() { LOG.info("Executing operation sayHi"); System.out.println("Executing operation sayHi\n"); return "Bonjour"; } public void pingMe() throws PingMeFault { FaultDetail faultDetail = new FaultDetail(); faultDetail.setMajor((short) 2); faultDetail.setMinor((short) 1); LOG.info("Executing operation pingMe, throwing PingMeFault exception"); System.out.println("Executing operation pingMe, throwing PingMeFault exception\n"); throw new PingMeFault("PingMeFault raised by server", faultDetail); } }
@WebService( serviceName = "GreeterService", portName = "GreeterPort", endpointInterface = "org.apache.cxf.greeter_control.Greeter", targetNamespace = "http://cxf.apache.org/greeter_control") public class GreeterSessionImpl implements Greeter { private static final Logger LOG = LogUtils.getLogger( GreeterSessionImpl.class, null, GreeterSessionImpl.class.getPackage().getName()); @Resource private WebServiceContext context; // greetMe will use session to return last called name public String greetMe(String me) { LOG.info("Executing operation greetMe"); LOG.info("Message received: " + me); MessageContext mc = context.getMessageContext(); HttpServletRequest req = (HttpServletRequest) mc.get(MessageContext.SERVLET_REQUEST); Cookie cookies[] = req.getCookies(); String val = ""; if (cookies != null) { for (Cookie cookie : cookies) { val += ";" + cookie.getName() + "=" + cookie.getValue(); } } HttpSession session = req.getSession(); // Get a session property "counter" from context if (session == null) { throw new WebServiceException("No session in WebServiceContext"); } String name = (String) session.getAttribute("name"); if (name == null) { name = me; LOG.info("Starting the Session"); } session.setAttribute("name", me); return "Hello " + name + val; } public String sayHi() { LOG.info("Executing operation sayHi"); return "Bonjour "; } public void pingMe() {} public Future<?> greetMeAsync(String requestType, AsyncHandler<GreetMeResponse> asyncHandler) { // TODO Auto-generated method stub return null; } public Response<GreetMeResponse> greetMeAsync(String requestType) { // TODO Auto-generated method stub return null; } public void greetMeOneWay(String me) { LOG.info("Executing operation greetMeOneWay"); LOG.info("Message received: " + me); MessageContext mc = context.getMessageContext(); HttpServletRequest req = (HttpServletRequest) mc.get(MessageContext.SERVLET_REQUEST); HttpSession session = req.getSession(); if (session == null) { throw new WebServiceException("No session in WebServiceContext"); } String name = (String) session.getAttribute("name"); if (name == null) { name = me; LOG.info("Starting the Session"); } session.setAttribute("name", me); } public Future<?> pingMeAsync(AsyncHandler<PingMeResponse> asyncHandler) { // TODO Auto-generated method stub return null; } public Response<PingMeResponse> pingMeAsync() { // TODO Auto-generated method stub return null; } public Future<?> sayHiAsync(AsyncHandler<SayHiResponse> asyncHandler) { // TODO Auto-generated method stub return null; } public Response<SayHiResponse> sayHiAsync() { // TODO Auto-generated method stub return null; } }
public class InterceptorFaultTest extends AbstractBusClientServerTestBase { public static final String PORT = allocatePort(Server.class); private static final Logger LOG = LogUtils.getLogger(InterceptorFaultTest.class); private static final QName SOAP_FAULT_CODE = new QName("http://schemas.xmlsoap.org/soap/envelope/", "Server"); private static final String FAULT_MESSAGE = "Could not send Message."; private static final String CONTROL_PORT_ADDRESS = "http://localhost:" + PORT + "/SoapContext/ControlPort"; private static int decoupledEndpointPort = 1; private static String decoupledEndpoint; /** * Tests that a fault thrown by a server side interceptor is reported back to the client in * appropriate form (plain Fault in case of one way requests, SoapFault in case of two way * requests). Also demonstrates how an interceptor on the server out fault chain can distinguish * different fault modes (the capability to do so is crucial to QOS interceptors such as the RM, * addressing and policy interceptors). */ public static class Server extends AbstractBusTestServerBase { Endpoint ep; protected void run() { SpringBusFactory factory = new SpringBusFactory(); Bus bus = factory.createBus(); BusFactory.setDefaultBus(bus); setBus(bus); ControlImpl implementor = new ControlImpl(); implementor.setAddress("http://localhost:" + PORT + "/SoapContext/GreeterPort"); GreeterImpl greeterImplementor = new GreeterImpl(); greeterImplementor.setThrowAlways(true); greeterImplementor.useLastOnewayArg(true); implementor.setImplementor(greeterImplementor); ep = Endpoint.publish(CONTROL_PORT_ADDRESS, implementor); LOG.fine("Published control endpoint."); } public void tearDown() { ep.stop(); ep = null; } public static void main(String[] args) { try { Server s = new Server(); s.start(); } catch (Exception ex) { ex.printStackTrace(); System.exit(-1); } finally { System.out.println("done!"); } } } private Bus controlBus; private Control control; private Bus greeterBus; private Greeter greeter; private List<Phase> inPhases; private PhaseComparator comparator; private Phase preLogicalPhase; @BeforeClass public static void startServers() throws Exception { System.setProperty("org.apache.cxf.transports.http_jetty.DontClosePort." + PORT, "true"); assertTrue("server did not launch correctly", launchServer(Server.class, true)); createStaticBus(); } @AfterClass public static void reset() { System.clearProperty("org.apache.cxf.transports.http_jetty.DontClosePort." + PORT); Bus b = BusFactory.getDefaultBus(false); if (b == null) { b = BusFactory.getThreadDefaultBus(false); } if (b == null) { b = BusFactory.getDefaultBus(); } b.shutdown(true); } @After public void tearDown() throws Exception { if (null != greeter) { ((java.io.Closeable) greeter).close(); assertTrue("Failed to stop greeter.", control.stopGreeter(null)); greeterBus.shutdown(true); greeterBus = null; } if (null != control) { assertTrue("Failed to stop greeter", control.stopGreeter(null)); ((java.io.Closeable) control).close(); controlBus.shutdown(true); } } @Test public void testWithoutAddressing() throws Exception { testWithoutAddressing(false); } @Test public void testRobustWithoutAddressing() throws Exception { testWithoutAddressing(true); } private void testWithoutAddressing(boolean robust) throws Exception { setupGreeter("org/apache/cxf/systest/interceptor/no-addr.xml", false); control.setRobustInOnlyMode(robust); // all interceptors pass testInterceptorsPass(robust); // behaviour is identicial for all phases FaultLocation location = new org.apache.cxf.greeter_control.types.ObjectFactory().createFaultLocation(); // test failure occuring before and after logical addressing interceptor // won't get a fault in case of oneways non-robust for the latter (partial response already // sent) testInterceptorFail(inPhases, location, robust); } @Test public void testWithAddressingAnonymousReplies() throws Exception { testWithAddressingAnonymousReplies(false); } @Test public void testRobustWithAddressingAnonymousReplies() throws Exception { testWithAddressingAnonymousReplies(true); } private void testWithAddressingAnonymousReplies(boolean robust) throws Exception { setupGreeter("org/apache/cxf/systest/interceptor/addr.xml", false); control.setRobustInOnlyMode(robust); // all interceptors pass testInterceptorsPass(robust); // test failure in phases before Phase.PRE_LOGICAL FaultLocation location = new org.apache.cxf.greeter_control.types.ObjectFactory().createFaultLocation(); location.setAfter(MAPAggregator.class.getName()); // test failure occuring before and after logical addressing interceptor // won't get a fault in case of oneways non-robust for the latter (partial response already // sent) testInterceptorFail(inPhases, location, robust); } private void testInterceptorFail(List<Phase> phases, FaultLocation location, boolean robust) throws PingMeFault { for (Phase p : phases) { location.setPhase(p.getName()); if (Phase.PRE_LOGICAL.equals(p.getName())) { continue; } else if (Phase.POST_INVOKE.equals(p.getName())) { break; } testFail(location, true, robust); } } private void testInterceptorsPass(boolean robust) { greeter.greetMeOneWay("one"); // wait 5 seconds for the non-robust case if (!robust) { try { Thread.sleep(5000); } catch (InterruptedException e) { // ignore } } // verify both the previous greetMeOneWay call and this greetMe call assertEquals("one", greeter.greetMe("two")); try { greeter.pingMe(); fail("Expected PingMeFault not thrown."); } catch (PingMeFault f) { assertEquals(20, f.getFaultInfo().getMajor()); assertEquals(10, f.getFaultInfo().getMinor()); } } private void testFail(FaultLocation location, boolean usingAddressing, boolean robust) throws PingMeFault { // System.out.print("Test interceptor failing in phase: " + location.getPhase()); control.setFaultLocation(location); // oneway reports a plain fault (although server sends a soap fault) boolean expectOnewayFault = robust || comparator.compare(preLogicalPhase, getPhase(location.getPhase())) > 0; try { greeter.greetMeOneWay("oneway"); if (expectOnewayFault) { fail("Oneway operation unexpectedly succeded for phase " + location.getPhase()); } } catch (WebServiceException ex) { if (!expectOnewayFault) { fail("Oneway operation unexpectedly failed."); } assertEquals(FAULT_MESSAGE, ex.getMessage()); } String expectedMsg = getExpectedInterceptorFaultMessage(location.getPhase()); try { greeter.greetMe("cxf"); fail("Twoway operation unexpectedly succeded."); } catch (WebServiceException ex) { Throwable cause = ex.getCause(); SoapFault sf = (SoapFault) cause; assertEquals(expectedMsg, sf.getReason()); assertEquals(SOAP_FAULT_CODE, sf.getFaultCode()); } try { greeter.pingMe(); fail("Expected PingMeFault not thrown."); } catch (WebServiceException ex) { Throwable cause = ex.getCause(); SoapFault sf = (SoapFault) cause; assertEquals(expectedMsg, sf.getReason()); assertEquals(SOAP_FAULT_CODE, sf.getFaultCode()); } } private void setupGreeter(String cfgResource, boolean useDecoupledEndpoint) throws NumberFormatException, MalformedURLException { SpringBusFactory bf = new SpringBusFactory(); controlBus = bf.createBus(); BusFactory.setDefaultBus(controlBus); ControlService cs = new ControlService(); control = cs.getControlPort(); updateAddressPort(control, PORT); assertTrue("Failed to start greeter", control.startGreeter(cfgResource)); greeterBus = bf.createBus(cfgResource); BusFactory.setDefaultBus(greeterBus); LOG.fine("Initialised greeter bus with configuration: " + cfgResource); if (null == comparator) { comparator = new PhaseComparator(); } if (null == inPhases) { inPhases = new ArrayList<Phase>(); inPhases.addAll(greeterBus.getExtension(PhaseManager.class).getInPhases()); Collections.sort(inPhases, comparator); } if (null == preLogicalPhase) { preLogicalPhase = getPhase(Phase.PRE_LOGICAL); } GreeterService gs = new GreeterService(); greeter = gs.getGreeterPort(); updateAddressPort(greeter, PORT); LOG.fine("Created greeter client."); if (!useDecoupledEndpoint) { return; } // programatically configure decoupled endpoint that is guaranteed to // be unique across all test cases decoupledEndpointPort++; decoupledEndpoint = "http://localhost:" + allocatePort("decoupled-" + decoupledEndpointPort) + "/decoupled_endpoint"; Client c = ClientProxy.getClient(greeter); HTTPConduit hc = (HTTPConduit) (c.getConduit()); HTTPClientPolicy cp = hc.getClient(); cp.setDecoupledEndpoint(decoupledEndpoint); LOG.fine("Using decoupled endpoint: " + cp.getDecoupledEndpoint()); } private String getExpectedInterceptorFaultMessage(String phase) { return FaultThrowingInterceptor.MESSAGE_FORMAT.format(new Object[] {phase}).toUpperCase(); } private Phase getPhase(String name) { for (Phase p : inPhases) { if (p.getName().equals(name)) { return p; } } return null; } }
/** Takes a Fault and converts it to a local exception type if possible. */ public class ClientFaultConverter extends AbstractInDatabindingInterceptor { public static final String DISABLE_FAULT_MAPPING = "disable-fault-mapping"; public static final Pattern CAUSE_SUFFIX_SPLITTER = Pattern.compile(Message.EXCEPTION_CAUSE_SUFFIX, Pattern.LITERAL | Pattern.MULTILINE); private static final Logger LOG = LogUtils.getLogger(ClientFaultConverter.class); public ClientFaultConverter() { super(Phase.UNMARSHAL); } public ClientFaultConverter(String phase) { super(phase); } public void handleMessage(Message msg) { Fault fault = (Fault) msg.getContent(Exception.class); if (fault.getDetail() != null && !MessageUtils.getContextualBoolean(msg, DISABLE_FAULT_MAPPING, false)) { processFaultDetail(fault, msg); setStackTrace(fault, msg); } FaultMode faultMode = FaultMode.UNCHECKED_APPLICATION_FAULT; // Check if the raised exception is declared in the WSDL or by the JAX-RS resource Method m = msg.getExchange().get(Method.class); if (m != null) { Exception e = msg.getContent(Exception.class); for (Class<?> cl : m.getExceptionTypes()) { if (cl.isInstance(e)) { faultMode = FaultMode.CHECKED_APPLICATION_FAULT; break; } } } msg.getExchange().put(FaultMode.class, faultMode); } protected void processFaultDetail(Fault fault, Message msg) { Element exDetail = (Element) DOMUtils.getChild(fault.getDetail(), Node.ELEMENT_NODE); if (exDetail == null) { return; } QName qname = new QName(exDetail.getNamespaceURI(), exDetail.getLocalName()); FaultInfo faultWanted = null; MessagePartInfo part = null; BindingOperationInfo boi = msg.getExchange().get(BindingOperationInfo.class); if (boi == null) { return; } if (boi.isUnwrapped()) { boi = boi.getWrappedOperation(); } for (FaultInfo faultInfo : boi.getOperationInfo().getFaults()) { for (MessagePartInfo mpi : faultInfo.getMessageParts()) { if (qname.equals(mpi.getConcreteName())) { faultWanted = faultInfo; part = mpi; break; } } if (faultWanted != null) { break; } } if (faultWanted == null) { // did not find it using the proper qualified names, we'll try again with just the localpart for (FaultInfo faultInfo : boi.getOperationInfo().getFaults()) { for (MessagePartInfo mpi : faultInfo.getMessageParts()) { if (qname.getLocalPart().equals(mpi.getConcreteName().getLocalPart())) { faultWanted = faultInfo; part = mpi; break; } } if (faultWanted != null) { break; } } } if (faultWanted == null) { return; } Service s = msg.getExchange().get(Service.class); DataBinding dataBinding = s.getDataBinding(); Object e = null; if (isDOMSupported(dataBinding)) { DataReader<Node> reader = this.getNodeDataReader(msg); reader.setProperty(DataReader.FAULT, fault); e = reader.read(part, exDetail); } else { DataReader<XMLStreamReader> reader = this.getDataReader(msg); XMLStreamReader xsr = new W3CDOMStreamReader(exDetail); try { xsr.nextTag(); } catch (XMLStreamException e1) { throw new Fault(e1); } reader.setProperty(DataReader.FAULT, fault); e = reader.read(part, xsr); } if (!(e instanceof Exception)) { try { Class<?> exClass = faultWanted.getProperty(Class.class.getName(), Class.class); if (exClass == null) { return; } if (e == null) { Constructor<?> constructor = exClass.getConstructor(new Class[] {String.class}); e = constructor.newInstance(new Object[] {fault.getMessage()}); } else { try { Constructor<?> constructor = getConstructor(exClass, e); e = constructor.newInstance(new Object[] {fault.getMessage(), e}); } catch (NoSuchMethodException e1) { // Use reflection to convert fault bean to exception e = convertFaultBean(exClass, e, fault); } } msg.setContent(Exception.class, e); } catch (Exception e1) { LogUtils.log(LOG, Level.INFO, "EXCEPTION_WHILE_CREATING_EXCEPTION", e1, e1.getMessage()); } } else { if (fault.getMessage() != null) { Field f; try { f = Throwable.class.getDeclaredField("detailMessage"); ReflectionUtil.setAccessible(f); f.set(e, fault.getMessage()); } catch (Exception e1) { // ignore } } msg.setContent(Exception.class, e); } } private Constructor<?> getConstructor(Class<?> faultClass, Object e) throws NoSuchMethodException { Class<?> beanClass = e.getClass(); Constructor<?> cons[] = faultClass.getConstructors(); for (Constructor<?> c : cons) { if (c.getParameterTypes().length == 2 && String.class.equals(c.getParameterTypes()[0]) && c.getParameterTypes()[1].isInstance(e)) { return c; } } try { return faultClass.getConstructor(new Class[] {String.class, beanClass}); } catch (NoSuchMethodException ex) { Class<?> cls = getPrimitiveClass(beanClass); if (cls != null) { return faultClass.getConstructor(new Class[] {String.class, cls}); } else { throw ex; } } } private boolean isDOMSupported(DataBinding db) { boolean supportsDOM = false; for (Class<?> c : db.getSupportedReaderFormats()) { if (c.equals(Node.class)) { supportsDOM = true; } } return supportsDOM; } private void setStackTrace(Fault fault, Message msg) { Throwable cause = null; Map<String, String> ns = new HashMap<String, String>(); XPathUtils xu = new XPathUtils(ns); ns.put("s", Fault.STACKTRACE_NAMESPACE); String ss = (String) xu.getValue( "//s:" + Fault.STACKTRACE + "/text()", fault.getDetail(), XPathConstants.STRING); List<StackTraceElement> stackTraceList = new ArrayList<StackTraceElement>(); if (!StringUtils.isEmpty(ss)) { Iterator<String> linesIterator = Arrays.asList(CAUSE_SUFFIX_SPLITTER.split(ss)).iterator(); while (linesIterator.hasNext()) { String oneLine = linesIterator.next(); if (oneLine.startsWith("Caused by:")) { cause = getCause(linesIterator, oneLine); break; } stackTraceList.add(parseStackTrackLine(oneLine)); } if (stackTraceList.size() > 0 || cause != null) { Exception e = msg.getContent(Exception.class); if (!stackTraceList.isEmpty()) { StackTraceElement[] stackTraceElement = new StackTraceElement[stackTraceList.size()]; e.setStackTrace(stackTraceList.toArray(stackTraceElement)); } if (cause != null) { e.initCause(cause); } } } } // recursively parse the causes and instantiate corresponding throwables private Throwable getCause(Iterator<String> linesIterator, String firstLine) { // The actual exception class of the cause might be unavailable at the // client -> use a standard throwable to represent the cause. Throwable res = new Throwable(firstLine.substring(firstLine.indexOf(":") + 2)); List<StackTraceElement> stackTraceList = new ArrayList<StackTraceElement>(); while (linesIterator.hasNext()) { String oneLine = linesIterator.next(); if (oneLine.startsWith("Caused by:")) { Throwable nestedCause = getCause(linesIterator, oneLine); res.initCause(nestedCause); break; } stackTraceList.add(parseStackTrackLine(oneLine)); } StackTraceElement[] stackTraceElement = new StackTraceElement[stackTraceList.size()]; res.setStackTrace(stackTraceList.toArray(stackTraceElement)); return res; } private static StackTraceElement parseStackTrackLine(String oneLine) { StringTokenizer stInner = new StringTokenizer(oneLine, "!"); return new StackTraceElement( stInner.nextToken(), stInner.nextToken(), stInner.nextToken(), Integer.parseInt(stInner.nextToken())); } private Class<?> getPrimitiveClass(Class<?> cls) { if (cls.isPrimitive()) { return cls; } try { Field field = cls.getField("TYPE"); Object obj = cls; Object type = field.get(obj); if (type instanceof Class) { return (Class<?>) type; } } catch (Exception e) { // do nothing } return null; } private Exception convertFaultBean(Class<?> exClass, Object faultBean, Fault fault) throws Exception { Constructor<?> constructor = exClass.getConstructor(new Class[] {String.class}); Exception e = (Exception) constructor.newInstance(new Object[] {fault.getMessage()}); // Copy fault bean fields to exception for (Class<?> obj = exClass; !obj.equals(Object.class); obj = obj.getSuperclass()) { Field[] fields = obj.getDeclaredFields(); for (Field f : fields) { try { Field beanField = faultBean.getClass().getDeclaredField(f.getName()); ReflectionUtil.setAccessible(beanField); ReflectionUtil.setAccessible(f); f.set(e, beanField.get(faultBean)); } catch (NoSuchFieldException e1) { // do nothing } } } // also use/try public getter/setter methods Method meth[] = faultBean.getClass().getMethods(); for (Method m : meth) { if (m.getParameterTypes().length == 0 && (m.getName().startsWith("get") || m.getName().startsWith("is"))) { try { String name; if (m.getName().startsWith("get")) { name = "set" + m.getName().substring(3); } else { name = "set" + m.getName().substring(2); } Method m2 = exClass.getMethod(name, m.getReturnType()); m2.invoke(e, m.invoke(faultBean)); } catch (Exception e1) { // ignore } } } return e; } }
public class AbstractGreeterImpl implements Greeter { private static final Logger LOG = LogUtils.getLogger(AbstractGreeterImpl.class); private long delay; private String lastOnewayArg; private boolean throwAlways; private boolean useLastOnewayArg; private int pingMeCount; public long getDelay() { return delay; } public void setDelay(long d) { delay = d; } public void resetLastOnewayArg() { lastOnewayArg = null; } public void useLastOnewayArg(Boolean use) { useLastOnewayArg = use; } public void setThrowAlways(boolean t) { throwAlways = t; } public String greetMe(String arg0) { LOG.fine("Executing operation greetMe with parameter: " + arg0); if (delay > 0) { try { Thread.sleep(delay); } catch (InterruptedException ex) { // ignore } } String result = null; synchronized (this) { result = useLastOnewayArg ? lastOnewayArg : arg0.toUpperCase(); } LOG.fine("returning: " + result); return result; } public Future<?> greetMeAsync(String arg0, AsyncHandler<GreetMeResponse> arg1) { // TODO Auto-generated method stub return null; } public Response<GreetMeResponse> greetMeAsync(String arg0) { // TODO Auto-generated method stub return null; } public void greetMeOneWay(String arg0) { synchronized (this) { lastOnewayArg = arg0; } LOG.fine("Executing operation greetMeOneWay with parameter: " + arg0); } public void pingMe() throws PingMeFault { pingMeCount++; if ((pingMeCount % 2) == 0 || throwAlways) { LOG.fine("Throwing PingMeFault while executiong operation pingMe"); FaultDetail fd = new FaultDetail(); fd.setMajor((short) 2); fd.setMinor((short) 1); throw new PingMeFault("Pings succeed only every other time.", fd); } else { LOG.fine("Executing operation pingMe"); } } public Response<PingMeResponse> pingMeAsync() { // TODO Auto-generated method stub return null; } public Future<?> pingMeAsync(AsyncHandler<PingMeResponse> arg0) { // TODO Auto-generated method stub return null; } public String sayHi() { // TODO Auto-generated method stub return null; } public Response<SayHiResponse> sayHiAsync() { // TODO Auto-generated method stub return null; } public Future<?> sayHiAsync(AsyncHandler<SayHiResponse> arg0) { // TODO Auto-generated method stub return null; } }
public class XmlBeansDataBinding extends AbstractDataBinding implements WrapperCapableDatabinding { private static final Logger LOG = LogUtils.getLogger(XmlBeansDataBinding.class); private static final Class<?> SUPPORTED_READER_FORMATS[] = new Class<?>[] {XMLStreamReader.class}; private static final Class<?> SUPPORTED_WRITER_FORMATS[] = new Class<?>[] {XMLStreamWriter.class, Node.class}; @SuppressWarnings("unchecked") public <T> DataWriter<T> createWriter(Class<T> c) { if (c == XMLStreamWriter.class) { return (DataWriter<T>) new DataWriterImpl(); } else if (c == Node.class) { return (DataWriter<T>) new NodeDataWriterImpl(); } return null; } @SuppressWarnings("unchecked") public <T> DataReader<T> createReader(Class<T> c) { DataReader<T> dr = null; if (c == XMLStreamReader.class) { dr = (DataReader<T>) new DataReaderImpl(); } return dr; } /** XmlBeans has no declared namespace prefixes. {@inheritDoc} */ public Map<String, String> getDeclaredNamespaceMappings() { return null; } public Class<?>[] getSupportedReaderFormats() { return SUPPORTED_READER_FORMATS; } public Class<?>[] getSupportedWriterFormats() { return SUPPORTED_WRITER_FORMATS; } public void initialize(Service service) { if (LOG.isLoggable(Level.FINER)) { LOG.log(Level.FINER, "Creating XmlBeansDatabinding for " + service.getName()); } for (ServiceInfo serviceInfo : service.getServiceInfos()) { SchemaCollection col = serviceInfo.getXmlSchemaCollection(); if (col.getXmlSchemas().length > 1) { // someone has already filled in the types continue; } XmlBeansSchemaInitializer schemaInit = new XmlBeansSchemaInitializer(serviceInfo, col, this); schemaInit.walk(); } } public WrapperHelper createWrapperHelper( Class<?> wrapperType, QName wrapperName, List<String> partNames, List<String> elTypeNames, List<Class<?>> partClasses) { List<Method> getMethods = new ArrayList<Method>(partNames.size()); List<Method> setMethods = new ArrayList<Method>(partNames.size()); List<Field> fields = new ArrayList<Field>(partNames.size()); Method allMethods[] = wrapperType.getMethods(); for (int x = 0; x < partNames.size(); x++) { String partName = partNames.get(x); if (partName == null) { getMethods.add(null); setMethods.add(null); fields.add(null); continue; } String getAccessor = JAXBUtils.nameToIdentifier(partName, JAXBUtils.IdentifierType.GETTER); String setAccessor = JAXBUtils.nameToIdentifier(partName, JAXBUtils.IdentifierType.SETTER); Method getMethod = null; Method setMethod = null; Class<?> valueClass = XmlBeansWrapperHelper.getXMLBeansValueType(wrapperType); allMethods = valueClass.getMethods(); try { getMethod = valueClass.getMethod(getAccessor, AbstractWrapperHelper.NO_CLASSES); } catch (NoSuchMethodException ex) { // ignore for now } for (Method method : allMethods) { if (method.getParameterTypes() != null && method.getParameterTypes().length == 1 && (setAccessor.equals(method.getName()))) { setMethod = method; break; } } getMethods.add(getMethod); setMethods.add(setMethod); // There is no filed in the XMLBeans type class fields.add(null); } return new XmlBeansWrapperHelper( wrapperType, setMethods.toArray(new Method[setMethods.size()]), getMethods.toArray(new Method[getMethods.size()]), fields.toArray(new Field[fields.size()])); } }
@WebService( serviceName = "ControlService", portName = "ControlPort", endpointInterface = "org.apache.cxf.greeter_control.Control", targetNamespace = "http://cxf.apache.org/greeter_control") public class ControlImpl extends org.apache.cxf.greeter_control.ControlImpl { private static final Logger LOG = LogUtils.getLogger(ControlImpl.class); @Override public boolean startGreeter(String cfgResource) { String derbyHome = System.getProperty("derby.system.home"); try { System.setProperty("derby.system.home", derbyHome + "-server"); SpringBusFactory bf = new SpringBusFactory(); greeterBus = bf.createBus(cfgResource); BusFactory.setDefaultBus(greeterBus); LOG.info("Initialised bus " + greeterBus + " with cfg file resource: " + cfgResource); LOG.fine("greeterBus inInterceptors: " + greeterBus.getInInterceptors()); Interceptor logIn = new LoggingInInterceptor(); Interceptor logOut = new LoggingOutInterceptor(); greeterBus.getInInterceptors().add(logIn); greeterBus.getOutInterceptors().add(logOut); greeterBus.getOutFaultInterceptors().add(logOut); if (cfgResource.indexOf("provider") == -1) { Endpoint.publish(address, implementor); LOG.info("Published greeter endpoint."); } else { Endpoint.publish(address, new GreeterProvider()); LOG.info("Published greeter provider."); } } finally { if (derbyHome != null) { System.setProperty("derby.system.home", derbyHome); } else { System.clearProperty("derby.system.home"); } } return true; } @WebService( serviceName = "GreeterService", portName = "GreeterPort", targetNamespace = "http://cxf.apache.org/greeter_control", wsdlLocation = "/wsdl/greeter_control.wsdl") @ServiceMode(Mode.PAYLOAD) public static class GreeterProvider implements Provider<Source> { public Source invoke(Source obj) { DOMSource ds = (DOMSource) obj; Element el = ((Document) ds.getNode()).getDocumentElement(); Map<String, String> ns = new HashMap<String, String>(); ns.put("ns", "http://cxf.apache.org/greeter_control/types"); XPathUtils xp = new XPathUtils(ns); String s = (String) xp.getValue("/ns:greetMe/ns:requestType", el, XPathConstants.STRING); if (s == null || "".equals(s)) { s = (String) xp.getValue("/ns:greetMeOneWay/ns:requestType", el, XPathConstants.STRING); System.out.println("greetMeOneWay arg: " + s); return null; } else { System.out.println("greetMe arg: " + s); String resp = "<greetMeResponse " + "xmlns=\"http://cxf.apache.org/greeter_control/types\">" + "<responseType>" + s.toUpperCase() + "</responseType>" + "</greetMeResponse>"; return new StreamSource(new StringReader(resp)); } } } }
@NoJSR250Annotations public class JAXBDataBinding extends AbstractInterceptorProvidingDataBinding implements WrapperCapableDatabinding, InterceptorProvider { public static final String SCHEMA_RESOURCE = "SCHEMRESOURCE"; public static final String MTOM_THRESHOLD = "org.apache.cxf.jaxb.mtomThreshold"; public static final String UNWRAP_JAXB_ELEMENT = "unwrap.jaxb.element"; public static final String USE_JAXB_BRIDGE = "use.jaxb.bridge"; public static final String JAXB_SCAN_PACKAGES = "jaxb.scanPackages"; private static final Logger LOG = LogUtils.getLogger(JAXBDataBinding.class); private static final Class<?> SUPPORTED_READER_FORMATS[] = new Class<?>[] {Node.class, XMLEventReader.class, XMLStreamReader.class}; private static final Class<?> SUPPORTED_WRITER_FORMATS[] = new Class<?>[] {OutputStream.class, Node.class, XMLEventWriter.class, XMLStreamWriter.class}; private static class DelayedDOMResult extends DOMResult { private final URL resource; private final String publicId; public DelayedDOMResult(URL url, String sysId, String pId) { super(null, sysId); resource = url; publicId = pId; } public synchronized Node getNode() { Node nd = super.getNode(); if (nd == null) { try { InputSource src = new InputSource(resource.openStream()); src.setSystemId(this.getSystemId()); src.setPublicId(publicId); Document doc = StaxUtils.read(src); setNode(doc); nd = super.getNode(); } catch (Exception ex) { throw new RuntimeException(ex); } } return nd; } } private static final Map<String, DOMResult> BUILT_IN_SCHEMAS = new HashMap<String, DOMResult>(); static { URIResolver resolver = new URIResolver(); try { resolver.resolve("", "classpath:/schemas/wsdl/ws-addr-wsdl.xsd", JAXBDataBinding.class); if (resolver.isResolved()) { resolver.getInputStream().close(); DOMResult dr = new DelayedDOMResult( resolver.getURL(), "classpath:/schemas/wsdl/ws-addr-wsdl.xsd", "http://www.w3.org/2005/02/addressing/wsdl"); BUILT_IN_SCHEMAS.put("http://www.w3.org/2005/02/addressing/wsdl", dr); resolver.unresolve(); } } catch (Exception e) { // IGNORE } try { resolver.resolve("", "classpath:/schemas/wsdl/ws-addr.xsd", JAXBDataBinding.class); if (resolver.isResolved()) { resolver.getInputStream().close(); DOMResult dr = new DelayedDOMResult( resolver.getURL(), "classpath:/schemas/wsdl/ws-addr.xsd", "http://www.w3.org/2005/08/addressing"); BUILT_IN_SCHEMAS.put("http://www.w3.org/2005/08/addressing", dr); resolver.unresolve(); } } catch (Exception e) { // IGNORE } try { resolver.resolve("", "classpath:/schemas/wsdl/wsrm.xsd", JAXBDataBinding.class); if (resolver.isResolved()) { resolver.getInputStream().close(); DOMResult dr = new DelayedDOMResult( resolver.getURL(), "classpath:/schemas/wsdl/wsrm.xsd", "http://schemas.xmlsoap.org/ws/2005/02/rm"); BUILT_IN_SCHEMAS.put("http://schemas.xmlsoap.org/ws/2005/02/rm", dr); resolver.unresolve(); } } catch (Exception e) { // IGNORE } } Class<?>[] extraClass; JAXBContext context; Set<Class<?>> contextClasses; Collection<Object> typeRefs = new ArrayList<Object>(); Class<?> cls; private Map<String, Object> contextProperties = Collections.emptyMap(); private Map<String, Object> marshallerProperties = Collections.emptyMap(); private Map<String, Object> unmarshallerProperties = Collections.emptyMap(); private Unmarshaller.Listener unmarshallerListener; private Marshaller.Listener marshallerListener; private ValidationEventHandler validationEventHandler; private boolean unwrapJAXBElement = true; private boolean scanPackages = true; private boolean qualifiedSchemas; public JAXBDataBinding() {} public JAXBDataBinding(boolean q) { this.qualifiedSchemas = q; } public JAXBDataBinding(Class<?>... classes) throws JAXBException { contextClasses = new LinkedHashSet<Class<?>>(); contextClasses.addAll(Arrays.asList(classes)); setContext(createJAXBContext(contextClasses)); // NOPMD - specifically allow this } public JAXBDataBinding(boolean qualified, Map<String, Object> props) throws JAXBException { this(qualified); if (props != null && props.get("jaxb.additionalContextClasses") != null) { Object o = props.get("jaxb.additionalContextClasses"); if (o instanceof Class) { o = new Class[] {(Class<?>) o}; } extraClass = (Class[]) o; } // the default for scan packages is true, so the jaxb scan packages // property must be explicitly set to false to disable it if (PropertyUtils.isFalse(props, JAXB_SCAN_PACKAGES)) { scanPackages = false; } } public JAXBDataBinding(JAXBContext context) { this(); setContext(context); } public JAXBContext getContext() { return context; } public final void setContext(JAXBContext ctx) { context = ctx; } @SuppressWarnings("unchecked") public <T> DataWriter<T> createWriter(Class<T> c) { Integer mtomThresholdInt = Integer.valueOf(getMtomThreshold()); if (c == XMLStreamWriter.class) { DataWriterImpl<XMLStreamWriter> r = new DataWriterImpl<XMLStreamWriter>(this); r.setMtomThreshold(mtomThresholdInt); return (DataWriter<T>) r; } else if (c == OutputStream.class) { DataWriterImpl<OutputStream> r = new DataWriterImpl<OutputStream>(this); r.setMtomThreshold(mtomThresholdInt); return (DataWriter<T>) r; } else if (c == XMLEventWriter.class) { DataWriterImpl<XMLEventWriter> r = new DataWriterImpl<XMLEventWriter>(this); r.setMtomThreshold(mtomThresholdInt); return (DataWriter<T>) r; } else if (c == Node.class) { DataWriterImpl<Node> r = new DataWriterImpl<Node>(this); r.setMtomThreshold(mtomThresholdInt); return (DataWriter<T>) r; } return null; } public Class<?>[] getSupportedWriterFormats() { return SUPPORTED_WRITER_FORMATS; } @SuppressWarnings("unchecked") public <T> DataReader<T> createReader(Class<T> c) { DataReader<T> dr = null; if (c == XMLStreamReader.class) { dr = (DataReader<T>) new DataReaderImpl<XMLStreamReader>(this, unwrapJAXBElement); } else if (c == XMLEventReader.class) { dr = (DataReader<T>) new DataReaderImpl<XMLEventReader>(this, unwrapJAXBElement); } else if (c == Node.class) { dr = (DataReader<T>) new DataReaderImpl<Node>(this, unwrapJAXBElement); } return dr; } public Class<?>[] getSupportedReaderFormats() { return SUPPORTED_READER_FORMATS; } @SuppressWarnings("unchecked") public synchronized void initialize(Service service) { inInterceptors.addIfAbsent(JAXBAttachmentSchemaValidationHack.INSTANCE); inFaultInterceptors.addIfAbsent(JAXBAttachmentSchemaValidationHack.INSTANCE); // context is already set, don't redo it if (context != null) { return; } contextClasses = new LinkedHashSet<Class<?>>(); Map<String, Object> unmarshallerProps = new HashMap<String, Object>(); this.setUnmarshallerProperties(unmarshallerProps); for (ServiceInfo serviceInfo : service.getServiceInfos()) { JAXBContextInitializer initializer = new JAXBContextInitializer( serviceInfo, contextClasses, typeRefs, this.getUnmarshallerProperties()); initializer.walk(); if (serviceInfo.getProperty("extra.class") != null) { Set<Class<?>> exClasses = serviceInfo.getProperty("extra.class", Set.class); contextClasses.addAll(exClasses); } } String tns = getNamespaceToUse(service); CachedContextAndSchemas cachedContextAndSchemas = null; JAXBContext ctx = null; try { cachedContextAndSchemas = createJAXBContextAndSchemas(contextClasses, tns); } catch (JAXBException e1) { throw new ServiceConstructionException(e1); } ctx = cachedContextAndSchemas.getContext(); if (LOG.isLoggable(Level.FINE)) { LOG.log(Level.FINE, "CREATED_JAXB_CONTEXT", new Object[] {ctx, contextClasses}); } setContext(ctx); for (ServiceInfo serviceInfo : service.getServiceInfos()) { SchemaCollection col = serviceInfo.getXmlSchemaCollection(); if (col.getXmlSchemas().length > 1) { // someone has already filled in the types justCheckForJAXBAnnotations(serviceInfo); continue; } boolean schemasFromCache = false; Collection<DOMSource> schemas = getSchemas(); if (schemas == null || schemas.size() == 0) { schemas = cachedContextAndSchemas.getSchemas(); if (schemas != null) { schemasFromCache = true; } } else { schemasFromCache = true; } Set<DOMSource> bi = new LinkedHashSet<DOMSource>(); if (schemas == null) { schemas = new LinkedHashSet<DOMSource>(); try { for (DOMResult r : generateJaxbSchemas()) { DOMSource src = new DOMSource(r.getNode(), r.getSystemId()); if (BUILT_IN_SCHEMAS.containsValue(r)) { bi.add(src); } else { schemas.add(src); } } // put any builtins at the end. Anything that DOES import them // will cause it to load automatically and we'll skip them later schemas.addAll(bi); } catch (IOException e) { throw new ServiceConstructionException("SCHEMA_GEN_EXC", LOG, e); } } Set<String> ids = new HashSet<String>(); for (DOMSource r : schemas) { ids.add(r.getSystemId()); } for (DOMSource r : schemas) { if (bi.contains(r)) { String ns = ((Document) r.getNode()).getDocumentElement().getAttribute("targetNamespace"); if (serviceInfo.getSchema(ns) != null) { continue; } } // StaxUtils.print(r.getNode()); // System.out.println(); addSchemaDocument(serviceInfo, col, (Document) r.getNode(), r.getSystemId()); } JAXBSchemaInitializer schemaInit = new JAXBSchemaInitializer(serviceInfo, col, context, this.qualifiedSchemas, tns); schemaInit.walk(); if (cachedContextAndSchemas != null && !schemasFromCache) { cachedContextAndSchemas.setSchemas(schemas); } } } private void justCheckForJAXBAnnotations(ServiceInfo serviceInfo) { for (MessageInfo mi : serviceInfo.getMessages().values()) { for (MessagePartInfo mpi : mi.getMessageParts()) { checkForJAXBAnnotations( mpi, serviceInfo.getXmlSchemaCollection(), serviceInfo.getTargetNamespace()); } } } private void checkForJAXBAnnotations( MessagePartInfo mpi, SchemaCollection schemaCollection, String ns) { Annotation[] anns = (Annotation[]) mpi.getProperty("parameter.annotations"); JAXBContextProxy ctx = JAXBUtils.createJAXBContextProxy(context, schemaCollection, ns); XmlJavaTypeAdapter jta = JAXBSchemaInitializer.findFromTypeAdapter(ctx, mpi.getTypeClass(), anns); if (jta != null) { JAXBBeanInfo jtaBeanInfo = JAXBSchemaInitializer.findFromTypeAdapter(ctx, jta.value()); JAXBBeanInfo beanInfo = JAXBSchemaInitializer.getBeanInfo(ctx, mpi.getTypeClass()); if (jtaBeanInfo != beanInfo) { mpi.setProperty("parameter.annotations", anns); mpi.setProperty("honor.jaxb.annotations", Boolean.TRUE); } } } private String getNamespaceToUse(Service service) { if ("true".equals(service.get("org.apache.cxf.databinding.namespace"))) { return null; } String tns = null; if (service.getServiceInfos().size() > 0) { tns = service.getServiceInfos().get(0).getInterface().getName().getNamespaceURI(); } else { tns = service.getName().getNamespaceURI(); } return tns; } public void setExtraClass(Class<?>[] userExtraClass) { extraClass = userExtraClass; } public Class<?>[] getExtraClass() { return extraClass; } // default access for tests. List<DOMResult> generateJaxbSchemas() throws IOException { return JAXBUtils.generateJaxbSchemas(context, BUILT_IN_SCHEMAS); } public JAXBContext createJAXBContext(Set<Class<?>> classes) throws JAXBException { return createJAXBContext(classes, null); } public JAXBContext createJAXBContext(Set<Class<?>> classes, String defaultNs) throws JAXBException { return createJAXBContextAndSchemas(classes, defaultNs).getContext(); } public CachedContextAndSchemas createJAXBContextAndSchemas( Set<Class<?>> classes, String defaultNs) throws JAXBException { // add user extra class into jaxb context if (extraClass != null && extraClass.length > 0) { for (Class<?> clz : extraClass) { classes.add(clz); } } if (scanPackages) { JAXBContextCache.scanPackages(classes); } addWsAddressingTypes(classes); return JAXBContextCache.getCachedContextAndSchemas( classes, defaultNs, contextProperties, typeRefs, true); } private void addWsAddressingTypes(Set<Class<?>> classes) { if (classes.contains(ObjectFactory.class)) { // ws-addressing is used, lets add the specific types try { classes.add(Class.forName("org.apache.cxf.ws.addressing.wsdl.ObjectFactory")); classes.add(Class.forName("org.apache.cxf.ws.addressing.wsdl.AttributedQNameType")); classes.add(Class.forName("org.apache.cxf.ws.addressing.wsdl.ServiceNameType")); } catch (ClassNotFoundException unused) { // REVISIT - ignorable if WS-ADDRESSING not available? // maybe add a way to allow interceptors to add stuff to the // context? } } } public Set<Class<?>> getContextClasses() { return Collections.unmodifiableSet(this.contextClasses); } /** * Return a map of properties. These properties are passed to JAXBContext.newInstance when this * object creates a context. * * @return the map of JAXB context properties. */ public Map<String, Object> getContextProperties() { return contextProperties; } /** * Set a map of JAXB context properties. These properties are passed to JAXBContext.newInstance * when this object creates a context. Note that if you create a JAXB context elsewhere, you will * not respect these properties unless you handle it manually. * * @param contextProperties map of properties. */ public void setContextProperties(Map<String, Object> contextProperties) { this.contextProperties = contextProperties; } /** * Return a map of properties. These properties are set into the JAXB Marshaller (via * Marshaller.setProperty(...) when the marshaller is created. * * @return the map of JAXB marshaller properties. */ public Map<String, Object> getMarshallerProperties() { return marshallerProperties; } /** * Set a map of JAXB marshaller properties. These properties are set into the JAXB Marshaller (via * Marshaller.setProperty(...) when the marshaller is created. * * @param marshallerProperties map of properties. */ public void setMarshallerProperties(Map<String, Object> marshallerProperties) { this.marshallerProperties = marshallerProperties; } /** * Return a map of properties. These properties are set into the JAXB Unmarshaller (via * Unmarshaller.setProperty(...) when the unmarshaller is created. * * @return the map of JAXB unmarshaller properties. */ public Map<String, Object> getUnmarshallerProperties() { return unmarshallerProperties; } /** * Set a map of JAXB unmarshaller properties. These properties are set into the JAXB Unmarshaller * (via Unmarshaller.setProperty(...) when the unmarshaller is created. * * @param unmarshallerProperties map of properties. */ public void setUnmarshallerProperties(Map<String, Object> unmarshallerProperties) { this.unmarshallerProperties = unmarshallerProperties; } /** * Returns the Unmarshaller.Listener that will be registered on the Unmarshallers * * @return */ public Unmarshaller.Listener getUnmarshallerListener() { return unmarshallerListener; } /** * Sets the Unmarshaller.Listener that will be registered on the Unmarshallers * * @param unmarshallerListener */ public void setUnmarshallerListener(Unmarshaller.Listener unmarshallerListener) { this.unmarshallerListener = unmarshallerListener; } /** * Returns the Marshaller.Listener that will be registered on the Marshallers * * @return */ public Marshaller.Listener getMarshallerListener() { return marshallerListener; } /** * Sets the Marshaller.Listener that will be registered on the Marshallers * * @param marshallerListener */ public void setMarshallerListener(Marshaller.Listener marshallerListener) { this.marshallerListener = marshallerListener; } public ValidationEventHandler getValidationEventHandler() { return validationEventHandler; } public void setValidationEventHandler(ValidationEventHandler validationEventHandler) { this.validationEventHandler = validationEventHandler; } public boolean isUnwrapJAXBElement() { return unwrapJAXBElement; } public void setUnwrapJAXBElement(boolean unwrapJAXBElement) { this.unwrapJAXBElement = unwrapJAXBElement; } public WrapperHelper createWrapperHelper( Class<?> wrapperType, QName wrapperName, List<String> partNames, List<String> elTypeNames, List<Class<?>> partClasses) { List<Method> getMethods = new ArrayList<Method>(partNames.size()); List<Method> setMethods = new ArrayList<Method>(partNames.size()); List<Method> jaxbMethods = new ArrayList<Method>(partNames.size()); List<Field> fields = new ArrayList<Field>(partNames.size()); Method allMethods[] = wrapperType.getMethods(); String packageName = PackageUtils.getPackageName(wrapperType); // if wrappertype class is generated by ASM,getPackage() always return null if (wrapperType.getPackage() != null) { packageName = wrapperType.getPackage().getName(); } String objectFactoryClassName = packageName + ".ObjectFactory"; Object objectFactory = null; try { objectFactory = wrapperType.getClassLoader().loadClass(objectFactoryClassName).newInstance(); } catch (Exception e) { // ignore, probably won't need it } Method allOFMethods[]; if (objectFactory != null) { allOFMethods = objectFactory.getClass().getMethods(); } else { allOFMethods = new Method[0]; } for (int x = 0; x < partNames.size(); x++) { String partName = partNames.get(x); if (partName == null) { getMethods.add(null); setMethods.add(null); fields.add(null); jaxbMethods.add(null); continue; } String elementType = elTypeNames.get(x); String getAccessor = JAXBUtils.nameToIdentifier(partName, JAXBUtils.IdentifierType.GETTER); String setAccessor = JAXBUtils.nameToIdentifier(partName, JAXBUtils.IdentifierType.SETTER); Method getMethod = null; Method setMethod = null; Class<?> valueClass = wrapperType; try { getMethod = valueClass.getMethod(getAccessor, AbstractWrapperHelper.NO_CLASSES); } catch (NoSuchMethodException ex) { // ignore for now } Field elField = getElField(partName, valueClass); if (getMethod == null && elementType != null && "boolean".equals(elementType.toLowerCase()) && (elField == null || (!Collection.class.isAssignableFrom(elField.getType()) && !elField.getType().isArray()))) { try { String newAcc = getAccessor.replaceFirst("get", "is"); getMethod = wrapperType.getMethod(newAcc, AbstractWrapperHelper.NO_CLASSES); } catch (NoSuchMethodException ex) { // ignore for now } } if (getMethod == null && "return".equals(partName)) { // RI generated code uses this try { getMethod = valueClass.getMethod("get_return", AbstractWrapperHelper.NO_CLASSES); } catch (NoSuchMethodException ex) { try { getMethod = valueClass.getMethod("is_return", new Class[0]); } catch (NoSuchMethodException ex2) { // ignore for now } } } if (getMethod == null && elField != null) { getAccessor = JAXBUtils.nameToIdentifier(elField.getName(), JAXBUtils.IdentifierType.GETTER); setAccessor = JAXBUtils.nameToIdentifier(elField.getName(), JAXBUtils.IdentifierType.SETTER); try { getMethod = valueClass.getMethod(getAccessor, AbstractWrapperHelper.NO_CLASSES); } catch (NoSuchMethodException ex) { // ignore for now } } String setAccessor2 = setAccessor; if ("return".equals(partName)) { // some versions of jaxb map "return" to "set_return" instead of "setReturn" setAccessor2 = "set_return"; } for (Method method : allMethods) { if (method.getParameterTypes() != null && method.getParameterTypes().length == 1 && (setAccessor.equals(method.getName()) || setAccessor2.equals(method.getName()))) { setMethod = method; break; } } getMethods.add(getMethod); setMethods.add(setMethod); if (setMethod != null && JAXBElement.class.isAssignableFrom(setMethod.getParameterTypes()[0])) { Type t = setMethod.getGenericParameterTypes()[0]; Class<?> pcls = null; if (t instanceof ParameterizedType) { t = ((ParameterizedType) t).getActualTypeArguments()[0]; } if (t instanceof Class) { pcls = (Class<?>) t; } String methodName = "create" + wrapperType.getSimpleName() + setMethod.getName().substring(3); for (Method m : allOFMethods) { if (m.getName().equals(methodName) && m.getParameterTypes().length == 1 && (pcls == null || pcls.equals(m.getParameterTypes()[0]))) { jaxbMethods.add(m); } } } else { jaxbMethods.add(null); } if (elField != null) { // JAXB Type get XmlElement Annotation XmlElement el = elField.getAnnotation(XmlElement.class); if (el != null && (partName.equals(el.name()) || "##default".equals(el.name()))) { ReflectionUtil.setAccessible(elField); fields.add(elField); } else { if (getMethod == null && setMethod == null) { if (el != null) { LOG.warning( "Could not create accessor for property " + partName + " of type " + wrapperType.getName() + " as the @XmlElement " + "defines the name as " + el.name()); } else { LOG.warning( "Could not create accessor for property " + partName + " of type " + wrapperType.getName()); } } fields.add(null); } } else { fields.add(null); } } return createWrapperHelper( wrapperType, setMethods.toArray(new Method[setMethods.size()]), getMethods.toArray(new Method[getMethods.size()]), jaxbMethods.toArray(new Method[jaxbMethods.size()]), fields.toArray(new Field[fields.size()]), objectFactory); } private static Field getElField(String partName, final Class<?> wrapperType) { String fieldName = JAXBUtils.nameToIdentifier(partName, JAXBUtils.IdentifierType.VARIABLE); Field[] fields = ReflectionUtil.getDeclaredFields(wrapperType); for (Field field : fields) { XmlElement el = field.getAnnotation(XmlElement.class); if (el != null && partName.equals(el.name())) { return field; } if (field.getName().equals(fieldName)) { return field; } } return null; } private static WrapperHelper createWrapperHelper( Class<?> wrapperType, Method setMethods[], Method getMethods[], Method jaxbMethods[], Field fields[], Object objectFactory) { WrapperHelper wh = compileWrapperHelper( wrapperType, setMethods, getMethods, jaxbMethods, fields, objectFactory); if (wh == null) { wh = new JAXBWrapperHelper( wrapperType, setMethods, getMethods, jaxbMethods, fields, objectFactory); } return wh; } private static WrapperHelper compileWrapperHelper( Class<?> wrapperType, Method setMethods[], Method getMethods[], Method jaxbMethods[], Field fields[], Object objectFactory) { return WrapperHelperCompiler.compileWrapperHelper( wrapperType, setMethods, getMethods, jaxbMethods, fields, objectFactory); } }
/** @deprecated use the logging module rt/features/logging instead */ @NoJSR250Annotations @Deprecated public class LoggingOutInterceptor extends AbstractLoggingInterceptor { private static final Logger LOG = LogUtils.getLogger(LoggingOutInterceptor.class); private static final String LOG_SETUP = LoggingOutInterceptor.class.getName() + ".log-setup"; public LoggingOutInterceptor(String phase) { super(phase); addBefore(StaxOutInterceptor.class.getName()); } public LoggingOutInterceptor() { this(Phase.PRE_STREAM); } public LoggingOutInterceptor(int lim) { this(); limit = lim; } public LoggingOutInterceptor(PrintWriter w) { this(); this.writer = w; } public void handleMessage(Message message) throws Fault { final OutputStream os = message.getContent(OutputStream.class); final Writer iowriter = message.getContent(Writer.class); if (os == null && iowriter == null) { return; } Logger logger = getMessageLogger(message); if (logger.isLoggable(Level.INFO) || writer != null) { // Write the output while caching it for the log message boolean hasLogged = message.containsKey(LOG_SETUP); if (!hasLogged) { message.put(LOG_SETUP, Boolean.TRUE); if (os != null) { final CacheAndWriteOutputStream newOut = new CacheAndWriteOutputStream(os); if (threshold > 0) { newOut.setThreshold(threshold); } if (limit > 0) { newOut.setCacheLimit(limit); } message.setContent(OutputStream.class, newOut); newOut.registerCallback(new LoggingCallback(logger, message, os)); } else { message.setContent(Writer.class, new LogWriter(logger, message, iowriter)); } } } } private LoggingMessage setupBuffer(Message message) { String id = (String) message.getExchange().get(LoggingMessage.ID_KEY); if (id == null) { id = LoggingMessage.nextId(); message.getExchange().put(LoggingMessage.ID_KEY, id); } final LoggingMessage buffer = new LoggingMessage("Outbound Message\n---------------------------", id); Integer responseCode = (Integer) message.get(Message.RESPONSE_CODE); if (responseCode != null) { buffer.getResponseCode().append(responseCode); } String encoding = (String) message.get(Message.ENCODING); if (encoding != null) { buffer.getEncoding().append(encoding); } String httpMethod = (String) message.get(Message.HTTP_REQUEST_METHOD); if (httpMethod != null) { buffer.getHttpMethod().append(httpMethod); } String address = (String) message.get(Message.ENDPOINT_ADDRESS); if (address != null) { buffer.getAddress().append(address); String uri = (String) message.get(Message.REQUEST_URI); if (uri != null && !address.startsWith(uri)) { if (!address.endsWith("/") && !uri.startsWith("/")) { buffer.getAddress().append("/"); } buffer.getAddress().append(uri); } } String ct = (String) message.get(Message.CONTENT_TYPE); if (ct != null) { buffer.getContentType().append(ct); } Object headers = message.get(Message.PROTOCOL_HEADERS); if (headers != null) { buffer.getHeader().append(headers); } return buffer; } private class LogWriter extends FilterWriter { StringWriter out2; int count; Logger logger; // NOPMD Message message; final int lim; LogWriter(Logger logger, Message message, Writer writer) { super(writer); this.logger = logger; this.message = message; if (!(writer instanceof StringWriter)) { out2 = new StringWriter(); } lim = limit == -1 ? Integer.MAX_VALUE : limit; } public void write(int c) throws IOException { super.write(c); if (out2 != null && count < lim) { out2.write(c); } count++; } public void write(char[] cbuf, int off, int len) throws IOException { super.write(cbuf, off, len); if (out2 != null && count < lim) { out2.write(cbuf, off, len); } count += len; } public void write(String str, int off, int len) throws IOException { super.write(str, off, len); if (out2 != null && count < lim) { out2.write(str, off, len); } count += len; } public void close() throws IOException { LoggingMessage buffer = setupBuffer(message); if (count >= lim) { buffer.getMessage().append("(message truncated to " + lim + " bytes)\n"); } StringWriter w2 = out2; if (w2 == null) { w2 = (StringWriter) out; } String ct = (String) message.get(Message.CONTENT_TYPE); try { writePayload(buffer.getPayload(), w2, ct); } catch (Exception ex) { // ignore } log(logger, formatLoggingMessage(buffer)); message.setContent(Writer.class, out); super.close(); } } protected String formatLoggingMessage(LoggingMessage buffer) { return buffer.toString(); } class LoggingCallback implements CachedOutputStreamCallback { private final Message message; private final OutputStream origStream; private final Logger logger; // NOPMD private final int lim; LoggingCallback(final Logger logger, final Message msg, final OutputStream os) { this.logger = logger; this.message = msg; this.origStream = os; this.lim = limit == -1 ? Integer.MAX_VALUE : limit; } public void onFlush(CachedOutputStream cos) {} public void onClose(CachedOutputStream cos) { LoggingMessage buffer = setupBuffer(message); String ct = (String) message.get(Message.CONTENT_TYPE); if (!isShowBinaryContent() && isBinaryContent(ct)) { buffer.getMessage().append(BINARY_CONTENT_MESSAGE).append('\n'); log(logger, formatLoggingMessage(buffer)); return; } if (!isShowMultipartContent() && isMultipartContent(ct)) { buffer.getMessage().append(MULTIPART_CONTENT_MESSAGE).append('\n'); log(logger, formatLoggingMessage(buffer)); return; } if (cos.getTempFile() == null) { // buffer.append("Outbound Message:\n"); if (cos.size() >= lim) { buffer.getMessage().append("(message truncated to " + lim + " bytes)\n"); } } else { buffer.getMessage().append("Outbound Message (saved to tmp file):\n"); buffer.getMessage().append("Filename: " + cos.getTempFile().getAbsolutePath() + "\n"); if (cos.size() >= lim) { buffer.getMessage().append("(message truncated to " + lim + " bytes)\n"); } } try { String encoding = (String) message.get(Message.ENCODING); writePayload(buffer.getPayload(), cos, encoding, ct); } catch (Exception ex) { // ignore } log(logger, formatLoggingMessage(buffer)); try { // empty out the cache cos.lockOutputStream(); cos.resetOut(null, false); } catch (Exception ex) { // ignore } message.setContent(OutputStream.class, origStream); } } @Override protected Logger getLogger() { return LOG; } }