1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package com.xpn.xwiki.store

File XWikiHibernateVersioningStore.java

 

Coverage histogram

../../../../img/srcFileCovDistChart9.png
38% of files have more coverage

Code metrics

10
84
19
1
321
235
28
0.33
4.42
19
1.47

Classes

Class Line # Actions
XWikiHibernateVersioningStore 55 84 0% 28 15
0.8672566486.7%
 

Contributing tests

No tests hitting this source file were found.

Source view

1    /*
2    * See the NOTICE file distributed with this work for additional
3    * information regarding copyright ownership.
4    *
5    * This is free software; you can redistribute it and/or modify it
6    * under the terms of the GNU Lesser General Public License as
7    * published by the Free Software Foundation; either version 2.1 of
8    * the License, or (at your option) any later version.
9    *
10    * This software is distributed in the hope that it will be useful,
11    * but WITHOUT ANY WARRANTY; without even the implied warranty of
12    * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13    * Lesser General Public License for more details.
14    *
15    * You should have received a copy of the GNU Lesser General Public
16    * License along with this software; if not, write to the Free
17    * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
18    * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
19    */
20    package com.xpn.xwiki.store;
21   
22    import java.util.Collection;
23    import java.util.Collections;
24    import java.util.Iterator;
25    import java.util.List;
26   
27    import javax.inject.Named;
28    import javax.inject.Singleton;
29   
30    import org.hibernate.HibernateException;
31    import org.hibernate.Session;
32    import org.hibernate.criterion.Restrictions;
33    import org.slf4j.Logger;
34    import org.slf4j.LoggerFactory;
35    import org.suigeneris.jrcs.rcs.Version;
36    import org.xwiki.component.annotation.Component;
37   
38    import com.xpn.xwiki.XWiki;
39    import com.xpn.xwiki.XWikiContext;
40    import com.xpn.xwiki.XWikiException;
41    import com.xpn.xwiki.doc.XWikiDocument;
42    import com.xpn.xwiki.doc.XWikiDocumentArchive;
43    import com.xpn.xwiki.doc.rcs.XWikiRCSNodeContent;
44    import com.xpn.xwiki.doc.rcs.XWikiRCSNodeId;
45    import com.xpn.xwiki.doc.rcs.XWikiRCSNodeInfo;
46   
47    /**
48    * Realization of {@link XWikiVersioningStoreInterface} for Hibernate-based storage.
49    *
50    * @version $Id: acf4130c8fdf85e17dc9edb9ed9a7b38e8a0c36f $
51    */
52    @Component
53    @Named("hibernate")
54    @Singleton
 
55    public class XWikiHibernateVersioningStore extends XWikiHibernateBaseStore implements XWikiVersioningStoreInterface
56    {
57    /** Logger. */
58    private static final Logger LOGGER = LoggerFactory.getLogger(XWikiHibernateVersioningStore.class);
59   
60    /**
61    * This allows to initialize our storage engine. The hibernate config file path is taken from xwiki.cfg or directly
62    * in the WEB-INF directory.
63    *
64    * @param xwiki The xwiki object
65    * @param context The current context
66    * @deprecated 1.6M1. use ComponentManager.lookup(XWikiVersioningStoreInterface.class) instead.
67    */
 
68  38 toggle @Deprecated
69    public XWikiHibernateVersioningStore(XWiki xwiki, XWikiContext context)
70    {
71  38 super(xwiki, context);
72    }
73   
74    /**
75    * Initialize the storage engine with a specific path This is used for tests.
76    *
77    * @param hibpath path to hibernate.hbm.xml file
78    * @deprecated 1.6M1. use ComponentManager.lookup(XWikiVersioningStoreInterface.class) instead.
79    */
 
80  0 toggle @Deprecated
81    public XWikiHibernateVersioningStore(String hibpath)
82    {
83  0 super(hibpath);
84    }
85   
86    /**
87    * @see #XWikiHibernateVersioningStore(XWiki, XWikiContext)
88    * @param context The current context
89    * @deprecated 1.6M1. use ComponentManager.lookup(XWikiVersioningStoreInterface.class) instead.
90    */
 
91  0 toggle @Deprecated
92    public XWikiHibernateVersioningStore(XWikiContext context)
93    {
94  0 this(context.getWiki(), context);
95    }
96   
97    /**
98    * Empty constructor needed for component manager.
99    */
 
100  87 toggle public XWikiHibernateVersioningStore()
101    {
102    }
103   
 
104  2127 toggle @Override
105    public Version[] getXWikiDocVersions(XWikiDocument doc, XWikiContext context) throws XWikiException
106    {
107  2127 try {
108  2127 XWikiDocumentArchive archive = getXWikiDocumentArchive(doc, context);
109  2127 if (archive == null) {
110  0 return new Version[0];
111    }
112  2127 Collection<XWikiRCSNodeInfo> nodes = archive.getNodes();
113  2127 Version[] versions = new Version[nodes.size()];
114  2127 Iterator<XWikiRCSNodeInfo> it = nodes.iterator();
115  2304 for (int i = 0; i < versions.length; i++) {
116  177 XWikiRCSNodeInfo node = it.next();
117  177 versions[versions.length - 1 - i] = node.getId().getVersion();
118    }
119  2127 return versions;
120    } catch (Exception e) {
121  0 Object[] args = { doc.getFullName() };
122  0 throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
123    XWikiException.ERROR_XWIKI_STORE_HIBERNATE_READING_REVISIONS,
124    "Exception while reading document {0} revisions", e, args);
125    }
126    }
127   
 
