Package org.eclipse.persistence.oxm.record

Source Code of org.eclipse.persistence.oxm.record.JSONWriterRecord$JSONWriterRecordContentHandler

/*******************************************************************************
* Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v1.0 and Eclipse Distribution License v. 1.0
* which accompanies this distribution.
* The Eclipse Public License is available at http://www.eclipse.org/legal/epl-v10.html
* and the Eclipse Distribution License is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* Contributors:
*     Blaise Doughan - 2.4 - initial implementation
******************************************************************************/
package org.eclipse.persistence.oxm.record;

import java.io.IOException;
import java.io.Writer;
import java.nio.charset.Charset;
import java.nio.charset.CharsetEncoder;
import java.util.Stack;

import javax.xml.namespace.QName;

import org.eclipse.persistence.exceptions.JAXBException;
import org.eclipse.persistence.exceptions.XMLMarshalException;
import org.eclipse.persistence.internal.helper.ClassConstants;
import org.eclipse.persistence.internal.oxm.TreeObjectBuilder;
import org.eclipse.persistence.internal.oxm.XMLBinaryDataHelper;
import org.eclipse.persistence.internal.oxm.XMLConversionManager;
import org.eclipse.persistence.internal.oxm.XPathFragment;
import org.eclipse.persistence.internal.oxm.record.ExtendedContentHandler;
import org.eclipse.persistence.internal.oxm.record.XMLFragmentReader;
import org.eclipse.persistence.oxm.CharacterEscapeHandler;
import org.eclipse.persistence.oxm.NamespaceResolver;
import org.eclipse.persistence.oxm.XMLConstants;
import org.eclipse.persistence.oxm.XMLDescriptor;
import org.eclipse.persistence.oxm.XMLMarshaller;
import org.eclipse.persistence.oxm.XMLRoot;
import org.w3c.dom.Attr;
import org.w3c.dom.Node;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.ext.LexicalHandler;

/**
* <p>Use this type of MarshalRecord when the marshal target is a Writer and the
* JSON should not be formatted with carriage returns or indenting.</p>
* <p><code>
* XMLContext xmlContext = new XMLContext("session-name");<br>
* XMLMarshaller xmlMarshaller = xmlContext.createMarshaller();<br>
* JSONRecord jsonWriterRecord = new JSONWriterRecord();<br>
* jsonWriterRecord.setWriter(myWriter);<br>
* xmlMarshaller.marshal(myObject, jsonWriterRecord);<br>
* </code></p>
* <p>If the marshal(Writer) and setMediaType(MediaType.APPLICATION_JSON) and
* setFormattedOutput(false) method is called on XMLMarshaller, then the Writer
* is automatically wrapped in a JSONWriterRecord.</p>
* <p><code>
* XMLContext xmlContext = new XMLContext("session-name");<br>
* XMLMarshaller xmlMarshaller = xmlContext.createMarshaller();<br>
* xmlMarshaller.setMediaType(MediaType.APPLICATION_JSON);
* xmlMarshaller xmlMarshaller.setFormattedOutput(false);<br>
* xmlMarshaller.marshal(myObject, myWriter);<br>
* </code></p>
* @see org.eclipse.persistence.oxm.XMLMarshaller
*/
public class JSONWriterRecord extends MarshalRecord {

    protected Writer writer;
    protected boolean isStartElementOpen = false;
    protected boolean isProcessingCData = false;
    protected Stack<Level> levels = new Stack<Level>();
    protected static final String NULL="null";
    protected String attributePrefix;
    protected boolean charactersAllowed = false;
    protected CharsetEncoder encoder;
    protected String space;
    protected CharacterEscapeHandler characterEscapeHandler;

    public JSONWriterRecord(){
        super();
        space = XMLConstants.EMPTY_STRING;
    }

