📄 xwikihibernatestore.java
字号:
/** * =================================================================== * * Copyright (c) 2003 Ludovic Dubost, All rights reserved. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * 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 General Public License for more details, published at * http://www.gnu.org/copyleft/gpl.html or in gpl.txt in the * root folder of this distribution. * * Created by * User: Ludovic Dubost * Date: 24 nov. 2003 * Time: 01:00:44 */package com.xpn.xwiki.store;import com.xpn.xwiki.XWiki;import com.xpn.xwiki.XWikiContext;import com.xpn.xwiki.XWikiException;import com.xpn.xwiki.monitor.api.MonitorPlugin;import com.xpn.xwiki.stats.impl.XWikiStats;import com.xpn.xwiki.doc.*;import com.xpn.xwiki.objects.*;import com.xpn.xwiki.objects.classes.BaseClass;import com.xpn.xwiki.objects.classes.PropertyClass;import com.xpn.xwiki.web.XWikiRequest;import org.hibernate.cfg.Configuration;import org.hibernate.dialect.Dialect;import org.hibernate.impl.SessionFactoryImpl;import org.hibernate.impl.SessionImpl;import org.hibernate.tool.hbm2ddl.DatabaseMetadata;import org.apache.commons.jrcs.rcs.Archive;import org.apache.commons.jrcs.rcs.Node;import org.apache.commons.jrcs.rcs.Version;import org.apache.commons.logging.Log;import org.apache.commons.logging.LogFactory;import org.apache.commons.lang.StringUtils;import org.hibernate.HibernateException;import org.hibernate.ObjectNotFoundException;import org.hibernate.Query;import org.hibernate.Session;import org.hibernate.SessionFactory;import org.hibernate.Transaction;import java.io.BufferedReader;import java.io.File;import java.io.Serializable;import java.net.MalformedURLException;import java.net.URL;import java.sql.Connection;import java.sql.SQLException;import java.sql.Statement;import java.util.*;public class XWikiHibernateStore extends XWikiDefaultStore { private static final Log log = LogFactory.getLog(XWikiHibernateStore.class); private Map connections = new HashMap(); private int nbConnections = 0; private SessionFactory sessionFactory; private Configuration configuration; private String hibpath; private URL hiburl; public XWikiHibernateStore(XWiki xwiki, XWikiContext context) { String path = xwiki.Param("xwiki.store.hibernate.path"); if (context.getEngineContext()==null) setPath(path); else { try { setHibUrl(context.getEngineContext().getResource(path)); } catch (MalformedURLException e) { } } } public XWikiHibernateStore(String hibpath) { setPath(hibpath); } public String getPath() { return hibpath; } public void setPath(String hibpath) { this.hibpath = hibpath; } public URL getHibUrl() { return hiburl; } public void setHibUrl(URL hiburl) { this.hiburl = hiburl; } // Helper Methods private void initHibernate() throws HibernateException { // Load Configuration and build SessionFactory String path = getPath(); if (path!=null) setConfiguration((new Configuration()).configure(new File(path))); else { URL hiburl = getHibUrl(); if (hiburl!=null) setConfiguration(new Configuration().configure(hiburl)); else setConfiguration(new Configuration().configure()); } setSessionFactory(getConfiguration().buildSessionFactory()); } public Session getSession(XWikiContext context) { Session session = (Session) context.get("hibsession"); return session; } public void setSession(Session session, XWikiContext context) { if (session==null) context.remove("hibsession"); else context.put("hibsession", session); } public Transaction getTransaction(XWikiContext context) { Transaction transaction = (Transaction) context.get("hibtransaction"); return transaction; } public void setTransaction(Transaction transaction, XWikiContext context) { if (transaction==null) context.remove("hibtransaction"); else context.put("hibtransaction", transaction); } public void shutdownHibernate(XWikiContext context) throws HibernateException { closeSession(getSession(context)); if (getSessionFactory()!=null) { ((SessionFactoryImpl)getSessionFactory()).getConnectionProvider().close(); } } public void updateSchema(XWikiContext context) throws HibernateException { updateSchema(context, false); } // Let's synchronize this, to only update one schema at a time public synchronized void updateSchema(XWikiContext context, boolean force) throws HibernateException { // No updating of schema if we have a config parameter saying so try { if ((!force)&&("0".equals(context.getWiki().Param("xwiki.store.hibernate.updateschema")))) { if (log.isErrorEnabled()) log.error("Schema update deactivated for wiki " + context.getDatabase()); return; } if (log.isErrorEnabled()) log.error("Schema update for wiki " + context.getDatabase()); } catch (Exception e) {} Session session; Connection connection; DatabaseMetadata meta; Statement stmt=null; Dialect dialect = Dialect.getDialect(getConfiguration().getProperties()); boolean bTransaction = true; try { try { bTransaction = beginTransaction(context); session = getSession(context); connection = session.connection(); setDatabase(session, context); meta = new DatabaseMetadata(connection, dialect); stmt = connection.createStatement(); } catch (SQLException sqle) { if ( log.isErrorEnabled() ) log.error("Failed updating schema: " + sqle.getMessage()); throw sqle; } String[] createSQL = configuration.generateSchemaUpdateScript(dialect, meta); MonitorPlugin monitor = getMonitorPlugin(context); // Start monitoring timer if (monitor!=null) monitor.startTimer("sqlupgrade"); try { for (int j = 0; j < createSQL.length; j++) { final String sql = createSQL[j]; if ( log.isDebugEnabled() ) log.debug("Update Schema sql: " + sql); stmt.executeUpdate(sql); } connection.commit(); } catch (SQLException e) { connection.rollback(); if ( log.isErrorEnabled() ) log.error("Failed updating schema: " + e.getMessage()); } finally { // End monitoring timer if (monitor!=null) monitor.endTimer("sqlupgrade"); } // Make sure we have no null valued in integer fields stmt.executeUpdate("update xwikidoc set xwd_translation=0 where xwd_translation is null"); stmt.executeUpdate("update xwikidoc set xwd_language='' where xwd_language is null"); stmt.executeUpdate("update xwikidoc set xwd_default_language='' where xwd_default_language is null"); String fullNameSQL; if (context.getWiki().isMySQL()) fullNameSQL = "CONCAT(xwd_web,'.',xwd_name)"; else fullNameSQL = "xwd_web||'.'||xwd_name"; stmt.executeUpdate("update xwikidoc set xwd_fullname=" + fullNameSQL + " where xwd_fullname is null"); connection.commit(); } catch (Exception e) { if ( log.isErrorEnabled() ) log.error("Failed updating schema: " + e.getMessage()); } finally { try { if (stmt!=null) stmt.close(); if (bTransaction) endTransaction(context, true); } catch (Exception e) { } } } public void checkHibernate(XWikiContext context) throws HibernateException { if (getSessionFactory()==null) { initHibernate(); /* Check Schema */ if (getSessionFactory()!=null) { updateSchema(context); } } } protected boolean isVirtual(XWikiContext context) { if ((context==null)||(context.getWiki()==null)) return true; return context.getWiki().isVirtual(); } public void setDatabase(Session session, XWikiContext context) throws XWikiException { if (isVirtual(context)) { String database = context.getDatabase(); try { if ( log.isDebugEnabled() ) log.debug("Switch database to: " + database); if (database!=null) session.connection().setCatalog(database); } catch (Exception e) { Object[] args = { database }; throw new XWikiException( XWikiException.MODULE_XWIKI_STORE, XWikiException.ERROR_XWIKI_STORE_HIBERNATE_SWITCH_DATABASE, "Exception while switching to database {0}", e, args); } } } public boolean beginTransaction(XWikiContext context) throws HibernateException, XWikiException { Transaction transaction = getTransaction(context); Session session = getSession(context); if (((session==null)&&(transaction!=null)) ||((transaction==null)&&(session!=null))) { if ( log.isWarnEnabled() ) log.warn("Incompatible session (" + session + ") and transaction (" + transaction + ") status"); return false; } if (transaction!=null) { if ( log.isDebugEnabled() ) log.debug("Taking session from context " + session); if ( log.isDebugEnabled() ) log.debug("Taking transaction from context " + transaction); return false; } if (session==null) { if ( log.isDebugEnabled() ) log.debug("Trying to get session from pool"); session = (SessionImpl)getSessionFactory().openSession(); if ( log.isDebugEnabled() ) log.debug("Taken session from pool " + session); // Keep some statistics about session and connections nbConnections++; addConnection(session.connection(), context); setSession(session, context); setDatabase(session, context); if ( log.isDebugEnabled() ) log.debug("Trying to open transaction"); transaction = session.beginTransaction(); if ( log.isDebugEnabled() ) log.debug("Opened transaction " + transaction); setTransaction(transaction, context); } return true; } private void addConnection(Connection connection, XWikiContext context) { if (connection!=null) connections.put(connection, new ConnectionMonitor(connection, context)); } private void removeConnection(Connection connection) { try { if (connection!=null) connections.remove(connection); } catch (Exception e) { } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -