1. Project Clover database Tue Dec 20 2016 21:24:09 CET
  2. Package org.xwiki.mail.internal.thread.context

File XWikiContextCopier.java

 

Coverage histogram

../../../../../../img/srcFileCovDistChart10.png
0% of files have more coverage

Code metrics

2
11
1
1
105
37
3
0.27
11
1
3

Classes

Class Line # Actions
XWikiContextCopier 51 11 0% 3 0
1.0100%
 

Contributing tests

This file is covered by 1 test. .

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 org.xwiki.mail.internal.thread.context;
21   
22    import java.net.URL;
23   
24    import javax.inject.Inject;
25    import javax.inject.Singleton;
26   
27    import org.xwiki.component.annotation.Component;
28   
29    import com.xpn.xwiki.XWikiContext;
30    import com.xpn.xwiki.web.XWikiRequest;
31    import com.xpn.xwiki.web.XWikiResponse;
32    import com.xpn.xwiki.web.XWikiServletResponseStub;
33    import com.xpn.xwiki.web.XWikiURLFactory;
34   
35    /**
36    * Additionally to using {@link XWikiContext#clone()}, this implementation also tries to make sure that the cloned
37    * context is usable in a different thread. To do this, the request and the response are stubbed, the URL factory is
38    * reinitialized and the store session/transaction are cleared. This latter point is sensible since there is currently
39    * no way to clear the session/transaction only in the copied context. So the session/transaction is cleared in the
40    * original context before cloning, causing a side effect on the original context. You should never copy a context
41    * while a create/update transaction is in progress, since some changes would get rollbacked.
42    * <p>
43    * Note: The clone is still rather shallow, since many fields will still be shared with the original
44    * {@link XWikiContext}.
45    *
46    * @version $Id: fbb5f2d90c586d8af53162d9d1528493b229f9f2 $
47    * @since 7.1M2
48    */
49    @Component
50    @Singleton
 
51    public class XWikiContextCopier implements Copier<XWikiContext>
52    {
53    @Inject
54    private Copier<XWikiRequest> xwikiRequestCloner;
55   
56    /**
57    * {@inheritDoc}
58    *
59    * Any in progress session/transaction on the store retained by the original context will be closed/rollbacked
60    * prior cloning (see {@link com.xpn.xwiki.store.XWikiStoreInterface#cleanUp(XWikiContext)}). Therefore,
61    * the copy operation has a side effect on the original context. You should never copy a context
62    * while a create/update transaction is in progress, since some changes would get rollbacked.
63    */
 
64  35 toggle @Override
65    public XWikiContext copy(XWikiContext originalXWikiContext)
66    {
67    // Clean up the store session/transaction before cloning. For the hibernate store, in progress
68    // session/transaction is stored in the context, and would be swallow copied when the context is cloned.
69    // Cleaning after clone would not help, since it would close/rollback the session/transaction still referenced
70    // in the original context as well, causing this context to be corrupted.
71    // The correct way would be to not shallow clone the session/transaction when cloning the original context,
72    // since session/transaction are lazy initialize on request when missing.
73  35 originalXWikiContext.getWiki().getStore().cleanUp(originalXWikiContext);
74   
75    // This is still a shallow clone, but at least for stuff like wikiID and userReference it gets the job done.
76  35 XWikiContext clonedXWikiContext = originalXWikiContext.clone();
77   
78    // lets now build the stub context
79   
80    // Copy the request from the context.
81  35 clonedXWikiContext.setRequest(this.xwikiRequestCloner.copy(originalXWikiContext.getRequest()));
82   
83    // Force forged context response to a stub response, since the current context response
84    // will not mean anything anymore when running in the scheduler's thread, and can cause
85    // errors.
86  35 XWikiResponse stub = new XWikiServletResponseStub();
87  35 clonedXWikiContext.setResponse(stub);
88   
89    // feed the dummy context
90  35 if (clonedXWikiContext.getURL() == null) {
91  1 try {
92  1 clonedXWikiContext.setURL(new URL("http://www.mystuburl.com/"));
93    } catch (Exception e) {
94    // the URL is clearly well formed
95    }
96    }
97   
98  35 XWikiURLFactory xurf =
99    originalXWikiContext.getWiki().getURLFactoryService()
100    .createURLFactory(originalXWikiContext.getMode(), originalXWikiContext);
101  35 clonedXWikiContext.setURLFactory(xurf);
102   
103  35 return clonedXWikiContext;
104    }
105    }