package org.hibernate.boot.cfgxml.spi;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import org.hibernate.boot.CacheRegionDefinition;
import org.hibernate.boot.jaxb.cfg.spi.JaxbCfgCollectionCacheType;
import org.hibernate.boot.jaxb.cfg.spi.JaxbCfgConfigPropertyType;
import org.hibernate.boot.jaxb.cfg.spi.JaxbCfgEntityCacheType;
import org.hibernate.boot.jaxb.cfg.spi.JaxbCfgEventListenerGroupType;
import org.hibernate.boot.jaxb.cfg.spi.JaxbCfgEventListenerType;
import org.hibernate.boot.jaxb.cfg.spi.JaxbCfgHibernateConfiguration;
import org.hibernate.boot.jaxb.cfg.spi.JaxbCfgMappingReferenceType;
import org.hibernate.event.spi.EventType;
import org.hibernate.secure.spi.GrantedPermission;
import org.hibernate.secure.spi.JaccPermissionDeclarations;
import org.jboss.logging.Logger;
public class LoadedConfig {
private static final Logger log = Logger.getLogger( LoadedConfig.class );
private String sessionFactoryName;
private final Map configurationValues = new ConcurrentHashMap( 16, 0.75f, 1 );
private Map<String,JaccPermissionDeclarations> jaccPermissionsByContextId;
private List<CacheRegionDefinition> cacheRegionDefinitions;
private List<MappingReference> mappingReferences;
private Map<EventType,Set<String>> eventListenerMap;
private LoadedConfig(String sessionFactoryName) {
this.sessionFactoryName = sessionFactoryName;
}
public String getSessionFactoryName() {
return sessionFactoryName;
}
public Map getConfigurationValues() {
return configurationValues;
}
public Map<String, JaccPermissionDeclarations> getJaccPermissionsByContextId() {
return jaccPermissionsByContextId;
}
public JaccPermissionDeclarations getJaccPermissions(String jaccContextId) {
return jaccPermissionsByContextId.get( jaccContextId );
}
public List<CacheRegionDefinition> getCacheRegionDefinitions() {
return cacheRegionDefinitions == null ? Collections.<CacheRegionDefinition>emptyList() : cacheRegionDefinitions;
}
public List<MappingReference> getMappingReferences() {
return mappingReferences == null ? Collections.<MappingReference>emptyList() : mappingReferences;
}
public Map<EventType, Set<String>> getEventListenerMap() {
return eventListenerMap == null ? Collections.<EventType, Set<String>>emptyMap() : eventListenerMap;
}
public static LoadedConfig consume(JaxbCfgHibernateConfiguration jaxbCfg) {
final LoadedConfig cfg = new LoadedConfig( jaxbCfg.getSessionFactory().getName() );
for ( JaxbCfgConfigPropertyType jaxbProperty : jaxbCfg.getSessionFactory().getProperty() ) {
cfg.addConfigurationValue( jaxbProperty.getName(), jaxbProperty.getValue() );
}
for ( JaxbCfgMappingReferenceType jaxbMapping : jaxbCfg.getSessionFactory().getMapping() ) {
cfg.addMappingReference( MappingReference.consume( jaxbMapping ) );
}
for ( Object cacheDeclaration : jaxbCfg.getSessionFactory().getClassCacheOrCollectionCache() ) {
cfg.addCacheRegionDefinition( parseCacheRegionDefinition( cacheDeclaration ) );
}
if ( jaxbCfg.getSecurity() != null ) {
for ( JaxbCfgHibernateConfiguration.JaxbCfgSecurity.JaxbCfgGrant grant : jaxbCfg.getSecurity().getGrant() ) {
final JaccPermissionDeclarations jaccPermissions = cfg.getOrCreateJaccPermissions(
jaxbCfg.getSecurity()
.getContext()
);
jaccPermissions.addPermissionDeclaration(
new GrantedPermission(
grant.getRole(),
grant.getEntityName(),
grant.getActions()
)
);
}
}
if ( !jaxbCfg.getSessionFactory().getListener().isEmpty() ) {
for ( JaxbCfgEventListenerType listener : jaxbCfg.getSessionFactory().getListener() ) {
final EventType eventType = EventType.resolveEventTypeByName( listener.getType().value() );
cfg.addEventListener( eventType, listener.getClazz() );
}
}
if ( !jaxbCfg.getSessionFactory().getEvent().isEmpty() ) {
for ( JaxbCfgEventListenerGroupType listenerGroup : jaxbCfg.getSessionFactory().getEvent() ) {
if ( listenerGroup.getListener().isEmpty() ) {
continue;
}
final String eventTypeName = listenerGroup.getType().value();
final EventType eventType = EventType.resolveEventTypeByName( eventTypeName );
for ( JaxbCfgEventListenerType listener : listenerGroup.getListener() ) {
if ( listener.getType() != null ) {
log.debugf( "Listener [%s] defined as part of a group also defined event type", listener.getClazz() );
}
cfg.addEventListener( eventType, listener.getClazz() );
}
}
}
return cfg;
}
private static String trim(String value) {
if ( value == null ) {
return null;
}
return value.trim();
}
@SuppressWarnings("unchecked")
private void addConfigurationValue(String propertyName, String value) {
value = trim( value );
configurationValues.put( propertyName, value );
if ( !propertyName.startsWith( "hibernate." ) ) {
configurationValues.put( "hibernate." + propertyName, value );
}
}
private void addMappingReference(MappingReference mappingReference) {
if ( mappingReferences == null ) {
mappingReferences = new ArrayList<MappingReference>();
}
mappingReferences.add( mappingReference );
}
private static CacheRegionDefinition parseCacheRegionDefinition(Object cacheDeclaration) {
if ( JaxbCfgEntityCacheType.class.isInstance( cacheDeclaration ) ) {
final JaxbCfgEntityCacheType jaxbClassCache = (JaxbCfgEntityCacheType) cacheDeclaration;
return new CacheRegionDefinition(
CacheRegionDefinition.CacheRegionType.ENTITY,
jaxbClassCache.getClazz(),
jaxbClassCache.getUsage().value(),
jaxbClassCache.getRegion(),
"all".equals( jaxbClassCache.getInclude() )
);
}
else {
final JaxbCfgCollectionCacheType jaxbCollectionCache = (JaxbCfgCollectionCacheType) cacheDeclaration;
return new CacheRegionDefinition(
CacheRegionDefinition.CacheRegionType.COLLECTION,
jaxbCollectionCache.getCollection(),
jaxbCollectionCache.getUsage().value(),
jaxbCollectionCache.getRegion(),
false
);
}
}
public void addCacheRegionDefinition(CacheRegionDefinition cacheRegionDefinition) {
if ( cacheRegionDefinitions == null ) {
cacheRegionDefinitions = new ArrayList<CacheRegionDefinition>();
}
cacheRegionDefinitions.add( cacheRegionDefinition );
}
public void addEventListener(EventType eventType, String listenerClass) {
if ( eventListenerMap == null ) {
eventListenerMap = new HashMap<EventType, Set<String>>();
}
Set<String> listenerClasses = eventListenerMap.get( eventType );
if ( listenerClasses == null ) {
listenerClasses = new HashSet<String>();
eventListenerMap.put( eventType, listenerClasses );
}
listenerClasses.add( listenerClass );
}
public JaccPermissionDeclarations getOrCreateJaccPermissions(String contextId) {
if ( jaccPermissionsByContextId == null ) {
jaccPermissionsByContextId = new HashMap<String, JaccPermissionDeclarations>();
}
JaccPermissionDeclarations jaccPermission = jaccPermissionsByContextId.get( contextId );
if ( jaccPermission == null ) {
jaccPermission = new JaccPermissionDeclarations( contextId );
}
jaccPermissionsByContextId.put( contextId, jaccPermission );
return jaccPermission;
}
public void merge(LoadedConfig incoming) {
if ( sessionFactoryName != null ) {
if ( incoming.getSessionFactoryName() != null ) {
log.debugf(
"More than one cfg.xml file attempted to supply SessionFactory name: [%s], [%s]. Keeping initially discovered one [%s]",
getSessionFactoryName(),
incoming.getSessionFactoryName(),
getSessionFactoryName()
);
}
}
else {
sessionFactoryName = incoming.getSessionFactoryName();
}
addConfigurationValues( incoming.getConfigurationValues() );
addMappingReferences( incoming.getMappingReferences() );
addCacheRegionDefinitions( incoming.getCacheRegionDefinitions() );
addJaccPermissions( incoming.getJaccPermissionsByContextId() );
addEventListeners( incoming.getEventListenerMap() );
}
@SuppressWarnings("unchecked")
private void addConfigurationValues(Map configurationValues) {
if ( configurationValues == null ) {
return;
}
this.configurationValues.putAll( configurationValues );
}
private void addMappingReferences(List<MappingReference> mappingReferences) {
if ( mappingReferences == null ) {
return;
}
if ( this.mappingReferences == null ) {
this.mappingReferences = new ArrayList<MappingReference>();
}
this.mappingReferences.addAll( mappingReferences );
}
private void addCacheRegionDefinitions(List<CacheRegionDefinition> cacheRegionDefinitions) {
if ( cacheRegionDefinitions == null ) {
return;
}
if ( this.cacheRegionDefinitions == null ) {
this.cacheRegionDefinitions = new ArrayList<CacheRegionDefinition>();
}
this.cacheRegionDefinitions.addAll( cacheRegionDefinitions );
}
private void addJaccPermissions(Map<String, JaccPermissionDeclarations> jaccPermissionsByContextId) {
if ( jaccPermissionsByContextId == null ) {
return;
}
if ( this.jaccPermissionsByContextId == null ) {
this.jaccPermissionsByContextId = new HashMap<String, JaccPermissionDeclarations>();
}
for ( Map.Entry<String, JaccPermissionDeclarations> incomingEntry : jaccPermissionsByContextId.entrySet() ) {
JaccPermissionDeclarations permissions = jaccPermissionsByContextId.get( incomingEntry.getKey() );
if ( permissions == null ) {
permissions = new JaccPermissionDeclarations( incomingEntry.getKey() );
this.jaccPermissionsByContextId.put( incomingEntry.getKey(), permissions );
}
permissions.addPermissionDeclarations( incomingEntry.getValue().getPermissionDeclarations() );
}
}
private void addEventListeners(Map<EventType, Set<String>> eventListenerMap) {
if ( eventListenerMap == null ) {
return;
}
if ( this.eventListenerMap == null ) {
this.eventListenerMap = new HashMap<EventType, Set<String>>();
}
for ( Map.Entry<EventType, Set<String>> incomingEntry : eventListenerMap.entrySet() ) {
Set<String> listenerClasses = this.eventListenerMap.get( incomingEntry.getKey() );
if ( listenerClasses == null ) {
listenerClasses = new HashSet<String>();
this.eventListenerMap.put( incomingEntry.getKey(), listenerClasses );
}
listenerClasses.addAll( incomingEntry.getValue() );
}
}
public static LoadedConfig baseline() {
return new LoadedConfig( null );
}
}