    /**
     * INTERNAL:
     */
    public void setMarshaller(XMLMarshaller marshaller) {
        super.setMarshaller(marshaller);
        attributePrefix = marshaller.getAttributePrefix();
        encoder = Charset.forName(marshaller.getEncoding()).newEncoder();       
        if(marshaller.getValueWrapper() != null){
          textWrapperFragment = new XPathFragment(marshaller.getValueWrapper());
        }
        characterEscapeHandler = marshaller.getCharacterEscapeHandler();       
    }

       
    /**
     * Handle marshal of an empty collection. 
     * @param xPathFragment
     * @param namespaceResolver
     * @param openGrouping if grouping elements should be marshalled for empty collections
     * @return
     */   
    public boolean emptyCollection(XPathFragment xPathFragment, NamespaceResolver namespaceResolver, boolean openGrouping) {     
       if(marshaller.isMarshalEmptyCollections()){ 
         super.emptyCollection(xPathFragment, namespaceResolver, true);
         startCollection();
         if(xPathFragment != null){
           openStartElement(xPathFragment, namespaceResolver);          
           if(!levels.isEmpty()){
                 Level position = levels.peek();
                 position.setNeedToCloseComplex(false);
                 position.setNeedToOpenComplex(false);
               }
           endElement(xPathFragment, namespaceResolver);
         }
         endEmptyCollection();
         return true;
       }else{
         return super.emptyCollection(xPathFragment, namespaceResolver, openGrouping);
       }
    }
   
    /**
     * Return the Writer that the object will be marshalled to.
     * @return The marshal target.
     */
    public Writer getWriter() {
        return writer;
    }

    /**
     * Set the Writer that the object will be marshalled to.
     * @param writer The marshal target.
     */
    public void setWriter(Writer writer) {
        this.writer = writer;
    }

    public void namespaceDeclaration(String prefix, String namespaceURI){
    }
   
    public void defaultNamespaceDeclaration(String defaultNamespace){
    }
   
    /**
     * INTERNAL:
     */
    public void startDocument(String encoding, String version) {
        try {
             if(!levels.isEmpty()) {
                 Level level = levels.peek();
                 if(level.isFirst()) {
                     level.setFirst(false);
                 } else {
                     writer.write(",");
                     writer.write(space);
                 }
             }
             levels.push(new Level(true, false));
             writer.write('{');
         } catch (IOException e) {
            throw XMLMarshalException.marshalException(e);
        }
    }

    /**
     * INTERNAL:
     */
    public void endDocument() {
        try {           
            closeComplex();
            levels.pop();
        } catch (IOException e) {
            throw XMLMarshalException.marshalException(e);
        }
    }

    /**
     * INTERNAL:
     */
    public void openStartElement(XPathFragment xPathFragment, NamespaceResolver namespaceResolver) {
        try {
          Level newLevel = null;
            Level position = null;
            if(levels.isEmpty()) {
              newLevel = new Level(true, true);
                levels.push(newLevel);
            } else {
                position = levels.peek();
                newLevel = new Level(true, true);
                levels.push(newLevel);
                if(position.isFirst()) {
                    position.setFirst(false);
                } else {
                    writer.write(',');                   
                }
            }
            if(xPathFragment.nameIsText()){
                if(position != null && position.isCollection() && position.isEmptyCollection()) {
                  if(!charactersAllowed){
                     throw JAXBException.jsonValuePropertyRequired("[");  
                  }
                    writer.write('[');                   
                    position.setEmptyCollection(false);
                    position.setNeedToOpenComplex(false);
                    charactersAllowed = true;                   
                    return;
                }
            }
           
            if(position !=null && position.needToOpenComplex){
                   writer.write('{');
                   position.needToOpenComplex = false;
                   position.needToCloseComplex = true;
           }
         
           //write the key unless this is a a non-empty collection
           if(!(position.isCollection() && !position.isEmptyCollection())){
             writeKey(xPathFragment);
             //if it is the first thing in the collection also add the [
           if(position.isCollection() && position.isEmptyCollection()){
                    writer.write('[');
                     position.setEmptyCollection(false);              
             }
           }
            
           
            charactersAllowed = true;
        } catch (IOException e) {
            throw XMLMarshalException.marshalException(e);
        }
    }

