All Downloads are FREE. Search and download functionalities are using the official Maven repository.

samples.typed.ConvertLexicalValues Maven / Gradle / Ivy

The newest version!
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 2004, 2023 Oracle and/or its affiliates. All rights reserved.
 *
 * Oracle 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
 *
 *      https://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.
 */

package samples.typed;

import com.sun.xml.analysis.types.SchemaProcessor;
import com.sun.xml.fastinfoset.types.XSDataType;
import com.sun.xml.fastinfoset.algorithm.BuiltInEncodingAlgorithmFactory;
import com.sun.xml.fastinfoset.sax.SAXDocumentParser;
import com.sun.xml.fastinfoset.sax.SAXDocumentSerializer;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.util.Map;
import java.util.Set;
import javax.xml.parsers.SAXParserFactory;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.stream.StreamResult;
import org.jvnet.fastinfoset.EncodingAlgorithmIndexes;
import org.jvnet.fastinfoset.FastInfosetSource;
import org.jvnet.fastinfoset.sax.PrimitiveTypeContentHandler;
import org.jvnet.fastinfoset.sax.helpers.EncodingAlgorithmAttributesImpl;
import org.jvnet.fastinfoset.sax.helpers.FastInfosetDefaultHandler;
import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLFilterImpl;

/**
 * Example of converting lexical values to primitive types for encoding
 * in binary form.
 *
 * @author [email protected]
 */
public class ConvertLexicalValues {
        
    static class LexicalFilter extends XMLFilterImpl {
        private Map> _elements;
        private Map> _attributes;
        private Set _textContent;
        
        public LexicalFilter(Map> elements, 
                Map> attributes) {
            _elements = elements;
            _attributes = attributes;
        }
        
        /*
         * Replace an the lexical value attribute with primitive data based
         * on the set of XS data type associated with the local name of the
         * attribute.
         */
        private void replaceAttributeValue(Set attributeTypes, 
                int index, EncodingAlgorithmAttributesImpl atts) {
            if (attributeTypes == null) return;
            
            char[] ch = atts.getValue(index).toCharArray();
            // Iterate through all possible types
            for (XSDataType dt : attributeTypes) {
                try {
                    // Switch on the type
                    switch(dt) {
                        case BASE64BINARY:
                            // Convert the lexical value to byte[]
                            byte[] b = (byte[])BuiltInEncodingAlgorithmFactory.
                                    base64EncodingAlgorithm.
                                    convertFromCharacters(ch, 0, ch.length);
                            // Replace the attribute value
                            atts.replaceWithAttributeAlgorithmData(index, 
                                    null, EncodingAlgorithmIndexes.BASE64, b);
                            return;
                        case FLOAT:
                            // Convert the lexical value to float[]
                            float[] f = (float[])BuiltInEncodingAlgorithmFactory.
                                    floatEncodingAlgorithm.
                                    convertFromCharacters(ch, 0, ch.length);
                            // Replace the attribute value
                            atts.replaceWithAttributeAlgorithmData(index, 
                                    null, EncodingAlgorithmIndexes.FLOAT, f);
                            return;
                        default:
                    }
                } catch (Exception e) {
                }
            }
            
        }
        
        @Override
        public void startElement(String uri, String localName, String qName,
                                 Attributes atts) throws SAXException {
            // Obtain the XS types associated with the local name of this 
            // element
            _textContent = _elements.get(localName);
            
            for (int i = 0; i < atts.getLength(); i++) {
                // Check if one or more attributes has a simple type associated with it
                if (_attributes.containsKey(atts.getLocalName(i))) {
                    // Copy the attributes
                    final EncodingAlgorithmAttributesImpl eatts = new EncodingAlgorithmAttributesImpl(atts);
                    
                    // Replace attribute lexical value with primitive types.
                    for (i = 0; i < atts.getLength(); i++) {
                        replaceAttributeValue(_attributes.get(atts.getLocalName(i)),
                                i, eatts);
                    }
                    
                    // Replace attributes passed to parent
                    atts = eatts;
                    break;
                }
            }

            // Pass event to parent
            super.startElement(uri, localName, qName, atts);
        }
        
