1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34 package info.magnolia.context;
35
36 import info.magnolia.cms.core.HierarchyManager;
37 import info.magnolia.cms.core.search.QueryManager;
38 import info.magnolia.cms.util.WorkspaceAccessUtil;
39 import info.magnolia.stats.JCRStats;
40
41 import java.util.HashMap;
42 import java.util.Map;
43
44 import javax.jcr.RepositoryException;
45 import javax.jcr.Session;
46 import javax.jcr.observation.EventListener;
47 import javax.jcr.observation.EventListenerIterator;
48 import javax.jcr.observation.ObservationManager;
49
50 import org.apache.commons.lang.UnhandledException;
51 import org.slf4j.Logger;
52 import org.slf4j.LoggerFactory;
53
54
55
56
57
58
59
60
61 public abstract class AbstractRepositoryStrategy implements RepositoryAcquiringStrategy {
62 private static final Logger log = LoggerFactory.getLogger(AbstractRepositoryStrategy.class);
63
64 private final Map<String, Session> jcrSessions = new HashMap<String, Session>();
65
66 private final Map<String, HierarchyManager> hierarchyManagers = new HashMap<String, HierarchyManager>();
67
68 public HierarchyManager getHierarchyManager(String repositoryId, String workspaceId) {
69 final String hmAttrName = repositoryId + "_" + workspaceId;
70 HierarchyManager hm = hierarchyManagers.get(hmAttrName);
71
72 if (hm == null) {
73 WorkspaceAccessUtil util = WorkspaceAccessUtil.getInstance();
74 try {
75 hm = util.createHierarchyManager(getUserId(),
76 getRepositorySession(repositoryId, workspaceId),
77 getAccessManager(repositoryId, workspaceId));
78 hierarchyManagers.put(hmAttrName, hm);
79 }
80 catch (RepositoryException e) {
81 throw new UnhandledException(e);
82 }
83 }
84
85 return hm;
86 }
87
88 abstract protected String getUserId();
89
90 public QueryManager getQueryManager(String repositoryId, String workspaceId) {
91 return this.getHierarchyManager(repositoryId, workspaceId).getQueryManager();
92 }
93
94 protected Session getRepositorySession(String repositoryName, String workspaceName) throws RepositoryException {
95 final String repoSessAttrName = repositoryName + "_" + workspaceName;
96
97 Session jcrSession = jcrSessions.get(repoSessAttrName);
98
99 if (jcrSession == null) {
100 log.debug("creating jcr session {} by thread {}", repositoryName, Thread.currentThread().getName());
101
102 WorkspaceAccessUtil util = WorkspaceAccessUtil.getInstance();
103 jcrSession = util.createRepositorySession(util.getDefaultCredentials(), repositoryName, workspaceName);
104 jcrSessions.put(repoSessAttrName, jcrSession);
105 incSessionCount(workspaceName);
106 }
107
108 return jcrSession;
109 }
110
111 protected void release(boolean checkObservation) {
112 log.debug("releasing jcr sessions");
113 for (Session session : jcrSessions.values()) {
114 releaseSession(session, checkObservation);
115 }
116 hierarchyManagers.clear();
117 jcrSessions.clear();
118 }
119
120 protected void releaseSession(final Session session, boolean checkObservation) {
121 final String workspaceName = session.getWorkspace().getName();
122 if (session.isLive()) {
123 try {
124 final ObservationManager observationManager = session.getWorkspace().getObservationManager();
125 final EventListenerIterator listeners = observationManager.getRegisteredEventListeners();
126 if (!checkObservation || !listeners.hasNext()) {
127 session.logout();
128 log.debug("logged out jcr session: {} by thread {}", session, Thread.currentThread().getName());
129
130 decSessionCount(workspaceName);
131 } else {
132 log.warn("won't close session because of registered observation listener {}", workspaceName);
133 if (log.isDebugEnabled()) {
134 while (listeners.hasNext()) {
135 EventListener listener = listeners.nextEventListener();
136 log.debug("registered listener {}", listener);
137 }
138 }
139 }
140 }
141 catch (RepositoryException e) {
142 log.error("can't check if event listeners are registered", e);
143 }
144 } else {
145 log.warn("session has been already closed {}", workspaceName);
146 }
147 }
148
149 protected void incSessionCount(String workspaceName) {
150 JCRStats.getInstance().incSessionCount();
151 }
152
153 protected void decSessionCount(String workspaceName) {
154 JCRStats.getInstance().decSessionCount();
155 }
156
157
158
159
160 protected int getLocalSessionCount() {
161 return jcrSessions.size();
162 }
163
164 }