    /**
     * INTERNAL:
     */
    public void element(XPathFragment frag) {
        try {
            if (isStartElementOpen) {
                writer.write('>');
                isStartElementOpen = false;
            }
            writer.write('<');
            writer.write(frag.getShortName());
            writer.write('/');
            writer.write('>');
        } catch (IOException e) {
            throw XMLMarshalException.marshalException(e);
        }
    }

    /**
     * INTERNAL:
     */
    public void attribute(String namespaceURI, String localName, String qName, String value) {
        XPathFragment xPathFragment = new XPathFragment();
        xPathFragment.setNamespaceURI(namespaceURI);
        xPathFragment.setAttribute(true);
        xPathFragment.setLocalName(localName);

        openStartElement(xPathFragment, namespaceResolver);
        characters(null, value, null, false, true);
        endElement(xPathFragment, namespaceResolver);
    }

    /**
     * INTERNAL:
     */
    public void attribute(XPathFragment xPathFragment, NamespaceResolver namespaceResolver, String value) {
        attribute(xPathFragment, namespaceResolver, value, null);
    }

    /**
     * INTERNAL:
     * override so we don't iterate over namespaces when startPrefixMapping doesn't do anything
     */
    public void startPrefixMappings(NamespaceResolver namespaceResolver) {
    }

    /**
     * INTERNAL:
     * override so we don't iterate over namespaces when endPrefixMapping doesn't do anything
     */
    public void endPrefixMappings(NamespaceResolver namespaceResolver) {
    }

    /**
     * INTERNAL:
     */
    public void closeStartElement() {}

    /**
     * INTERNAL:
     */
    public void endElement(XPathFragment xPathFragment, NamespaceResolver namespaceResolver) {
        try{
            if(!levels.isEmpty()) {
                Level position = levels.pop();
                if(position.needToOpenComplex){
                    writer.write('{');
                    closeComplex();
                } else if(position.needToCloseComplex){
                    closeComplex();
                }
                charactersAllowed = false;
            }
        } catch (IOException e) {
             throw XMLMarshalException.marshalException(e);
        }
    }

    protected void closeComplex() throws IOException {
        writer.write('}');
    }

    @Override
    public void startCollection() {
        if(levels.isEmpty()) {
            try {
                writer.write('[');
                levels.push(new Level(true, false));
            } catch(IOException e) {
                throw XMLMarshalException.marshalException(e);
            }
        } else {
            levels.peek().setCollection(true);
            levels.peek().setEmptyCollection(true);
        }
    }
   
    protected void endEmptyCollection(){
      endCollection();
    }

    @Override
    public void endCollection() {
        try {
            if(levels.size() == 1) {
                writer.write(']');
            } else {
                Level position = levels.peek();
                if(position != null && position.isCollection() && !position.isEmptyCollection()) {
                    writer.write(']');
                }
            }
            levels.peek().setCollection(false);
        } catch (IOException e) {
            throw XMLMarshalException.marshalException(e);
        }
    }

    /**
     * INTERNAL:
     */
    public void characters(String value) {
      characters(value, true, false);
    }
    /**
     * INTERNAL:
     */
     public void characters(String value, boolean isString, boolean isAttribute) {
        boolean textWrapperOpened = false;
          if(!charactersAllowed){   
             if(textWrapperFragment != null){
               openStartElement(textWrapperFragment, namespaceResolver);
               textWrapperOpened = true;
             }
         }
      
           Level position = levels.peek();
           position.setNeedToOpenComplex(false);
           try {
             if(isString){
                      writer.write('"');
                      writeValue(value, isAttribute);
                      writer.write('"');
             }else{
               writer.write(value);
             }
              
           } catch (IOException e) {
               throw XMLMarshalException.marshalException(e);
           }       
           if(textWrapperOpened){   
               if(textWrapperFragment != null){
                    endElement(textWrapperFragment, namespaceResolver);
               }
           }          
     }