128  12255 toggle @Override
129    public XWikiDocumentArchive getXWikiDocumentArchive(XWikiDocument doc, XWikiContext inputxcontext)
130    throws XWikiException
131    {
132  12255 XWikiContext context = getXWikiContext(inputxcontext);
133   
134  12255 XWikiDocumentArchive archiveDoc = doc.getDocumentArchive();
135  12255 if (archiveDoc != null) {
136  8293 return archiveDoc;
137    }
138   
139  3962 String db = context.getWikiId();
140  3962 try {
141  3962 if (doc.getDatabase() != null) {
142  3962 context.setWikiId(doc.getDatabase());
143    }
144  3962 archiveDoc = new XWikiDocumentArchive(doc.getId());
145  3962 loadXWikiDocArchive(archiveDoc, true, context);
146  3962 doc.setDocumentArchive(archiveDoc);
147    } finally {
148  3962 context.setWikiId(db);
149    }
150  3962 return archiveDoc;
151    }
152   
 
153  3962 toggle @Override
154    public void loadXWikiDocArchive(XWikiDocumentArchive archivedoc, boolean bTransaction, XWikiContext context)
155    throws XWikiException
156    {
157  3962 try {
158  3962 List<XWikiRCSNodeInfo> nodes = loadAllRCSNodeInfo(context, archivedoc.getId(), bTransaction);
159  3962 archivedoc.setNodes(nodes);
160    } catch (Exception e) {
161  0 Object[] args = { new Long(archivedoc.getId()) };
162  0 throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
163    XWikiException.ERROR_XWIKI_STORE_HIBERNATE_LOADING_OBJECT, "Exception while loading archive {0}", e,
164    args);
165    }
166    }
167   
 
168  5821 toggle @Override
169    public void saveXWikiDocArchive(final XWikiDocumentArchive archivedoc, boolean bTransaction, XWikiContext context)
170    throws XWikiException
171    {
172  5821 executeWrite(context, bTransaction, new HibernateCallback<Object>()
173    {
 
174  5821 toggle @Override
175    public Object doInHibernate(Session session) throws HibernateException
176    {
177  5821 for (XWikiRCSNodeInfo ni : archivedoc.getDeletedNodeInfo()) {
178  2 session.delete(ni);
179    }
180  5821 archivedoc.getDeletedNodeInfo().clear();
181  5821 for (XWikiRCSNodeInfo ni : archivedoc.getUpdatedNodeInfos()) {
182  5862 session.saveOrUpdate(ni);
183    }
184  5821 archivedoc.getUpdatedNodeInfos().clear();
185  5821 for (XWikiRCSNodeContent nc : archivedoc.getUpdatedNodeContents()) {
186  6196 session.update(nc);
187    }
188  5821 archivedoc.getUpdatedNodeContents().clear();
189  5821 return null;
190    }
191    });
192    }
193   
 
194  31 toggle @Override
195    public XWikiDocument loadXWikiDoc(XWikiDocument basedoc, String sversion, XWikiContext inputxcontext)
196    throws XWikiException
197    {
198  31 XWikiContext context = getXWikiContext(inputxcontext);
199   
200  31 XWikiDocumentArchive archive = getXWikiDocumentArchive(basedoc, context);
201  31 Version version = new Version(sversion);
202   
203  31 XWikiDocument doc = archive.loadDocument(version, context);
204  31 if (doc == null) {
205  2 Object[] args = { basedoc.getDocumentReferenceWithLocale(), version.toString() };
206  2 throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
207    XWikiException.ERROR_XWIKI_STORE_HIBERNATE_UNEXISTANT_VERSION,
208    "Version {1} does not exist while reading document {0}", null, args);
209    }
210   
211    // Make sure the document has the same name
212    // as the new document (in case there was a name change
213    // FIXME: is this really needed ?
214  29 doc.setDocumentReference(basedoc.getDocumentReference());
215   
216  29 doc.setStore(basedoc.getStore());
217   
218  29 return doc;
219    }
220   
 
