View Javadoc
1   /*
2    * Copyright (C) 2003-2011 eXo Platform SAS.
3    *
4    * This program is free software: you can redistribute it and/or modify
5    * it under the terms of the GNU Affero General Public License as published by
6    * the Free Software Foundation, either version 3 of the License, or
7    * (at your option) any later version.
8    *
9    * This program is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12   * GNU Affero General Public License for more details.
13   *
14   * You should have received a copy of the GNU Affero General Public License
15   * along with this program. If not, see <http://www.gnu.org/licenses/>.
16   */
17  
18  package org.exoplatform.social.core.storage.impl;
19  
20  import java.util.Iterator;
21  
22  import javax.jcr.Node;
23  import javax.jcr.NodeIterator;
24  import javax.jcr.query.Query;
25  import javax.jcr.query.QueryManager;
26  
27  import org.chromattic.api.ChromatticSession;
28  import org.chromattic.api.Status;
29  import org.exoplatform.commons.chromattic.ChromatticManager;
30  import org.exoplatform.container.PortalContainer;
31  import org.exoplatform.container.component.BaseComponentPlugin;
32  import org.exoplatform.services.jcr.impl.core.query.QueryImpl;
33  import org.exoplatform.services.log.ExoLogger;
34  import org.exoplatform.services.log.Log;
35  import org.exoplatform.social.common.lifecycle.SocialChromatticLifeCycle;
36  import org.exoplatform.social.core.chromattic.entity.HidableEntity;
37  import org.exoplatform.social.core.chromattic.entity.ProviderRootEntity;
38  import org.exoplatform.social.core.chromattic.entity.SpaceRootEntity;
39  import org.exoplatform.social.core.storage.exception.NodeNotFoundException;
40  
41  /**
42   * @author <a href="mailto:alain.defrance@exoplatform.com">Alain Defrance</a>
43   * @version $Revision$
44   */
45  public abstract class AbstractStorage extends BaseComponentPlugin {
46    
47    private static final Log LOG = ExoLogger.getLogger(AbstractStorage.class);
48  
49    //
50    protected final SocialChromatticLifeCycle lifeCycle;
51  
52    //
53    protected static final String NS_JCR = "jcr:";
54    protected static final String NS_EXO = "exo:";
55  
56    //
57    protected static final String NODETYPE_PROVIDERS = "soc:providers";
58    protected static final String NODETYPE_SPACES = "soc:spaces";
59  
60    //
61    protected static final String SENDER = "sender";
62    protected static final String RECEIVER = "receiver";
63  
64    // for SOC-4525
65    protected static final String SPACE_NODETYPE_PATH = "/soc:providers/soc:space/";
66  
67    protected AbstractStorage() {
68  
69      this.lifeCycle = lifecycleLookup();
70  
71    }
72  
73    protected ChromatticSession getSession() {
74      return lifeCycle.getSession();
75    }
76  
77    private <T> T getRoot(String nodetypeName, Class<T> t) {
78      boolean created = startSynchronization();
79      try {
80        T got = getSession().findByPath(t, nodetypeName);
81        if (got == null) {
82          got = getSession().insert(t, nodetypeName);
83        }
84        return got;
85      }
86      finally {
87        stopSynchronization(created);
88      }
89    }
90  
91    public ProviderRootEntity getProviderRoot() {
92      if (lifeCycle.getProviderRoot().get() == null) {
93        lifeCycle.getProviderRoot().set(getRoot(NODETYPE_PROVIDERS, ProviderRootEntity.class));
94      }
95  
96      return (ProviderRootEntity) lifeCycle.getProviderRoot().get();
97    }
98    
99  
100   public SpaceRootEntity getSpaceRoot() {
101     if (lifeCycle.getSpaceRoot().get() == null) {
102       lifeCycle.getSpaceRoot().set(getRoot(NODETYPE_SPACES, SpaceRootEntity.class));
103     }
104     return (SpaceRootEntity) lifeCycle.getSpaceRoot().get();
105   }
106 
107   protected <T> T _findById(final Class<T> clazz, final String nodeId) throws NodeNotFoundException {
108 
109     if (nodeId == null) {
110       throw new NodeNotFoundException("null id cannot be found");
111     }
112 
113     //
114     T got = getSession().findById(clazz, nodeId);
115 
116     //
117     if (got == null) {
118       throw new NodeNotFoundException(nodeId + " doesn't exists");
119     }
120 
121     return got;
122   }
123 
124   protected <T> T _findByPath(final Class<T> clazz, final String nodePath) throws NodeNotFoundException {
125     if (nodePath == null) {
126       throw new NodeNotFoundException("null nodePath cannot be found");
127     }
128 
129     //
130     T got = getSession().findByPath(clazz, nodePath, true);
131 
132     //
133     if (got == null) {
134       throw new NodeNotFoundException(nodePath + " doesn't exists");
135     }
136 
137     return got;
138   }
139 
140   protected void _removeById(final Class<?> clazz, final String nodeId) {
141     getSession().remove(getSession().findById(clazz, nodeId));
142   }
143   
144   protected <T> Status getStatus(final Class<T> clazz, final Object entity) throws IllegalArgumentException {
145     if (clazz != entity.getClass()) {
146       throw new IllegalArgumentException("Entity argument is wrong.");
147     }
148     return getSession().getStatus(entity);
149   }
150   
151   protected boolean isJcrProperty(String name) {
152     return !name.startsWith(NS_JCR);
153   }
154 
155   protected void _skip(Iterator<?> it, long offset) {
156 
157     // TODO : use JCR skip
158 
159     while (it.hasNext()) {
160       if (offset == 0) {
161         return;
162       }
163       else {
164         it.next();
165         --offset;
166       }
167     }
168   }
169   
170   protected <M> M _getMixin(Object o, Class<M> mixinType, boolean create) {
171     M mixin = getSession().getEmbedded(o, mixinType);
172     if (mixin == null && create) {
173       mixin = getSession().create(mixinType);
174       getSession().setEmbedded(o, mixinType, mixin);
175     }
176     //Fix for case old activity node without mixinType Hidable.
177     if (mixin != null && mixinType.equals(HidableEntity.class)) {
178       HidableEntity hidableEntity = (HidableEntity) mixin;
179       if (hidableEntity.getHidden() == null) {
180         hidableEntity.setHidden(false);
181         getSession().save();
182       }
183     }
184     return mixin;
185   }
186 
187   protected <M> boolean _removeMixin(Object o, Class<M> mixinType) {
188     M mixin = getSession().getEmbedded(o, mixinType);
189     if (mixin != null) {
190       getSession().setEmbedded(o, mixinType, null);
191       return true;
192     } else {
193       return false;
194     }
195   }
196   
197   protected <M> boolean _hasMixin(Object o, Class<M> mixinType) {
198     M mixin = getSession().getEmbedded(o, mixinType);
199     return mixin != null;
200   }
201   
202   /**
203    * Gets NodeIterator with Statement with offset and limit
204    * 
205    * @param statement
206    * @return
207    */
208   protected NodeIterator nodes(String statement) {
209     //
210     if (statement == null) return null;
211     
212     //
213     try {
214       QueryManager queryMgr = getSession().getJCRSession().getWorkspace().getQueryManager();
215       Query query = queryMgr.createQuery(statement, Query.SQL);
216       if (query instanceof QueryImpl) {
217         QueryImpl impl = (QueryImpl) query;
218         
219         return impl.execute().getNodes();
220       }
221       
222       //
223       return query.execute().getNodes();
224     } catch (Exception ex) {
225       LOG.error("Query is failed!.", ex);
226       return null;
227     }
228   }
229   
230   /**
231    * Gets NodeIterator with Statement with offset and limit
232    * 
233    * @param statement
234    * @param offset
235    * @param limit
236    * @return
237    */
238   protected NodeIterator nodes(String statement, long offset, long limit) {
239     //
240     if (statement == null) return null;
241     
242     //
243     try {
244       QueryManager queryMgr = getSession().getJCRSession().getWorkspace().getQueryManager();
245       Query query = queryMgr.createQuery(statement, Query.SQL);
246       if (query instanceof QueryImpl) {
247         QueryImpl impl = (QueryImpl) query;
248         
249         //
250         impl.setOffset(offset);
251         impl.setLimit(limit);
252         
253         return impl.execute().getNodes();
254       }
255       
256       //
257       return query.execute().getNodes();
258     } catch (Exception ex) {
259       return null;
260     }
261   }
262   
263   /**
264    * Gets Node by the node path (jcr path)
265    * 
266    * @param jcrPath
267    * @return
268    */
269   protected Node node(String jcrPath) {
270     //
271     if (jcrPath == null) return null;
272     try {
273       return (Node) getSession().getJCRSession().getItem(jcrPath);
274     } catch (Exception ex) {
275       return null;
276     }
277   }
278 
279   public static boolean startSynchronization() {
280 
281     SocialChromatticLifeCycle lc = lifecycleLookup();
282 
283     if (lc.getManager().getSynchronization() == null) {
284       lc.getManager().beginRequest();
285       return true;
286     }
287     return false;
288   }
289 
290   public static void stopSynchronization(boolean requestClose) {
291 
292     SocialChromatticLifeCycle lc = lifecycleLookup();
293     if (requestClose) {
294       lc.getManager().endRequest(true);
295     }
296   }
297 
298   public static SocialChromatticLifeCycle lifecycleLookup() {
299 
300     PortalContainer container = PortalContainer.getInstance();
301     ChromatticManager manager = (ChromatticManager) container.getComponentInstanceOfType(ChromatticManager.class);
302     return (SocialChromatticLifeCycle) manager.getLifeCycle(SocialChromatticLifeCycle.SOCIAL_LIFECYCLE_NAME);
303 
304   }
305   
306 }