Author: dandiep Date: Fri May 25 14:49:06 2007 New Revision: 541791 URL: http://svn.apache.org/viewvc?view=rev&rev=541791 Log: Support other attachment types beyond DataHandlers. Also write a more correct content-type for the SwA case.
Modified: incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentSerializer.java incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/AttachmentOutInterceptor.java incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/Messages.properties incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/SwAInInterceptor.java incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/SwAOutInterceptor.java incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/swa/ClientServerSwaTest.java incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/swa/resources/attach.xml Modified: incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentSerializer.java URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentSerializer.java?view=diff&rev=541791&r1=541790&r2=541791 ============================================================================== --- incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentSerializer.java (original) +++ incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/attachment/AttachmentSerializer.java Fri May 25 14:49:06 2007 @@ -35,6 +35,7 @@ private String bodyBoundary; private OutputStreamWriter writer; private OutputStream out; + private boolean xop = true; public AttachmentSerializer(Message messageParam) { message = messageParam; @@ -56,9 +57,12 @@ // Set transport mime type StringBuilder ct = new StringBuilder(); - ct.append("multipart/related; ") - .append("type=\"application/xop+xml\"; ") - .append("boundary=\"") + ct.append("multipart/related; "); + if (xop) { + ct.append("type=\"application/xop+xml\"; "); + } + + ct.append("boundary=\"") .append(bodyBoundary) .append("\"; ") .append("start=\"<") @@ -133,4 +137,13 @@ writer.flush(); } + + public boolean isXop() { + return xop; + } + + public void setXop(boolean xop) { + this.xop = xop; + } + } Modified: incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/AttachmentOutInterceptor.java URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/AttachmentOutInterceptor.java?view=diff&rev=541791&r1=541790&r2=541791 ============================================================================== --- incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/AttachmentOutInterceptor.java (original) +++ incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/AttachmentOutInterceptor.java Fri May 25 14:49:06 2007 @@ -42,13 +42,17 @@ public void handleMessage(Message message) { - if (!MessageUtils.isTrue(message.getContextualProperty( - org.apache.cxf.message.Message.MTOM_ENABLED)) - && !MessageUtils.isTrue(message.getContextualProperty(WRITE_ATTACHMENTS))) { + boolean mtomEnabled = MessageUtils.isTrue( + message.getContextualProperty(org.apache.cxf.message.Message.MTOM_ENABLED)); + boolean writeAtts = MessageUtils.isTrue(message.getContextualProperty(WRITE_ATTACHMENTS)); + + if (!mtomEnabled && !writeAtts) { return; } AttachmentSerializer serializer = new AttachmentSerializer(message); + serializer.setXop(mtomEnabled); + try { serializer.writeProlog(); } catch (IOException e) { Modified: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/Messages.properties URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/Messages.properties?view=diff&rev=541791&r1=541790&r2=541791 ============================================================================== --- incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/Messages.properties (original) +++ incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/Messages.properties Fri May 25 14:49:06 2007 @@ -22,4 +22,5 @@ NO_GETFAULTINFO_METHOD = JAX-WS faults are required to have a getFaultInfo method. COULD_NOT_INVOKE = Could not invoke getFaultInfo method on Exception. DISPATCH_OBJECT_CANNOT_BE_NULL = Null object passed into Dispatch marshalling -EXCEPTION_WRITING_OBJECT = Exception occured while marshalling Dispatch object to stream \ No newline at end of file +EXCEPTION_WRITING_OBJECT = Exception occured while marshalling Dispatch object to stream +ATACCHMENT_NOT_SUPPORTED = Attachments of type {0} are not supported. \ No newline at end of file Modified: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/SwAInInterceptor.java URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/SwAInInterceptor.java?view=diff&rev=541791&r1=541790&r2=541791 ============================================================================== --- incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/SwAInInterceptor.java (original) +++ incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/SwAInInterceptor.java Fri May 25 14:49:06 2007 @@ -18,14 +18,20 @@ */ package org.apache.cxf.jaxws.interceptors; +import java.io.IOException; import java.util.List; +import javax.activation.DataHandler; +import javax.imageio.ImageIO; +import javax.xml.transform.stream.StreamSource; + import org.apache.cxf.binding.soap.SoapMessage; import org.apache.cxf.binding.soap.interceptor.AbstractSoapInterceptor; import org.apache.cxf.binding.soap.model.SoapBodyInfo; import org.apache.cxf.helpers.CastUtils; import org.apache.cxf.interceptor.Fault; import org.apache.cxf.message.Attachment; +import org.apache.cxf.message.Message; import org.apache.cxf.phase.Phase; import org.apache.cxf.service.model.BindingMessageInfo; import org.apache.cxf.service.model.BindingOperationInfo; @@ -68,28 +74,37 @@ String partName = mpi.getConcreteName().getLocalPart(); String start = partName + "="; + boolean found = false; for (Attachment a : message.getAttachments()) { if (a.getId().startsWith(start)) { -// String ct = (String) mpi.getProperty(Message.CONTENT_TYPE); -// -// System.out.println("Content type " + ct); -// Object content = null; -// try { -// DataFlavor flavor = new DataFlavor(ct); -// content = a.getDataHandler().getTransferData(flavor); -// } catch (IOException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } catch (UnsupportedFlavorException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } catch (ClassNotFoundException e) { -// // TODO Auto-generated catch block -// e.printStackTrace(); -// } -// System.out.println("Content " + content); - inObjects.add(a.getDataHandler()); + String ct = (String) mpi.getProperty(Message.CONTENT_TYPE); + + DataHandler dh = a.getDataHandler(); + Object o = null; + if (ct.startsWith("image/")) { + try { + o = ImageIO.read(dh.getInputStream()); + } catch (IOException e) { + throw new Fault(e); + } + } else if (ct.startsWith("text/xml") || ct.startsWith("application/xml")) { + try { + o = new StreamSource(dh.getInputStream()); + } catch (IOException e) { + throw new Fault(e); + } + } else { + o = dh; + } + + inObjects.add(o); + found = true; + break; } + } + + if (!found) { + inObjects.add(null); } } } Modified: incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/SwAOutInterceptor.java URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/SwAOutInterceptor.java?view=diff&rev=541791&r1=541790&r2=541791 ============================================================================== --- incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/SwAOutInterceptor.java (original) +++ incubator/cxf/trunk/rt/frontend/jaxws/src/main/java/org/apache/cxf/jaxws/interceptors/SwAOutInterceptor.java Fri May 25 14:49:06 2007 @@ -17,16 +17,34 @@ * under the License. */ package org.apache.cxf.jaxws.interceptors; - +import java.awt.Component; +import java.awt.Graphics; +import java.awt.Image; +import java.awt.MediaTracker; +import java.awt.image.BufferedImage; +import java.io.ByteArrayOutputStream; +import java.io.IOException; import java.util.ArrayList; import java.util.Collection; +import java.util.Iterator; import java.util.List; import java.util.UUID; +import java.util.logging.Logger; import javax.activation.DataHandler; +import javax.activation.DataSource; +import javax.imageio.ImageIO; +import javax.imageio.ImageWriter; +import javax.mail.util.ByteArrayDataSource; import javax.xml.bind.JAXBContext; +import javax.xml.transform.Source; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.stream.StreamResult; import com.sun.xml.bind.v2.runtime.JAXBContextImpl; +import com.sun.xml.bind.v2.util.DataSourceSource; import org.apache.cxf.attachment.AttachmentImpl; import org.apache.cxf.binding.soap.SoapMessage; @@ -46,7 +64,8 @@ import org.apache.cxf.service.model.MessagePartInfo; public class SwAOutInterceptor extends AbstractSoapInterceptor { - + private static final Logger LOG = Logger.getLogger(SwAOutInterceptor.class.getName()); + public SwAOutInterceptor() { super(); addAfter(HolderOutInterceptor.class.getName()); @@ -95,6 +114,7 @@ int bodyParts = sbi.getParts().size(); for (MessagePartInfo mpi : sbi.getAttachments()) { String partName = mpi.getConcreteName().getLocalPart(); + final String ct = (String) mpi.getProperty(Message.CONTENT_TYPE); String id = new StringBuilder().append(partName) .append("=") @@ -102,14 +122,91 @@ .append("@apache.org").toString(); Object o = outObjects.remove(bodyParts); + if (o == null) { + continue; + } + + DataHandler dh = null; + + if (o instanceof Source) { + DataSource ds = null; + + if (o instanceof DataSourceSource) { + ds = (DataSource) o; + } else { + TransformerFactory tf = TransformerFactory.newInstance(); + try { + Transformer transformer = tf.newTransformer(); + + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + transformer.transform((Source) o, new StreamResult(bos)); + ds = new ByteArrayDataSource(bos.toByteArray(), ct); + } catch (TransformerException e) { + throw new Fault(e); + } + } + + dh = new DataHandler(ds); + + } else if (o instanceof Image) { + // TODO: make this streamable. This is one of my pet + // peeves in JAXB RI as well, so if you fix this, submit the + // code to the JAXB RI as well (see RuntimeBuiltinLeafInfoImpl)! - DD + ByteArrayOutputStream bos = new ByteArrayOutputStream(); + Iterator<ImageWriter> writers = ImageIO.getImageWritersByMIMEType(ct); + if (writers.hasNext()) { + ImageWriter writer = writers.next(); + + try { + BufferedImage bimg = convertToBufferedImage((Image) o); + writer.setOutput(ImageIO.createImageOutputStream(bos)); + writer.write(bimg); + writer.dispose(); + bos.close(); + } catch (IOException e) { + throw new Fault(e); + } + } + + dh = new DataHandler(new ByteArrayDataSource(bos.toByteArray(), ct)); + } else if (o instanceof DataHandler) { + dh = (DataHandler) o; + } else { + throw new Fault(new org.apache.cxf.common.i18n.Message("ATTACHMENT_NOT_SUPPORTED", + LOG, o.getClass())); + } AttachmentImpl att = new AttachmentImpl(id); - att.setDataHandler((DataHandler) o); + att.setDataHandler(dh); att.setHeader("Content-Type", (String)mpi.getProperty(Message.CONTENT_TYPE)); atts.add(att); } } + private BufferedImage convertToBufferedImage(Image image) throws IOException { + if (image instanceof BufferedImage) { + return (BufferedImage)image; + } else { + MediaTracker tracker = new MediaTracker(new Component() { }); + tracker.addImage(image, 0); + try { + tracker.waitForAll(); + } catch (InterruptedException e) { + IOException ioe = new IOException(e.getMessage()); + ioe.initCause(e); + throw ioe; + } + BufferedImage bufImage = new BufferedImage( + image.getWidth(null), + image.getHeight(null), + BufferedImage.TYPE_INT_ARGB); + + Graphics g = bufImage.createGraphics(); + g.drawImage(image, 0, 0, null); + return bufImage; + } + } + private Collection<Attachment> setupAttachmentOutput(SoapMessage message) { // We have attachments, so add the interceptor message.getInterceptorChain().add(new AttachmentOutInterceptor()); Modified: incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/swa/ClientServerSwaTest.java URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/swa/ClientServerSwaTest.java?view=diff&rev=541791&r1=541790&r2=541791 ============================================================================== --- incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/swa/ClientServerSwaTest.java (original) +++ incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/swa/ClientServerSwaTest.java Fri May 25 14:49:06 2007 @@ -36,7 +36,6 @@ import org.apache.cxf.swa.types.VoidRequest; import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase; import org.junit.BeforeClass; -import org.junit.Ignore; import org.junit.Test; public class ClientServerSwaTest extends AbstractBusClientServerTestBase { @@ -103,7 +102,6 @@ } @Test - @Ignore public void testSwaTypes() throws Exception { SwAService service = new SwAService(); @@ -134,7 +132,6 @@ OutputResponseAll response = port.echoAllAttachmentTypes(request, attach1, attach2, attach3, attach4, attach5); assertNotNull(response); - } } Modified: incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/swa/resources/attach.xml URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/swa/resources/attach.xml?view=diff&rev=541791&r1=541790&r2=541791 ============================================================================== --- incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/swa/resources/attach.xml (original) +++ incubator/cxf/trunk/systests/src/test/java/org/apache/cxf/systest/swa/resources/attach.xml Fri May 25 14:49:06 2007 @@ -1,18 +1,20 @@ -/** - * 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. - */ \ No newline at end of file +<?xml version="1.0" encoding="UTF-8"?> +<!-- + 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. +--> +<test/> \ No newline at end of file