1. Project Clover database Sat Feb 2 2019 06:45:20 CET
  2. Package com.xpn.xwiki.store

File XWikiHibernateVersioningStore.java

 

Coverage histogram

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

Code metrics

12
95
19
1
345
254
29
0.31
5
19
1.53

Classes

Class Line # Actions
XWikiHibernateVersioningStore 56 95 0% 29 15
0.8809523688.1%
 

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.XWikiAttachment;
42    import com.xpn.xwiki.doc.XWikiDocument;
43    import com.xpn.xwiki.doc.XWikiDocumentArchive;
44    import com.xpn.xwiki.doc.rcs.XWikiRCSNodeContent;
45    import com.xpn.xwiki.doc.rcs.XWikiRCSNodeId;
46    import com.xpn.xwiki.doc.rcs.XWikiRCSNodeInfo;
47   
48    /**
49    * Realization of {@link XWikiVersioningStoreInterface} for Hibernate-based storage.
50    *
51    * @version $Id: a1ce1d59e8384fca960b19b16c84f45b953a0b16 $
52    */
53    @Component
54    @Named(XWikiHibernateBaseStore.HINT)
55    @Singleton
 
56    public class XWikiHibernateVersioningStore extends XWikiHibernateBaseStore implements XWikiVersioningStoreInterface
57    {
58    /** Logger. */
59    private static final Logger LOGGER = LoggerFactory.getLogger(XWikiHibernateVersioningStore.class);
60   
61    /**
62    * This allows to initialize our storage engine. The hibernate config file path is taken from xwiki.cfg or directly
63    * in the WEB-INF directory.
64    *
65    * @param xwiki The xwiki object
66    * @param context The current context
67    * @deprecated 1.6M1. use ComponentManager.lookup(XWikiVersioningStoreInterface.class) instead.
68    */
 
69  41 toggle @Deprecated
70    public XWikiHibernateVersioningStore(XWiki xwiki, XWikiContext context)
71    {
72  41 super(xwiki, context);
73    }
74   
75    /**
76    * Initialize the storage engine with a specific path This is used for tests.
77    *
78    * @param hibpath path to hibernate.hbm.xml file
79    * @deprecated 1.6M1. use ComponentManager.lookup(XWikiVersioningStoreInterface.class) instead.
80    */
 
81  0 toggle @Deprecated
82    public XWikiHibernateVersioningStore(String hibpath)
83    {
84  0 super(hibpath);
85    }
86   
87    /**
88    * @see #XWikiHibernateVersioningStore(XWiki, XWikiContext)
89    * @param context The current context
90    * @deprecated 1.6M1. use ComponentManager.lookup(XWikiVersioningStoreInterface.class) instead.
91    */
 
92  0 toggle @Deprecated
93    public XWikiHibernateVersioningStore(XWikiContext context)
94    {
95  0 this(context.getWiki(), context);
96    }
97   
98    /**
99    * Empty constructor needed for component manager.
100    */
 
101  106 toggle public XWikiHibernateVersioningStore()
102    {
103    }
104   
 
105  284 toggle @Override
106    public Version[] getXWikiDocVersions(XWikiDocument doc, XWikiContext context) throws XWikiException
107    {
108  284 try {
109  284 XWikiDocumentArchive archive = getXWikiDocumentArchive(doc, context);
110  284 if (archive == null) {
111  0 return new Version[0];
112    }
113  284 Collection<XWikiRCSNodeInfo> nodes = archive.getNodes();
114  284 Version[] versions = new Version[nodes.size()];
115  284 Iterator<XWikiRCSNodeInfo> it = nodes.iterator();
116  450 for (int i = 0; i < versions.length; i++) {
117  166 XWikiRCSNodeInfo node = it.next();
118  166 versions[versions.length - 1 - i] = node.getId().getVersion();
119    }
120  284 return versions;
121    } catch (Exception e) {
122  0 Object[] args = { doc.getFullName() };
123  0 throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
124    XWikiException.ERROR_XWIKI_STORE_HIBERNATE_READING_REVISIONS,
125    "Exception while reading document {0} revisions", e, args);
126    }
127    }
128   
 