        @Override
        public void characters (char ch[], int start, int length)
            throws SAXException {
            if (_textContent == null) {
                /*
                 * If there are no types associated with element 
                 * use the lexical value and defer to the parent.
                 */
                super.characters(ch, start, length);
                return;
            }

            // Iterate through all possible types
            for (XSDataType dt : _textContent) {
                try {
                    // Switch on the type
                    switch(dt) {
                        case BASE64BINARY:
                            // Convert the lexical value to byte[]
                            byte[] b = (byte[])BuiltInEncodingAlgorithmFactory.
                                    base64EncodingAlgorithm.
                                    convertFromCharacters(ch, start, length);
                            // Directly call the PrimitiveTypeContentHandler
                            ((PrimitiveTypeContentHandler)getContentHandler()).
                                    bytes(b, 0, b.length);
                            _textContent = null;
                            return;
                        case FLOAT:
                            // Convert the lexical value to float[]
                            float[] f = (float[])BuiltInEncodingAlgorithmFactory.
                                    floatEncodingAlgorithm.
                                    convertFromCharacters(ch, start, length);
                            // Directly call the PrimitiveTypeContentHandler
                            ((PrimitiveTypeContentHandler)getContentHandler()).
                                    floats(f, 0, f.length);
                            _textContent = null;
                            return;
                        default:
                    }
                } catch (Exception e) {
                    // If conversion failed try the next type
                }
            }
    
            /*
             * If all conversions failed use the lexical value
             * and defer to the parent.
             */
            super.characters(ch, start, length);
        }
    }
        
    /**
     * Parse an XML document and convert to an FI document while using the schema
     * to convert lexical values that are base64 or floating point values to
     * binary representations.
     * 

* Arg 0 is the path to the schema (XSD or RNG). *

* Arg 1 is the path to the XML document to be converted. *

*/ public static void main(String[] args) throws Exception { /* Process the schema to obtain a mapping of attribute/element local name to a set of XS data types. */ SchemaProcessor sp = new SchemaProcessor(new File(args[0]).toURI().toURL()); sp.process(); // Create an instance of the SAX document serializer SAXDocumentSerializer s = new SAXDocumentSerializer(); // Set the location of where the fast infoset document will be written ByteArrayOutputStream baos = new ByteArrayOutputStream(); s.setOutputStream(baos); /* * Create a lexical filter whose parent is a JAXP XMLReader. * Pass in the element/attribute local name to XS data type * maps to the constructor. */ LexicalFilter lf = new LexicalFilter(sp.getElementToXSDataTypeMap(), sp.getAttributeToXSDataTypeMap()); lf.setContentHandler(s); lf.setParent(getXMLReader()); // Parse the XML document to create a fast infoset document lf.parse(new InputSource(new FileInputStream(args[1]))); /* * Transform the fast infoset document to an XML document * using a FastInfosetSource and the transform API. */ FastInfosetSource source = new FastInfosetSource( new ByteArrayInputStream(baos.toByteArray())); StreamResult result = new StreamResult(System.out); TransformerFactory tf = TransformerFactory.newInstance(); Transformer t = tf.newTransformer(); t.transform(source, result); System.out.println(); /* * Parse the fast infoset document using a SAX document * parser. Register a PrimitiveContentHandler to access * binary data as arrays of primitives. */ SAXDocumentParser p = new SAXDocumentParser(); FastInfosetDefaultHandler h = new FastInfosetDefaultHandler() { @Override public void bytes(byte[] b, int start, int length) throws SAXException { System.out.println("Byte: " + b[start]); } @Override public void floats(float[] f, int start, int length) throws SAXException { System.out.println("Float: " + f[start]); } }; p.setContentHandler(h); p.setPrimitiveTypeContentHandler(h); p.parse(new ByteArrayInputStream(baos.toByteArray())); } public static XMLReader getXMLReader() throws Exception { SAXParserFactory spf = SAXParserFactory.newInstance(); spf.setNamespaceAware(true); return spf.newSAXParser().getXMLReader(); } }





© 2015 - 2025 Weber Informatics LLC | Privacy Policy