From: <jbo...@li...> - 2006-06-30 08:55:51
|
Author: hei...@jb... Date: 2006-06-30 04:55:45 -0400 (Fri, 30 Jun 2006) New Revision: 526 Added: branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/ branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/SimpleDataSource.java branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPContext.java branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPMarshallerImpl.java branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPScanner.java branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPUnmarshallerImpl.java branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPinlineBuilder.java Log: init Added: branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/SimpleDataSource.java =================================================================== --- branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/SimpleDataSource.java 2006-06-30 08:49:02 UTC (rev 525) +++ branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/SimpleDataSource.java 2006-06-30 08:55:45 UTC (rev 526) @@ -0,0 +1,72 @@ +package org.jboss.ws.xop; + +import java.io.ByteArrayInputStream; +import java.io.ByteArrayOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.ObjectOutputStream; +import java.io.OutputStream; +import javax.activation.DataSource; +import org.jboss.xb.binding.JBossXBRuntimeException; + +/** + * @author <a href="mailto:al...@jb...">Alexey Loubyansky</a> + * @version <tt>$Revision$</tt> + */ +public class SimpleDataSource + implements DataSource +{ + public final byte[] bytes; + public final String contentType; + + public SimpleDataSource(Object o, String contentType) + { + ByteArrayOutputStream baos = new ByteArrayOutputStream(); + ObjectOutputStream oos = null; + try + { + oos = new ObjectOutputStream(baos); + oos.writeObject(o); + } + catch(IOException e) + { + throw new JBossXBRuntimeException("XOP failed to serialize object " + o + ": " + e.getMessage()); + } + finally + { + if(oos != null) + { + try + { + oos.close(); + } + catch(IOException e) + { + } + } + } + bytes = baos.toByteArray(); + + this.contentType = contentType; + } + + public String getContentType() + { + return contentType; + } + + public InputStream getInputStream() throws IOException + { + return new ByteArrayInputStream(bytes); + } + + public String getName() + { + throw new UnsupportedOperationException("getName is not implemented."); + } + + public OutputStream getOutputStream() throws IOException + { + throw new UnsupportedOperationException("getOutputStream is not implemented."); + } +} Property changes on: branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/SimpleDataSource.java ___________________________________________________________________ Name: svn:keywords + Id Revision Name: svn:eol-style + LF Added: branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPContext.java =================================================================== --- branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPContext.java 2006-06-30 08:49:02 UTC (rev 525) +++ branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPContext.java 2006-06-30 08:55:45 UTC (rev 526) @@ -0,0 +1,148 @@ +/* +* JBoss, Home of Professional Open Source +* Copyright 2005, JBoss Inc., and individual contributors as indicated +* by the @authors tag. See the copyright.txt in the distribution for a +* full listing of individual contributors. +* +* This is free software; you can redistribute it and/or modify it +* under the terms of the GNU Lesser General Public License as +* published by the Free Software Foundation; either version 2.1 of +* the License, or (at your option) any later version. +* +* This software is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +* Lesser General Public License for more details. +* +* You should have received a copy of the GNU Lesser General Public +* License along with this software; if not, write to the Free +* Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA +* 02110-1301 USA, or see the FSF site: http://www.fsf.org. +*/ +package org.jboss.ws.xop; + +import org.jboss.util.xml.DOMUtils; +import org.jboss.ws.soap.MessageContextAssociation; +import org.jboss.ws.soap.SOAPMessageContextImpl; +import org.jboss.ws.soap.SOAPMessageImpl; +import org.jboss.ws.utils.ThreadLocalAssociation; +import org.jboss.xb.binding.sunday.xop.XOPUnmarshaller; +import org.jboss.xb.binding.SimpleTypeBindings; +import org.w3c.dom.Element; + +import javax.xml.soap.SOAPElement; +import javax.activation.DataHandler; +import javax.activation.DataSource; +import java.util.Iterator; + +/** + * XOP context that associated with a message context. + * + * @author Heiko Braun <hei...@jb...> + * @since May 10, 2006 + */ +public class XOPContext { + + public static final String CID_PREFIX = "cid:"; + + public static boolean isXOPPackage() { + boolean isXOP = false; + SOAPMessageContextImpl msgContext = MessageContextAssociation.peekMessageContext(); + if(msgContext!=null) { + SOAPMessageImpl soapMessage = (SOAPMessageImpl)msgContext.getMessage(); + isXOP = (soapMessage != null && soapMessage.isXOPMessage()); + } + return isXOP; + } + + /** + * Force inline representation. + */ + public static void setInlineBase64() + { + ThreadLocalAssociation.localXOPCalleeAssoc().set(Boolean.TRUE); + } + + /** + * Unset inline representation flag. + */ + public static void unsetInlineBase64() + { + ThreadLocalAssociation.localXOPCalleeAssoc().set(Boolean.FALSE); + } + + /** + * Should the current message be inlined? + * An inlined message contains the base64 representation instead + * if the <code>xop:Include</code> element. + */ + public static boolean doInlineBase64() + { + Boolean b = ThreadLocalAssociation.localXOPCalleeAssoc().get() != null ? + ThreadLocalAssociation.localXOPCalleeAssoc().get():Boolean.FALSE; + return b.booleanValue(); + } + + /** + * Replace all <code>xop:Include</code> elements with it's base64 representation + */ + public static void inlineXOPData(SOAPElement xopElement) + { + Iterator it = DOMUtils.getChildElements(xopElement); + while(it.hasNext()) + { + SOAPElement childElement = (SOAPElement)it.next(); + String ns = childElement.getNamespaceURI()!=null ? childElement.getNamespaceURI(): ""; + String localName = childElement.getLocalName(); + if(ns.equals("http://www.w3.org/2004/08/xop/include") && localName.equals("Include")) + { + replaceXOPInclude(xopElement, childElement); + } + else + { + inlineXOPData(childElement); + } + } + } + + private static void replaceXOPInclude(SOAPElement parent, SOAPElement child) + { + String cid = child.getAttribute("href"); + if(cid!=null) + { + XOPUnmarshaller unm = new XOPUnmarshallerImpl(); + byte[] data = unm.getAttachmentAsByteArray(cid); + String base64 = SimpleTypeBindings.marshalBase64(data); + parent.removeChild(child); + parent.setValue(base64); + } + } + + public static DataHandler getDataHandler(Object o) + { + DataHandler dataHandler; + // todo: contentType + if(o instanceof java.awt.Image) + { + dataHandler = new DataHandler(o, "image/jpeg"); + } + else if(o instanceof javax.xml.transform.Source) + { + dataHandler = new DataHandler(o, "application/xml"); + } + else if(o instanceof String) + { + dataHandler = new DataHandler(o, "text/xml"); + } + else if(o instanceof DataHandler) + { + dataHandler = (DataHandler)o;//new DataHandler(o, "application/octet-stream"); + } + else + { + DataSource ds = new SimpleDataSource(o, "application/octet-stream"); + dataHandler = new DataHandler(ds); + } + return dataHandler; + } +} Property changes on: branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPContext.java ___________________________________________________________________ Name: svn:keywords + Id Revision Name: svn:eol-style + LF Added: branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPMarshallerImpl.java =================================================================== --- branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPMarshallerImpl.java 2006-06-30 08:49:02 UTC (rev 525) +++ branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPMarshallerImpl.java 2006-06-30 08:55:45 UTC (rev 526) @@ -0,0 +1,100 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2005, JBoss Inc., and individual contributors as indicated + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.ws.xop; + +import org.jboss.logging.Logger; +import org.jboss.util.NotImplementedException; +import org.jboss.ws.soap.MessageContextAssociation; +import org.jboss.ws.soap.SOAPMessageContextImpl; +import org.jboss.ws.soap.SOAPMessageImpl; +import org.jboss.ws.soap.attachment.MimeConstants; +import org.jboss.xb.binding.sunday.xop.XOPMarshaller; +import org.jboss.xb.binding.sunday.xop.XOPObject; + +import javax.activation.DataHandler; +import javax.activation.DataSource; +import javax.xml.namespace.QName; +import javax.xml.soap.AttachmentPart; + +/** + * The XOPMarshallerImpl allows callbacks from the binding layer towards the + * soap processing components in order to optimize binary processing. + * + * @see org.jboss.ws.xop.XOPUnmarshallerImpl + * @see org.jboss.ws.jaxrpc.encoding.JAXBSerializer + * @see org.jboss.ws.jaxrpc.encoding.SimpleSerializer + * + * @author Heiko Braun <hei...@jb...> + * @since May 9, 2006 + */ +public class XOPMarshallerImpl implements XOPMarshaller { + + private static final Logger log = Logger.getLogger(XOPMarshallerImpl.class); + + public boolean isXOPPackage() + { + return XOPContext.isXOPPackage(); + } + + public String addMtomAttachment(XOPObject obj, String elementNamespace, String elementName) + { + + QName xmlName = new QName(elementNamespace, elementName); + log.debug("serialize: [xmlName=" + xmlName + "]"); + + SOAPMessageContextImpl msgContext = (SOAPMessageContextImpl)MessageContextAssociation.peekMessageContext(); + SOAPMessageImpl soapMessage = (SOAPMessageImpl)msgContext.getMessage(); + + String cid = soapMessage.getCidGenerator().generateFromName(xmlName.getLocalPart()); + + DataHandler dataHandler = XOPContext.getDataHandler(obj.getContent()); + obj.setContentType(dataHandler.getContentType()); + + AttachmentPart xopPart = soapMessage.createAttachmentPart(dataHandler); + xopPart.addMimeHeader(MimeConstants.CONTENT_ID, '<'+cid+'>'); // RFC2392 requirement + soapMessage.addAttachmentPart(xopPart); + + return "cid:" + cid; + + } + + public String addMtomAttachment(byte[] data, String elementNamespace, String elementName) + { + /* + TODO: this requires a java mail upgrade + ByteArrayDataSource ds = new ByteArrayDataSource(data, MimeConstants.TYPE_APPLICATION_OCTET_STREAM); + return addMtomAttachment( + new DataHandler( + ds, MimeConstants.TYPE_APPLICATION_OCTET_STREAM), + elementNamespace, elementName + );*/ + + throw new NotImplementedException("Not implemented yet"); + } + + public String addSwaRefAttachment(Object obj) + { + throw new NotImplementedException(); + } + + +} Property changes on: branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPMarshallerImpl.java ___________________________________________________________________ Name: svn:keywords + Id Revision Name: svn:eol-style + LF Added: branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPScanner.java =================================================================== --- branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPScanner.java 2006-06-30 08:49:02 UTC (rev 525) +++ branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPScanner.java 2006-06-30 08:55:45 UTC (rev 526) @@ -0,0 +1,126 @@ +package org.jboss.ws.xop; + +import org.apache.xerces.xs.*; + +import java.util.List; +import java.util.ArrayList; + +/** + * Scans complex type definitions for nested XOP type declarations. + * A XOP type declaration is identified as a complex type + * that derives from xsd:base64Binary, i.e: + * + * <code> <pre> + * <xs:complexType name="MyXOPElement" > + * <xs:simpleContent> + * <xs:extension base="xs:base64Binary" > + * <xs:attribute ref="xmime:contentType" /> + * </xs:extension> + * </xs:simpleContent> + * </xs:complexType> + * </pre></code> + * + * @author Heiko Braun <hei...@jb...> + * @since Jun 9, 2006 + */ +public class XOPScanner { + + // avoid circular scans + private List<String> scannedItems = new ArrayList<String>(); + + /** + * Query a complex type for nested XOP type definitions. + */ + public XSTypeDefinition findXOPTypeDef(XSTypeDefinition typeDef) + { + XSTypeDefinition result = null; + + if(typeDef instanceof XSComplexTypeDefinition) + { + XSComplexTypeDefinition complexTypeDef = (XSComplexTypeDefinition)typeDef; + String name = complexTypeDef.getName(); + String namespace = complexTypeDef.getNamespace()!=null ? complexTypeDef.getNamespace():""; + if(name!=null) + { + String typeKey = namespace+":"+name; + + if(scannedItems.contains(typeKey)) + { + return null; + } + else + { + scannedItems.add(typeKey); + } + } + + //System.out.println("ct -> " + complexTypeDef); + + /*for(int x=0; x<complexTypeDef.getAttributeUses().getLength(); x++) + { + // TODO: access content type attribute value + XSAttributeUseImpl att = (XSAttributeUseImpl)complexTypeDef.getAttributeUses().item(x); + //System.out.println("! " + att.getAttrDeclaration().getName()); + }*/ + + // An XOP parameter is detected if it is a complex type + // that derives from xsd:base64Binary + if (complexTypeDef.getSimpleType() != null) + { + String typeName = complexTypeDef.getSimpleType().getName(); + if ("base64Binary".equals(typeName)) + return complexTypeDef; + } + else + { + + XSModelGroup xm = null; + if(complexTypeDef.getContentType() != XSComplexTypeDefinition.CONTENTTYPE_EMPTY) + { + XSParticle xp = complexTypeDef.getParticle(); + if (xp != null) + { + XSTerm xterm = xp.getTerm(); + if(xterm instanceof XSModelGroup) + { + xm = (XSModelGroup)xterm; + //System.out.println("xm -> " + xm); + + XSObjectList xo = xm.getParticles(); + + // interate over nested particles + for(int i=0; i<xm.getParticles().getLength(); i++ ) + { + XSTerm xsterm = ((XSParticle)xo.item(i)).getTerm(); + + // Can be either XSModelGroup, XSWildcard, XSElementDeclaration + // We only proceed with XSElementDeclaration + if(xsterm instanceof XSElementDeclaration) + { + XSElementDeclaration xe = (XSElementDeclaration)xsterm; + XSTypeDefinition nestedTypeDef = xe.getTypeDefinition(); + + //System.out.println("Query nested -> " + xe.getName()); + result = findXOPTypeDef(nestedTypeDef); + } + } + } + } + } + + } + + //System.out.println("result -> " + result); + + } + + return result; + + } + + public void reset() + { + scannedItems.clear(); + } + +} \ No newline at end of file Property changes on: branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPScanner.java ___________________________________________________________________ Name: svn:keywords + Id Revision Name: svn:eol-style + LF Added: branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPUnmarshallerImpl.java =================================================================== --- branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPUnmarshallerImpl.java 2006-06-30 08:49:02 UTC (rev 525) +++ branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPUnmarshallerImpl.java 2006-06-30 08:55:45 UTC (rev 526) @@ -0,0 +1,118 @@ +/* + * JBoss, Home of Professional Open Source + * Copyright 2005, JBoss Inc., and individual contributors as indicated + * by the @authors tag. See the copyright.txt in the distribution for a + * full listing of individual contributors. + * + * This is free software; you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 of + * the License, or (at your option) any later version. + * + * This software is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this software; if not, write to the Free + * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA + * 02110-1301 USA, or see the FSF site: http://www.fsf.org. + */ +package org.jboss.ws.xop; + +import org.jboss.logging.Logger; +import org.jboss.ws.WSException; +import org.jboss.ws.soap.MessageContextAssociation; +import org.jboss.ws.soap.SOAPMessageContextImpl; +import org.jboss.ws.soap.SOAPMessageImpl; +import org.jboss.xb.binding.sunday.xop.XOPUnmarshaller; +import org.jboss.xb.binding.sunday.xop.XOPObject; + +import javax.activation.DataHandler; +import javax.xml.soap.AttachmentPart; +import javax.xml.soap.SOAPException; +import java.io.ByteArrayOutputStream; +import java.io.IOException; + +/** + * The XOPUnmarshallerImpl allows callbacks from the binding layer towards the + * soap processing components in order to optimize binary processing. + * + * @see XOPMarshallerImpl + * @see org.jboss.ws.jaxrpc.encoding.JAXBDeserializer + * @see org.jboss.ws.jaxrpc.encoding.SimpleDeserializer + * + * @author Heiko Braun <hei...@jb...> + * @since May 9, 2006 + */ +public class XOPUnmarshallerImpl implements XOPUnmarshaller { + + private static final Logger log = Logger.getLogger(XOPUnmarshallerImpl.class); + + public boolean isXOPPackage() + { + return XOPContext.isXOPPackage(); + } + + public XOPObject getAttachmentAsDataHandler(String cid) + { + try + { + AttachmentPart part = getAttachementByCID(cid); + + XOPObject xopObject = new XOPObject(part.getDataHandler().getContent()); + xopObject.setContentType(part.getDataHandler().getContentType()); + + return xopObject; + } + catch (SOAPException ex) + { + throw new WSException(ex); + } + catch(IOException e) + { + throw new WSException("Unable to retrieve content for cid:" + cid, e); + } + + } + + public byte[] getAttachmentAsByteArray(String cid) + { + try + { + AttachmentPart part = getAttachementByCID(cid); + DataHandler dh = part.getDataHandler(); + ByteArrayOutputStream bout = new ByteArrayOutputStream(); + dh.writeTo(bout); + + return bout.toByteArray(); + } + catch (SOAPException ex) + { + throw new WSException(ex); + } + catch(IOException e) + { + throw new WSException(e); + } + + } + + private AttachmentPart getAttachementByCID(String cid) throws SOAPException + { + SOAPMessageContextImpl msgContext = MessageContextAssociation.peekMessageContext(); + SOAPMessageImpl soapMessage = (SOAPMessageImpl)msgContext.getMessage(); + + // RFC2392 requires the 'cid:' part to be stripped from the cid + if(cid.startsWith("cid:")) cid = cid.substring(4); + cid = '<'+cid+'>'; + + AttachmentPart part = soapMessage.getAttachmentByContentId(cid); + if (part == null) + throw new WSException("Cannot find attachment part for: " + cid); + + return part; + } + +} Property changes on: branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPUnmarshallerImpl.java ___________________________________________________________________ Name: svn:keywords + Id Revision Name: svn:eol-style + LF Added: branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPinlineBuilder.java =================================================================== --- branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPinlineBuilder.java 2006-06-30 08:49:02 UTC (rev 525) +++ branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPinlineBuilder.java 2006-06-30 08:55:45 UTC (rev 526) @@ -0,0 +1,8 @@ +package org.jboss.ws.xop; + +/** + * @author Heiko Braun <hei...@jb...> + * @since Jun 30, 2006 + */ +public class XOPinlineBuilder { +} Property changes on: branches/jbossws-1.0/src/main/java/org/jboss/ws/xop/XOPinlineBuilder.java ___________________________________________________________________ Name: svn:keywords + Id Revision Name: svn:eol-style + LF |