129  8902 toggle @Override
130    public XWikiDocumentArchive getXWikiDocumentArchive(XWikiDocument doc, XWikiContext inputxcontext)
131    throws XWikiException
132    {
133  8902 XWikiDocumentArchive archiveDoc = doc.getDocumentArchive();
134  8902 if (archiveDoc != null) {
135  765 return archiveDoc;
136    }
137   
138  8137 XWikiContext context = getExecutionXContext(inputxcontext, true);
139   
140  8137 String db = context.getWikiId();
141  8137 try {
142  8137 if (doc.getDatabase() != null) {
143  8137 context.setWikiId(doc.getDatabase());
144    }
145  8137 archiveDoc = new XWikiDocumentArchive(doc.getId());
146  8137 loadXWikiDocArchive(archiveDoc, true, context);
147  8137 doc.setDocumentArchive(archiveDoc);
148    } finally {
149  8137 context.setWikiId(db);
150   
151  8137 restoreExecutionXContext();
152    }
153   
154  8137 return archiveDoc;
155    }
156   
 
157  8137 toggle @Override
158    public void loadXWikiDocArchive(XWikiDocumentArchive archivedoc, boolean bTransaction, XWikiContext context)
159    throws XWikiException
160    {
161  8137 try {
162  8137 List<XWikiRCSNodeInfo> nodes = loadAllRCSNodeInfo(context, archivedoc.getId(), bTransaction);
163  8137 archivedoc.setNodes(nodes);
164    } catch (Exception e) {
165  0 Object[] args = { Long.valueOf(archivedoc.getId()) };
166  0 throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
167    XWikiException.ERROR_XWIKI_STORE_HIBERNATE_LOADING_OBJECT, "Exception while loading archive {0}", e,
168    args);
169    }
170    }
171   
 
172  8138 toggle @Override
173    public void saveXWikiDocArchive(final XWikiDocumentArchive archivedoc, boolean bTransaction, XWikiContext context)
174    throws XWikiException
175    {
176  8138 executeWrite(context, bTransaction, new HibernateCallback<Object>()
177    {
 
178  8138 toggle @Override
179    public Object doInHibernate(Session session) throws HibernateException
180    {
181  8138 for (XWikiRCSNodeInfo ni : archivedoc.getDeletedNodeInfo()) {
182  3 session.delete(ni);
183    }
184  8138 archivedoc.getDeletedNodeInfo().clear();
185  8138 for (XWikiRCSNodeInfo ni : archivedoc.getUpdatedNodeInfos()) {
186  8209 session.saveOrUpdate(ni);
187    }
188  8138 archivedoc.getUpdatedNodeInfos().clear();
189  8138 for (XWikiRCSNodeContent nc : archivedoc.getUpdatedNodeContents()) {
190  10285 session.update(nc);
191    }
192  8138 archivedoc.getUpdatedNodeContents().clear();
193  8138 return null;
194    }
195    });
196    }
197   
 
198  52 toggle @Override
199    public XWikiDocument loadXWikiDoc(XWikiDocument basedoc, String sversion, XWikiContext inputxcontext)
200    throws XWikiException
201    {
202  52 XWikiContext context = getExecutionXContext(inputxcontext, true);
203   
204  52 try {
205  52 XWikiDocumentArchive archive = getXWikiDocumentArchive(basedoc, context);
206  52 Version version = new Version(sversion);
207   
208  46 XWikiDocument doc = archive.loadDocument(version, context);
209  46 if (doc == null) {
210  6 Object[] args = { basedoc.getDocumentReferenceWithLocale(), version.toString() };
211  6 throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
212    XWikiException.ERROR_XWIKI_STORE_HIBERNATE_UNEXISTANT_VERSION,
213    "Version {1} does not exist while reading document {0}", null, args);
214    }
215   
216    // Make sure the document has the same name
217    // as the new document (in case there was a name change
218    // FIXME: is this really needed ?
219  40 doc.setDocumentReference(basedoc.getDocumentReference());
220   
221  40 doc.setStore(basedoc.getStore());
222   
223    // Make sure the attachment of the revision document have the right store
224  40 for (XWikiAttachment revisionAttachment : doc.getAttachmentList()) {
225  10 XWikiAttachment attachment = basedoc.getAttachment(revisionAttachment.getFilename());
226   
227  10 if (attachment != null) {
228  9 revisionAttachment.setContentStore(attachment.getContentStore());
229  9 revisionAttachment.setArchiveStore(attachment.getArchiveStore());
230    }
231    }
232   
233  40 return doc;
234    } finally {
235  52 restoreExecutionXContext();
236    }
237    }
238   
 
