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 public abstract class AbstractRepositoryStrategy implements RepositoryAcquiringStrategy {
61 private static final Logger log = LoggerFactory.getLogger(AbstractRepositoryStrategy.class);
62
63 private final Map<String, Session> jcrSessions = new HashMap<String, Session>();
64
65 private final Map<String, HierarchyManager> hierarchyManagers = new HashMap<String, HierarchyManager>();
66
67 public HierarchyManager getHierarchyManager(String repositoryId, String workspaceId) {
68 final String hmAttrName = repositoryId + "_" + workspaceId;
69 HierarchyManager hm = hierarchyManagers.get(hmAttrName);
70
71 if (hm == null) {
72 WorkspaceAccessUtil util = WorkspaceAccessUtil.getInstance();
73 try {
74 hm = util.createHierarchyManager(getUserId(),
75 getRepositorySession(repositoryId, workspaceId),
76 getAccessManager(repositoryId, workspaceId));
77 hierarchyManagers.put(hmAttrName, hm);
78 }
79 catch (RepositoryException e) {
80 throw new UnhandledException(e);
81 }
82 }
83
84 return hm;
85 }
86
87 abstract protected String getUserId();
88
89 public QueryManager getQueryManager(String repositoryId, String workspaceId) {
90 return this.getHierarchyManager(repositoryId, workspaceId).getQueryManager();
91 }
92
93 protected Session getRepositorySession(String repositoryName, String workspaceName) throws RepositoryException {
94 final String repoSessAttrName = repositoryName + "_" + workspaceName;
95
96 Session jcrSession = jcrSessions.get(repoSessAttrName);
97
98 if (jcrSession == null) {
99 log.debug("creating jcr session {} by thread {}", repositoryName, Thread.currentThread().getName());
100
101 WorkspaceAccessUtil util = WorkspaceAccessUtil.getInstance();
102 jcrSession = util.createRepositorySession(util.getDefaultCredentials(), repositoryName, workspaceName);
103 jcrSessions.put(repoSessAttrName, jcrSession);
104 incSessionCount(workspaceName);
105 }
106
107 return jcrSession;
108 }
109
110 protected void release(boolean checkObservation) {
111 log.debug("releasing jcr sessions");
112 for (Session session : jcrSessions.values()) {
113 releaseSession(session, checkObservation);
114 }
115 hierarchyManagers.clear();
116 jcrSessions.clear();
117 }
118
119 protected void releaseSession(final Session session, boolean checkObservation) {
120 final String workspaceName = session.getWorkspace().getName();
121 if (session.isLive()) {
122 try {
123 final ObservationManager observationManager = session.getWorkspace().getObservationManager();
124 final EventListenerIterator listeners = observationManager.getRegisteredEventListeners();
125 if (!checkObservation || !listeners.hasNext()) {
126 session.logout();
127 log.debug("logged out jcr session: {} by thread {}", session, Thread.currentThread().getName());
128
129 decSessionCount(workspaceName);
130 } else {
131 log.warn("won't close session because of registered observation listener {}", workspaceName);
132 if (log.isDebugEnabled()) {
133 while (listeners.hasNext()) {
134 EventListener listener = listeners.nextEventListener();
135 log.debug("registered listener {}", listener);
136 }
137 }
138 }
139 }
140 catch (RepositoryException e) {
141 log.error("can't check if event listeners are registered", e);
142 }
143 } else {
144 log.warn("session has been already closed {}", workspaceName);
145 }
146 }
147
148 protected void incSessionCount(String workspaceName) {
149 JCRStats.getInstance().incSessionCount();
150 }
151
152 protected void decSessionCount(String workspaceName) {
153 JCRStats.getInstance().decSessionCount();
154 }
155
156
157
158
159 protected int getLocalSessionCount() {
160 return jcrSessions.size();
161 }
162
163 }