     public void attribute(XPathFragment xPathFragment, NamespaceResolver namespaceResolver,  Object value, QName schemaType){
         if(xPathFragment.getNamespaceURI() != null && xPathFragment.getNamespaceURI() == XMLConstants.XMLNS_URL){
             return;
         }
         xPathFragment.setAttribute(true);
         openStartElement(xPathFragment, namespaceResolver);
         characters(schemaType, value, null, false, true);
         endElement(xPathFragment, namespaceResolver);
     }

     public void characters(QName schemaType, Object value, String mimeType, boolean isCDATA){        
        characters(schemaType, value, mimeType, isCDATA, false);
     }
    
     public void characters(QName schemaType, Object value, String mimeType, boolean isCDATA, boolean isAttribute){             
     
         Level position = levels.peek();
         position.setNeedToOpenComplex(false);
         if(mimeType != null) {
             value = XMLBinaryDataHelper.getXMLBinaryDataHelper().getBytesForBinaryValue(//
                     value, marshaller, mimeType).getData();
         }
         if(schemaType != null && XMLConstants.QNAME_QNAME.equals(schemaType)){
             String convertedValue = getStringForQName((QName)value);
             characters((String)convertedValue);
         } else if(value.getClass() == String.class){
             //if schemaType is set and it's a numeric or boolean type don't treat as a string
             if(schemaType != null && isNumericOrBooleanType(schemaType)){
                 String convertedValue = ((String) ((XMLConversionManager) session.getDatasourcePlatform().getConversionManager()).convertObject(value, ClassConstants.STRING, schemaType));
                 characters(convertedValue, false, isAttribute);
             }else if(isCDATA){
                 cdata((String)value);
             }else{
                 characters((String)value);
             }
        }else{
            String convertedValue = ((String) ((XMLConversionManager) session.getDatasourcePlatform().getConversionManager()).convertObject(value, ClassConstants.STRING, schemaType));
            if(schemaType == null){
                if(value.getClass() == ClassConstants.BOOLEAN || ClassConstants.NUMBER.isAssignableFrom(value.getClass())){
                  characters(convertedValue, false, isAttribute);
                }else{
                    characters(convertedValue);

                }
            }else if(schemaType != null && !isNumericOrBooleanType(schemaType)){
                //if schemaType exists and is not boolean or number do write quotes
                characters(convertedValue);
            } else if(isCDATA){
                cdata(convertedValue);
            }else{
              characters(convertedValue, false, isAttribute);
            }
        }
         charactersAllowed = false;
      
     }

    
     private boolean isNumericOrBooleanType(QName schemaType){
         if(schemaType == null){
             return false;
         }else if(schemaType.equals(XMLConstants.BOOLEAN_QNAME)
                 || schemaType.equals(XMLConstants.INTEGER_QNAME)
                 || schemaType.equals(XMLConstants.INT_QNAME)
                 || schemaType.equals(XMLConstants.DECIMAL_QNAME)
                 || schemaType.equals(XMLConstants.FLOAT_QNAME)
                 || schemaType.equals(XMLConstants.DOUBLE_QNAME)
                 || schemaType.equals(XMLConstants.SHORT_QNAME)
         ){
             return true;
         }
         return false;
     }

    /**
     * INTERNAL:
     */
     public void namespaceDeclarations(NamespaceResolver namespaceResolver) {
     }

    /**
     * INTERNAL:
     */
     public void nilComplex(XPathFragment xPathFragment, NamespaceResolver namespaceResolver){
         XPathFragment groupingFragment = openStartGroupingElements(namespaceResolver);
         closeStartGroupingElements(groupingFragment);
         openStartElement(xPathFragment, namespaceResolver);
         characters(NULL, false, false);
         endElement(xPathFragment, namespaceResolver);
     }

    /**
     * INTERNAL:
     */
     public void nilSimple(NamespaceResolver namespaceResolver){
         XPathFragment groupingFragment = openStartGroupingElements(namespaceResolver);        
         characters(NULL, false, false);
         closeStartGroupingElements(groupingFragment);
     }

