HHH-12872 Reduce memory consumption of XSD schema validations
This commit is contained in:
parent
7da105be0a
commit
d67278a6d2
|
@ -6,74 +6,47 @@
|
|||
*/
|
||||
package org.hibernate.boot.xsd;
|
||||
|
||||
import org.jboss.logging.Logger;
|
||||
|
||||
/**
|
||||
* Support for XSD handling related to Hibernate's `cfg.xml` and
|
||||
* JPA's `persistence.xml`.
|
||||
* The implementation attempts to not load XsdDescriptor instances which are not
|
||||
* necessary and favours memory efficiency over CPU efficiency, as this is expected
|
||||
* to be used only during bootstrap.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
* @author Sanne Grinovero
|
||||
*/
|
||||
@SuppressWarnings("unused")
|
||||
public class ConfigXsdSupport {
|
||||
private static final Logger log = Logger.getLogger( ConfigXsdSupport.class );
|
||||
|
||||
/**
|
||||
* Singleton access
|
||||
* Needs synchronization on any access.
|
||||
* Custom keys:
|
||||
* 0: cfgXml
|
||||
* 1: JPA 1.0
|
||||
* 2: JPA 2.0
|
||||
* 3: JPA 2.1
|
||||
* 4: JPA 2.2
|
||||
*/
|
||||
public static final ConfigXsdSupport INSTANCE = new ConfigXsdSupport();
|
||||
|
||||
private ConfigXsdSupport() {
|
||||
//Do not construct new instances
|
||||
}
|
||||
|
||||
private final XsdDescriptor jpa10 = LocalXsdResolver.buildXsdDescriptor(
|
||||
"org/hibernate/jpa/persistence_1_0.xsd",
|
||||
"1.0",
|
||||
"http://java.sun.com/xml/ns/persistence"
|
||||
);
|
||||
|
||||
private final XsdDescriptor jpa20 = LocalXsdResolver.buildXsdDescriptor(
|
||||
"org/hibernate/jpa/persistence_2_0.xsd",
|
||||
"2.0" ,
|
||||
"http://java.sun.com/xml/ns/persistence"
|
||||
);
|
||||
|
||||
private final XsdDescriptor jpa21 = LocalXsdResolver.buildXsdDescriptor(
|
||||
"org/hibernate/jpa/persistence_2_1.xsd",
|
||||
"2.1",
|
||||
"http://xmlns.jcp.org/xml/ns/persistence"
|
||||
);
|
||||
|
||||
private final XsdDescriptor jpa22 = LocalXsdResolver.buildXsdDescriptor(
|
||||
"org/hibernate/jpa/persistence_2_2.xsd",
|
||||
"2.2" ,
|
||||
"http://xmlns.jcp.org/xml/ns/persistence"
|
||||
);
|
||||
|
||||
private final XsdDescriptor cfgXml = LocalXsdResolver.buildXsdDescriptor(
|
||||
"org/hibernate/xsd/cfg/legacy-configuration-4.0.xsd",
|
||||
"4.0" ,
|
||||
"http://www.hibernate.org/xsd/orm/cfg"
|
||||
);
|
||||
private static final XsdDescriptor[] xsdCache = new XsdDescriptor[5];
|
||||
|
||||
public XsdDescriptor latestJpaDescriptor() {
|
||||
return jpa22;
|
||||
return getJPA22();
|
||||
}
|
||||
|
||||
public XsdDescriptor jpaXsd(String version) {
|
||||
switch ( version ) {
|
||||
case "1.0": {
|
||||
return jpa10;
|
||||
return getJPA10();
|
||||
}
|
||||
case "2.0": {
|
||||
return jpa20;
|
||||
return getJPA20();
|
||||
}
|
||||
case "2.1": {
|
||||
return jpa21;
|
||||
return getJPA21();
|
||||
}
|
||||
case "2.2": {
|
||||
return jpa22;
|
||||
return getJPA22();
|
||||
}
|
||||
default: {
|
||||
throw new IllegalArgumentException( "Unrecognized JPA persistence.xml XSD version : `" + version + "`" );
|
||||
|
@ -82,6 +55,83 @@ public class ConfigXsdSupport {
|
|||
}
|
||||
|
||||
public XsdDescriptor cfgXsd() {
|
||||
final int index = 0;
|
||||
synchronized ( xsdCache ) {
|
||||
XsdDescriptor cfgXml = xsdCache[index];
|
||||
if ( cfgXml == null ) {
|
||||
cfgXml = LocalXsdResolver.buildXsdDescriptor(
|
||||
"org/hibernate/xsd/cfg/legacy-configuration-4.0.xsd",
|
||||
"4.0" ,
|
||||
"http://www.hibernate.org/xsd/orm/cfg"
|
||||
);
|
||||
xsdCache[index] = cfgXml;
|
||||
}
|
||||
return cfgXml;
|
||||
}
|
||||
}
|
||||
|
||||
private XsdDescriptor getJPA10() {
|
||||
final int index = 1;
|
||||
synchronized ( xsdCache ) {
|
||||
XsdDescriptor jpa10 = xsdCache[index];
|
||||
if ( jpa10 == null ) {
|
||||
jpa10 = LocalXsdResolver.buildXsdDescriptor(
|
||||
"org/hibernate/jpa/persistence_1_0.xsd",
|
||||
"1.0",
|
||||
"http://java.sun.com/xml/ns/persistence"
|
||||
);
|
||||
xsdCache[index] = jpa10;
|
||||
}
|
||||
return jpa10;
|
||||
}
|
||||
}
|
||||
|
||||
private XsdDescriptor getJPA20() {
|
||||
final int index = 2;
|
||||
synchronized ( xsdCache ) {
|
||||
XsdDescriptor jpa20 = xsdCache[index];
|
||||
if ( jpa20 == null ) {
|
||||
jpa20 = LocalXsdResolver.buildXsdDescriptor(
|
||||
"org/hibernate/jpa/persistence_2_0.xsd",
|
||||
"2.0" ,
|
||||
"http://java.sun.com/xml/ns/persistence"
|
||||
);
|
||||
xsdCache[index] = jpa20;
|
||||
}
|
||||
return jpa20;
|
||||
}
|
||||
}
|
||||
|
||||
private XsdDescriptor getJPA21() {
|
||||
final int index = 3;
|
||||
synchronized ( xsdCache ) {
|
||||
XsdDescriptor jpa21 = xsdCache[index];
|
||||
if ( jpa21 == null ) {
|
||||
jpa21 = LocalXsdResolver.buildXsdDescriptor(
|
||||
"org/hibernate/jpa/persistence_2_1.xsd",
|
||||
"2.1",
|
||||
"http://xmlns.jcp.org/xml/ns/persistence"
|
||||
);
|
||||
xsdCache[index] = jpa21;
|
||||
}
|
||||
return jpa21;
|
||||
}
|
||||
}
|
||||
|
||||
private XsdDescriptor getJPA22() {
|
||||
final int index = 4;
|
||||
synchronized ( xsdCache ) {
|
||||
XsdDescriptor jpa22 = xsdCache[index];
|
||||
if ( jpa22 == null ) {
|
||||
jpa22 = LocalXsdResolver.buildXsdDescriptor(
|
||||
"org/hibernate/jpa/persistence_2_2.xsd",
|
||||
"2.2",
|
||||
"http://xmlns.jcp.org/xml/ns/persistence"
|
||||
);
|
||||
xsdCache[index] = jpa22;
|
||||
}
|
||||
return jpa22;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -32,16 +32,21 @@ import org.xml.sax.SAXException;
|
|||
*/
|
||||
@SuppressWarnings("WeakerAccess")
|
||||
public class LocalXsdResolver {
|
||||
private static final Logger log = Logger.getLogger( LocalXsdResolver.class );
|
||||
|
||||
private static final List<String> VALID_JPA_VERSIONS = Arrays.asList( "1.0", "2.0", "2.1", "2.2" );
|
||||
|
||||
public static String latestJpaVerison() {
|
||||
return "2.2";
|
||||
}
|
||||
|
||||
public static boolean isValidJpaVersion(String version) {
|
||||
return VALID_JPA_VERSIONS.contains( version );
|
||||
switch ( version ) {
|
||||
case "1.0":
|
||||
case "2.0":
|
||||
case "2.1":
|
||||
case "2.2":
|
||||
return true;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static URL resolveLocalXsdUrl(String resourceName) {
|
||||
|
@ -98,7 +103,7 @@ public class LocalXsdResolver {
|
|||
schemaStream.close();
|
||||
}
|
||||
catch ( IOException e ) {
|
||||
log.debugf( "Problem closing schema stream [%s]", e.toString() );
|
||||
Logger.getLogger( LocalXsdResolver.class ).debugf( "Problem closing schema stream [%s]", e.toString() );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -464,7 +464,7 @@ public class PersistenceXmlParser {
|
|||
// todo : add ability to disable validation...
|
||||
|
||||
final String version = document.getDocumentElement().getAttribute( "version" );
|
||||
final Validator validator = ConfigXsdSupport.INSTANCE.jpaXsd( version ).getSchema().newValidator();
|
||||
final Validator validator = new ConfigXsdSupport().jpaXsd( version ).getSchema().newValidator();
|
||||
|
||||
List<SAXException> errors = new ArrayList<>();
|
||||
validator.setErrorHandler( new ErrorHandlerImpl( errors ) );
|
||||
|
|
Loading…
Reference in New Issue