239  139 toggle @Override
240    public void resetRCSArchive(final XWikiDocument doc, boolean bTransaction, final XWikiContext inputxcontext)
241    throws XWikiException
242    {
243  139 XWikiContext context = getExecutionXContext(inputxcontext, true);
244   
245  139 try {
246  139 executeWrite(context, true, new HibernateCallback<Object>()
247    {
 
248  139 toggle @Override
249    public Object doInHibernate(Session session) throws HibernateException, XWikiException
250    {
251  139 XWikiDocumentArchive archive = getXWikiDocumentArchive(doc, context);
252  139 archive.resetArchive();
253  139 archive.getDeletedNodeInfo().clear();
254  139 doc.setMinorEdit(false);
255  139 deleteArchive(doc, false, context);
256  139 updateXWikiDocArchive(doc, false, context);
257  139 return null;
258    }
259    });
260    } finally {
261  139 restoreExecutionXContext();
262    }
263    }
264   
 
265  8063 toggle @Override
266    public void updateXWikiDocArchive(XWikiDocument doc, boolean bTransaction, XWikiContext inputxcontext)
267    throws XWikiException
268    {
269  8063 XWikiContext context = getExecutionXContext(inputxcontext, true);
270   
271  8063 try {
272  8063 XWikiDocumentArchive archiveDoc = getXWikiDocumentArchive(doc, context);
273  8063 archiveDoc.updateArchive(doc, doc.getAuthor(), doc.getDate(), doc.getComment(), doc.getRCSVersion(),
274    context);
275  8063 doc.setRCSVersion(archiveDoc.getLatestVersion());
276  8063 saveXWikiDocArchive(archiveDoc, bTransaction, context);
277    } catch (Exception e) {
278  0 Object[] args = { doc.getFullName() };
279  0 throw new XWikiException(XWikiException.MODULE_XWIKI_STORE,
280    XWikiException.ERROR_XWIKI_STORE_HIBERNATE_SAVING_OBJECT, "Exception while updating archive {0}", e,
281    args);
282    } finally {
283  8063 restoreExecutionXContext();
284    }
285    }
286   
287    /**
288    * @param context the XWiki context
289    * @param id {@link XWikiRCSNodeContent#getId()}
290    * @param bTransaction should store to use old transaction(false) or create new (true)
291    * @return loaded rcs node content
292    * @throws XWikiException if any error
293    */
 
294  8137 toggle protected List<XWikiRCSNodeInfo> loadAllRCSNodeInfo(XWikiContext context, final long id, boolean bTransaction)
295    throws XWikiException
296    {
297  8137 return executeRead(context, bTransaction, new HibernateCallback<List<XWikiRCSNodeInfo>>()
298    {
 
299  8137 toggle @SuppressWarnings("unchecked")
300    @Override
301    public List<XWikiRCSNodeInfo> doInHibernate(Session session) throws HibernateException
302    {
303  8137 try {
304  8137 return session.createCriteria(XWikiRCSNodeInfo.class)
305    .add(Restrictions.eq("id.docId", Long.valueOf(id))).add(Restrictions.isNotNull("diff")).list();
306    } catch (IllegalArgumentException ex) {
307    // This happens when the database has wrong values...
308  0 LOGGER.warn("Invalid history for document " + id);
309  0 return Collections.emptyList();
310    }
311    }
312    });
313    }
314   
 
315  2651 toggle @Override
316    public XWikiRCSNodeContent loadRCSNodeContent(final XWikiRCSNodeId id, boolean bTransaction, XWikiContext context)
317    throws XWikiException
318    {
319  2651 return executeRead(context, bTransaction, new HibernateCallback<XWikiRCSNodeContent>()
320    {
 
321  2651 toggle @Override
322    public XWikiRCSNodeContent doInHibernate(Session session) throws HibernateException
323    {
324  2651 XWikiRCSNodeContent content = new XWikiRCSNodeContent(id);
325  2651 session.load(content, content.getId());
326  2651 return content;
327    }
328    });
329    }
330   
 
331  565 toggle @Override
332    public void deleteArchive(final XWikiDocument doc, boolean bTransaction, XWikiContext context) throws XWikiException
333    {
334  565 executeWrite(context, bTransaction, new HibernateCallback<Object>()
335    {
 
336  565 toggle @Override
337    public Object doInHibernate(Session session) throws HibernateException, XWikiException
338    {
339  565 session.createQuery("delete from " + XWikiRCSNodeInfo.class.getName() + " where id.docId=?")
340    .setLong(0, doc.getId()).executeUpdate();
341  565 return null;
342    }
343    });
344    }
345    }