package it.satanet.hibernate3;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.FilenameFilter;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Map;
import java.util.MissingResourceException;
import java.util.Properties;
import java.util.ResourceBundle;
import java.util.Set;
import java.util.StringTokenizer;

import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;

import org.apache.log4j.Logger;
import org.hibernate.Hibernate;
import org.hibernate.HibernateException;
import org.hibernate.Query;
import org.hibernate.SessionFactory;
import org.hibernate.StaleObjectStateException;
import org.hibernate.cfg.Configuration;
import org.hibernate.dialect.Dialect;
import org.hibernate.dialect.PostgreSQLDialect;
import org.hibernate.dialect.SAPDBDialect;
import org.hibernate.engine.SessionImplementor;
import org.hibernate.id.TableHiLoGenerator;
import org.hibernate.proxy.HibernateProxy;
import org.hibernate.proxy.LazyInitializer;
import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
import org.hibernate.util.ReflectHelper;
import org.w3c.dom.Document;

public class Session {

  /* Statics */

  private static final ClassLoader CLASS_LOADER = Session.class.getClassLoader();

  private static final ResourceBundle CONFIGURATION = ResourceBundle.getBundle("hibernate-utils");

  private static final Logger ROOT_LOGGER = Logger.getRootLogger();

  private static Configuration cfg;

  private static SessionFactory sf;

  private static Dialect dialect;

  private static TableHiLoGenerator hiLoGenerator;

  private static ResourceBundle errorMessages;

  static {
    cfg = new Configuration();
    try {
      addMappingFiles();
      sf = cfg.configure(getConfigurationFile("hibernate.cfg.xml")).buildSessionFactory();
      dialect = getDialect();
      hiLoGenerator = new TableHiLoGenerator();
      hiLoGenerator.configure(Hibernate.LONG, new Properties(), dialect);
    } catch (Exception e) {
      ROOT_LOGGER.error("Error configuring the environment", e);
    }
    try {
      errorMessages = ResourceBundle.getBundle(CONFIGURATION.getString("error-messages"));
    } catch (MissingResourceException e) {
      ROOT_LOGGER.warn("Error bundle not found. Using the default one.");
      errorMessages = ResourceBundle.getBundle("it.satanet.hibernate3.error-messages");
    }
  }

  /* Instance attribs */

  private String errorMessage;

  Session() {}

  /* Default access */

  boolean beginTransaction() {
    boolean retval = false;
    try {
      sf.getCurrentSession().beginTransaction();
      retval = true;
    } catch (Exception e) {
      ROOT_LOGGER.error("Unespected error", e);
      setErrorMessage(e);
    }
    return retval;
  }

  boolean commitTransaction() {
    boolean retval = false;
    try {
      sf.getCurrentSession().getTransaction().commit();
      retval = true;
    } catch (Exception e) {
      ROOT_LOGGER.error("Unespected error", e);
      setErrorMessage(e);
    }
    return retval;
  }

  boolean rollbackTransaction() {
    boolean retval = false;
    try {
      sf.getCurrentSession().getTransaction().rollback();
      retval = true;
    } catch (Exception e) {
      ROOT_LOGGER.error("Unespected error", e);
      setErrorMessage(e);
    }
    return retval;
  }

  boolean endTransaction() {
    boolean retval = true;
    if (!(retval = commitTransaction())) {
      rollbackTransaction();
    }
    return retval;
  }

  Connection getConnection() {
    return sf.getCurrentSession().connection();
  }

  String getErrorMessage() {
    String retval = errorMessage;
    errorMessage = null;
    return retval;
  }

  void setErrorMessage(Throwable e) {
    setErrorMessage(null, getMessage(e));
  }

  /* Publics */

  public String[] generateDropSchemaScript() throws HibernateException {
    return cfg.generateDropSchemaScript(dialect);
  }

  public String[] generateSchemaCreationScript() throws HibernateException {
    return cfg.generateSchemaCreationScript(dialect);
  }

  public String[] generateSchemaUpdateScript() throws HibernateException, SQLException {
    return cfg.generateSchemaUpdateScript(dialect, new DatabaseMetadata(sf.getCurrentSession().connection(), dialect));
  }

  public void clear() {
    sf.getCurrentSession().clear();
  }

  public void evict(Serializable o) {
    try {
      sf.getCurrentSession().evict(o);
    } catch (Exception e) {
      ROOT_LOGGER.error("Unespected error", e);
      setErrorMessage(e);
    }
  }

