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

com.sun.xml.bind.unmarshaller.SAXUnmarshallerHandlerImpl Maven / Gradle / Ivy

There is a newer version: 4.0.5
Show newest version
/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2011 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package com.sun.xml.bind.unmarshaller;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.Iterator;
import java.util.List;
import java.util.Stack;
import java.util.StringTokenizer;

import javax.xml.XMLConstants;
import javax.xml.bind.JAXBException;
import javax.xml.bind.UnmarshalException;
import javax.xml.bind.ValidationEvent;

import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.xml.sax.SAXParseException;

import com.sun.xml.bind.TypeRegistry;
import com.sun.xml.bind.util.AttributesImpl;

/**
 * Implementation of {@link UnmarshallerHandler}.
 * 
 * This object converts SAX events into unmarshaller events and
 * cooridnates the entire unmarshalling process.
 *
 * @author
 *  =0; i-=2 ) {
            if(prefix.equals(nsBind[i]))
                return nsBind[i+1];
        }
        return null;
    }
    //
    //  NamespaceContext2 implementation 
    //
    public Iterator getPrefixes(String uri) {
        // TODO: could be implemented much faster
        // wrap it into unmodifiable list so that the remove method
        // will throw UnsupportedOperationException.
        return Collections.unmodifiableList(
            getAllPrefixesInList(uri)).iterator();
    }
    
    private List getAllPrefixesInList(String uri) {
        List a = new ArrayList();
        
        if( uri.equals(XMLConstants.XML_NS_URI) ) {
            a.add(XMLConstants.XML_NS_PREFIX);
            return a;
        }
        if( uri.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI) ) {
            a.add(XMLConstants.XMLNS_ATTRIBUTE);
            return a;
        }
        if( uri==null )
            throw new IllegalArgumentException();
          
        for( int i=nsLen-2; i>=0; i-=2 )
            if(uri.equals(nsBind[i+1]))
                if( getNamespaceURI(nsBind[i]).equals(nsBind[i+1]) )
                    // make sure that this prefix is still effective.
                    a.add(nsBind[i]);
         
        return a;
    }

    public String getPrefix(String uri) {
        if( uri.equals(XMLConstants.XML_NS_URI) )
            return XMLConstants.XML_NS_PREFIX;
        if( uri.equals(XMLConstants.XMLNS_ATTRIBUTE_NS_URI) )
            return XMLConstants.XMLNS_ATTRIBUTE;
        if( uri==null )
            throw new IllegalArgumentException();
          
        for( int i=idxStack[idxStackTop]-2; i>=0; i-=2 )
            if(uri.equals(nsBind[i+1]))
                if( getNamespaceURI(nsBind[i]).equals(nsBind[i+1]) )
                    // make sure that this prefix is still effective.
                    return nsBind[i];
         
        return null;
    }

     public String getNamespaceURI(String prefix) {
         if( prefix.equals(XMLConstants.XMLNS_ATTRIBUTE) )
             return XMLConstants.XMLNS_ATTRIBUTE_NS_URI;
         if( prefix==null )
             throw new IllegalArgumentException();
        
         return resolveNamespacePrefix(prefix);
     }

//
//
// Attribute handling
//
//
    // TODO: implementation can be more efficient
    private final Stack attStack = new Stack();
    
    public void pushAttributes( Attributes atts ) {
        // since Attributes object is mutable, it is criticall important
        // to make a copy.
        // also symbolize attribute names
        AttributesImpl a = new AttributesImpl();
        for( int i=0; isome value is a valid fragment, however
        // we need a look ahead to correctly handle this case.
        // (because when we process @xsi:nil, we don't know what the value is,
        // and by the time we read "false", we can't cancel this attribute anymore.)
        //
        // as a quick workaround, we remove @xsi:nil if the value is false.
        int idx = a.getIndex("http://www.w3.org/2001/XMLSchema-instance","nil");
        if(idx!=-1) {
            String v = a.getValue(idx).trim();
            if(v.equals("false") || v.equals("0"))
                a.removeAttribute(idx);
        }
        
        attStack.push(a);
        
        // start a new namespace scope
        if( ++idxStackTop==idxStack.length ) {
            // reallocation
            int[] newBuf = new int[idxStack.length*2];
            System.arraycopy(idxStack,0,newBuf,0,idxStack.length);
            idxStack = newBuf;
        }
        idxStack[idxStackTop] = nsLen;
    }
    public void popAttributes() {
        attStack.pop();
        
        idxStackTop--;
    }
    public Attributes getUnconsumedAttributes() {
        return (Attributes)attStack.peek();
    }
    public int getAttribute( String uri, String local ) {
        // Consider a class that corresponds to the root element.
        // if this class has a transition from final state by an attribute,
        // then this attribute transitions are checked when the final
        // leaveElement event is consumed.
        //
        // to handle this case, return "not found" if there is no active
        // attribute scope
        if(attStack.isEmpty())  return -1;
        
        Attributes a = (Attributes)attStack.peek();
        
        return a.getIndex(uri,local);
    }
    public void consumeAttribute( int idx ) throws UnreportedException {
        AttributesImpl a = (AttributesImpl)attStack.peek();
        
        String uri = a.getURI(idx).intern();
        String local = a.getLocalName(idx).intern();
        String value = a.getValue(idx).intern();

        // mark the attribute as consumed
        // we need to remove the attribute before we process it
        // because the event handler might access attributes.
        a.removeAttribute(idx);
        
        
        getCurrentHandler().enterAttribute(uri,local);
        consumeText(value,false);
        getCurrentHandler().leaveAttribute(uri,local);
    }

//
//
// ID/IDREF related code
//
//
    /**
     * Submitted patchers in the order they've submitted.
     * Many XML vocabulary doesn't use ID/IDREF at all, so we
     * initialize it with null.
     */
    private Runnable[] patchers = null;
    private int patchersLen = 0;
    
    public void addPatcher( Runnable job ) {
        // re-allocate buffer if necessary
        if( patchers==null )
            patchers = new Runnable[32];
        if( patchers.length == patchersLen ) {
            Runnable[] buf = new Runnable[patchersLen*2];
            System.arraycopy(patchers,0,buf,0,patchersLen);
            patchers = buf;
        }
        patchers[patchersLen++] = job;
    }
    
    /** Executes all the patchers. */
    private void runPatchers() {
        if( patchers!=null ) {
            for( int i=0; iObject map. */
    private Hashtable idmap = null;

    public String addToIdTable( String id ) {
        if(idmap==null)     idmap = new Hashtable();
        idmap.put( id, getCurrentHandler().owner() );
        return id;
    }
    
    public UnmarshallableObject getObjectFromId( String id ) {
        if(idmap==null)     return null;
        return (UnmarshallableObject)idmap.get(id);
    }
    


//
//
// Other SAX callbacks
//
//
    public void skippedEntity( String name ) {
        // TODO: throw an exception, perhaps?
    }
    public void processingInstruction( String target, String data ) {
        // just ignore
    }
    public void setDocumentLocator( Locator loc ) {
        locator = loc;
    }
    public Locator getLocator() { return locator; }
    
    private Locator locator;


//
//
// error handling
//
//
    private final UnmarshallerImpl parent;
    private boolean aborted = false;
    
    public boolean handleEvent(ValidationEvent event) {
        try {
            // if the handler says "abort", we will not return
            // the object.
            boolean recover = parent.getEventHandler().handleEvent(event);
            if(!recover)    aborted = true;
            return recover;
        } catch( JAXBException e ) {
            // we are not allowed to throw an exception from this method.
            return false;
        } catch( RuntimeException re ) {
            // if client event handler causes a runtime exception, then we
            // have to return false.
            return false;
        }
    }
    
    public void reportAndThrow( UnreportedException e ) throws SAXException {
        handleEvent(e.createValidationEvent());
        
        // rewrap it into UnmarshalException.
        // we further re-wrap it into SAXException again so that
        // it can be tunneled through SAX Parser.
        throw new SAXException( e.createUnmarshalException() );
    }
  
//
//
// ValidationContext implementation
//
//
    public String getBaseUri() { return null; }
    public boolean isUnparsedEntity(String s) { return true; }
    public boolean isNotation(String s) { return true; }


//
//
// debug trace methods
//
//
    private Tracer tracer;
    public void setTracer( Tracer t ) {
        this.tracer = t;
    }
    public Tracer getTracer() {
        if(tracer==null)
            tracer = new Tracer.Standard();
        return tracer;
    }
    

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy