r972 - in xwiki/trunk: . src/main/java/com/xpn/xwiki src/main/java/com/xpn/xwiki/api src/main/java/com/xpn/xwiki/doc src/main/java/com/xpn/xwiki/monitor/api src/main/java/com/xpn/xwiki/pdf/impl src/main/java/com/xpn/xwiki/plugin src/main/java/com/xpn/xwiki/plugin/image src/main/java/com/xpn/xwiki/store src/main/java/com/xpn/xwiki/user/impl/LDAP src/main/java/com/xpn/xwiki/user/impl/xwiki src/main/java/com/xpn/xwiki/web src/main/web/templates src/test/java/com/xpn/xwiki/test src/test/resources

Ludovic Dubost ludovic at users.forge.objectweb.org
Sun Mar 12 23:36:16 CET 2006


Author: ludovic
Date: 2006-03-12 23:36:14 +0100 (Sun, 12 Mar 2006)
New Revision: 972

Added:
   xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiAttachmentStoreInterface.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiHibernateAttachmentStore.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiHibernateBaseStore.java
Modified:
   xwiki/trunk/src/main/java/com/xpn/xwiki/XWiki.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/api/Document.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/doc/XWikiAttachment.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/doc/XWikiDocument.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/monitor/api/MonitorPlugin.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/pdf/impl/PdfURLFactory.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/XWikiDefaultPlugin.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/XWikiPluginManager.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/image/ImagePlugin.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiCacheStore.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiCacheStoreInterface.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiHibernateStore.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiStoreInterface.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/user/impl/LDAP/LDAPAuthServiceImpl.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/user/impl/xwiki/MyFormAuthenticator.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/user/impl/xwiki/XWikiAuthServiceImpl.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/web/XWikiDefaultURLFactory.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/web/XWikiServletURLFactory.java
   xwiki/trunk/src/main/java/com/xpn/xwiki/web/XWikiURLFactory.java
   xwiki/trunk/src/main/web/templates/attach.vm
   xwiki/trunk/src/main/web/templates/attachments.vm
   xwiki/trunk/src/main/web/templates/attachwysiwyg.vm
   xwiki/trunk/src/main/web/templates/viewattachrev.vm
   xwiki/trunk/src/test/java/com/xpn/xwiki/test/StoreTest.java
   xwiki/trunk/src/test/resources/hibernate-test.cfg.xml
   xwiki/trunk/xwiki.iml
   xwiki/trunk/xwiki.ipr
   xwiki/trunk/xwiki.iws
Log:
Split Store and AttachmentStore
Modified ImagePlugin and  to support also thumbnail by width
Added APIs to get thumbnails from attached images
Made createUserFromLDAP a public method
Remove white spaces from LDAP username when creating the xwiki name
Fix issue of FIFO buffer only holding 32 elements. Remove items before adding new items

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/XWiki.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/XWiki.java	2006-03-12 08:36:43 UTC (rev 971)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/XWiki.java	2006-03-12 22:36:14 UTC (rev 972)
@@ -52,10 +52,7 @@
 import com.xpn.xwiki.stats.api.XWikiStatsService;
 import com.xpn.xwiki.stats.impl.SearchEngineRule;
 import com.xpn.xwiki.stats.impl.XWikiStatsServiceImpl;
-import com.xpn.xwiki.store.XWikiCacheStore;
-import com.xpn.xwiki.store.XWikiCacheStoreInterface;
-import com.xpn.xwiki.store.XWikiHibernateStore;
-import com.xpn.xwiki.store.XWikiStoreInterface;
+import com.xpn.xwiki.store.*;
 import com.xpn.xwiki.user.api.XWikiAuthService;
 import com.xpn.xwiki.user.api.XWikiGroupService;
 import com.xpn.xwiki.user.api.XWikiRightService;
@@ -83,10 +80,10 @@
 import org.apache.ecs.filter.CharacterFilter;
 import org.apache.ecs.xhtml.textarea;
 import org.apache.velocity.VelocityContext;
-import org.exoplatform.container.PortalContainer;
-import org.exoplatform.container.RootContainer;
 import org.hibernate.HibernateException;
 import org.securityfilter.filter.URLPatternMatcher;
+import org.exoplatform.container.RootContainer;
+import org.exoplatform.container.PortalContainer;
 
 import javax.naming.Context;
 import javax.naming.InitialContext;
@@ -111,6 +108,7 @@
 
     private XWikiConfig config;
     private XWikiStoreInterface store;
+    private XWikiAttachmentStoreInterface attachmentStore;
     private XWikiRenderingEngine renderingEngine;
     private XWikiPluginManager pluginManager;
     private XWikiNotificationManager notificationManager;
@@ -447,6 +445,23 @@
         } else
             setStore(basestore);
 
+        String attachmentStoreclass = Param("xwiki.store.attachment.class", "com.xpn.xwiki.store.XWikiHibernateAttachmentStore");
+        try {
+            Class[] classes = new Class[]{this.getClass(), context.getClass()};
+            Object[] args = new Object[]{this, context};
+            setAttachmentStore( (XWikiAttachmentStoreInterface) Class.forName(attachmentStoreclass).getConstructor(classes).newInstance(args));
+        } catch (InvocationTargetException e) {
+            Object[] args = {storeclass};
+            throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
+                    XWikiException.ERROR_XWIKI_STORE_CLASSINVOCATIONERROR,
+                    "Cannot load store class {0}", e.getTargetException(), args);
+        } catch (Exception e) {
+            Object[] args = {storeclass};
+            throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
+                    XWikiException.ERROR_XWIKI_STORE_CLASSINVOCATIONERROR,
+                    "Cannot load store class {0}", e, args);
+        }
+
         resetRenderingEngine(context);
 
         // Prepare the Plugin Engine
@@ -629,6 +644,10 @@
         return store;
     }
 
+    public XWikiAttachmentStoreInterface getAttachmentStore() {
+        return attachmentStore;
+    }
+
     public void saveDocument(XWikiDocument doc, XWikiContext context) throws XWikiException {
         getStore().saveXWikiDoc(doc, context);
     }
@@ -1375,6 +1394,10 @@
         this.store = store;
     }
 
+    public void setAttachmentStore(XWikiAttachmentStoreInterface attachmentStore) {
+          this.attachmentStore = attachmentStore;
+    }
+
     public void setVersion(String version) {
         this.version = version;
     }
@@ -2206,7 +2229,7 @@
                     if (attachlist.size() > 0) {
                         for (int i = 0; i < attachlist.size(); i++) {
                             XWikiAttachment attachment = (XWikiAttachment) attachlist.get(i);
-                            getStore().saveAttachmentContent(attachment, false, context, true);
+                            getAttachmentStore().saveAttachmentContent(attachment, false, context, true);
                         }
                     }
 
@@ -2271,7 +2294,7 @@
                     if (attachlist.size() > 0) {
                         for (int i = 0; i < attachlist.size(); i++) {
                             XWikiAttachment attachment = (XWikiAttachment) attachlist.get(i);
-                            getStore().saveAttachmentContent(attachment, false, context, true);
+                            getAttachmentStore().saveAttachmentContent(attachment, false, context, true);
                         }
                     }
                 }

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/api/Document.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/api/Document.java	2006-03-12 08:36:43 UTC (rev 971)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/api/Document.java	2006-03-12 22:36:14 UTC (rev 972)
@@ -212,10 +212,18 @@
         return doc.getAttachmentURL(filename, action, context);
     }
 
+    public String getAttachmentURL(String filename, String action, String querystring) {
+        return doc.getAttachmentURL(filename, action, querystring, context);
+    }
+
     public String getAttachmentRevisionURL(String filename, String version) {
         return doc.getAttachmentRevisionURL(filename, version, context);
     }
 
+    public String getAttachmentRevisionURL(String filename, String version, String querystring) {
+        return doc.getAttachmentRevisionURL(filename, version, querystring, context);
+    }
+
     public String getURL() {
         return doc.getURL("view", context);
     }

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/doc/XWikiAttachment.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/doc/XWikiAttachment.java	2006-03-12 08:36:43 UTC (rev 971)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/doc/XWikiAttachment.java	2006-03-12 22:36:14 UTC (rev 972)
@@ -397,7 +397,7 @@
     }
 
 
