Package org.hibernate.service.internal

Source Code of org.hibernate.service.internal.JaxbProcessor$ContextProvidingValidationEventHandler

/*
* Hibernate, Relational Persistence for Idiomatic Java
*
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
* indicated by the @author tags or express copyright attribution
* statements applied by the authors.  All third-party contributions are
* distributed under license by Red Hat Inc.
*
* This copyrighted material is made available to anyone wishing to use, modify,
* copy, or redistribute it subject to the terms and conditions of the GNU
* Lesser General Public License, as published by the Free Software Foundation.
*
* This program 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 distribution; if not, write to:
* Free Software Foundation, Inc.
* 51 Franklin Street, Fifth Floor
* Boston, MA  02110-1301  USA
*/
package org.hibernate.service.internal;

import javax.xml.XMLConstants;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.JAXBException;
import javax.xml.bind.Unmarshaller;
import javax.xml.bind.ValidationEvent;
import javax.xml.bind.ValidationEventHandler;
import javax.xml.bind.ValidationEventLocator;
import javax.xml.stream.XMLInputFactory;
import javax.xml.stream.XMLStreamException;
import javax.xml.stream.XMLStreamReader;
import javax.xml.transform.stream.StreamSource;
import javax.xml.validation.Schema;
import javax.xml.validation.SchemaFactory;
import java.io.IOException;
import java.io.InputStream;
import java.net.URL;

import org.jboss.logging.Logger;
import org.xml.sax.SAXException;

import org.hibernate.internal.jaxb.Origin;
import org.hibernate.internal.util.config.ConfigurationException;
import org.hibernate.metamodel.source.MappingException;
import org.hibernate.metamodel.source.XsdException;
import org.hibernate.internal.jaxb.cfg.JaxbHibernateConfiguration;
import org.hibernate.service.classloading.spi.ClassLoaderService;

/**
* @author Steve Ebersole
*/
public class JaxbProcessor {
  private static final Logger log = Logger.getLogger( JaxbProcessor.class );

  private final ClassLoaderService classLoaderService;

  public JaxbProcessor(ClassLoaderService classLoaderService) {
    this.classLoaderService = classLoaderService;
  }

  public JaxbHibernateConfiguration unmarshal(InputStream stream, Origin origin) {
    try {
      XMLStreamReader staxReader = staxFactory().createXMLStreamReader( stream );
      try {
        return unmarshal( staxReader, origin );
      }
      finally {
        try {
          staxReader.close();
        }
        catch ( Exception ignore ) {
        }
      }
    }
    catch ( XMLStreamException e ) {
      throw new MappingException( "Unable to create stax reader", e, origin );
    }
  }

  private XMLInputFactory staxFactory;

  private XMLInputFactory staxFactory() {
    if ( staxFactory == null ) {
      staxFactory = buildStaxFactory();
    }
    return staxFactory;
  }

  @SuppressWarnings( { "UnnecessaryLocalVariable" })
  private XMLInputFactory buildStaxFactory() {
    XMLInputFactory staxFactory = XMLInputFactory.newInstance();
    return staxFactory;
  }

  @SuppressWarnings( { "unchecked" })
  private JaxbHibernateConfiguration unmarshal(XMLStreamReader staxReader, final Origin origin) {
    final Object target;
    final ContextProvidingValidationEventHandler handler = new ContextProvidingValidationEventHandler();
    try {
      JAXBContext jaxbContext = JAXBContext.newInstance( JaxbHibernateConfiguration.class );
      Unmarshaller unmarshaller = jaxbContext.createUnmarshaller();
      unmarshaller.setSchema( schema() );
      unmarshaller.setEventHandler( handler );
      target = unmarshaller.unmarshal( staxReader );
      return (JaxbHibernateConfiguration) target;
    }
    catch ( JAXBException e ) {
      StringBuilder builder = new StringBuilder();
      builder.append( "Unable to perform unmarshalling at line number " )
          .append( handler.getLineNumber() )
          .append( " and column " )
          .append( handler.getColumnNumber() )
          .append( " in " ).append( origin.getType().name() ).append( " " ).append( origin.getName() )
          .append( ". Message: " )
          .append( handler.getMessage() );
      throw new ConfigurationException( builder.toString(), e );
    }
  }

  private Schema schema;

  private Schema schema() {
    if ( schema == null ) {
      schema = resolveLocalSchema( "/org/hibernate/hibernate-configuration-4.0.xsd" );
    }
    return schema;
  }

  private Schema resolveLocalSchema(String schemaName) {
    return resolveLocalSchema( schemaName, XMLConstants.W3C_XML_SCHEMA_NS_URI );
  }

  private Schema resolveLocalSchema(String schemaName, String schemaLanguage) {
    URL url = classLoaderService.locateResource( schemaName );
    if ( url == null ) {
      throw new XsdException( "Unable to locate schema [" + schemaName + "] via classpath", schemaName );
    }
    try {
      InputStream schemaStream = url.openStream();
      try {
        StreamSource source = new StreamSource( url.openStream() );
        SchemaFactory schemaFactory = SchemaFactory.newInstance( schemaLanguage );
        return schemaFactory.newSchema( source );
      }
      catch ( SAXException e ) {
        throw new XsdException( "Unable to load schema [" + schemaName + "]", e, schemaName );
      }
      catch ( IOException e ) {
        throw new XsdException( "Unable to load schema [" + schemaName + "]", e, schemaName );
      }
      finally {
        try {
          schemaStream.close();
        }
        catch ( IOException e ) {
          log.debugf( "Problem closing schema stream [%s]", e.toString() );
        }
      }
    }
    catch ( IOException e ) {
      throw new XsdException( "Stream error handling schema url [" + url.toExternalForm() + "]", schemaName );
    }
  }

  static class ContextProvidingValidationEventHandler implements ValidationEventHandler {
    private int lineNumber;
    private int columnNumber;
    private String message;

    @Override
    public boolean handleEvent(ValidationEvent validationEvent) {
      ValidationEventLocator locator = validationEvent.getLocator();
      lineNumber = locator.getLineNumber();
      columnNumber = locator.getColumnNumber();
      message = validationEvent.getMessage();
      return false;
    }

    public int getLineNumber() {
      return lineNumber;
    }

    public int getColumnNumber() {
      return columnNumber;
    }

    public String getMessage() {
      return message;
    }
  }
}
TOP

Related Classes of org.hibernate.service.internal.JaxbProcessor$ContextProvidingValidationEventHandler

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.