sascha@176: package de.intevation.flys.backend;
sascha@176: 
sascha@176: import de.intevation.artifacts.common.utils.Config;
sascha@176: 
ingo@2337: import java.lang.management.ManagementFactory;
sascha@176: import java.util.Properties;
sascha@176: 
ingo@2337: import javax.management.InstanceAlreadyExistsException;
ingo@2337: import javax.management.MalformedObjectNameException;
ingo@2337: import javax.management.MBeanRegistrationException;
ingo@2337: import javax.management.MBeanServer;
ingo@2337: import javax.management.NotCompliantMBeanException;
ingo@2337: import javax.management.ObjectName;
ingo@2337: 
sascha@176: import org.hibernate.SessionFactory;
sascha@176: 
ingo@2361: import org.hibernate.impl.SessionFactoryImpl;
ingo@2361: 
ingo@2337: import org.hibernate.jmx.StatisticsService;
ingo@2337: 
sascha@176: import org.hibernate.cfg.Configuration;
sascha@176: import org.hibernate.cfg.Environment;
sascha@176: 
sascha@176: import de.intevation.flys.model.Annotation;
sascha@763: import de.intevation.flys.model.AnnotationType;
sascha@176: import de.intevation.flys.model.Attribute;
ingo@2810: import de.intevation.flys.model.BedHeightEpoch;
ingo@2810: import de.intevation.flys.model.BedHeightEpochValue;
ingo@2809: import de.intevation.flys.model.BedHeightSingle;
ingo@2809: import de.intevation.flys.model.BedHeightSingleValue;
ingo@2809: import de.intevation.flys.model.BedHeightType;
ingo@1230: import de.intevation.flys.model.Building;
ingo@2364: import de.intevation.flys.model.Catchment;
sascha@1194: import de.intevation.flys.model.CrossSection;
sascha@1203: import de.intevation.flys.model.CrossSectionLine;
sascha@1194: import de.intevation.flys.model.CrossSectionPoint;
ingo@1230: import de.intevation.flys.model.CrossSectionTrack;
ingo@2817: import de.intevation.flys.model.Depth;
ingo@1236: import de.intevation.flys.model.DGM;
sascha@176: import de.intevation.flys.model.DischargeTable;
sascha@176: import de.intevation.flys.model.DischargeTableValue;
ingo@2825: import de.intevation.flys.model.DischargeZone;
sascha@760: import de.intevation.flys.model.Edge;
ingo@2809: import de.intevation.flys.model.ElevationModel;
ingo@1230: import de.intevation.flys.model.Fixpoint;
ingo@2799: import de.intevation.flys.model.Floodmaps;
ingo@1237: import de.intevation.flys.model.Floodplain;
ingo@2832: import de.intevation.flys.model.FlowVelocityMeasurement;
ingo@2832: import de.intevation.flys.model.FlowVelocityMeasurementValue;
ingo@2825: import de.intevation.flys.model.FlowVelocityModel;
ingo@2825: import de.intevation.flys.model.FlowVelocityModelValue;
sascha@176: import de.intevation.flys.model.Gauge;
ingo@2837: import de.intevation.flys.model.GrainFraction;
ingo@2363: import de.intevation.flys.model.Hws;
sascha@1210: import de.intevation.flys.model.HYK;
sascha@1210: import de.intevation.flys.model.HYKEntry;
sascha@1210: import de.intevation.flys.model.HYKFormation;
sascha@1210: import de.intevation.flys.model.HYKFlowZoneType;
sascha@1210: import de.intevation.flys.model.HYKFlowZone;
ingo@1230: import de.intevation.flys.model.Line;
ingo@2809: import de.intevation.flys.model.LocationSystem;
sascha@176: import de.intevation.flys.model.MainValueType;
ingo@2818: import de.intevation.flys.model.MorphologicalWidth;
ingo@2818: import de.intevation.flys.model.MorphologicalWidthValue;
sascha@189: import de.intevation.flys.model.NamedMainValue;
sascha@189: import de.intevation.flys.model.MainValue;
sascha@176: import de.intevation.flys.model.Position;
sascha@176: import de.intevation.flys.model.Range;
sascha@176: import de.intevation.flys.model.River;
ingo@1230: import de.intevation.flys.model.RiverAxis;
ingo@2360: import de.intevation.flys.model.RiverAxisKm;
ingo@2817: import de.intevation.flys.model.SedimentDensity;
ingo@2817: import de.intevation.flys.model.SedimentDensityValue;
ingo@2837: import de.intevation.flys.model.SedimentYield;
ingo@2837: import de.intevation.flys.model.SedimentYieldValue;
sascha@176: import de.intevation.flys.model.TimeInterval;
ingo@2346: import de.intevation.flys.model.Unit;
ingo@2842: import de.intevation.flys.model.Waterlevel;
ingo@2847: import de.intevation.flys.model.WaterlevelDifference;
ingo@2847: import de.intevation.flys.model.WaterlevelDifferenceColumn;
ingo@2847: import de.intevation.flys.model.WaterlevelDifferenceValue;
ingo@2842: import de.intevation.flys.model.WaterlevelQRange;
ingo@2842: import de.intevation.flys.model.WaterlevelValue;
sascha@176: import de.intevation.flys.model.WstColumn;
sascha@176: import de.intevation.flys.model.WstColumnQRange;
sascha@176: import de.intevation.flys.model.WstColumnValue;
sascha@176: import de.intevation.flys.model.Wst;
sascha@176: import de.intevation.flys.model.WstQRange;
sascha@176: 
sascha@176: import org.apache.log4j.Logger;
sascha@176: 
sascha@176: public final class SessionFactoryProvider
sascha@176: {
sascha@176:     private static Logger log = Logger.getLogger(SessionFactoryProvider.class);
sascha@176: 
sascha@176:     public static final String XPATH_USER =
sascha@176:         "/artifact-database/backend-database/user/text()";
sascha@176: 
sascha@176:     public static final String XPATH_PASSWORD =
sascha@176:         "/artifact-database/backend-database/password/text()";
sascha@176: 
sascha@176:     public static final String XPATH_DIALECT =
sascha@176:         "/artifact-database/backend-database/dialect/text()";
sascha@176: 
sascha@176:     public static final String XPATH_DRIVER =
sascha@176:         "/artifact-database/backend-database/driver/text()";
sascha@176: 
sascha@176:     public static final String XPATH_URL =
sascha@176:         "/artifact-database/backend-database/url/text()";
sascha@176: 
sascha@179:     public static final String DEFAULT_USER =
sascha@179:         System.getProperty("flys.backend.user", "flys");
sascha@179: 
sascha@179:     public static final String DEFAULT_PASSWORD =
sascha@179:         System.getProperty("flys.backend.password", "flys");
sascha@179: 
sascha@179:     public static final String DEFAULT_DIALECT =
sascha@179:         System.getProperty(
sascha@179:             "flys.backend.dialect",
ingo@1232:             "org.hibernate.dialect.PostgreSQLDialect");
sascha@176: 
sascha@176:     public static final String DEFAULT_DRIVER =
sascha@179:         System.getProperty(
sascha@179:             "flys.backend.driver",
sascha@179:             "org.postgresql.Driver");
sascha@176: 
sascha@176:     public static final String DEFAULT_URL =
sascha@179:         System.getProperty(
sascha@179:             "flys.backend.url",
sascha@179:             "jdbc:postgresql://localhost:5432/flys");
sascha@176: 
ingo@2337:     public static final boolean ENABLE_JMX =
ingo@2337:         Boolean.getBoolean("flys.backend.enablejmx");
ingo@2337: 
sascha@176:     private static SessionFactory sessionFactory;
sascha@176: 
sascha@176:     private SessionFactoryProvider() {
sascha@176:     }
sascha@176: 
sascha@176:     public static synchronized SessionFactory getSessionFactory() {
sascha@176:         if (sessionFactory == null) {
sascha@178:             String user =
sascha@178:                 Config.getStringXPath(XPATH_USER, DEFAULT_USER);
sascha@178:             String password =
sascha@178:                 Config.getStringXPath(XPATH_PASSWORD, DEFAULT_PASSWORD);
sascha@178:             String dialect =
sascha@178:                 Config.getStringXPath(XPATH_DIALECT, DEFAULT_DIALECT);
sascha@464:             String driver =
sascha@178:                 Config.getStringXPath(XPATH_DRIVER, DEFAULT_DRIVER);
sascha@178:             String url =
sascha@178:                 Config.getStringXPath(XPATH_URL, DEFAULT_URL);
sascha@178: 
sascha@178:             sessionFactory = createSessionFactory(
sascha@178:                 user, password, dialect, driver, url);
sascha@176:         }
sascha@176:         return sessionFactory;
sascha@176:     }
sascha@176: 
sascha@179:     public static SessionFactory createSessionFactory() {
sascha@179:         return createSessionFactory(
sascha@179:             DEFAULT_USER,
sascha@179:             DEFAULT_PASSWORD,
sascha@179:             DEFAULT_DIALECT,
sascha@179:             DEFAULT_DRIVER,
sascha@179:             DEFAULT_URL);
sascha@179:     }
sascha@179: 
sascha@178:     public static SessionFactory createSessionFactory(
sascha@178:         String user,
sascha@178:         String password,
sascha@178:         String dialect,
sascha@178:         String driver,
sascha@178:         String url
sascha@178:     ) {
sascha@1229:         Configuration cfg = createConfiguration(
sascha@1229:             user, password, dialect, driver, url);
sascha@1229: 
ingo@2337:         SessionFactory factory = cfg.buildSessionFactory();
ingo@2337: 
ingo@2337:         if (ENABLE_JMX) {
ingo@2337:             registerAsMBean(factory);
ingo@2337:         }
ingo@2337:         else {
ingo@2337:             log.info("No JMX support for hibernate.");
ingo@2337:         }
ingo@2337: 
ingo@2337:         return factory;
sascha@1229:     }
sascha@1229: 
ingo@2337: 
ingo@2337:     public static void registerAsMBean(SessionFactory factory) {
ingo@2337: 
ingo@2337:         StatisticsService statsMBean = new StatisticsService();
ingo@2337:         statsMBean.setSessionFactory(factory);
ingo@2337:         statsMBean.setStatisticsEnabled(true);
ingo@2337: 
ingo@2337:         try {
ingo@2337:             MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
ingo@2337:             mbs.registerMBean(
ingo@2337:                 statsMBean,
ingo@2337:                 new ObjectName("Hibernate:application=Statistics"));
ingo@2337: 
ingo@2337:             log.info("Enabled JMX support for hibernate.");
ingo@2337:         }
ingo@2337:         catch (MalformedObjectNameException mone) {
ingo@2337:             log.warn(mone, mone);
ingo@2337:         }
ingo@2337:         catch (InstanceAlreadyExistsException iaee) {
ingo@2337:             log.warn(iaee, iaee);
ingo@2337:         }
ingo@2337:         catch (MBeanRegistrationException mbre) {
ingo@2337:             log.warn(mbre, mbre);
ingo@2337:         }
ingo@2337:         catch (NotCompliantMBeanException ncmbe) {
ingo@2337:             log.warn(ncmbe, ncmbe);
ingo@2337:         }
ingo@2337:     }
ingo@2337: 
ingo@2337: 
sascha@1229:     public static Configuration createConfiguration() {
sascha@1229:         return createConfiguration(
sascha@1229:             DEFAULT_USER,
sascha@1229:             DEFAULT_PASSWORD,
sascha@1229:             DEFAULT_DIALECT,
sascha@1229:             DEFAULT_DRIVER,
sascha@1229:             DEFAULT_URL);
sascha@1229:     }
sascha@1229: 
sascha@1229:     public static Configuration createConfiguration(
sascha@1229:         String user,
sascha@1229:         String password,
sascha@1229:         String dialect,
sascha@1229:         String driver,
sascha@1229:         String url
sascha@1229:     ) {
sascha@176:         Configuration cfg = new Configuration();
sascha@176: 
sascha@176:         // TODO: Use package reflection here.
sascha@176:         cfg.addAnnotatedClass(Annotation.class);
sascha@763:         cfg.addAnnotatedClass(AnnotationType.class);
sascha@176:         cfg.addAnnotatedClass(Attribute.class);
ingo@2810:         cfg.addAnnotatedClass(BedHeightEpoch.class);
ingo@2810:         cfg.addAnnotatedClass(BedHeightEpochValue.class);
ingo@2809:         cfg.addAnnotatedClass(BedHeightSingle.class);
ingo@2809:         cfg.addAnnotatedClass(BedHeightSingleValue.class);
ingo@2809:         cfg.addAnnotatedClass(BedHeightType.class);
ingo@1230:         cfg.addAnnotatedClass(Building.class);
ingo@2364:         cfg.addAnnotatedClass(Catchment.class);
sascha@1194:         cfg.addAnnotatedClass(CrossSection.class);
sascha@1203:         cfg.addAnnotatedClass(CrossSectionLine.class);
sascha@1194:         cfg.addAnnotatedClass(CrossSectionPoint.class);
ingo@1230:         cfg.addAnnotatedClass(CrossSectionTrack.class);
ingo@2817:         cfg.addAnnotatedClass(Depth.class);
ingo@1236:         cfg.addAnnotatedClass(DGM.class);
sascha@176:         cfg.addAnnotatedClass(DischargeTable.class);
sascha@176:         cfg.addAnnotatedClass(DischargeTableValue.class);
ingo@2825:         cfg.addAnnotatedClass(DischargeZone.class);
sascha@760:         cfg.addAnnotatedClass(Edge.class);
ingo@2809:         cfg.addAnnotatedClass(ElevationModel.class);
ingo@1230:         cfg.addAnnotatedClass(Fixpoint.class);
ingo@1237:         cfg.addAnnotatedClass(Floodplain.class);
ingo@2802:         cfg.addAnnotatedClass(Floodmaps.class);
ingo@2832:         cfg.addAnnotatedClass(FlowVelocityMeasurement.class);
ingo@2832:         cfg.addAnnotatedClass(FlowVelocityMeasurementValue.class);
ingo@2825:         cfg.addAnnotatedClass(FlowVelocityModel.class);
ingo@2825:         cfg.addAnnotatedClass(FlowVelocityModelValue.class);
sascha@176:         cfg.addAnnotatedClass(Gauge.class);
ingo@2837:         cfg.addAnnotatedClass(GrainFraction.class);
ingo@2363:         cfg.addAnnotatedClass(Hws.class);
sascha@1210:         cfg.addAnnotatedClass(HYK.class);
sascha@1210:         cfg.addAnnotatedClass(HYKEntry.class);
sascha@1210:         cfg.addAnnotatedClass(HYKFormation.class);
sascha@1210:         cfg.addAnnotatedClass(HYKFlowZoneType.class);
sascha@1210:         cfg.addAnnotatedClass(HYKFlowZone.class);
ingo@1230:         cfg.addAnnotatedClass(Line.class);
ingo@2809:         cfg.addAnnotatedClass(LocationSystem.class);
sascha@176:         cfg.addAnnotatedClass(MainValueType.class);
ingo@2818:         cfg.addAnnotatedClass(MorphologicalWidth.class);
ingo@2818:         cfg.addAnnotatedClass(MorphologicalWidthValue.class);
sascha@189:         cfg.addAnnotatedClass(NamedMainValue.class);
sascha@189:         cfg.addAnnotatedClass(MainValue.class);
sascha@176:         cfg.addAnnotatedClass(Position.class);
sascha@176:         cfg.addAnnotatedClass(Range.class);
sascha@176:         cfg.addAnnotatedClass(River.class);
ingo@1230:         cfg.addAnnotatedClass(RiverAxis.class);
ingo@2360:         cfg.addAnnotatedClass(RiverAxisKm.class);
ingo@2817:         cfg.addAnnotatedClass(SedimentDensity.class);
ingo@2817:         cfg.addAnnotatedClass(SedimentDensityValue.class);
ingo@2837:         cfg.addAnnotatedClass(SedimentYield.class);
ingo@2837:         cfg.addAnnotatedClass(SedimentYieldValue.class);
sascha@176:         cfg.addAnnotatedClass(TimeInterval.class);
ingo@2346:         cfg.addAnnotatedClass(Unit.class);
ingo@2842:         cfg.addAnnotatedClass(Waterlevel.class);
ingo@2847:         cfg.addAnnotatedClass(WaterlevelDifference.class);
ingo@2847:         cfg.addAnnotatedClass(WaterlevelDifferenceColumn.class);
ingo@2847:         cfg.addAnnotatedClass(WaterlevelDifferenceValue.class);
ingo@2842:         cfg.addAnnotatedClass(WaterlevelQRange.class);
ingo@2842:         cfg.addAnnotatedClass(WaterlevelValue.class);
sascha@176:         cfg.addAnnotatedClass(WstColumn.class);
sascha@176:         cfg.addAnnotatedClass(WstColumnQRange.class);
sascha@176:         cfg.addAnnotatedClass(WstColumnValue.class);
sascha@176:         cfg.addAnnotatedClass(Wst.class);
sascha@176:         cfg.addAnnotatedClass(WstQRange.class);
sascha@176: 
sascha@176:         if (log.isDebugEnabled()) {
sascha@176:             log.debug("user: "    + user);
sascha@176:             log.debug("dialect: " + dialect);
sascha@176:             log.debug("driver: "  + driver);
sascha@176:             log.debug("url: "     + url);
sascha@176:         }
sascha@176: 
sascha@176:         Properties props = new Properties();
sascha@176: 
sascha@176:         // We rely on our own connection pool
sascha@176:         props.setProperty(
sascha@176:             "hibernate.connection.provider_class",
sascha@176:             "org.hibernate.connection.DBCPConnectionProvider");
sascha@176: 
sascha@176:         props.setProperty(Environment.DIALECT, dialect);
sascha@176:         props.setProperty(Environment.USER,    user);
sascha@176:         props.setProperty(Environment.PASS,    password);
sascha@176:         props.setProperty(Environment.DRIVER,  driver);
sascha@176:         props.setProperty(Environment.URL,     url);
sascha@176: 
sascha@176:         cfg.mergeProperties(props);
sascha@176: 
sascha@1229:         return cfg;
sascha@176:     }
ingo@2361: 
ingo@2361: 
ingo@2362:     public static String getProperty(SessionFactoryImpl factory, String key) {
ingo@2361:         Properties props = factory.getProperties();
ingo@2362:         return props.getProperty(key);
ingo@2362:     }
ingo@2361: 
ingo@2362:     public static String getUser(SessionFactoryImpl factory) {
ingo@2362:         return getProperty(factory, Environment.USER);
ingo@2362:     }
ingo@2362: 
ingo@2362: 
ingo@2362:     public static String getPass(SessionFactoryImpl factory) {
ingo@2362:         return getProperty(factory, Environment.PASS);
ingo@2362:     }
ingo@2362: 
ingo@2362: 
ingo@2362:     public static String getURL(SessionFactoryImpl factory) {
ingo@2362:         return getProperty(factory, Environment.URL);
ingo@2362:     }
ingo@2362: 
ingo@2362: 
ingo@2362:     public static String getDriver(SessionFactoryImpl factory) {
ingo@2362:         return getProperty(factory, Environment.DRIVER);
ingo@2361:     }
sascha@176: }
sascha@176: // vim:set ts=4 sw=4 si et sta sts=4 fenc=utf8 :