     /**
      * Used when an empty simple value should be written
      * @since EclipseLink 2.4
      */
     public void emptySimple(NamespaceResolver namespaceResolver){
         nilSimple(namespaceResolver);
     }

     /**
      * Used when an empty complex item should be written
      * @since EclipseLink 2.4
      */
     public void emptyComplex(XPathFragment xPathFragment, NamespaceResolver namespaceResolver){
         XPathFragment groupingFragment = openStartGroupingElements(namespaceResolver);
         closeStartGroupingElements(groupingFragment);
         openStartElement(xPathFragment, namespaceResolver);
         endElement(xPathFragment, namespaceResolver);
     }

     public void marshalWithoutRootElement(TreeObjectBuilder treeObjectBuilder, Object object, XMLDescriptor descriptor, XMLRoot root, boolean isXMLRoot){
       if(treeObjectBuilder != null){
             treeObjectBuilder.addXsiTypeAndClassIndicatorIfRequired(this, descriptor, null, descriptor.getDefaultRootElementField(), root, object, isXMLRoot, true);
             treeObjectBuilder.marshalAttributes(this, object, session);
       }        
      }
     
    /**
     * INTERNAL:
     */
    public void cdata(String value) {
        characters(value);
    }

    /**
     * INTERNAL:
   * The character used to separate the prefix and uri portions when namespaces are present
     * @since 2.4
     */
    public char getNamespaceSeparator(){     
      return marshaller.getNamespaceSeparator();
    }
   
    /**
     * INTERNAL:
     * The optional fragment used to wrap the text() mappings
     * @since 2.4
     */
    public XPathFragment getTextWrapperFragment() {
        return textWrapperFragment;
    }

    protected void writeKey(XPathFragment xPathFragment) throws IOException {
        super.openStartElement(xPathFragment, namespaceResolver);
        isStartElementOpen = true;
        writer.write('"');
        if(xPathFragment.isAttribute() && attributePrefix != null){
            writer.write(attributePrefix);
        }

        if(isNamespaceAware()){
            if(xPathFragment.getNamespaceURI() != null){
                String prefix = null;
                if(getNamespaceResolver() !=null){
                    prefix = getNamespaceResolver().resolveNamespaceURI(xPathFragment.getNamespaceURI());
                } else if(namespaceResolver != null){
                    prefix = namespaceResolver.resolveNamespaceURI(xPathFragment.getNamespaceURI());
                }
                if(prefix != null && !prefix.equals(XMLConstants.EMPTY_STRING)){
                    writer.write(prefix);
                    writer.write(getNamespaceSeparator());
                }
            }
        }

        writer.write(xPathFragment.getLocalName());
        writer.write("\"");
        writer.write(space);
        writer.write(XMLConstants.COLON);
        writer.write(space);       
    }

    /**
     * INTERNAL:
     */
    protected void writeValue(String value, boolean isAttribute) {
        try {                      
               if (characterEscapeHandler != null) {
                   try {
                     characterEscapeHandler.escape(value.toCharArray(), 0, value.length(), isAttribute, writer);
                   } catch (IOException e) {
                       throw XMLMarshalException.marshalException(e);
                   }
                   return;
               }
         
            char[] chars = value.toCharArray();
              for (int x = 0, charsSize = chars.length; x < charsSize; x++) {
                  char character = chars[x];
                  switch (character){
                      case '"' : {
                          writer.write("\\\"");
                          break;
                      }
                      case '\b': {
                          writer.write("\\");
                          writer.write("b");
                          break;
                      }
                      case '\f': {
                          writer.write("\\");
                          writer.write("f");
                          break;
                      }
                      case '\n': {
                          writer.write("\\");
                          writer.write("n");
                          break;
                      }
                      case '\r': {
                          writer.write("\\");
                          writer.write("r");
                          break;
                      }
                      case '\t': {
                          writer.write("\\");
                          writer.write("t");
                          break;
                      }
                      case '\\': {
                          writer.write("\\");
                          writer.write("\\");
                          break;
                      }
                      default: {
                          if(Character.isISOControl(character) || !encoder.canEncode(character)){
                              writer.write("\\u");
                              String hex = Integer.toHexString(character).toUpperCase();
                              for(int i=hex.length(); i<4; i++){
                                  writer.write("0");
                              }
                              writer.write(hex);
                          }else{
                              writer.write(character);
                          }
                      }
                  }
              }
        } catch (IOException e) {
            throw XMLMarshalException.marshalException(e);
        }
    }
   