  public List find(String query) {
    List retval = null;
    try {
      retval = sf.getCurrentSession().createQuery(query).list();
      dropEquals(retval);
    } catch (Exception e) {
      ROOT_LOGGER.error("Unespected error", e);
      setErrorMessage(e);
    }
    return retval;
  }

  public List find(String query, List numberedParameters) {
    List retval = null;
    if (numberedParameters.size() != 0) {
      try {
        Query q = sf.getCurrentSession().createQuery(query);
        for (int ii = 0; ii < numberedParameters.size(); ii++) {
          q.setParameter(ii, numberedParameters.get(ii));
        }
        retval = q.list();
        dropEquals(retval);
      } catch (Exception e) {
        ROOT_LOGGER.error("Unespected error", e);
        setErrorMessage(e);
      }
    } else {
      ROOT_LOGGER.error("Can not find parameters");
      setErrorMessage("operationFailed", null);
    }
    return retval;
  }

  public List find(String query, Map namedParameters) {
    List retval = null;
    if (!namedParameters.isEmpty()) {
      try {
        Query q = sf.getCurrentSession().createQuery(query);
        boolean execute = true;
        for (Iterator iter = namedParameters.keySet().iterator(); execute && iter.hasNext();) {
          String name = (String) iter.next();
          Object value = namedParameters.get(name);
          if (Collection.class.isAssignableFrom(value.getClass())) {
            Collection parameterList = (Collection) value;
            execute = parameterList.size() != 0;
            q.setParameterList(name, parameterList);
          } else {
            q.setParameter(name, value);
          }
        }
        if (execute) {
          retval = q.list();
          dropEquals(retval);
        } else {
          ROOT_LOGGER.error("Can not find parameters");
          setErrorMessage("operationFailed", null);
        }
      } catch (Exception e) {
        ROOT_LOGGER.error("Unespected error", e);
        setErrorMessage(e);
      }
    } else {
      ROOT_LOGGER.error("Can not find parameters");
      setErrorMessage("operationFailed", null);
    }
    return retval;
  }

  public Object get(Class clazz, Serializable id) {
    Object retval = null;
    try {
      retval = sf.getCurrentSession().get(clazz, id);
    } catch (Exception e) {
      ROOT_LOGGER.error("Unespected error", e);
      setErrorMessage(e);
    }
    return retval;
  }

  public Serializable save(Serializable o) {
    Serializable retval = null;
    try {
      retval = sf.getCurrentSession().save(o);
    } catch (Exception e) {
      ROOT_LOGGER.error("Unespected error", e);
      setErrorMessage(e);
    }
    return retval;
  }

  public Serializable merge(Serializable o) {
    Serializable retval = null;
    try {
      retval = (Serializable) sf.getCurrentSession().merge(o);
    } catch (Exception e) {
      ROOT_LOGGER.error("Unespected error", e);
      setErrorMessage(e);
    }
    return retval;
  }

  public boolean update(Serializable o) {
    boolean retval = false;
    try {
      sf.getCurrentSession().update(o);
      retval = true;
    } catch (Exception e) {
      ROOT_LOGGER.error("Unespected error", e);
      setErrorMessage(e);
    }
    return retval;
  }

  public boolean executeUpdate(String query) {
    boolean retval = false;
    try {
      Query q = sf.getCurrentSession().createQuery(query);
      q.executeUpdate();
      retval = true;
    } catch (Exception e) {
      ROOT_LOGGER.error("Unespected error", e);
      setErrorMessage(e);
    }
    return retval;
  }

  public boolean executeUpdate(String query, List numberedParameters) {
    boolean retval = false;
    if (numberedParameters.size() != 0) {
      try {
        Query q = sf.getCurrentSession().createQuery(query);
        for (int ii = 0; ii < numberedParameters.size(); ii++) {
          q.setParameter(ii, numberedParameters.get(ii));
        }
        q.executeUpdate();
        retval = true;
      } catch (Exception e) {
        ROOT_LOGGER.error("Unespected error", e);
        setErrorMessage(e);
      }
    } else {
      ROOT_LOGGER.error("Can not find parameters");
      if (query.toLowerCase().startsWith("update")) {
        setErrorMessage("updateFailed", null);
      } else {
        setErrorMessage("deleteFailed", null);
      }
    }
    return retval;
  }