221  2071 toggle @Override
222    public void resetRCSArchive(final XWikiDocument doc, boolean bTransaction, final XWikiContext inputxcontext)
223    throws XWikiException
224    {
225  2071 XWikiContext context = getXWikiContext(inputxcontext);
226   
227  2071 executeWrite(context, true, new HibernateCallback<Object>()
228    {
 
229  2071 toggle @Override
230    public Object doInHibernate(Session session) throws HibernateException, XWikiException
231    {
232  2071 XWikiDocumentArchive archive = getXWikiDocumentArchive(doc, context);
233  2071 archive.resetArchive();
234  2071 archive.getDeletedNodeInfo().clear();
235  2071 doc.setMinorEdit(false);
236  2071 deleteArchive(doc, false, context);
237  2071 updateXWikiDocArchive(doc, false, context);
238  2071 return null;
239    }
240    });
241    }
242   
 
243  5731 toggle @Override
244    public void updateXWikiDocArchive(XWikiDocument doc, boolean bTransaction, XWikiContext inputxcontext)
245    throws XWikiException
246    {
247  5731 XWikiContext context = getXWikiContext(inputxcontext);
248   
249  5731 try {
250  5731 XWikiDocumentArchive archiveDoc = getXWikiDocumentArchive(doc, context);
251  5731 archiveDoc.updateArchive(doc, doc.getAuthor(), doc.getDate(), doc.getComment(), doc.getRCSVersion(),
252    context);
253  5731 doc.setRCSVersion(archiveDoc.getLatestVersion());
254  5731 saveXWikiDocArchive(archiveDoc, bTransaction, context);
255    } catch (Exception e) {
256  0 Object[] args = { doc.getFullName() };
257  0 throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
258    XWikiException.ERROR_XWIKI_STORE_HIBERNATE_SAVING_OBJECT, "Exception while updating archive {0}", e,
259    args);
260    }
261    }
262   
263    /**
264    * @param context the XWiki context
265    * @param id {@link XWikiRCSNodeContent#getId()}
266    * @param bTransaction should store to use old transaction(false) or create new (true)
267    * @return loaded rcs node content
268    * @throws XWikiException if any error
269    */
 
270  3962 toggle protected List<XWikiRCSNodeInfo> loadAllRCSNodeInfo(XWikiContext context, final long id, boolean bTransaction)
271    throws XWikiException
272    {
273  3962 return executeRead(context, bTransaction, new HibernateCallback<List<XWikiRCSNodeInfo>>()
274    {
 
275  3962 toggle @SuppressWarnings("unchecked")
276    @Override
277    public List<XWikiRCSNodeInfo> doInHibernate(Session session) throws HibernateException
278    {
279  3962 try {
280  3962 return session.createCriteria(XWikiRCSNodeInfo.class)
281    .add(Restrictions.eq("id.docId", Long.valueOf(id))).add(Restrictions.isNotNull("diff")).list();
282    } catch (IllegalArgumentException ex) {
283    // This happens when the database has wrong values...
284  0 LOGGER.warn("Invalid history for document " + id);
285  0 return Collections.emptyList();
286    }
287    }
288    });
289    }
290   
 
291  675 toggle @Override
292    public XWikiRCSNodeContent loadRCSNodeContent(final XWikiRCSNodeId id, boolean bTransaction, XWikiContext context)
293    throws XWikiException
294    {
295  675 return executeRead(context, bTransaction, new HibernateCallback<XWikiRCSNodeContent>()
296    {
 
297  675 toggle @Override
298    public XWikiRCSNodeContent doInHibernate(Session session) throws HibernateException
299    {
300  675 XWikiRCSNodeContent content = new XWikiRCSNodeContent(id);
301  675 session.load(content, content.getId());
302  675 return content;
303    }
304    });
305    }
306   
 
307  2224 toggle @Override
308    public void deleteArchive(final XWikiDocument doc, boolean bTransaction, XWikiContext context) throws XWikiException
309    {
310  2224 executeWrite(context, bTransaction, new HibernateCallback<Object>()
311    {
 
312  2224 toggle @Override
313    public Object doInHibernate(Session session) throws HibernateException, XWikiException
314    {
315  2224 session.createQuery("delete from " + XWikiRCSNodeInfo.class.getName() + " where id.docId=?")
316    .setLong(0, doc.getId()).executeUpdate();
317  2224 return null;
318    }
319    });
320    }
321    }