    protected String getStringForQName(QName qName){
        if(null == qName) {
            return null;
        }
        XMLConversionManager xmlConversionManager = (XMLConversionManager) getSession().getDatasourcePlatform().getConversionManager();

        return (String) xmlConversionManager.convertObject(qName, String.class);      
    }

    /**
     * Receive notification of a node.
     * @param node The Node to be added to the document
     * @param namespaceResolver The NamespaceResolver can be used to resolve the
     * namespace URI/prefix of the node
     */
    public void node(Node node, NamespaceResolver namespaceResolver) {
        if (node.getNodeType() == Node.ATTRIBUTE_NODE) {
            Attr attr = (Attr) node;
            String resolverPfx = null;
            if (getNamespaceResolver() != null) {
                resolverPfx = this.getNamespaceResolver().resolveNamespaceURI(attr.getNamespaceURI());
            }
            String namespaceURI = attr.getNamespaceURI();
            // If the namespace resolver contains a prefix for the attribute's URI,
            // use it instead of what is set on the attribute
            if (resolverPfx != null) {
                attribute(attr.getNamespaceURI(), XMLConstants.EMPTY_STRING, resolverPfx+XMLConstants.COLON+attr.getLocalName(), attr.getNodeValue());
            } else {
                attribute(attr.getNamespaceURI(), XMLConstants.EMPTY_STRING, attr.getName(), attr.getNodeValue());
                // May need to declare the URI locally
                if (attr.getNamespaceURI() != null) {
                    attribute(XMLConstants.XMLNS_URL, XMLConstants.EMPTY_STRING,XMLConstants.XMLNS + XMLConstants.COLON + attr.getPrefix(), attr.getNamespaceURI());
                    this.getNamespaceResolver().put(attr.getPrefix(), attr.getNamespaceURI());
                }
            }
        } else if (node.getNodeType() == Node.TEXT_NODE) {
          characters(node.getNodeValue(), false, false);
        } else {
            try {
              JSONWriterRecordContentHandler wrcHandler = new JSONWriterRecordContentHandler();
             
                XMLFragmentReader xfragReader = new XMLFragmentReader(namespaceResolver);
                xfragReader.setContentHandler(wrcHandler);
                xfragReader.setProperty("http://xml.org/sax/properties/lexical-handler", wrcHandler);
                xfragReader.parse(node);
            } catch (SAXException sex) {
                throw XMLMarshalException.marshalException(sex);
            }
        }
    }

    /**
     * This class will typically be used in conjunction with an XMLFragmentReader.
     * The XMLFragmentReader will walk a given XMLFragment node and report events
     * to this class - the event's data is then written to the enclosing class'
     * writer.
     *
     * @see org.eclipse.persistence.internal.oxm.record.XMLFragmentReader
     */
    protected class JSONWriterRecordContentHandler implements ExtendedContentHandler, LexicalHandler {

      JSONWriterRecordContentHandler() {
        }

        // --------------------- CONTENTHANDLER METHODS --------------------- //
        public void startElement(String namespaceURI, String localName, String qName, Attributes atts) throws SAXException {
              XPathFragment xPathFragment = new XPathFragment(localName);
              xPathFragment.setNamespaceURI(namespaceURI);
              openStartElement(xPathFragment, namespaceResolver);
        }