  public boolean executeUpdate(String query, Map namedParameters) {
    boolean retval = false;
    if (!namedParameters.isEmpty()) {
      try {
        Query q = sf.getCurrentSession().createQuery(query);
        boolean execute = true;
        for (Iterator iter = namedParameters.keySet().iterator(); execute && iter.hasNext();) {
          String name = (String) iter.next();
          Object value = namedParameters.get(name);
          if (Collection.class.isAssignableFrom(value.getClass())) {
            Collection parameterList = (Collection) value;
            execute = parameterList.size() != 0;
            q.setParameterList(name, parameterList);
          } else {
            q.setParameter(name, value);
          }
        }
        if (execute) {
          q.executeUpdate();
          retval = true;
        } else {
          ROOT_LOGGER.error("Can not find parameters");
          if (query.toLowerCase().startsWith("update")) {
            setErrorMessage("updateFailed", null);
          } else {
            setErrorMessage("deleteFailed", null);
          }
        }
      } catch (Exception e) {
        ROOT_LOGGER.error("Unespected error", e);
        setErrorMessage(e);
      }
    } else {
      ROOT_LOGGER.error("Can not find parameters");
      if (query.toLowerCase().startsWith("update")) {
        setErrorMessage("updateFailed", null);
      } else {
        setErrorMessage("deleteFailed", null);
      }
    }
    return retval;
  }

  public boolean delete(Serializable o) {
    boolean retval = false;
    try {
      sf.getCurrentSession().delete(o);
      retval = true;
    } catch (Exception e) {
      ROOT_LOGGER.error("Unespected error", e);
      setErrorMessage(e);
    }
    return retval;
  }

  public boolean refresh(Object o) {
    boolean retval = false;
    try {
      sf.getCurrentSession().refresh(o);
      retval = true;
    } catch (Exception e) {
      ROOT_LOGGER.error("Unespected error", e);
      setErrorMessage(e);
    }
    return retval;
  }

  public boolean flush() {
    boolean retval = false;
    try {
      sf.getCurrentSession().flush();
      retval = true;
    } catch (Exception e) {
      ROOT_LOGGER.error("Unespected error", e);
      setErrorMessage(e);
    }
    return retval;
  }

  public boolean initialize(Object proxy) {
    boolean retval = false;
    try {
      Hibernate.initialize(proxy);
      retval = true;
    } catch (Exception e) {
      ROOT_LOGGER.error("Unespected error", e);
      setErrorMessage(e);
    }
    return retval;
  }

  public boolean instanceOf(Object object, Class clazz) {
    if (object instanceof HibernateProxy) {
      HibernateProxy proxy = (HibernateProxy) object;
      LazyInitializer li = proxy.getHibernateLazyInitializer();
      return li.getImplementation().getClass().equals(clazz);
    }
    return object.getClass().equals(clazz);
  }

  public Serializable getGeneratedKey() {
    Serializable retval = null;
    try {
      retval = hiLoGenerator.generate((SessionImplementor) sf.getCurrentSession(), sf.getCurrentSession());
    } catch (Exception e) {
      ROOT_LOGGER.error("Unespected error", e);
      setErrorMessage(e);
    }
    return retval;
  }

  public void setErrorMessage(String key, String message) {
    if (key != null) {
      errorMessage = errorMessages.getString(key);
    } else if (message != null) {
      errorMessage = message;
    } else {
      ROOT_LOGGER.warn("You can not pass either not null key and message parameters. One of these has to be null.");
      errorMessage = "<undefined error message>";
    }
  }

  /* Privates */

  private static void addMappingFiles() throws Exception {
    File mappingDir = new File(CLASS_LOADER.getResource(CONFIGURATION.getString("mapping.dir")).getPath().replaceAll("%20", " "));
    if (mappingDir.exists() && mappingDir.isDirectory()) {
      String[] mappingFileNames = mappingDir.list(new FilenameFilter() {

        public boolean accept(File dir, String name) {
          return name.endsWith(".hbm.xml");
        }
      });
      for (int ii = 0; ii < mappingFileNames.length; ii++) {
        ROOT_LOGGER.info("Adding mapping file \"" + mappingFileNames[ii] + "\".");
        cfg.addDocument(getConfigurationFile(mappingFileNames[ii]));
      }
    }
  }