-    public Version[] getVersions() {
+    public synchronized Version[] getVersions() {
         Node[] nodes = getArchive().changeLog();
         Version[] versions = new Version[nodes.length];
         for (int i=0;i<nodes.length;i++) {
@@ -408,7 +408,7 @@
 
     // We assume versions go from 1.1 to the current one
     // This allows not to read the full archive file
-    public List getVersionList() throws XWikiException {
+    public synchronized List getVersionList() throws XWikiException {
             List list = new ArrayList();
             Version v = new Version("1.1");
             while (true) {
@@ -430,12 +430,12 @@
 
     public void loadContent(XWikiContext context) throws XWikiException {
         if (attachment_content==null)
-            getDoc().getStore().loadAttachmentContent(this, context, true);
+            context.getWiki().getAttachmentStore().loadAttachmentContent(this, context, true);
     }
 
     public void loadArchive(XWikiContext context) throws XWikiException {
         if (attachment_archive==null)
-            getDoc().getStore().loadAttachmentArchive(this, context, true);
+            context.getWiki().getAttachmentStore().loadAttachmentArchive(this, context, true);
     }
 
     public void updateContentArchive(XWikiContext context) throws XWikiException {
@@ -444,7 +444,7 @@
 
         if (attachment_archive==null) {
              try {
-               getDoc().getStore().loadAttachmentArchive(this, context, true);
+               context.getWiki().getAttachmentStore().loadAttachmentArchive(this, context, true);
              } catch (XWikiException e) {
                 if (!(e.getException() instanceof ObjectNotFoundException))
                     throw e;
@@ -479,7 +479,7 @@
     public XWikiAttachment getAttachmentRevision(String rev, XWikiContext context) throws XWikiException {
 
         try {
-            context.getWiki().getStore().loadAttachmentArchive(this, context, true);
+            context.getWiki().getAttachmentStore().loadAttachmentArchive(this, context, true);
 
             Archive archive = getArchive();
 

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/doc/XWikiDocument.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/doc/XWikiDocument.java	2006-03-12 08:36:43 UTC (rev 971)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/doc/XWikiDocument.java	2006-03-12 22:36:14 UTC (rev 972)
@@ -471,15 +471,25 @@
     }
 
     public String getAttachmentURL(String filename, String action, XWikiContext context) {
-        URL url = context.getURLFactory().createAttachmentURL(filename, getWeb(), getName(), action, context);
+        URL url = context.getURLFactory().createAttachmentURL(filename, getWeb(), getName(), action, null, context);
         return context.getURLFactory().getURL(url, context);
     }
 
+    public String getAttachmentURL(String filename, String action, String querystring, XWikiContext context) {
+        URL url = context.getURLFactory().createAttachmentURL(filename, getWeb(), getName(), action, querystring, context);
+        return context.getURLFactory().getURL(url, context);
+    }
+
     public String getAttachmentRevisionURL(String filename, String revision, XWikiContext context) {
-        URL url = context.getURLFactory().createAttachmentRevisionURL(filename, getWeb(), getName(), revision, context);
+        URL url = context.getURLFactory().createAttachmentRevisionURL(filename, getWeb(), getName(), revision, null, context);
         return context.getURLFactory().getURL(url, context);
     }
 
+    public String getAttachmentRevisionURL(String filename, String revision, String querystring, XWikiContext context) {
+        URL url = context.getURLFactory().createAttachmentRevisionURL(filename, getWeb(), getName(), revision, querystring, context);
+        return context.getURLFactory().getURL(url, context);
+    }
+
     public String getURL(String action, boolean redirect, XWikiContext context) {
         URL url = context.getURLFactory().createURL(getWeb(), getName(), action, redirect, context);
         if (redirect) {
@@ -1614,7 +1624,7 @@
             if (getDatabase() != null)
                 context.setDatabase(getDatabase());
 
-            getStore().saveAttachmentContent(attachment, context, true);
+            context.getWiki().getAttachmentStore().saveAttachmentContent(attachment, context, true);
         } finally {
             if (database != null)
                 context.setDatabase(database);
@@ -1629,7 +1639,7 @@
             if (getDatabase() != null)
                 context.setDatabase(getDatabase());
 
-            getStore().loadAttachmentContent(attachment, context, true);
+            context.getWiki().getAttachmentStore().loadAttachmentContent(attachment, context, true);
         } finally {
             if (database != null)
                 context.setDatabase(database);
@@ -1644,7 +1654,7 @@
             if (getDatabase() != null)
                 context.setDatabase(getDatabase());
 
-            getStore().deleteXWikiAttachment(attachment, context, true);
+            context.getWiki().getAttachmentStore().deleteXWikiAttachment(attachment, context, true);
         } finally {
             if (database != null)
                 context.setDatabase(database);

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/monitor/api/MonitorPlugin.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/monitor/api/MonitorPlugin.java	2006-03-12 08:36:43 UTC (rev 971)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/monitor/api/MonitorPlugin.java	2006-03-12 22:36:14 UTC (rev 972)
@@ -1,24 +1,24 @@
-/*
- * Copyright 2006, XpertNet SARL, and individual contributors as indicated
- * by the contributors.txt.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- * @author sdumitriu
- */
+/*
+ * Copyright 2006, XpertNet SARL, and individual contributors as indicated
+ * by the contributors.txt.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ * @author sdumitriu
+ */
 
 package com.xpn.xwiki.monitor.api;
 
@@ -70,8 +70,8 @@
             Thread cthread = Thread.currentThread();
             MonitorData mdata = (MonitorData) activeTimerDataList.get(cthread);
             if (mdata!=null) {
-                activeTimerDataList.remove(cthread);
-                lastUnfinishedTimerDataList.add(mdata);
+                removeFromActiveTimerDataList(cthread);
+                addToLastUnfinishedTimerDataList(mdata);
                 if (log.isInfoEnabled()) {
                     log.info("MONITOR: Thread " + cthread.getName() + " for page " + mdata.getWikiPage() + " did not call endRequest");
                 }
@@ -87,6 +87,13 @@
         }
     }
 
+    private void addToLastUnfinishedTimerDataList(MonitorData mdata) {
+        // We should remove the oldest entry
+        if (lastUnfinishedTimerDataList.isFull())
+         lastUnfinishedTimerDataList.remove(lastUnfinishedTimerDataList.get());
+        lastUnfinishedTimerDataList.add(mdata);
+    }
+
     public void endRequest() {
         if (isActive()==false)
             return;
@@ -103,8 +110,8 @@
             mdata.endRequest(true);
             addDuration(mdata.getDuration());
             addTimerDuration(mdata);
-            activeTimerDataList.remove(cthread);
-            lastTimerDataList.add(mdata);
+            removeFromActiveTimerDataList(cthread);
+            addToTimerDataList(mdata);
         } catch (Throwable e) {
             if (log.isWarnEnabled()) {
                 log.warn("MONITOR: endRequest failed with exception " + e);
@@ -113,6 +120,18 @@
         }
     }
 
+    private void removeFromActiveTimerDataList(Thread cthread) {
+        if (activeTimerDataList.containsKey(cthread))
+         activeTimerDataList.remove(cthread);
+    }
+
+    private void addToTimerDataList(MonitorData mdata) {
+        // We should remove the oldest entry
+        if (lastTimerDataList.isFull())
+         lastTimerDataList.remove(lastTimerDataList.get());
+        lastTimerDataList.add(mdata);
+    }
+
     public void setWikiPage(String page) {
         if (isActive()==false)
             return;

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/pdf/impl/PdfURLFactory.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/pdf/impl/PdfURLFactory.java	2006-03-12 08:36:43 UTC (rev 971)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/pdf/impl/PdfURLFactory.java	2006-03-12 22:36:14 UTC (rev 972)
@@ -54,7 +54,7 @@
             return file.toURL();
         } catch (Exception e) {
             e.printStackTrace();
-            return super.createAttachmentURL(filename, web, name, action, xwikidb, context);
+            return super.createAttachmentURL(filename, web, name, action, null, xwikidb, context);
         }
     }
 

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/XWikiDefaultPlugin.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/XWikiDefaultPlugin.java	2006-03-12 08:36:43 UTC (rev 971)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/XWikiDefaultPlugin.java	2006-03-12 22:36:14 UTC (rev 972)
@@ -1,24 +1,24 @@
-/*
- * Copyright 2006, XpertNet SARL, and individual contributors as indicated
- * by the contributors.txt.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- * @author moghrabix
- */
+/*
+ * Copyright 2006, XpertNet SARL, and individual contributors as indicated
+ * by the contributors.txt.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ * @author moghrabix
+ */
 
 package com.xpn.xwiki.plugin;
 

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/XWikiPluginManager.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/XWikiPluginManager.java	2006-03-12 08:36:43 UTC (rev 971)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/XWikiPluginManager.java	2006-03-12 22:36:14 UTC (rev 972)
@@ -1,25 +1,25 @@
-/*
- * Copyright 2006, XpertNet SARL, and individual contributors as indicated
- * by the contributors.txt.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- * @author moghrabix
- * @author sdumitriu
- */
+/*
+ * Copyright 2006, XpertNet SARL, and individual contributors as indicated
+ * by the contributors.txt.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ * @author moghrabix
+ * @author sdumitriu
+ */
 
 package com.xpn.xwiki.plugin;
 
@@ -180,12 +180,13 @@
     }
 
     public XWikiAttachment downloadAttachment(XWikiAttachment attachment, XWikiContext context) {
-	for (int i=0;i<plugins.size();i++) {
-	    try {
-	    } catch (Exception e)
-	    {}
-	}
-	return attachment;
+        XWikiAttachment attach = attachment;
+        for (int i=0;i<plugins.size();i++) {
+            try {
+                attach = ((XWikiPluginInterface)plugins_classes.get(plugins.get(i))).downloadAttachment(attach, context);
+            } catch (Exception e)
+            {}
+        }
+        return attach;
     }
-
 }

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/image/ImagePlugin.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/image/ImagePlugin.java	2006-03-12 08:36:43 UTC (rev 971)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/plugin/image/ImagePlugin.java	2006-03-12 22:36:14 UTC (rev 972)
@@ -31,10 +31,12 @@
 import java.awt.Toolkit;
 import java.awt.image.BufferedImage;
 import java.io.ByteArrayOutputStream;
+import java.io.IOException;
 
 import javax.imageio.ImageIO;
 
 import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.XWikiException;
 import com.xpn.xwiki.cache.api.XWikiCache;
 import com.xpn.xwiki.cache.api.XWikiCacheNeedsRefreshException;
 import com.xpn.xwiki.cache.impl.OSCacheCache;
@@ -91,21 +93,33 @@
 	public XWikiAttachment downloadAttachment(XWikiAttachment attachment, XWikiContext context) {
 
 		int height = 0;
+        int width = 0;
 		XWikiAttachment attachmentClone = null;
 		try {
-			
-			height = Integer.parseInt(context.getRequest().getParameter("height"));
-			
+			String sheight = context.getRequest().getParameter("height");
+            String swidth = context.getRequest().getParameter("width");
+
+            if (sheight!=null)
+             height = Integer.parseInt(sheight);
+            if (swidth!=null)
+            width = Integer.parseInt(swidth);
+
 			attachmentClone = (XWikiAttachment) attachment.clone();
-			String key = attachmentClone.getId() + "-" + TYPE_PNG + "-" + height;
+			String key = attachmentClone.getId() + "-" + attachmentClone.getVersion() + "-" + TYPE_PNG + "-" + width + "-" + height;
 			
 			if (imageCache != null) {
 				try {
 					attachmentClone.setContent((byte []) imageCache.getFromCache(key));
 				} catch (XWikiCacheNeedsRefreshException e) {
 					try {
-						attachmentClone = this.getImageByHeight(attachmentClone, height, context);
-						imageCache.putInCache(key, attachmentClone.getContent(context));
+                        if (width==0)
+						 attachmentClone = this.getImageByHeight(attachmentClone, height, context);
+						else if (height==0)
+                            attachmentClone = this.getImageByWidth(attachmentClone, width, context);
+                        else
+                            attachmentClone = this.getImage(attachmentClone, width, height, context);
+
+                        imageCache.putInCache(key, attachmentClone.getContent(context));
 					} catch (Exception e2) {
 						imageCache.cancelUpdate(key);
 						throw e2;
@@ -127,14 +141,9 @@
 			throw new PluginException(name,  PluginException.ERROR_XWIKI_NOT_IMPLEMENTED,
 					"Only JPG, PNG or BMP images are supported.");
 
-		Toolkit tk = Toolkit.getDefaultToolkit();
-		Image imgOri = tk.createImage(attachment.getContent(context));
+        Image imgOri = getImage(attachment, context);
 
-		MediaTracker mediaTracker = new MediaTracker(new Container());
-		mediaTracker.addImage(imgOri, 0);
-		mediaTracker.waitForID(0);
-
-		int imgOriWidth = imgOri.getWidth(null);
+        int imgOriWidth = imgOri.getWidth(null);
 		int imgOriHeight = imgOri.getHeight(null);
 
 		if (thumbnailHeight >= imgOriHeight)
@@ -143,34 +152,88 @@
 
 		double imageRatio = (double) imgOriWidth / (double) imgOriHeight;
 		int thumbnailWidth = (int) (thumbnailHeight * imageRatio);
+        createThumbnail(thumbnailWidth, thumbnailHeight, imgOri, attachment);
+        return attachment;
+	}
 
-		// draw original image to thumbnail image object and
-		// scale it to the new size on-the-fly
-		BufferedImage imgTN = new BufferedImage(thumbnailWidth, thumbnailHeight, BufferedImage.TYPE_INT_RGB);
-		Graphics2D graphics2D = imgTN.createGraphics();
-		graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
-		graphics2D.drawImage(imgOri, 0, 0, thumbnailWidth, thumbnailHeight, null);
+    public XWikiAttachment getImage(XWikiAttachment attachment, int thumbnailWidth, int thumbnailHeight, XWikiContext context) throws Exception {
 
-		// save thumbnail image to bout
-		ByteArrayOutputStream bout = new ByteArrayOutputStream();
-		ImageIO.write(imgTN, "PNG", bout);
+        if (getType(attachment.getMimeType(context)) == 0)
+            throw new PluginException(name,  PluginException.ERROR_XWIKI_NOT_IMPLEMENTED,
+                    "Only JPG, PNG or BMP images are supported.");
 
-		
-		attachment.setContent(bout.toByteArray());
-		
-		return attachment;
-	}
+        Image imgOri = getImage(attachment, context);
 
-	public static int getType(String mimeType) {
-	        if (mimeType.equals("image/jpg"))
-	            return TYPE_JPG;
-	        if (mimeType.equals("image/jpeg"))
-	            return TYPE_JPG;
-	        if (mimeType.equals("image/png"))
-	            return TYPE_PNG;
-	        if (mimeType.equals("image/bmp"))
-	            return TYPE_BMP;
-	        return 0;
-	}
+        int imgOriWidth = imgOri.getWidth(null);
+        int imgOriHeight = imgOri.getHeight(null);
 
+        if (thumbnailHeight >= imgOriHeight)
+            throw new PluginException(name, PluginException.ERROR_XWIKI_DIFF_METADATA_ERROR,
+                    "Thumbnail image not created: the height is higher than the original one.");
+
+        if (thumbnailWidth >= imgOriWidth)
+            throw new PluginException(name, PluginException.ERROR_XWIKI_DIFF_METADATA_ERROR,
+                    "Thumbnail image not created: the width is higher than the original one.");
+
+        createThumbnail(thumbnailWidth, thumbnailHeight, imgOri, attachment);
+        return attachment;
+    }
+
+    private Image getImage(XWikiAttachment attachment, XWikiContext context) throws XWikiException, InterruptedException {
+        Toolkit tk = Toolkit.getDefaultToolkit();
+        Image imgOri = tk.createImage(attachment.getContent(context));
+
+        MediaTracker mediaTracker = new MediaTracker(new Container());
+        mediaTracker.addImage(imgOri, 0);
+        mediaTracker.waitForID(0);
+        return imgOri;
+    }
+
+    public XWikiAttachment getImageByWidth(XWikiAttachment attachment, int thumbnailWidth, XWikiContext context) throws Exception {
+
+        if (getType(attachment.getMimeType(context)) == 0)
+            throw new PluginException(name,  PluginException.ERROR_XWIKI_NOT_IMPLEMENTED,
+                    "Only JPG, PNG or BMP images are supported.");
+
+        Image imgOri = getImage(attachment, context);
+        int imgOriWidth = imgOri.getWidth(null);
+        int imgOriHeight = imgOri.getHeight(null);
+
+        if (thumbnailWidth >= imgOriWidth)
+            throw new PluginException(name, PluginException.ERROR_XWIKI_DIFF_METADATA_ERROR,
+                    "Thumbnail image not created: the width is higher than the original one.");
+
+        double imageRatio = (double) imgOriWidth / (double) imgOriHeight;
+        int thumbnailHeight = (int) (thumbnailWidth / imageRatio);
+
+        createThumbnail(thumbnailWidth, thumbnailHeight, imgOri, attachment);
+        return attachment;
+    }
+
+    private void createThumbnail(int thumbnailWidth, int thumbnailHeight, Image imgOri, XWikiAttachment attachment) throws IOException {
+        // draw original image to thumbnail image object and
+        // scale it to the new size on-the-fly
+        BufferedImage imgTN = new BufferedImage(thumbnailWidth, thumbnailHeight, BufferedImage.TYPE_INT_RGB);
+        Graphics2D graphics2D = imgTN.createGraphics();
+        graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
+        graphics2D.drawImage(imgOri, 0, 0, thumbnailWidth, thumbnailHeight, null);
+
+        // save thumbnail image to bout
+        ByteArrayOutputStream bout = new ByteArrayOutputStream();
+        ImageIO.write(imgTN, "PNG", bout);
+        attachment.setContent(bout.toByteArray());
+    }
+
+    public static int getType(String mimeType) {
+            if (mimeType.equals("image/jpg"))
+                return TYPE_JPG;
+            if (mimeType.equals("image/jpeg"))
+                return TYPE_JPG;
+            if (mimeType.equals("image/png"))
+                return TYPE_PNG;
+            if (mimeType.equals("image/bmp"))
+                return TYPE_BMP;
+            return 0;
+    }
+
 }

Added: xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiAttachmentStoreInterface.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiAttachmentStoreInterface.java	2006-03-12 08:36:43 UTC (rev 971)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiAttachmentStoreInterface.java	2006-03-12 22:36:14 UTC (rev 972)
@@ -0,0 +1,22 @@
+package com.xpn.xwiki.store;
+
+import com.xpn.xwiki.doc.XWikiAttachment;
+import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.XWikiException;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: ludovic
+ * Date: 10 mars 2006
+ * Time: 13:58:58
+ * To change this template use File | Settings | File Templates.
+ */
+public interface XWikiAttachmentStoreInterface {
+    public void saveAttachmentContent(XWikiAttachment attachment, XWikiContext context, boolean bTransaction) throws XWikiException;
+    public void saveAttachmentContent(XWikiAttachment attachment, boolean bParentUpdate, XWikiContext context, boolean bTransaction) throws XWikiException;
+    public void loadAttachmentContent(XWikiAttachment attachment, XWikiContext context, boolean bTransaction) throws XWikiException;
+    public void loadAttachmentArchive(XWikiAttachment attachment, XWikiContext context, boolean bTransaction) throws XWikiException;
+    public void deleteXWikiAttachment(XWikiAttachment attachment, XWikiContext context, boolean bTransaction) throws XWikiException;
+    public void deleteXWikiAttachment(XWikiAttachment attachment, boolean parentUpdate, XWikiContext context, boolean bTransaction) throws XWikiException;
+    public void cleanUp(XWikiContext context);
+}

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiCacheStore.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiCacheStore.java	2006-03-12 08:36:43 UTC (rev 971)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiCacheStore.java	2006-03-12 22:36:14 UTC (rev 972)
@@ -1,26 +1,26 @@
-/*
- * Copyright 2006, XpertNet SARL, and individual contributors as indicated
- * by the contributors.txt.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- * @author ludovic
- * @author sdumitriu
- * @author thomas
- */
+/*
+ * Copyright 2006, XpertNet SARL, and individual contributors as indicated
+ * by the contributors.txt.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ * @author ludovic
+ * @author sdumitriu
+ * @author thomas
+ */
 
 package com.xpn.xwiki.store;
 
@@ -238,26 +238,6 @@
         return store.searchDocuments(wheresql, distinctbyname, customMapping, checkRight, nb, start, context);
     }
 
-    public void saveAttachmentContent(XWikiAttachment attachment, XWikiContext context, boolean bTransaction) throws XWikiException {
-        store.saveAttachmentContent(attachment, context, bTransaction);
-    }
-
-    public void saveAttachmentContent(XWikiAttachment attachment, boolean bParentUpdate, XWikiContext context, boolean bTransaction) throws XWikiException {
-        store.saveAttachmentContent(attachment, bParentUpdate, context, bTransaction);
-    }
-
-    public void loadAttachmentContent(XWikiAttachment attachment, XWikiContext context, boolean bTransaction) throws XWikiException {
-        store.loadAttachmentContent(attachment, context, bTransaction);
-    }
-
-    public void loadAttachmentArchive(XWikiAttachment attachment, XWikiContext context, boolean bTransaction) throws XWikiException {
-        store.loadAttachmentArchive(attachment, context, bTransaction);
-    }
-
-    public void deleteXWikiAttachment(XWikiAttachment attachment, XWikiContext context, boolean bTransaction) throws XWikiException {
-        store.deleteXWikiAttachment(attachment, context, bTransaction);
-    }
-
     public XWikiLock loadLock(long docId, XWikiContext context, boolean bTransaction) throws XWikiException {
         return store.loadLock(docId, context, bTransaction);
     }

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiCacheStoreInterface.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiCacheStoreInterface.java	2006-03-12 08:36:43 UTC (rev 971)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiCacheStoreInterface.java	2006-03-12 22:36:14 UTC (rev 972)
@@ -1,24 +1,24 @@
-/*
- * Copyright 2006, XpertNet SARL, and individual contributors as indicated
- * by the contributors.txt.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- * @author ludovic
- */
+/*
+ * Copyright 2006, XpertNet SARL, and individual contributors as indicated
+ * by the contributors.txt.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ * @author ludovic
+ */
 
 package com.xpn.xwiki.store;
 

Added: xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiHibernateAttachmentStore.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiHibernateAttachmentStore.java	2006-03-12 08:36:43 UTC (rev 971)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiHibernateAttachmentStore.java	2006-03-12 22:36:14 UTC (rev 972)
@@ -0,0 +1,201 @@
+package com.xpn.xwiki.store;
+
+import com.xpn.xwiki.doc.XWikiAttachment;
+import com.xpn.xwiki.doc.XWikiAttachmentContent;
+import com.xpn.xwiki.doc.XWikiAttachmentArchive;
+import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.XWiki;
+import org.hibernate.Session;
+import org.hibernate.Query;
+import org.hibernate.SessionFactory;
+
+import java.util.List;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: ludovic
+ * Date: 10 mars 2006
+ * Time: 14:02:58
+ * To change this template use File | Settings | File Templates.
+ */
+public class XWikiHibernateAttachmentStore extends XWikiHibernateBaseStore implements XWikiAttachmentStoreInterface {
+
+    /**
+     * THis allows to initialize our storage engine.
+     * The hibernate config file path is taken from xwiki.cfg
+     * or directly in the WEB-INF directory.
+     * @param xwiki
+     * @param context
+     */
+    public XWikiHibernateAttachmentStore(XWiki xwiki, XWikiContext context) {
+        super(xwiki, context);
+    }
+
+    /**
+     * Initialize the storage engine with a specific path
+     * This is used for tests.
+     * @param hibpath
+     */
+    public XWikiHibernateAttachmentStore(String hibpath) {
+        super(hibpath);
+    }
+
+    public void saveAttachmentContent(XWikiAttachment attachment, XWikiContext context, boolean bTransaction) throws XWikiException {
+        saveAttachmentContent(attachment, true, context, bTransaction);
+    }
+
+    public void saveAttachmentContent(XWikiAttachment attachment, boolean parentUpdate, XWikiContext context, boolean bTransaction) throws XWikiException {
+        try {
+            XWikiAttachmentContent content = attachment.getAttachment_content();
+            if (content.isContentDirty()) {
+                attachment.updateContentArchive(context);
+            }
+            XWikiAttachmentArchive archive = attachment.getAttachment_archive();
+
+            if (bTransaction) {
+                checkHibernate(context);
+                bTransaction = beginTransaction(context);
+            }
+            Session session = getSession(context);
+
+
+            Query query = session.createQuery("select attach.id from XWikiAttachmentContent as attach where attach.id = :id");
+            query.setLong("id", content.getId());
+            if (query.uniqueResult()==null)
+                session.save(content);
+            else
+                session.update(content);
+
+            query = session.createQuery("select attach.id from XWikiAttachmentArchive as attach where attach.id = :id");
+            query.setLong("id", archive.getId());
+            if (query.uniqueResult()==null)
+                session.save(archive);
+            else
+                session.update(archive);
+
+            if (parentUpdate)
+                context.getWiki().getStore().saveXWikiDoc(attachment.getDoc(), context, true);
+            if (bTransaction) {
+                endTransaction(context, true);
+            }
+        }
+        catch (Exception e) {
+            Object[] args = { attachment.getFilename(), attachment.getDoc().getFullName() };
+            throw new XWikiException( XWikiException.MODULE_XWIKI_STORE, XWikiException.ERROR_XWIKI_STORE_HIBERNATE_SAVING_ATTACHMENT,
+                    "Exception while saving attachment {0} of document {1}", e, args);
+        } finally {
+            try {
+                if (bTransaction)
+                    endTransaction(context, false);
+            } catch (Exception e) {}
+        }
+
+    }
+
+    public void loadAttachmentContent(XWikiAttachment attachment, XWikiContext context, boolean bTransaction) throws XWikiException {
+        try {
+            if (bTransaction) {
+                checkHibernate(context);
+                bTransaction = beginTransaction(false, context);
+            }
+            Session session = getSession(context);
+
+
+            XWikiAttachmentContent content = new XWikiAttachmentContent(attachment);
+            attachment.setAttachment_content(content);
+
+            session.load(content, new Long(content.getId()));
+
+            if (bTransaction)
+                endTransaction(context, false, false);
+        }
+        catch (Exception e) {
+            Object[] args = { attachment.getFilename(), attachment.getDoc().getFullName() };
+            throw new XWikiException( XWikiException.MODULE_XWIKI_STORE, XWikiException.ERROR_XWIKI_STORE_HIBERNATE_LOADING_ATTACHMENT,
+                    "Exception while loading attachment {0} of document {1}", e, args);
+        } finally {
+            try {
+                if (bTransaction)
+                    endTransaction(context, false, false);
+            } catch (Exception e) {}
+        }
+    }
+
+    public void loadAttachmentArchive(XWikiAttachment attachment, XWikiContext context, boolean bTransaction) throws XWikiException {
+        try {
+            if (bTransaction) {
+                checkHibernate(context);
+                bTransaction = beginTransaction(false, context);
+            }
+            Session session = getSession(context);
+
+
+            XWikiAttachmentArchive archive = new XWikiAttachmentArchive();
+            archive.setAttachment(attachment);
+            attachment.setAttachment_archive(archive);
+
+            session.load(archive, new Long(archive.getId()));
+
+            if (bTransaction)
+                endTransaction(context, false, false);
+        }
+        catch (Exception e) {
+            Object[] args = { attachment.getFilename(), attachment.getDoc().getFullName() };
+            throw new XWikiException( XWikiException.MODULE_XWIKI_STORE, XWikiException.ERROR_XWIKI_STORE_HIBERNATE_LOADING_ATTACHMENT,
+                    "Exception while loading attachment {0} of document {1}", e, args);
+        } finally {
+            try {
+                if (bTransaction)
+                    endTransaction(context, false, false);
+            } catch (Exception e) {}
+        }
+    }
+
+    public void deleteXWikiAttachment(XWikiAttachment attachment,  XWikiContext context, boolean bTransaction) throws XWikiException {
+        deleteXWikiAttachment(attachment, true, context, bTransaction);
+    }
+
+    public void deleteXWikiAttachment(XWikiAttachment attachment, boolean parentUpdate, XWikiContext context, boolean bTransaction) throws XWikiException {
+        try {
+            if (bTransaction) {
+                checkHibernate(context);
+                bTransaction = beginTransaction(context);
+            }
+
+            Session session = getSession(context);
+
+            // Delete the three attachement entries
+            loadAttachmentContent(attachment, context, false);
+            session.delete(attachment.getAttachment_content());
+            loadAttachmentArchive(attachment, context, false);
+            session.delete(attachment.getAttachment_archive());
+            session.delete(attachment);
+
+            if (parentUpdate) {
+                List list = attachment.getDoc().getAttachmentList();
+                for (int i=0;i<list.size();i++) {
+                    XWikiAttachment attach = (XWikiAttachment) list.get(i);
+                    if (attachment.getFilename().equals(attach.getFilename())) {
+                        list.remove(i);
+                        break;
+                    }
+                }
+                context.getWiki().getStore().saveXWikiDoc(attachment.getDoc(), context, false);
+            }
+            if (bTransaction) {
+                endTransaction(context, true);
+            }
+        }
+        catch (Exception e) {
+            Object[] args = { attachment.getFilename(), attachment.getDoc().getFullName() };
+            throw new XWikiException( XWikiException.MODULE_XWIKI_STORE, XWikiException.ERROR_XWIKI_STORE_HIBERNATE_DELETING_ATTACHMENT,
+                    "Exception while deleting attachment {0} of document {1}", e, args);
+        } finally {
+            try {
+                if (bTransaction)
+                    endTransaction(context, false);
+            } catch (Exception e) {}
+        }
+    }
+}

Added: xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiHibernateBaseStore.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiHibernateBaseStore.java	2006-03-12 08:36:43 UTC (rev 971)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiHibernateBaseStore.java	2006-03-12 22:36:14 UTC (rev 972)
@@ -0,0 +1,717 @@
+package com.xpn.xwiki.store;
+
+import org.hibernate.SessionFactory;
+import org.hibernate.HibernateException;
+import org.hibernate.Session;
+import org.hibernate.Transaction;
+import org.hibernate.dialect.Dialect;
+import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
+import org.hibernate.impl.SessionFactoryImpl;
+import org.hibernate.impl.SessionImpl;
+import org.hibernate.cfg.Configuration;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
+
+import java.util.Map;
+import java.util.HashMap;
+import java.util.Collection;
+import java.util.Date;
+import java.net.URL;
+import java.net.MalformedURLException;
+import java.io.File;
+import java.sql.Connection;
+import java.sql.Statement;
+
+import com.xpn.xwiki.XWiki;
+import com.xpn.xwiki.XWikiContext;
+import com.xpn.xwiki.XWikiException;
+import com.xpn.xwiki.web.XWikiRequest;
+import com.xpn.xwiki.objects.classes.BaseClass;
+import com.xpn.xwiki.util.Util;
+import com.xpn.xwiki.monitor.api.MonitorPlugin;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: ludovic
+ * Date: 10 mars 2006
+ * Time: 14:04:13
+ * To change this template use File | Settings | File Templates.
+ */
+public class XWikiHibernateBaseStore {
+    private static final Log log = LogFactory.getLog(XWikiHibernateBaseStore.class);
+
+    private Map connections = new HashMap();
+    private int nbConnections = 0;
+    private SessionFactory sessionFactory;
+    private Configuration configuration;
+
+    private String hibpath;
+    private URL hiburl;
+
+    /**
+     * THis allows to initialize our storage engine.
+     * The hibernate config file path is taken from xwiki.cfg
+     * or directly in the WEB-INF directory.
+     * @param xwiki
+     * @param context
+     */
+    public XWikiHibernateBaseStore(XWiki xwiki, XWikiContext context) {
+        String path = xwiki.Param("xwiki.store.hibernate.path");
+        if (new File(path).exists() || context.getEngineContext() == null){
+            setPath (path);
+        } else {
+            try {
+                setHibUrl(context.getEngineContext().getResource(path));
+            } catch (MalformedURLException e) {
+            }
+        }
+    }
+
+    /**
+     * Initialize the storage engine with a specific path
+     * This is used for tests.
+     * @param hibpath
+     */
+    public XWikiHibernateBaseStore(String hibpath) {
+        setPath(hibpath);
+    }
+
+    /**
+     * Allows to get the current hibernate config file path
+     * @return
+     */
+    public String getPath() {
+        return hibpath;
+    }
+
+    /**
+     * Allows to set the current hibernate config file path
+     * @param hibpath
+     */
+    public void setPath(String hibpath) {
+        this.hibpath = hibpath;
+    }
+
+    /**
+     * Get's the hibernate config path as an URL
+     * @return
+     */
+    public URL getHibUrl() {
+        return hiburl;
+    }
+
+    /**
+     * Set the hibernate config path as an URL
+     * @param hiburl
+     */
+    public void setHibUrl(URL hiburl) {
+        this.hiburl = hiburl;
+    }
+
+    /**
+     * Allows to init the hibernate configuration
+     * @throws org.hibernate.HibernateException
+     */
+    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());
+    }
+
+    /**
+     * This get's the current session.
+     * This is set in beginTransaction
+     * @param context
+     * @return
+     */
+    public Session getSession(XWikiContext context) {
+        Session session = (Session) context.get("hibsession");
+        return session;
+    }
+
+    /**
+     * Allows to set the current session in the context
+     * This is set in beginTransaction
+     * @param session
+     * @param context
+     */
+    public void setSession(Session session, XWikiContext context) {
+        if (session==null)
+            context.remove("hibsession");
+        else
+            context.put("hibsession", session);
+    }
+
+
+    /**
+     * Allows to get the current transaction from the context
+     * This is set in beginTransaction
+     * @param context
+     * @return
+     */
+    public Transaction getTransaction(XWikiContext context) {
+        Transaction transaction = (Transaction) context.get("hibtransaction");
+        return transaction;
+    }
+
+    /**
+     * Allows to set the current transaction
+     * This is set in beginTransaction
+     * @param transaction
+     * @param context
+     */
+    public void setTransaction(Transaction transaction, XWikiContext context) {
+        if (transaction==null)
+            context.remove("hibtransaction");
+        else
+            context.put("hibtransaction", transaction);
+    }
+
+
+    /**
+     * Allows to shut down the hibernate configuration
+     * Closing all pools and connections
+     * @param context
+     * @throws HibernateException
+     */
+    public void shutdownHibernate(XWikiContext context) throws HibernateException {
+        closeSession(getSession(context));
+        if (getSessionFactory()!=null) {
+            ((SessionFactoryImpl)getSessionFactory()).getConnectionProvider().close();
+        }
+    }
+
+    /**
+     * Allows to update the schema to match the hibernate mapping
+     * @param context
+     * @throws HibernateException
+     */
+    public void updateSchema(XWikiContext context) throws HibernateException {
+        updateSchema(context, false);
+    }
+
+
+    /**
+     * Allows to update the schema to match the hibernate mapping
+     * @param context
+     * @param force defines wether or not to force the update despite the xwiki.cfg settings
+     * @throws HibernateException
+     */
+    public synchronized void updateSchema(XWikiContext context, boolean force) throws HibernateException {
+        try {
+            // 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.isInfoEnabled())
+                        log.info("Schema update deactivated for wiki " + context.getDatabase());
+                    return;
+                }
+
+                if (log.isInfoEnabled())
+                    log.info("Schema update for wiki " + context.getDatabase());
+
+            } catch (Exception e) {}
+
+            String fullName = ((context!=null)&&(context.getWiki()!=null)&&(context.getWiki().isMySQL())) ?  "concat('xwd_web','.','xwd_name)" : "xwd_fullname";
+            String[] schemaSQL = getSchemaUpdateScript(getConfiguration(), context);
+            String[] addSQL = {
+                // Make sure we have no null valued in integer fields
+                "update xwikidoc set xwd_translation=0 where xwd_translation is null",
+                "update xwikidoc set xwd_language='' where xwd_language is null",
+                "update xwikidoc set xwd_default_language='' where xwd_default_language is null",
+                "update xwikidoc set xwd_fullname=" + fullName + " where xwd_fullname is null",
+                "update xwikidoc set xwd_elements=3 where xwd_elements is null",
+                "delete from xwikiproperties where xwp_name like 'editbox_%' and xwp_classtype='com.xpn.xwiki.objects.LongProperty'",
+                "delete from xwikilongs where xwl_name like 'editbox_%'"
+                };
+
+            String[] sql = new String[schemaSQL.length+addSQL.length];
+            for (int i=0;i<schemaSQL.length;i++)
+                sql[i] = schemaSQL[i];
+            for (int i=0;i<addSQL.length;i++)
+                sql[i + schemaSQL.length] = addSQL[i];
+
+            updateSchema(sql, context);
+        } finally {
+
+            if (log.isInfoEnabled())
+                log.info("Schema update for wiki " + context.getDatabase() + " done");
+        }
+    }
+
+    /**
+     * This function gets the schema update scripts generated by comparing the current database
+     * woth the current hibernate mapping config.
+     * @param config
+     * @param context
+     * @return
+     * @throws HibernateException
+     */
+    public String[] getSchemaUpdateScript(Configuration config, XWikiContext context) throws HibernateException {
+        String[] schemaSQL = null;
+
+        Session session;
+        Connection connection;
+        DatabaseMetadata meta;
+        Statement stmt=null;
+        Dialect dialect = Dialect.getDialect(getConfiguration().getProperties());
+        boolean bTransaction = true;
+
+        try {
+            bTransaction = beginTransaction(false, context);
+            session = getSession(context);
+            connection = session.connection();
+            setDatabase(session, context);
+
+            meta = new DatabaseMetadata(connection, dialect);
+            stmt = connection.createStatement();
+
+            schemaSQL = config.generateSchemaUpdateScript(dialect, meta);
+        }
+        catch (Exception e) {
+            if ( log.isErrorEnabled() ) log.error("Failed updating schema: " + e.getMessage());
+        }
+        finally {
+            try {
+                if (stmt!=null) stmt.close();
+                if (bTransaction)
+                    endTransaction(context, false, false);
+            }
+            catch (Exception e) {
+            }
+        }
+        return schemaSQL;
+    }
+
+    /**
+     * Runs the update script on the current database
+     * @param createSQL
+     * @param context
+     */
+    public void updateSchema(String[] createSQL, XWikiContext context) {
+        // Updating the schema for custom mappings
+        Session session;
+        Connection connection;
+        Statement stmt=null;
+        boolean bTransaction = true;
+        MonitorPlugin monitor  = Util.getMonitorPlugin(context);
+
+        try {
+            bTransaction = beginTransaction(context);
+            session = getSession(context);
+            connection = session.connection();
+            setDatabase(session, context);
+            stmt = connection.createStatement();
+
+            // Start monitoring timer
+            if (monitor!=null)
+                monitor.startTimer("sqlupgrade");
+            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 (Exception e) {
+            if ( log.isErrorEnabled() ) log.error("Failed updating schema: " + e.getMessage());
+        }
+        finally {
+            try {
+                if (stmt!=null) stmt.close();
+            } catch (Exception e)  {};
+            try {
+                if (bTransaction)
+                    endTransaction(context, true);
+            } catch (Exception e) {}
+
+            // End monitoring timer
+            if (monitor!=null)
+                monitor.endTimer("sqlupgrade");
+        }
+    }
+
+
+    /**
+     * Custom Mapping
+     * This function update the schema based on the dynamic custom mapping
+     * provided by the class
+     * @param bclass
+     * @param context
+     * @throws com.xpn.xwiki.XWikiException
+     */
+    public void updateSchema(BaseClass bclass, XWikiContext context) throws XWikiException {
+        String custommapping = bclass.getCustomMapping();
+        if (!bclass.hasExternalCustomMapping())
+         return;
+
+        Configuration config = makeMapping(bclass.getName(), custommapping);
+        /* if (isValidCustomMapping(bclass.getName(), config, bclass)==false) {
+            throw new XWikiException( XWikiException.MODULE_XWIKI_STORE, XWikiException.ERROR_XWIKI_STORE_HIBERNATE_INVALID_MAPPING,
+                    "Cannot update schema for class " + bclass.getName() + " because of an invalid mapping");
+        } */
+
+        String[] sql = getSchemaUpdateScript(config, context);
+        updateSchema(sql, context);
+    }
+
+    /**
+     * Initializes hibernate and calls updateSchema if necessary
+     * @param context
+     * @throws HibernateException
+     */
+    public void checkHibernate(XWikiContext context) throws HibernateException {
+
+        if (getSessionFactory()==null) {
+            initHibernate();
+
+            /* Check Schema */
+            if (getSessionFactory()!=null) {
+                updateSchema(context);
+            }
+        }
+    }
+
+    /**
+     * Checks if this xwiki setup is virtual
+     * meaning if multiple wikis can be accessed using the same database pool
+     * @param context
+     * @return
+     */
+    protected boolean isVirtual(XWikiContext context) {
+        if ((context==null)||(context.getWiki()==null))
+            return true;
+        return context.getWiki().isVirtual();
+    }
+
+    /**
+     * Virtual Wikis
+     * Allows to switch database connection
+     * @param session
+     * @param context
+     * @throws XWikiException
+     */
+    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) {
+                    if (!database.equals(session.connection().getCatalog()))
+                          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);
+            }
+        }
+    }
+
+    /**
+     * Begins a transaction
+     * @param context
+     * @return
+     * @throws XWikiException
+     */
+    public boolean beginTransaction(XWikiContext context) throws XWikiException {
+            return beginTransaction(null, true, context);
+    }
+
+    /**
+     * Begins a transaction
+     * @param withTransaction
+     * @param context
+     * @return
+     * @throws XWikiException
+     */
+    public boolean beginTransaction(boolean withTransaction, XWikiContext context) throws XWikiException {
+            return beginTransaction(null, withTransaction, context);
+    }
+
+    /**
+     * Begins a transaction with a specific SessionFactory
+     * @param sfactory
+     * @param context
+     * @return
+     * @throws XWikiException
+     */
+    public boolean beginTransaction(SessionFactory sfactory, XWikiContext context) throws XWikiException {
+        return beginTransaction(sfactory, true, context);
+    }
+
+    /**
+     * Begins a transaction with a specific SessionFactory
+     * @param sfactory
+     * @param withTransaction
+     * @param context
+     * @return
+     * @throws HibernateException
+     * @throws XWikiException
+     */
+    public boolean beginTransaction(SessionFactory sfactory, boolean withTransaction, 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 (session!=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");
+            if (sfactory==null)
+                session = (SessionImpl)getSessionFactory().openSession();
+            else
+                session = sfactory.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;
+    }
+
+    /**
+     * Adding a connection to the Monitor module
+     * @param connection
+     * @param context
+     */
+    private void addConnection(Connection connection, XWikiContext context) {
+        if (connection!=null)
+            connections.put(connection, new ConnectionMonitor(connection, context));
+    }
+
+    /**
+     * Remove a connection to the Monitor module
+     * @param connection
+     */
+    private void removeConnection(Connection connection) {
+        try {
+            if (connection!=null)
+                connections.remove(connection);
+        } catch (Exception e) {
+        }
+    }
+
+    /**
+     * Ends a transaction
+     * @param context
+     * @param commit should we commit or not
+     */
+    public void endTransaction(XWikiContext context, boolean commit) {
+        endTransaction(context, commit, false);
+    }
+
+    /**
+     * Ends a transaction
+     * @param context
+     * @param commit should we commit or not
+     * @param withTransaction
+     * @throws HibernateException
+     */
+    public void endTransaction(XWikiContext context, boolean commit, boolean withTransaction)
+            throws HibernateException {
+        Session session = null;
+        try {
+            session = getSession(context);
+            Transaction transaction = getTransaction(context);
+            setSession(null, context);
+            setTransaction(null, context);
+
+            if (transaction!=null) {
+                if ( log.isDebugEnabled() ) log.debug("Releasing hibernate transaction " + transaction);
+                if (commit) {
+                    transaction.commit();
+                } else {
+                    transaction.rollback();
+                }
+            }
+        } finally {
+            if (session!=null) {
+                closeSession(session);
+            }
+        }
+    }
+
+    /**
+     * Closes the hibernate session
+     * @param session
+     * @throws HibernateException
+     */
+    private void closeSession(Session session) throws HibernateException {
+        if (session!=null) {
+            try {
+                if ( log.isDebugEnabled() ) log.debug("Releasing hibernate session " + session);
+                Connection connection = session.connection();
+                if ((connection!=null)) {
+                    nbConnections--;
+                    try {
+                        removeConnection(connection);
+                    } catch (Throwable e) {
+                        // This should not happen
+                        e.printStackTrace();
+                    }
+                }
+            } finally {
+                session.close();
+            }
+        }
+    }
+
+    /**
+     * Cleanup all sessions
+     * Used at the shutdown time
+     * @param context
+     */
+    public void cleanUp(XWikiContext context) {
+        try {
+            Session session = getSession(context);
+            if (session!=null) {
+                if ( log.isWarnEnabled() ) log.warn("Cleanup of session was needed: " + session);
+                endTransaction(context, false);
+            }
+        } catch (HibernateException e) {
+        }
+    }
+
+    public SessionFactory getSessionFactory() {
+        return sessionFactory;
+    }
+
+    public void setSessionFactory(SessionFactory sessionFactory) {
+        this.sessionFactory = sessionFactory;
+    }
+
+    public Configuration getConfiguration() {
+        return configuration;
+    }
+
+    public void setConfiguration(Configuration configuration) {
+        this.configuration = configuration;
+    }
+
+    public Collection getConnections() {
+        return connections.values();
+    }
+
+    public int getNbConnections() {
+        return nbConnections;
+    }
+
+    public void setNbConnections(int nbConnections) {
+        this.nbConnections = nbConnections;
+    }
+
+
+    public class ConnectionMonitor {
+        private Exception exception;
+        private Connection connection;
+        private Date date;
+        private URL url = null;
+
+        public ConnectionMonitor(Connection connection, XWikiContext context) {
+            this.setConnection(connection);
+
+            try {
+                setDate(new Date());
+                setException(new XWikiException());
+                XWikiRequest request = context.getRequest();
+                if (request!=null)
+                    setURL(XWiki.getRequestURL(context.getRequest()));
+            } catch (Throwable e) {
+            }
+
+        }
+
+        public Connection getConnection() {
+            return connection;
+        }
+
+        public void setConnection(Connection connection) {
+            this.connection = connection;
+        }
+
+        public Date getDate() {
+            return date;
+        }
+
+        public void setDate(Date date) {
+            this.date = date;
+        }
+
+        public Exception getException() {
+            return exception;
+        }
+
+        public void setException(Exception exception) {
+            this.exception = exception;
+        }
+
+        public URL getURL() {
+            return url;
+        }
+
+        public void setURL(URL url) {
+            this.url = url;
+        }
+
+    }
+
+    protected Configuration makeMapping(String className, String custommapping1) {
+        Configuration hibconfig = new Configuration();
+        {
+            hibconfig.addXML(makeMapping(className , "xwikicustom_" + className.replace('.','_'), custommapping1));
+        }
+        hibconfig.buildMappings();
+        return hibconfig;
+    }
+
+    protected String makeMapping(String entityName, String tableName, String custommapping1) {
+        String custommapping = "<?xml version=\"1.0\"?>\n" +
+                "<!DOCTYPE hibernate-mapping PUBLIC\n" +
+                "\t\"-//Hibernate/Hibernate Mapping DTD//EN\"\n" +
+                "\t\"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd\">\n" +
+                "<hibernate-mapping>" +
+                "<class entity-name=\"" + entityName + "\" table=\"" + tableName+ "\">\n" +
+                " <id name=\"id\" type=\"integer\" unsaved-value=\"any\">\n" +
+                "   <column name=\"XWO_ID\" not-null=\"true\" />\n" +
+                "   <generator class=\"assigned\" />\n" +
+                " </id>\n" +
+                custommapping1 +
+                "</class>\n" +
+                "</hibernate-mapping>";
+        return custommapping;
+    }
+}

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiHibernateStore.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiHibernateStore.java	2006-03-12 08:36:43 UTC (rev 971)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiHibernateStore.java	2006-03-12 22:36:14 UTC (rev 972)
@@ -42,7 +42,6 @@
 import com.xpn.xwiki.objects.classes.TextAreaClass;
 import com.xpn.xwiki.objects.classes.StringClass;
 import com.xpn.xwiki.util.Util;
-import com.xpn.xwiki.web.XWikiRequest;
 import org.apache.commons.jrcs.rcs.Archive;
 import org.apache.commons.jrcs.rcs.Node;
 import org.apache.commons.jrcs.rcs.Version;
@@ -55,33 +54,19 @@
 import org.hibernate.connection.ConnectionProvider;
 import org.hibernate.cfg.Configuration;
 import org.hibernate.cfg.Settings;
-import org.hibernate.dialect.Dialect;
 import org.hibernate.impl.SessionFactoryImpl;
-import org.hibernate.impl.SessionImpl;
-import org.hibernate.tool.hbm2ddl.DatabaseMetadata;
 
-import java.io.File;
 import java.io.Serializable;
 import java.io.BufferedReader;
-import java.net.MalformedURLException;
-import java.net.URL;
 import java.sql.Connection;
 import java.sql.Statement;
 import java.util.*;
 import java.lang.reflect.Field;
 
 
-public class XWikiHibernateStore extends XWikiDefaultStore {
+public class XWikiHibernateStore extends XWikiHibernateBaseStore implements XWikiStoreInterface {
 
     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;
     private Map validTypesMap = new HashMap();
 
     /**
@@ -92,15 +77,7 @@
      * @param context
      */
     public XWikiHibernateStore(XWiki xwiki, XWikiContext context) {
-        String path = xwiki.Param("xwiki.store.hibernate.path");
-        if (new File(path).exists() || context.getEngineContext() == null){
-            setPath (path);
-        } else {
-            try {
-                setHibUrl(context.getEngineContext().getResource(path));
-            } catch (MalformedURLException e) {
-            }
-        }
+        super(xwiki, context);
         initValidColumTypes();
     }
 
@@ -110,7 +87,8 @@
      * @param hibpath
      */
     public XWikiHibernateStore(String hibpath) {
-        setPath(hibpath);
+        super(hibpath);
+        initValidColumTypes();
     }
 
     /**
@@ -131,537 +109,8 @@
         validTypesMap.put("com.xpn.xwiki.objects.classes.BooleanClass" , boolean_types);
     }
 
-    /**
-     * Allows to get the current hibernate config file path
-     * @return
-     */
-    public String getPath() {
-        return hibpath;
-    }
 
     /**
-     * Allows to set the current hibernate config file path
-     * @param hibpath
-     */
-    public void setPath(String hibpath) {
-        this.hibpath = hibpath;
-    }
-
-    /**
-     * Get's the hibernate config path as an URL
-     * @return
-     */
-    public URL getHibUrl() {
-        return hiburl;
-    }
-
-    /**
-     * Set the hibernate config path as an URL
-     * @param hiburl
-     */
-    public void setHibUrl(URL hiburl) {
-        this.hiburl = hiburl;
-    }
-
-    /**
-     * Allows to init the hibernate configuration
-     * @throws HibernateException
-     */
-    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());
-    }
-
-    /**
-     * This get's the current session.
-     * This is set in beginTransaction
-     * @param context
-     * @return
-     */
-    public Session getSession(XWikiContext context) {
-        Session session = (Session) context.get("hibsession");
-        return session;
-    }
-
-    /**
-     * Allows to set the current session in the context
-     * This is set in beginTransaction
-     * @param session
-     * @param context
-     */
-    public void setSession(Session session, XWikiContext context) {
-        if (session==null)
-            context.remove("hibsession");
-        else
-            context.put("hibsession", session);
-    }
-
-
-    /**
-     * Allows to get the current transaction from the context
-     * This is set in beginTransaction
-     * @param context
-     * @return
-     */
-    public Transaction getTransaction(XWikiContext context) {
-        Transaction transaction = (Transaction) context.get("hibtransaction");
-        return transaction;
-    }
-
-    /**
-     * Allows to set the current transaction
-     * This is set in beginTransaction
-     * @param transaction
-     * @param context
-     */
-    public void setTransaction(Transaction transaction, XWikiContext context) {
-        if (transaction==null)
-            context.remove("hibtransaction");
-        else
-            context.put("hibtransaction", transaction);
-    }
-
-
-    /**
-     * Allows to shut down the hibernate configuration
-     * Closing all pools and connections
-     * @param context
-     * @throws HibernateException
-     */
-    public void shutdownHibernate(XWikiContext context) throws HibernateException {
-        closeSession(getSession(context));
-        if (getSessionFactory()!=null) {
-            ((SessionFactoryImpl)getSessionFactory()).getConnectionProvider().close();
-        }
-    }
-
-    /**
-     * Allows to update the schema to match the hibernate mapping
-     * @param context
-     * @throws HibernateException
-     */
-    public void updateSchema(XWikiContext context) throws HibernateException {
-        updateSchema(context, false);
-    }
-
-
-    /**
-     * Allows to update the schema to match the hibernate mapping
-     * @param context
-     * @param force defines wether or not to force the update despite the xwiki.cfg settings
-     * @throws HibernateException
-     */
-    public synchronized void updateSchema(XWikiContext context, boolean force) throws HibernateException {
-        try {
-            // 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.isInfoEnabled())
-                        log.info("Schema update deactivated for wiki " + context.getDatabase());
-                    return;
-                }
-
-                if (log.isInfoEnabled())
-                    log.info("Schema update for wiki " + context.getDatabase());
-
-            } catch (Exception e) {}
-
-            String fullName = ((context!=null)&&(context.getWiki()!=null)&&(context.getWiki().isMySQL())) ?  "concat('xwd_web','.','xwd_name)" : "xwd_fullname";
-            String[] schemaSQL = getSchemaUpdateScript(getConfiguration(), context);
-            String[] addSQL = {
-                // Make sure we have no null valued in integer fields
-                "update xwikidoc set xwd_translation=0 where xwd_translation is null",
-                "update xwikidoc set xwd_language='' where xwd_language is null",
-                "update xwikidoc set xwd_default_language='' where xwd_default_language is null",
-                "update xwikidoc set xwd_fullname=" + fullName + " where xwd_fullname is null",
-                "update xwikidoc set xwd_elements=3 where xwd_elements is null",
-                "delete from xwikiproperties where xwp_name like 'editbox_%' and xwp_classtype='com.xpn.xwiki.objects.LongProperty'",
-                "delete from xwikilongs where xwl_name like 'editbox_%'"    
-                };
-
-            String[] sql = new String[schemaSQL.length+addSQL.length];
-            for (int i=0;i<schemaSQL.length;i++)
-                sql[i] = schemaSQL[i];
-            for (int i=0;i<addSQL.length;i++)
-                sql[i + schemaSQL.length] = addSQL[i];
-
-            updateSchema(sql, context);
-        } finally {
-
-            if (log.isInfoEnabled())
-                log.info("Schema update for wiki " + context.getDatabase() + " done");
-        }
-    }
-
-    /**
-     * This function gets the schema update scripts generated by comparing the current database
-     * woth the current hibernate mapping config.
-     * @param config
-     * @param context
-     * @return
-     * @throws HibernateException
-     */
-    public String[] getSchemaUpdateScript(Configuration config, XWikiContext context) throws HibernateException {
-        String[] schemaSQL = null;
-
-        Session session;
-        Connection connection;
-        DatabaseMetadata meta;
-        Statement stmt=null;
-        Dialect dialect = Dialect.getDialect(getConfiguration().getProperties());
-        boolean bTransaction = true;
-
-        try {
-            bTransaction = beginTransaction(false, context);
-            session = getSession(context);
-            connection = session.connection();
-            setDatabase(session, context);
-
-            meta = new DatabaseMetadata(connection, dialect);
-            stmt = connection.createStatement();
-
-            schemaSQL = config.generateSchemaUpdateScript(dialect, meta);
-        }
-        catch (Exception e) {
-            if ( log.isErrorEnabled() ) log.error("Failed updating schema: " + e.getMessage());
-        }
-        finally {
-            try {
-                if (stmt!=null) stmt.close();
-                if (bTransaction)
-                    endTransaction(context, false, false);
-            }
-            catch (Exception e) {
-            }
-        }
-        return schemaSQL;
-    }
-
-    /**
-     * Runs the update script on the current database
-     * @param createSQL
-     * @param context
-     */
-    public void updateSchema(String[] createSQL, XWikiContext context) {
-        // Updating the schema for custom mappings
-        Session session;
-        Connection connection;
-        Statement stmt=null;
-        boolean bTransaction = true;
-        MonitorPlugin monitor  = Util.getMonitorPlugin(context);
-
-        try {
-            bTransaction = beginTransaction(context);
-            session = getSession(context);
-            connection = session.connection();
-            setDatabase(session, context);
-            stmt = connection.createStatement();
-
-            // Start monitoring timer
-            if (monitor!=null)
-                monitor.startTimer("sqlupgrade");
-            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 (Exception e) {
-            if ( log.isErrorEnabled() ) log.error("Failed updating schema: " + e.getMessage());
-        }
-        finally {
-            try {
-                if (stmt!=null) stmt.close();
-            } catch (Exception e)  {};
-            try {
-                if (bTransaction)
-                    endTransaction(context, true);
-            } catch (Exception e) {}
-
-            // End monitoring timer
-            if (monitor!=null)
-                monitor.endTimer("sqlupgrade");
-        }
-    }
-
-
-    /**
-     * Custom Mapping
-     * This function update the schema based on the dynamic custom mapping
-     * provided by the class
-     * @param bclass
-     * @param context
-     * @throws XWikiException
-     */
-    public void updateSchema(BaseClass bclass, XWikiContext context) throws XWikiException {
-        String custommapping = bclass.getCustomMapping();
-        if (!bclass.hasExternalCustomMapping())
-         return;
-
-        Configuration config = makeMapping(bclass.getName(), custommapping);
-        /* if (isValidCustomMapping(bclass.getName(), config, bclass)==false) {
-            throw new XWikiException( XWikiException.MODULE_XWIKI_STORE, XWikiException.ERROR_XWIKI_STORE_HIBERNATE_INVALID_MAPPING,
-                    "Cannot update schema for class " + bclass.getName() + " because of an invalid mapping");
-        } */
-
-        String[] sql = getSchemaUpdateScript(config, context);
-        updateSchema(sql, context);
-    }
-
-    /**
-     * Initializes hibernate and calls updateSchema if necessary
-     * @param context
-     * @throws HibernateException
-     */
-    public void checkHibernate(XWikiContext context) throws HibernateException {
-
-        if (getSessionFactory()==null) {
-            initHibernate();
-
-            /* Check Schema */
-            if (getSessionFactory()!=null) {
-                updateSchema(context);
-            }
-        }
-    }
-
-    /**
-     * Checks if this xwiki setup is virtual
-     * meaning if multiple wikis can be accessed using the same database pool
-     * @param context
-     * @return
-     */
-    protected boolean isVirtual(XWikiContext context) {
-        if ((context==null)||(context.getWiki()==null))
-            return true;
-        return context.getWiki().isVirtual();
-    }
-
-    /**
-     * Virtual Wikis
-     * Allows to switch database connection
-     * @param session
-     * @param context
-     * @throws XWikiException
-     */
-    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) {
-                    if (!database.equals(session.connection().getCatalog()))
-                          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);
-            }
-        }
-    }
-
-    /**
-     * Begins a transaction
-     * @param context
-     * @return
-     * @throws XWikiException
-     */
-    public boolean beginTransaction(XWikiContext context) throws XWikiException {
-            return beginTransaction(null, true, context);
-    }
-
-    /**
-     * Begins a transaction
-     * @param withTransaction
-     * @param context
-     * @return
-     * @throws XWikiException
-     */
-    public boolean beginTransaction(boolean withTransaction, XWikiContext context) throws XWikiException {
-            return beginTransaction(null, withTransaction, context);
-    }
-
-    /**
-     * Begins a transaction with a specific SessionFactory
-     * @param sfactory
-     * @param context
-     * @return
-     * @throws XWikiException
-     */
-    public boolean beginTransaction(SessionFactory sfactory, XWikiContext context) throws XWikiException {
-        return beginTransaction(sfactory, true, context);
-    }
-
-    /**
-     * Begins a transaction with a specific SessionFactory
-     * @param sfactory
-     * @param withTransaction
-     * @param context
-     * @return
-     * @throws HibernateException
-     * @throws XWikiException
-     */
-    public boolean beginTransaction(SessionFactory sfactory, boolean withTransaction, 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 (session!=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");
-            if (sfactory==null)
-                session = (SessionImpl)getSessionFactory().openSession();
-            else
-                session = sfactory.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;
-    }
-
-    /**
-     * Adding a connection to the Monitor module
-     * @param connection
-     * @param context
-     */
-    private void addConnection(Connection connection, XWikiContext context) {
-        if (connection!=null)
-            connections.put(connection, new ConnectionMonitor(connection, context));
-    }
-
-    /**
-     * Remove a connection to the Monitor module
-     * @param connection
-     */
-    private void removeConnection(Connection connection) {
-        try {
-            if (connection!=null)
-                connections.remove(connection);
-        } catch (Exception e) {
-        }
-    }
-
-    /**
-     * Ends a transaction
-     * @param context
-     * @param commit should we commit or not
-     */
-    public void endTransaction(XWikiContext context, boolean commit) {
-        endTransaction(context, commit, false);
-    }
-
-    /**
-     * Ends a transaction
-     * @param context
-     * @param commit should we commit or not
-     * @param withTransaction
-     * @throws HibernateException
-     */
-    public void endTransaction(XWikiContext context, boolean commit, boolean withTransaction)
-            throws HibernateException {
-        Session session = null;
-        try {
-            session = getSession(context);
-            Transaction transaction = getTransaction(context);
-            setSession(null, context);
-            setTransaction(null, context);
-
-            if (transaction!=null) {
-                if ( log.isDebugEnabled() ) log.debug("Releasing hibernate transaction " + transaction);
-                if (commit) {
-                    transaction.commit();
-                } else {
-                    transaction.rollback();
-                }
-            }
-        } finally {
-            if (session!=null) {
-                closeSession(session);
-            }
-        }
-    }
-
-    /**
-     * Closes the hibernate session
-     * @param session
-     * @throws HibernateException
-     */
-    private void closeSession(Session session) throws HibernateException {
-        if (session!=null) {
-            try {
-                if ( log.isDebugEnabled() ) log.debug("Releasing hibernate session " + session);
-                Connection connection = session.connection();
-                if ((connection!=null)) {
-                    nbConnections--;
-                    try {
-                        removeConnection(connection);
-                    } catch (Throwable e) {
-                        // This should not happen
-                        e.printStackTrace();
-                    }
-                }
-            } finally {
-                session.close();
-            }
-        }
-    }
-
-    /**
-     * Cleanup all sessions
-     * Used at the shutdown time
-     * @param context
-     */
-    public void cleanUp(XWikiContext context) {
-        try {
-            Session session = getSession(context);
-            if (session!=null) {
-                if ( log.isWarnEnabled() ) log.warn("Cleanup of session was needed: " + session);
-                endTransaction(context, false);
-            }
-        } catch (HibernateException e) {
-        }
-    }
-
-    /**
      * Allows to create a new wiki database
      * and initialize the default tables
      * @param wikiName
@@ -1091,7 +540,7 @@
             List attachlist = doc.getAttachmentList();
             for (int i=0;i<attachlist.size();i++) {
                 XWikiAttachment attachment = (XWikiAttachment) attachlist.get(i);
-                deleteXWikiAttachment(attachment, false, context, false);
+                context.getWiki().getAttachmentStore().deleteXWikiAttachment(attachment, false, context, true);
             }
 
             // deleting XWikiLinks
@@ -1872,7 +1321,7 @@
                 session.update(attachment);
 
             if (parentUpdate)
-                saveXWikiDoc(attachment.getDoc(), context, false);
+                context.getWiki().getStore().saveXWikiDoc(attachment.getDoc(), context, false);
             if (bTransaction) {
                 endTransaction(context, true);
             }
@@ -1888,123 +1337,7 @@
             } catch (Exception e) {}
         }
     }
-    public void saveAttachmentContent(XWikiAttachment attachment, XWikiContext context, boolean bTransaction) throws XWikiException {
-        saveAttachmentContent(attachment, true, context, bTransaction);
-    }
 
-    public void saveAttachmentContent(XWikiAttachment attachment, boolean parentUpdate, XWikiContext context, boolean bTransaction) throws XWikiException {
-        try {
-            XWikiAttachmentContent content = attachment.getAttachment_content();
-            if (content.isContentDirty()) {
-                attachment.updateContentArchive(context);
-            }
-            XWikiAttachmentArchive archive = attachment.getAttachment_archive();
-
-            if (bTransaction) {
-                checkHibernate(context);
-
-                SessionFactory sfactory = injectCustomMappingsInSessionFactory(attachment.getDoc(), context);
-                bTransaction = beginTransaction(sfactory, context);
-            }
-            Session session = getSession(context);
-
-
-            Query query = session.createQuery("select attach.id from XWikiAttachmentContent as attach where attach.id = :id");
-            query.setLong("id", content.getId());
-            if (query.uniqueResult()==null)
-                session.save(content);
-            else
-                session.update(content);
-
-            query = session.createQuery("select attach.id from XWikiAttachmentArchive as attach where attach.id = :id");
-            query.setLong("id", archive.getId());
-            if (query.uniqueResult()==null)
-                session.save(archive);
-            else
-                session.update(archive);
-
-            if (parentUpdate)
-                saveXWikiDoc(attachment.getDoc(), context, false);
-            if (bTransaction) {
-                endTransaction(context, true);
-            }
-        }
-        catch (Exception e) {
-            Object[] args = { attachment.getFilename(), attachment.getDoc().getFullName() };
-            throw new XWikiException( XWikiException.MODULE_XWIKI_STORE, XWikiException.ERROR_XWIKI_STORE_HIBERNATE_SAVING_ATTACHMENT,
-                    "Exception while saving attachment {0} of document {1}", e, args);
-        } finally {
-            try {
-                if (bTransaction)
-                    endTransaction(context, false);
-            } catch (Exception e) {}
-        }
-
-    }
-
-    public void loadAttachmentContent(XWikiAttachment attachment, XWikiContext context, boolean bTransaction) throws XWikiException {
-        try {
-            if (bTransaction) {
-                checkHibernate(context);
-                bTransaction = beginTransaction(false, context);
-            }
-            Session session = getSession(context);
-
-
-            XWikiAttachmentContent content = new XWikiAttachmentContent(attachment);
-            attachment.setAttachment_content(content);
-
-            session.load(content, new Long(content.getId()));
-
-            if (bTransaction)
-                endTransaction(context, false, false);
-        }
-        catch (Exception e) {
-            Object[] args = { attachment.getFilename(), attachment.getDoc().getFullName() };
-            throw new XWikiException( XWikiException.MODULE_XWIKI_STORE, XWikiException.ERROR_XWIKI_STORE_HIBERNATE_LOADING_ATTACHMENT,
-                    "Exception while loading attachment {0} of document {1}", e, args);
-        } finally {
-            try {
-                if (bTransaction)
-                    endTransaction(context, false, false);
-            } catch (Exception e) {}
-        }
-    }
-
-    public void loadAttachmentArchive(XWikiAttachment attachment, XWikiContext context, boolean bTransaction) throws XWikiException {
-        try {
-            if (bTransaction) {
-                checkHibernate(context);
-                bTransaction = beginTransaction(false, context);
-            }
-            Session session = getSession(context);
-
-
-            XWikiAttachmentArchive archive = new XWikiAttachmentArchive();
-            archive.setAttachment(attachment);
-            attachment.setAttachment_archive(archive);
-
-            session.load(archive, new Long(archive.getId()));
-
-            if (bTransaction)
-                endTransaction(context, false, false);
-        }
-        catch (Exception e) {
-            Object[] args = { attachment.getFilename(), attachment.getDoc().getFullName() };
-            throw new XWikiException( XWikiException.MODULE_XWIKI_STORE, XWikiException.ERROR_XWIKI_STORE_HIBERNATE_LOADING_ATTACHMENT,
-                    "Exception while loading attachment {0} of document {1}", e, args);
-        } finally {
-            try {
-                if (bTransaction)
-                    endTransaction(context, false, false);
-            } catch (Exception e) {}
-        }
-    }
-
-    public void deleteXWikiAttachment(XWikiAttachment attachment,  XWikiContext context, boolean bTransaction) throws XWikiException {
-        deleteXWikiAttachment(attachment, true, context, bTransaction);
-    }
-
     public XWikiLock loadLock(long docId, XWikiContext context, boolean bTransaction) throws XWikiException {
         XWikiLock lock=null;
         try {
@@ -2229,50 +1562,7 @@
         }
     }
 
-    public void deleteXWikiAttachment(XWikiAttachment attachment, boolean parentUpdate, XWikiContext context, boolean bTransaction) throws XWikiException {
-        try {
-            if (bTransaction) {
-                checkHibernate(context);
-                bTransaction = beginTransaction(context);
-            }
 
-            Session session = getSession(context);
-
-            // Delete the three attachement entries
-            loadAttachmentContent(attachment, context, false);
-            session.delete(attachment.getAttachment_content());
-            loadAttachmentArchive(attachment, context, false);
-            session.delete(attachment.getAttachment_archive());
-            session.delete(attachment);
-
-            if (parentUpdate) {
-                List list = attachment.getDoc().getAttachmentList();
-                for (int i=0;i<list.size();i++) {
-                    XWikiAttachment attach = (XWikiAttachment) list.get(i);
-                    if (attachment.getFilename().equals(attach.getFilename())) {
-                        list.remove(i);
-                        break;
-                    }
-                }
-                saveXWikiDoc(attachment.getDoc(), context, false);
-            }
-            if (bTransaction) {
-                endTransaction(context, true);
-            }
-        }
-        catch (Exception e) {
-            Object[] args = { attachment.getFilename(), attachment.getDoc().getFullName() };
-            throw new XWikiException( XWikiException.MODULE_XWIKI_STORE, XWikiException.ERROR_XWIKI_STORE_HIBERNATE_DELETING_ATTACHMENT,
-                    "Exception while deleting attachment {0} of document {1}", e, args);
-        } finally {
-            try {
-                if (bTransaction)
-                    endTransaction(context, false);
-            } catch (Exception e) {}
-        }
-    }
-
-
     public void getContent(XWikiDocument doc, StringBuffer buf) {
         buf.append(doc.getContent());
     }
@@ -2612,90 +1902,6 @@
         }
     }
 
-    public SessionFactory getSessionFactory() {
-        return sessionFactory;
-    }
-
-    public void setSessionFactory(SessionFactory sessionFactory) {
-        this.sessionFactory = sessionFactory;
-    }
-
-    public Configuration getConfiguration() {
-        return configuration;
-    }
-
-    public void setConfiguration(Configuration configuration) {
-        this.configuration = configuration;
-    }
-
-    public Collection getConnections() {
-        return connections.values();
-    }
-
-    public int getNbConnections() {
-        return nbConnections;
-    }
-
-    public void setNbConnections(int nbConnections) {
-        this.nbConnections = nbConnections;
-    }
-
-
-    public class ConnectionMonitor {
-        private Exception exception;
-        private Connection connection;
-        private Date date;
-        private URL url = null;
-
-        public ConnectionMonitor(Connection connection, XWikiContext context) {
-            this.setConnection(connection);
-
-            try {
-                setDate(new Date());
-                setException(new XWikiException());
-                XWikiRequest request = context.getRequest();
-                if (request!=null)
-                    setURL(XWiki.getRequestURL(context.getRequest()));
-            } catch (Throwable e) {
-            }
-
-        }
-
-        public Connection getConnection() {
-            return connection;
-        }
-
-        public void setConnection(Connection connection) {
-            this.connection = connection;
-        }
-
-        public Date getDate() {
-            return date;
-        }
-
-        public void setDate(Date date) {
-            this.date = date;
-        }
-
-        public Exception getException() {
-            return exception;
-        }
-
-        public void setException(Exception exception) {
-            this.exception = exception;
-        }
-
-        public URL getURL() {
-            return url;
-        }
-
-        public void setURL(URL url) {
-            this.url = url;
-        }
-
-    }
-
-
     public boolean isCustomMappingValid(BaseClass bclass, String custommapping1, XWikiContext context) {
         try {
             Configuration hibconfig = makeMapping(bclass.getName(), custommapping1);
@@ -2872,32 +2078,7 @@
         return list;
     }
 
-    private Configuration makeMapping(String className, String custommapping1) {
-        Configuration hibconfig = new Configuration();
-        {
-            hibconfig.addXML(makeMapping(className , "xwikicustom_" + className.replace('.','_'), custommapping1));
-        }
-        hibconfig.buildMappings();
-        return hibconfig;
-    }
 
-    private String makeMapping(String entityName, String tableName, String custommapping1) {
-        String custommapping = "<?xml version=\"1.0\"?>\n" +
-                "<!DOCTYPE hibernate-mapping PUBLIC\n" +
-                "\t\"-//Hibernate/Hibernate Mapping DTD//EN\"\n" +
-                "\t\"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd\">\n" +
-                "<hibernate-mapping>" +
-                "<class entity-name=\"" + entityName + "\" table=\"" + tableName+ "\">\n" +
-                " <id name=\"id\" type=\"integer\" unsaved-value=\"any\">\n" +
-                "   <column name=\"XWO_ID\" not-null=\"true\" />\n" +
-                "   <generator class=\"assigned\" />\n" +
-                " </id>\n" +
-                custommapping1 +
-                "</class>\n" +
-                "</hibernate-mapping>";
-        return custommapping;
-    }
-
     private boolean isValidColumnType(String name, String className) {
         String[] validtypes = (String[]) validTypesMap.get(className);
         if (validtypes==null)
@@ -2914,5 +2095,36 @@
         XWikiBatcher.getSQLStats().resetStats();
     }
 
+    public List searchDocumentsNames(String wheresql, XWikiContext context) throws XWikiException {
+        return searchDocumentsNames(wheresql, 0, 0, "", context);
+    }
+
+    public List searchDocumentsNames(String wheresql, int nb, int start, XWikiContext context) throws XWikiException {
+        return searchDocumentsNames(wheresql, nb, start, "", context);
+    }
+
+    public List searchDocuments(String wheresql, XWikiContext context) throws XWikiException {
+        return searchDocuments(wheresql, true, 0, 0, context);
+    }
+
+    public List searchDocuments(String wheresql, boolean distinctbylanguage, XWikiContext context) throws XWikiException {
+        return searchDocuments(wheresql, distinctbylanguage, 0, 0, context);
+    }
+
+    public List searchDocuments(String wheresql, boolean distinctbylanguage, boolean customMapping, XWikiContext context) throws XWikiException {
+        return searchDocuments(wheresql, distinctbylanguage, customMapping, 0, 0, context);
+    }
+
+    public List searchDocuments(String wheresql, int nb, int start, XWikiContext context) throws XWikiException {
+        return searchDocuments(wheresql, true, nb, start, context);
+    }
+
+    public List searchDocuments(String wheresql, boolean distinctbyname, int nb, int start, XWikiContext context) throws XWikiException {
+          return searchDocuments(wheresql, distinctbyname, false, nb, start, context);
+    }
+
+    public List searchDocuments(String wheresql, boolean distinctbyname, boolean customMapping, int nb, int start, XWikiContext context) throws XWikiException {
+        return searchDocuments(wheresql,  distinctbyname, customMapping, true, nb, start, context);
+    }
 }
 

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiStoreInterface.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiStoreInterface.java	2006-03-12 08:36:43 UTC (rev 971)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/store/XWikiStoreInterface.java	2006-03-12 22:36:14 UTC (rev 972)
@@ -1,26 +1,26 @@
-/*
- * Copyright 2006, XpertNet SARL, and individual contributors as indicated
- * by the contributors.txt.
- *
- * This is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2.1 of
- * the License, or (at your option) any later version.
- *
- * This software 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
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this software; if not, write to the Free
- * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
- * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
- *
- * @author ludovic
- * @author sdumitriu
- * @author thomas
- */
+/*
+ * Copyright 2006, XpertNet SARL, and individual contributors as indicated
+ * by the contributors.txt.
+ *
+ * This is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as
+ * published by the Free Software Foundation; either version 2.1 of
+ * the License, or (at your option) any later version.
+ *
+ * This software 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this software; if not, write to the Free
+ * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
+ * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
+ *
+ * @author ludovic
+ * @author sdumitriu
+ * @author thomas
+ */
 
 
 package com.xpn.xwiki.store;
@@ -52,11 +52,6 @@
     public List searchDocuments(String wheresql, boolean distinctbyname, boolean customMapping, int nb, int start, XWikiContext context) throws XWikiException;
     public List searchDocuments(String wheresql, XWikiContext context) throws XWikiException;
     public List searchDocuments(String wheresql, int nb, int start, XWikiContext context) throws XWikiException;
-    public void saveAttachmentContent(XWikiAttachment attachment, XWikiContext context, boolean bTransaction) throws XWikiException;
-    public void saveAttachmentContent(XWikiAttachment attachment, boolean bParentUpdate, XWikiContext context, boolean bTransaction) throws XWikiException;
-    public void loadAttachmentContent(XWikiAttachment attachment, XWikiContext context, boolean bTransaction) throws XWikiException;
-    public void loadAttachmentArchive(XWikiAttachment attachment, XWikiContext context, boolean bTransaction) throws XWikiException;
-    public void deleteXWikiAttachment(XWikiAttachment attachment, XWikiContext context, boolean bTransaction) throws XWikiException;
     public XWikiLock loadLock(long docId, XWikiContext context, boolean bTransaction) throws XWikiException;
     public void saveLock(XWikiLock lock, XWikiContext context, boolean bTransaction) throws XWikiException;
     public void deleteLock(XWikiLock lock, XWikiContext context, boolean bTransaction) throws XWikiException;

Modified: xwiki/trunk/src/main/java/com/xpn/xwiki/user/impl/LDAP/LDAPAuthServiceImpl.java
===================================================================
--- xwiki/trunk/src/main/java/com/xpn/xwiki/user/impl/LDAP/LDAPAuthServiceImpl.java	2006-03-12 08:36:43 UTC (rev 971)
+++ xwiki/trunk/src/main/java/com/xpn/xwiki/user/impl/LDAP/LDAPAuthServiceImpl.java	2006-03-12 22:36:14 UTC (rev 972)
@@ -45,15 +45,16 @@
 public class LDAPAuthServiceImpl extends XWikiAuthServiceImpl {
     private static final Log log = LogFactory.getLog(LDAPAuthServiceImpl.class);
 
-    public Principal authenticate(String username, String password, XWikiContext context) throws XWikiException {
+    public Principal authenticate(String ldapusername, String password, XWikiContext context) throws XWikiException {
         Principal principal = null;
 
-        if ((username == null) || (username.trim().equals("")))
+        if ((ldapusername==null)||(ldapusername.trim().equals("")))
             return null;
 
         if ((password == null) || (password.trim().equals("")))
             return null;
 
+        String username  = ldapusername.replaceAll(" ", "");
         String superadmin = "superadmin";
         if (username.equals(superadmin)) {
             String superadminpassword = context.getWiki().Param("xwiki.superadminpassword");
@@ -74,51 +75,71 @@
             if (i != -1)
                 susername = username.substring(i + 1);
 
-            String DN = getLDAP_DN(susername, context);
+           String DN = getLDAP_DN(ldapusername, context);
 
-            if (DN != null && DN.length() != 0) {
-                if (checkDNPassword(DN, susername, password, context)) {
-                    principal = GetUserPrincipal(susername, context);
-                }
-            } else {
-                HashMap attributes = new HashMap();
-                if (checkUserPassword(susername, password, attributes, context)) {
-                    principal = GetUserPrincipal(susername, context);
-                    if (principal == null && attributes.size() > 0) {
-                        // In case of Virtual Wikis, users should be added in the main wiki
-                        // if ldap is not configured for the virtual wiki
-                        if (context.isVirtual()) {
-                            String db = context.getDatabase();
-                            try {
-                                // Switch to the main database in case of
-                                // virtual and if not local LDAP configuration
-                                if (context.getWiki().getXWikiPreference("ldap_server", context) == null || context.getWiki().getXWikiPreference("ldap_server", context).length() == 0)
-                                {
-                                    context.setDatabase(context.getWiki().getDatabase());
-                                }
-                                try {
-                                    CreateUserFromLDAP(susername, attributes, context);
-                                    principal = GetUserPrincipal(susername, context);
-                                } catch (Exception e) {
-                                }
-                            } finally {
-                                context.setDatabase(db);
-                            }
-                        } else {
-                            CreateUserFromLDAP(susername, attributes, context);
-                            principal = GetUserPrincipal(susername, context);
-                        }
-                        context.getWiki().flushCache();
-                    }
-                }
+           if (DN != null && DN.length()!=0)
+           {
+               if (checkDNPassword(DN, ldapusername, password, context))
+               {
+                   principal = GetUserPrincipal(susername, context);
+               }
+           }
+           else
+            {
+               HashMap attributes = new HashMap();
+               if (checkUserPassword(ldapusername, password, attributes, context))
+               {
+                   if (log.isDebugEnabled())
+                        log.debug("User authenticated successfully");
+                   principal = GetUserPrincipal(susername, context);
+                   if (principal == null && attributes.size() > 0)
+                   {
+                       if (log.isDebugEnabled())
+                            log.debug("Ready to create user from LDAP");
+
+                	   // In case of Virtual Wikis, users should be added in the main wiki
+                	   	// if ldap is not configured for the virtual wiki
+						if (context.isVirtual()) {
+							String db = context.getDatabase();
+							try {
+								// Switch to the main database in case of
+								// virtual and if not local LDAP configuration
+								if (context.getWiki().getXWikiPreference("ldap_server", context) == null || context.getWiki().getXWikiPreference("ldap_server", context).length() == 0) {
+									context.setDatabase(context.getWiki().getDatabase());
+								}
+								try {
+									CreateUserFromLDAP(attributes,	context);
+                                    log.debug("Looking for user again " + susername);
+									principal = GetUserPrincipal(susername, context);
+								} catch (Exception e) {
+								}
+							} finally {
+								context.setDatabase(db);
+							}
+						} else {
+							CreateUserFromLDAP(attributes, context);
+                            log.debug("Looking for user again " + susername);
+							principal = GetUserPrincipal(susername, context);
+						}
+						context.getWiki().flushCache();
+                   }
+                   if (principal ==null) {
+                       if (log.isDebugEnabled())
+                          log.debug("Accept user even without account");
+                       principal = new SimplePrincipal("XWiki." + susername);
+                   }
+               }
             }
         }
         return principal;
     }
 
-    private void CreateUserFromLDAP(String susername, HashMap attributes, XWikiContext context) throws XWikiException {
-        String ldapFieldMapping = getParam("ldap_fields_mapping", context);
-        if (ldapFieldMapping != null && ldapFieldMapping.length() > 0) {
+    private void CreateUserFromLDAP(HashMap attributes, XWikiContext context) throws XWikiException {
+        String ldapFieldMapping = getParam("ldap_fields_mapping",context);
+        if (log.isDebugEnabled())
+             log.debug("Ready to create user from LDAP with field " + ldapFieldMapping);
+        if (ldapFieldMapping != null && ldapFieldMapping.length() > 0)
+        {
             String[] fields = ldapFieldMapping.split(",");
             BaseClass bclass = context.getWiki().getUserClass(context);
             BaseObject bobj = new BaseObject();
@@ -127,19 +148,27 @@
             String fullwikiname = null;
             for (int i = 0; i < fields.length; i++) {
                 String[] field = fields[i].split("=");
-                if (2 == field.length) {
-                    String fieldName = field[0];
-                    if (attributes.containsKey(field[1])) {
-                        String fieldValue;
-                        fieldValue = (String) attributes.get(field[1]);
-                        if (fieldName.equals("name")) {
-                            name = fieldValue;
-                            fullwikiname = "XWiki." + name;
-                            bobj.setName(fullwikiname);
-                        } else {
-                            bobj.setStringValue(fieldName, fieldValue);
-                        }
-                    }
+                if (2 == field.length)
+                {
+                   String fieldName = field[0];
+                   if (log.isDebugEnabled())
+                         log.debug("Create user from LDAP looking at field " + fieldName);
+                   if (attributes.containsKey(field[1]))
+                   {
+                       String fieldValue;
+                       fieldValue = (String)attributes.get(field[1]);
+                       if (fieldName.equals("name"))
+                       {
+                           name = fieldValue.replaceAll(" ", "");
+                           fullwikiname = "XWiki." + name;
+                           bobj.setName(fullwikiname);
+                       }
+                       else
+                       {
+                           log.debug("Create user from LDAP setting field " + fieldName);
+                           bobj.setStringValue(fieldName, fieldValue);
+                       }
+                   }
                 }
             }
 
@@ -163,8 +192,12 @@
 
         // First we check in the local database
         try {
+            if (log.isDebugEnabled())
+                 log.debug("Finding user " + susername);
             String user = findUser(susername, context);
             if (user != null) {
+                if (log.isDebugEnabled())
+                     log.debug("Found user " + susername);
                 principal = new SimplePrincipal(user);
             }
         } catch (Exception e) {
@@ -254,6 +287,8 @@
             String bindPasswordFormat = getParam("ldap_bind_pass", context);
 
             int checkLevel = GetCheckLevel(context);
+            if (log.isDebugEnabled())
+                 log.debug("LDAP Check level is " + checkLevel);
 
             Object[] arguments = {
                     username,
@@ -274,9 +309,10 @@
             result = Bind(bindDN, bindPassword, lc, ldapVersion);
 
             if (log.isDebugEnabled())
-                log.debug("LDAP Bind returned");
+                 log.debug("LDAP Bind returned with result " + result);
 
-            if (result && checkLevel > 0) {
+            if (result && (checkLevel > 0))
+            {
                 if (log.isDebugEnabled())
                     log.debug("LDAP searching user");
 
@@ -337,13 +373,13 @@
                         log.debug("LDAP search user failed");
                     notinLDAP = true;
                 }
+            }
 
-                if (log.isInfoEnabled()) {
-                    if (result)
-                        log.info("LDAP Password check for user " + username + " successfull");
-                    else
-                        log.info("LDAP Password check for user " + username + " failed");
-                }
+            if (log.isInfoEnabled()) {
+                if (result)
+                 log.info("LDAP Password check for user " + username + " successfull");
+                else
+                 log.info("LDAP Password check for user " + username + " failed");
             }
         }
         catch (LDAPException e) {
@@ -378,7 +414,7 @@
                 log.debug("LDAP Password check reverting to XWiki");
 
             // Use XWiki password if user not in LDAP
-            result = checkPassword(username, password, context);
+            result = checkPassword(username.replaceAll(" ",""), password, context);
             foundDN = null;
         }
 
@@ -404,6 +440,7 @@
 
     protected int GetCheckLevel(XWikiContext context) {
         String checkLevel = getParam("ldap_check_level", context);
+        checkLevel = (checkLevel==null) ? "" : checkLevel.trim();
         int val = 2;
         if ("1".equals(checkLevel))
             val = 1;
@@ -474,7 +511,7 @@
     private boolean Bind(String bindDN, String bindPassword, LDAPConnection lc, int ldapVersion) throws UnsupportedEncodingException {
         boolean bound = false;
         if (log.isDebugEnabled())
-            log.debug("LDAP Bind starting");
+             log.debug("LDAP Bind starting");
 
         if (bindDN != null && bindDN.length() > 0 && bindPassword != null) {
             try {
@@ -495,4 +532,123 @@
         }
         return bound;