Save This Page
Home » axiom-1.2.8-src » org.apache.axiom.om.impl.llom » [javadoc | source]
    1   /*
    2    * Licensed to the Apache Software Foundation (ASF) under one
    3    * or more contributor license agreements. See the NOTICE file
    4    * distributed with this work for additional information
    5    * regarding copyright ownership. The ASF licenses this file
    6    * to you under the Apache License, Version 2.0 (the
    7    * "License"); you may not use this file except in compliance
    8    * with the License. You may obtain a copy of the License at
    9    *
   10    * http://www.apache.org/licenses/LICENSE-2.0
   11    *
   12    * Unless required by applicable law or agreed to in writing,
   13    * software distributed under the License is distributed on an
   14    * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
   15    * KIND, either express or implied. See the License for the
   16    * specific language governing permissions and limitations
   17    * under the License.
   18    */
   19   
   20   package org.apache.axiom.om.impl.llom;
   21   
   22   
   23   import org.apache.axiom.om.OMAttribute;
   24   import org.apache.axiom.om.OMConstants;
   25   import org.apache.axiom.om.OMContainer;
   26   import org.apache.axiom.om.OMElement;
   27   import org.apache.axiom.om.OMException;
   28   import org.apache.axiom.om.OMFactory;
   29   import org.apache.axiom.om.OMNamespace;
   30   import org.apache.axiom.om.OMText;
   31   import org.apache.axiom.om.OMXMLParserWrapper;
   32   import org.apache.axiom.om.impl.MTOMXMLStreamWriter;
   33   import org.apache.axiom.om.impl.OMNamespaceImpl;
   34   import org.apache.axiom.om.impl.builder.XOPBuilder;
   35   import org.apache.axiom.om.impl.util.OMSerializerUtil;
   36   import org.apache.axiom.om.util.TextHelper;
   37   import org.apache.axiom.om.util.UUIDGenerator;
   38   
   39   import javax.xml.namespace.QName;
   40   import javax.xml.stream.XMLStreamException;
   41   import javax.xml.stream.XMLStreamWriter;
   42   import java.io.IOException;
   43   import java.io.InputStream;
   44   
   45   public class OMTextImpl extends OMNodeImpl implements OMText, OMConstants {
   46       /** Field nameSpace used when serializing Binary stuff as MTOM optimized. */
   47       public static final OMNamespace XOP_NS = new OMNamespaceImpl(
   48               "http://www.w3.org/2004/08/xop/include", "xop");
   49   
   50       protected String value = null;
   51       protected char[] charArray;
   52   
   53       private boolean calcNS;  // Set to true after textNS is calculated
   54       protected OMNamespace textNS;
   55   
   56       protected String mimeType;
   57   
   58       protected boolean optimize = false;
   59   
   60       protected boolean isBinary = false;
   61   
   62       /** Field contentID for the mime part used when serializing Binary stuff as MTOM optimized. */
   63       private String contentID = null;
   64   
   65       /**
   66        * Field dataHandler contains the DataHandler Declaring as Object to remove the dependency on
   67        * Javax.activation.DataHandler
   68        */
   69       private Object dataHandlerObject = null;
   70   
   71       /** Field localName used when serializing Binary stuff as MTOM optimized. */
   72       protected String localName = "Include";
   73   
   74       /** Field attributes used when serializing Binary stuff as MTOM optimized. */
   75       protected OMAttribute attribute;
   76       private static final String EMTPY_STRING = "";
   77   
   78       /**
   79        * Constructor OMTextImpl.
   80        *
   81        * @param s
   82        */
   83       public OMTextImpl(String s, OMFactory factory) {
   84           this(s, TEXT_NODE, factory);
   85       }
   86   
   87       /**
   88        * @param s
   89        * @param nodeType - OMText can handle CHARACTERS, SPACES, CDATA and ENTITY REFERENCES.
   90        *                 Constants for this can be found in OMNode.
   91        */
   92       public OMTextImpl(String s, int nodeType, OMFactory factory) {
   93           this(null, s, nodeType, factory);
   94       }
   95   
   96       /**
   97        * Constructor OMTextImpl.
   98        *
   99        * @param parent
  100        * @param text
  101        */
  102       public OMTextImpl(OMContainer parent, String text, OMFactory factory) {
  103           this(parent, text, TEXT_NODE, factory);
  104       }
  105       
  106       /**
  107        * Construct OMTextImpl that is a copy of the source OMTextImpl
  108        * @param parent
  109        * @param source OMTextImpl
  110        * @param factory
  111        */
  112       public OMTextImpl(OMContainer parent, OMTextImpl source, OMFactory factory) {
  113           super(parent, factory, true);
  114           // Copy the value of the text
  115           this.value = source.value;
  116           this.nodeType = source.nodeType;
  117           
  118           // Clone the charArray (if it exists)
  119           if (source.charArray != null) {
  120               this.charArray = new char[source.charArray.length];
  121               System.arraycopy(source.charArray, 0, this.charArray, 0, source.charArray.length);
  122           }
  123           
  124           // Turn off calcNS...the namespace will need to be recalculated
  125           // in the new tree's context.
  126           this.calcNS = false;
  127           this.textNS = null;
  128           
  129           // Copy the optimized related settings.
  130           this.optimize = source.optimize;
  131           this.mimeType = source.mimeType;
  132           this.isBinary = source.isBinary;
  133           
  134           // TODO
  135           // Do we need a deep copy of the data-handler 
  136           this.contentID = source.contentID;
  137           this.dataHandlerObject = source.dataHandlerObject;
  138           
  139           this.localName = source.localName;
  140           if (source.attribute != null) {
  141               this.attribute = factory.createOMAttribute(source.attribute.getLocalName(),
  142                                                          source.attribute.getNamespace(),
  143                                                          source.attribute.getAttributeValue());
  144           }
  145       }
  146   
  147       public OMTextImpl(OMContainer parent, String text, int nodeType,
  148                         OMFactory factory) {
  149           super(parent, factory, true);
  150           this.value = text == null ? EMTPY_STRING : text;
  151           this.nodeType = nodeType;
  152       }
  153   
  154       public OMTextImpl(OMContainer parent, char[] charArray, int nodeType,
  155                         OMFactory factory) {
  156           super(parent, factory, true);
  157           this.charArray = charArray;
  158           this.nodeType = nodeType;
  159       }
  160   
  161   
  162       public OMTextImpl(OMContainer parent, QName text, OMFactory factory) {
  163           this(parent, text, TEXT_NODE, factory);
  164       }
  165   
  166       public OMTextImpl(OMContainer parent, QName text, int nodeType,
  167                         OMFactory factory) {
  168           super(parent, factory, true);
  169           if (text == null) throw new IllegalArgumentException("QName text arg cannot be null!");
  170           this.calcNS = true;
  171           this.textNS =
  172                   ((OMElementImpl) parent).handleNamespace(text.getNamespaceURI(), text.getPrefix());
  173           this.value = textNS.getPrefix() + ":" + text.getLocalPart();
  174           this.nodeType = nodeType;
  175       }
  176   
  177       /**
  178        * @param s        - base64 encoded String representation of Binary
  179        * @param mimeType of the Binary
  180        */
  181       public OMTextImpl(String s, String mimeType, boolean optimize,
  182                         OMFactory factory) {
  183           this(null, s, mimeType, optimize, factory);
  184       }
  185   
  186       /**
  187        * @param parent
  188        * @param s        - base64 encoded String representation of Binary
  189        * @param mimeType of the Binary
  190        */
  191       public OMTextImpl(OMContainer parent, String s, String mimeType,
  192                         boolean optimize, OMFactory factory) {
  193           this(parent, s, factory);
  194           this.mimeType = mimeType;
  195           this.optimize = optimize;
  196           this.isBinary = true;
  197           done = true;
  198           this.nodeType = TEXT_NODE;
  199       }
  200   
  201       /** @param dataHandler To send binary optimised content Created programatically. */
  202       public OMTextImpl(Object dataHandler, OMFactory factory) {
  203           this(dataHandler, true, factory);
  204       }
  205   
  206       /**
  207        * @param dataHandler
  208        * @param optimize    To send binary content. Created progrmatically.
  209        */
  210       public OMTextImpl(Object dataHandler, boolean optimize, OMFactory factory) {
  211           super(factory);
  212           this.dataHandlerObject = dataHandler;
  213           this.isBinary = true;
  214           this.optimize = optimize;
  215           done = true;
  216           this.nodeType = TEXT_NODE;
  217       }
  218   
  219       /**
  220        * @param contentID
  221        * @param parent
  222        * @param builder   Used when the builder is encountered with a XOP:Include tag Stores a
  223        *                  reference to the builder and the content-id. Supports deferred parsing of
  224        *                  MIME messages.
  225        */
  226       public OMTextImpl(String contentID, OMContainer parent,
  227                         OMXMLParserWrapper builder, OMFactory factory) {
  228           super(parent, factory, false);
  229           this.contentID = contentID;
  230           this.optimize = true;
  231           this.isBinary = true;
  232           this.builder = builder;
  233           this.nodeType = TEXT_NODE;
  234       }
  235   
  236       /**
  237        * @param writer
  238        * @throws XMLStreamException
  239        */
  240       public void internalSerialize(XMLStreamWriter writer) throws XMLStreamException {
  241           internalSerializeLocal(writer);
  242       }
  243   
  244       /**
  245        * Writes the relevant output.
  246        *
  247        * @param writer
  248        * @throws XMLStreamException
  249        */
  250       private void writeOutput(XMLStreamWriter writer) throws XMLStreamException {
  251           int type = getType();
  252           if (type == TEXT_NODE || type == SPACE_NODE) {
  253               writer.writeCharacters(this.getText());
  254           } else if (type == CDATA_SECTION_NODE) {
  255               writer.writeCData(this.getText());
  256           } else if (type == ENTITY_REFERENCE_NODE) {
  257               writer.writeEntityRef(this.getText());
  258           }
  259       }
  260   
  261       /** Returns the value. */
  262       public String getText() throws OMException {
  263           if (charArray != null || this.value != null) {
  264               return getTextFromProperPlace();
  265           } else {
  266               try {
  267                   return TextHelper.toString(getInputStream());
  268               } catch (Exception e) {
  269                   throw new OMException(e);
  270               }
  271           }
  272       }
  273   
  274       public char[] getTextCharacters() {
  275           return charArray != null ? charArray : value.toCharArray();
  276       }
  277   
  278       public boolean isCharacters() {
  279           return charArray != null;
  280       }
  281   
  282       /**
  283        * This OMText contains two data source:value and charArray. This method will return text from
  284        * correct place.
  285        */
  286       private String getTextFromProperPlace() {
  287           return charArray != null ? new String(charArray) : value;
  288       }
  289   
  290   
  291       /** Returns the value. */
  292       public QName getTextAsQName() throws OMException {
  293           return ((OMElement)parent).resolveQName(getTextFromProperPlace());
  294       }
  295   
  296       /* (non-Javadoc)
  297         * @see org.apache.axiom.om.OMText#getNamespace()
  298         */
  299       public OMNamespace getNamespace() {
  300           // If the namespace has already been determined, return it
  301           // Otherwise calculate the namespace if the text contains a colon and is not detached.
  302           if (calcNS) {
  303               return textNS;
  304           } else {
  305               calcNS = true;
  306               if (getParent() != null) {
  307                   String text = getTextFromProperPlace();
  308                   if (text != null) {
  309                       int colon = text.indexOf(':');
  310                       if (colon > 0) {
  311                           textNS = ((OMElementImpl) getParent()).
  312                                   findNamespaceURI(text.substring(0, colon));
  313                           if (textNS != null) {
  314                               charArray = null;
  315                               value = text.substring(colon + 1);
  316                           }
  317                       }
  318                   }
  319               }
  320           }
  321           return textNS;
  322       }
  323   
  324       public boolean isOptimized() {
  325           return optimize;
  326       }
  327   
  328       public void setOptimize(boolean value) {
  329           this.optimize = value;
  330           if (value) {
  331               isBinary = true;
  332           }
  333       }
  334   
  335       /**
  336        * Receiving binary can happen as either MTOM attachments or as Base64 Text In the case of
  337        * Base64 user has to explicitly specify that the content is binary, before calling
  338        * getDataHandler(), getInputStream()....
  339        */
  340       public void setBinary(boolean value) {
  341           isBinary = value;
  342       }
  343   
  344       public boolean isBinary() {
  345           return isBinary;
  346       }
  347   
  348   
  349       /**
  350        * Gets the datahandler.
  351        *
  352        * @return Returns javax.activation.DataHandler
  353        */
  354       public Object getDataHandler() {
  355           if ((value != null || charArray != null) && isBinary) {
  356               String text = getTextFromProperPlace();
  357               return org.apache.axiom.attachments.utils.DataHandlerUtils
  358                       .getDataHandlerFromText(text, mimeType);
  359           } else {
  360   
  361               if (dataHandlerObject == null) {
  362                   if (contentID == null) {
  363                       throw new RuntimeException("ContentID is null");
  364                   }
  365                   dataHandlerObject = ((XOPBuilder) builder)
  366                           .getDataHandler(contentID);
  367               }
  368               return dataHandlerObject;
  369           }
  370       }
  371   
  372       public String getLocalName() {
  373           return localName;
  374       }
  375   
  376       public java.io.InputStream getInputStream() throws OMException {
  377           if (isBinary) {
  378               if (dataHandlerObject == null) {
  379                   getDataHandler();
  380               }
  381               InputStream inStream;
  382               javax.activation.DataHandler dataHandler =
  383                       (javax.activation.DataHandler) dataHandlerObject;
  384               try {
  385                   inStream = dataHandler.getDataSource().getInputStream();
  386               } catch (IOException e) {
  387                   throw new OMException(
  388                           "Cannot get InputStream from DataHandler." + e);
  389               }
  390               return inStream;
  391           } else {
  392               throw new OMException("Unsupported Operation");
  393           }
  394       }
  395   
  396       public String getContentID() {
  397           if (contentID == null) {
  398               contentID = UUIDGenerator.getUUID()
  399                       + "@apache.org";
  400           }
  401           return this.contentID;
  402       }
  403   
  404       public void internalSerializeAndConsume(XMLStreamWriter writer)
  405               throws XMLStreamException {
  406           internalSerializeLocal(writer);
  407       }
  408   
  409       private void internalSerializeLocal(XMLStreamWriter writer2) throws XMLStreamException {
  410   
  411           if ((!this.isBinary) || (!this.isOptimized())) {
  412               writeOutput(writer2);
  413           } else {
  414               //check whether we have a MTOMXMLStreamWriter. if so
  415               //we can optimize the writing!
  416               if (writer2 instanceof MTOMXMLStreamWriter) {
  417                   MTOMXMLStreamWriter writer = (MTOMXMLStreamWriter) writer2;
  418                   if (writer.isOptimized() && writer.isOptimizedThreshold(this)) {
  419                       if (contentID == null) {
  420                           contentID = writer.getNextContentId();
  421                       }
  422                       // send binary as MTOM optimised
  423                       this.attribute = new OMAttributeImpl("href",
  424                                                            new OMNamespaceImpl("", ""),
  425                                                            "cid:" + getContentID(), this.factory);
  426                       this.serializeStartpart(writer);
  427                       writer.writeOptimized(this);
  428                       writer.writeEndElement();
  429                   } else {
  430                       //do normal base64
  431                       writeOutput(writer);
  432                   }
  433               } else {
  434                   //we do not have a optimized writer. Just do the normal
  435                   //base64 writing
  436                   writeOutput(writer2);
  437               }
  438   
  439           }
  440       }
  441   
  442       /*
  443        * Methods to copy from OMSerialize utils
  444        */
  445       private void serializeStartpart(XMLStreamWriter writer)
  446               throws XMLStreamException {
  447           String nameSpaceName = XOP_NS.getNamespaceURI();
  448           String writer_prefix = writer.getPrefix(nameSpaceName);
  449           String prefix = XOP_NS.getPrefix();
  450           if (writer_prefix != null) {
  451               writer.writeStartElement(nameSpaceName, this
  452                       .getLocalName());
  453           } else {
  454               // According to StAX, setPrefix must occur before
  455               // writeStartElement
  456               if (OMSerializerUtil.isSetPrefixBeforeStartElement(writer)) {
  457                   writer.setPrefix(prefix, nameSpaceName);
  458                   writer.writeStartElement(prefix, this.getLocalName(),
  459                                            nameSpaceName);
  460               } else {
  461                   writer.writeStartElement(prefix, this.getLocalName(),
  462                                            nameSpaceName);
  463                   writer.setPrefix(prefix, nameSpaceName);
  464               }
  465           }
  466           // add the elements attribute "href"
  467           serializeAttribute(this.attribute, writer);
  468           // add the namespace
  469           serializeNamespace(XOP_NS, writer);
  470       }
  471   
  472       /**
  473        * Method serializeAttribute.
  474        *
  475        * @param attr
  476        * @throws XMLStreamException
  477        */
  478       static void serializeAttribute(OMAttribute attr, XMLStreamWriter writer)
  479               throws XMLStreamException {
  480           // first check whether the attribute is associated with a namespace
  481           OMNamespace ns = attr.getNamespace();
  482           String prefix;
  483           String namespaceName;
  484           if (ns != null) {
  485               // add the prefix if it's availble
  486               prefix = ns.getPrefix();
  487               namespaceName = ns.getNamespaceURI();
  488               if (prefix != null) {
  489                   writer.writeAttribute(prefix, namespaceName, attr
  490                           .getLocalName(), attr.getAttributeValue());
  491               } else {
  492                   writer.writeAttribute(namespaceName, attr.getLocalName(), attr
  493                           .getAttributeValue());
  494               }
  495           } else {
  496               writer.writeAttribute(attr.getLocalName(), attr.getAttributeValue());
  497           }
  498       }
  499   
  500       /**
  501        * Method serializeNamespace.
  502        *
  503        * @param namespace
  504        * @param writer
  505        * @throws XMLStreamException
  506        */
  507       static void serializeNamespace(OMNamespace namespace, XMLStreamWriter writer)
  508               throws XMLStreamException {
  509           if (namespace != null) {
  510               String uri = namespace.getNamespaceURI();
  511               String ns_prefix = namespace.getPrefix();
  512               writer.writeNamespace(ns_prefix, namespace.getNamespaceURI());
  513               writer.setPrefix(ns_prefix, uri);
  514           }
  515       }
  516   
  517       /**
  518        * A slightly different implementation of the discard method.
  519        *
  520        * @throws OMException
  521        */
  522       public void discard() throws OMException {
  523           if (done) {
  524               this.detach();
  525           } 
  526       }
  527   
  528       /* (non-Javadoc)
  529         * @see org.apache.axiom.om.OMNode#buildAll()
  530         */
  531       public void buildWithAttachments() {
  532           if (!this.done) {
  533               this.build();
  534           }
  535           if (isOptimized()) {
  536               this.getDataHandler();
  537           }
  538       }
  539       
  540       public void setContentID(String cid) {
  541           this.contentID = cid;
  542       }
  543   
  544   }

Save This Page
Home » axiom-1.2.8-src » org.apache.axiom.om.impl.llom » [javadoc | source]