  private static Document getConfigurationFile(String fileName) throws Exception {
    Document retval = null;
    File confFile = new File(CLASS_LOADER.getResource(CONFIGURATION.getString("mapping.dir") + "/" + fileName).getPath());
    File serConfFile = new File(System.getProperty("java.io.tmpdir"), CONFIGURATION.getString("serialized-files.prefix") + "."
        + fileName + ".ser");
    if (serConfFile.exists() && confFile.lastModified() < serConfFile.lastModified()) {
      ROOT_LOGGER.info("The serialized file \"" + serConfFile.getName() + "\" exists: loading it.");
      ObjectInputStream ois = new ObjectInputStream(new FileInputStream(serConfFile));
      retval = (Document) ois.readObject();
      ois.close();
    } else {
      ROOT_LOGGER.info("The serialized file \"" + serConfFile.getName() + "\" does not exist or it is older than the xml file: "
          + "loading and serializing the xml file \"" + fileName + "\".");
      DocumentBuilder builder = DocumentBuilderFactory.newInstance().newDocumentBuilder();
      retval = builder.parse(CLASS_LOADER.getResourceAsStream(CONFIGURATION.getString("mapping.dir") + "/" + fileName));
      ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(serConfFile));
      oos.writeObject(retval);
      oos.flush();
      oos.close();
    }
    return retval;
  }

  private static Dialect getDialect() throws HibernateException {
    String dialectName = cfg.getProperty("hibernate.dialect");
    if (dialectName == null) {
      throw new HibernateException("The dialect is not set. Please set the property hibernate.dialect in the cfg.xml file.");
    }
    try {
      return (Dialect) ReflectHelper.classForName(dialectName).newInstance();
    } catch (ClassNotFoundException cnfe) {
      throw new HibernateException("Dialect class not found: " + dialectName);
    } catch (Exception e) {
      throw new HibernateException("Could not instantiate dialect class", e);
    }
  }

  private void dropEquals(List list) {
    if (list.size() != 0) {
      Set set = new LinkedHashSet();
      set.addAll(list);
      list.clear();
      list.addAll(set);
    }
  }

  private String getMessage(Throwable e) {
    for (Throwable cause = e.getCause(); cause != null && !cause.equals(e);) {
      e = cause;
    }
    String message = errorMessages.getString("unknownError") + " (" + e.toString() + ").";
    String errorName = null;
    String key = "noKey";
    if (SQLException.class.isAssignableFrom(e.getClass())) {
      if (dialect.getClass().equals(SAPDBDialect.class)) {
        key = "SAPDB." + ((SQLException) e).getErrorCode();
      } else if (dialect.getClass().equals(PostgreSQLDialect.class)) {
        SQLException nextException = ((SQLException) e).getNextException();
        if (nextException != null) {
          e = nextException;
        }
        key = "PostgreSQL";
        if (e.getMessage().indexOf("duplicate key") != -1) {
          errorName = e.getMessage().substring(e.getMessage().indexOf("index") + 5).trim();
          key = key + ".insertFailed.duplicateKey";
        } else if (e.getMessage().indexOf("value too long") != -1) {
          key = key + ".insertFailed.valueTooLong";
        } else if (e.getMessage().indexOf("violates foreign key constraint") != -1) {
          StringTokenizer tokenizer = new StringTokenizer(e.getMessage(), "\"");
          for (int ii = 1; ii < 4; ii++) {
            tokenizer.nextToken();
          }
          errorName = tokenizer.nextToken();
          key = key + ".deleteFailed";
        }

      }
    } else if (e instanceof StaleObjectStateException) {
      if (e.getMessage().startsWith("Row was updated or deleted by another transaction")) {
        errorName = e.getMessage().substring(e.getMessage().lastIndexOf('.') + 1, e.getMessage().indexOf('#')).toLowerCase();
        key = "rowAlreadyUpdatedOrDeleted";
      }
    }
    if (errorName != null) {
      try {
        message = CONFIGURATION.getString(errorName);
      } catch (MissingResourceException e1) {
        message = getDefaultMessage(e, key);
      }
    } else {
      message = getDefaultMessage(e, key);
    }
    e.printStackTrace();
    return message;
  }

  private String getDefaultMessage(Throwable e, String key) {
    String retval = null;
    try {
      retval = errorMessages.getString(key);
    } catch (MissingResourceException e2) {
      retval = e.getMessage().replaceAll("\\n", "\\\\n");
    }
    return retval;
  }
}
---------------------------------------------------------------------
To start a new topic, e-mail: users@tomcat.apache.org
To unsubscribe, e-mail: [EMAIL PROTECTED]
For additional commands, e-mail: [EMAIL PROTECTED]

Reply via email to