        public void endElement(String namespaceURI, String localName, String qName) throws SAXException {
          XPathFragment xPathFragment = new XPathFragment(localName);
          xPathFragment.setNamespaceURI(namespaceURI);
         
          JSONWriterRecord.this.endElement(xPathFragment, namespaceResolver);       
        }

        public void startPrefixMapping(String prefix, String uri) throws SAXException {
        }

        public void characters(char[] ch, int start, int length) throws SAXException {
            String characters = new String (ch, start, length);
            characters(characters);
        }

        public void characters(CharSequence characters) throws SAXException {         
          JSONWriterRecord.this.characters(characters.toString());     
        }

        // --------------------- LEXICALHANDLER METHODS --------------------- //
        public void comment(char[] ch, int start, int length) throws SAXException {
        }

        public void startCDATA() throws SAXException {
            isProcessingCData = true;
        }

        public void endCDATA() throws SAXException {
            isProcessingCData = false;
        }

        // --------------------- CONVENIENCE METHODS --------------------- //
           protected void handleAttributes(Attributes atts) {
            for (int i=0, attsLength = atts.getLength(); i<attsLength; i++) {
                String qName = atts.getQName(i);
                if((qName != null && (qName.startsWith(XMLConstants.XMLNS + XMLConstants.COLON) || qName.equals(XMLConstants.XMLNS)))) {
                    continue;
                }
                attribute(atts.getURI(i), atts.getLocalName(i), qName, atts.getValue(i));
            }
        }

        protected void writeComment(char[] chars, int start, int length) {       
        }
      
        protected void writeCharacters(char[] chars, int start, int length) {
          try {
        characters(chars, start, length);
      } catch (SAXException e) {
                throw XMLMarshalException.marshalException(e);
      }          
        }
        // --------------- SATISFY CONTENTHANDLER INTERFACE --------------- //
        public void endPrefixMapping(String prefix) throws SAXException {}
        public void processingInstruction(String target, String data) throws SAXException {}
        public void setDocumentLocator(Locator locator) {}
        public void startDocument() throws SAXException {}
        public void endDocument() throws SAXException {}
        public void skippedEntity(String name) throws SAXException {}
        public void ignorableWhitespace(char[] ch, int start, int length) throws SAXException {}

        // --------------- SATISFY LEXICALHANDLER INTERFACE --------------- //
        public void startEntity(String name) throws SAXException {}
        public void endEntity(String name) throws SAXException {}
        public void startDTD(String name, String publicId, String systemId) throws SAXException {}
        public void endDTD() throws SAXException {}

    }

    /**
     * Instances of this class are used to maintain state about the current
     * level of the JSON message being marshalled.
     */
    protected static class Level {

        private boolean first;
        private boolean collection;
        private boolean emptyCollection;
        private boolean needToOpenComplex;
        private boolean needToCloseComplex;
        public Level(boolean value, boolean needToOpen) {
            this.first = value;
            needToOpenComplex = needToOpen;
        }

        public boolean isNeedToOpenComplex() {
            return needToOpenComplex;
        }

        public void setNeedToOpenComplex(boolean needToOpenComplex) {
            this.needToOpenComplex = needToOpenComplex;
        }

        public boolean isNeedToCloseComplex() {
            return needToCloseComplex;
        }

        public void setNeedToCloseComplex(boolean needToCloseComplex) {
            this.needToCloseComplex = needToCloseComplex;
        }

        public boolean isEmptyCollection() {
            return emptyCollection;
        }

        public void setEmptyCollection(boolean emptyCollection) {
            this.emptyCollection = emptyCollection;
        }

        public boolean isFirst() {
            return first;
        }

        public void setFirst(boolean value) {
            this.first = value;
        }

        public boolean isCollection() {
            return collection;
        }

        public void setCollection(boolean collection) {
            this.collection = collection;
        }
    }

}
TOP

Related Classes of org.eclipse.persistence.oxm.record.JSONWriterRecord$JSONWriterRecordContentHandler

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.