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.repository;
35
36 import info.magnolia.audit.MgnlAuditLoggingContentDecorator;
37 import info.magnolia.audit.MgnlAuditLoggingContentDecoratorSessionWrapper;
38 import info.magnolia.cms.core.SystemProperty;
39 import info.magnolia.cms.core.version.MgnlVersioningSession;
40 import info.magnolia.cms.security.AccessDeniedException;
41 import info.magnolia.cms.util.ConfigUtil;
42 import info.magnolia.context.MgnlContext;
43 import info.magnolia.jcr.RuntimeRepositoryException;
44 import info.magnolia.jcr.predicate.AbstractPredicate;
45 import info.magnolia.jcr.util.NodeTypes;
46 import info.magnolia.jcr.util.NodeUtil;
47 import info.magnolia.jcr.wrapper.MgnlPropertySettingContentDecorator;
48 import info.magnolia.objectfactory.Classes;
49 import info.magnolia.objectfactory.Components;
50 import info.magnolia.repository.definition.RepositoryDefinition;
51 import info.magnolia.repository.definition.RepositoryMappingDefinition;
52 import info.magnolia.repository.definition.RepositoryMappingDefinitionReader;
53 import info.magnolia.repository.definition.WorkspaceMappingDefinition;
54 import info.magnolia.repository.mbean.TrackingSessionWrapper;
55 import info.magnolia.stats.JCRStats;
56
57 import java.io.InputStream;
58 import java.util.Collection;
59
60 import javax.inject.Singleton;
61 import javax.jcr.Credentials;
62 import javax.jcr.NoSuchWorkspaceException;
63 import javax.jcr.Node;
64 import javax.jcr.Repository;
65 import javax.jcr.RepositoryException;
66 import javax.jcr.Session;
67
68 import org.apache.commons.io.IOUtils;
69 import org.slf4j.Logger;
70 import org.slf4j.LoggerFactory;
71
72
73
74
75 @Singleton
76 public final class DefaultRepositoryManager implements RepositoryManager {
77
78 private static final Logger log = LoggerFactory.getLogger(DefaultRepositoryManager.class);
79
80 private final WorkspaceMapping workspaceMapping = new WorkspaceMapping();
81
82 @Override
83 public void init() {
84 log.info("Loading JCR");
85 workspaceMapping.clearRepositories();
86 try {
87 loadRepositories();
88 log.debug("JCR loaded");
89 } catch (Exception e) {
90 log.error(e.getMessage(), e);
91 }
92 }
93
94 @Override
95 public void shutdown() {
96 log.info("Shutting down JCR");
97 for (RepositoryDefinition repositoryDefinition : workspaceMapping.getRepositoryDefinitions()) {
98 Provider provider = workspaceMapping.getRepositoryProvider(repositoryDefinition.getName());
99 provider.shutdownRepository();
100 }
101 workspaceMapping.clearAll();
102 }
103
104 @Override
105 public boolean checkIfInitialized() throws AccessDeniedException, RepositoryException {
106 Collection<String> workspaceNames = workspaceMapping.getLogicalWorkspaceNames();
107 for (String workspace : workspaceNames) {
108 if (checkIfInitialized(workspace)) {
109 return true;
110 }
111 }
112 return false;
113 }
114
115 @Override
116 public boolean checkIfInitialized(String logicalWorkspace) throws RepositoryException, AccessDeniedException {
117 log.debug("Checking [{}] repository.", logicalWorkspace);
118
119 Session session = MgnlContext.getSystemContext().getJCRSession(logicalWorkspace);
120
121 if (session == null) {
122 throw new RuntimeException("Repository [" + logicalWorkspace + "] not loaded");
123 }
124
125 Node startPage = session.getRootNode();
126
127
128 Iterable<Node> children = NodeUtil.getNodes(startPage, new AbstractPredicate<Node>() {
129 @Override
130 public boolean evaluateTyped(Node content) {
131 String name;
132 try {
133 name = content.getName();
134 } catch (RepositoryException e) {
135 throw new RuntimeRepositoryException(e);
136 }
137 return (!name.startsWith(NodeTypes.JCR_PREFIX) && !name.startsWith(NodeTypes.REP_PREFIX));
138 }
139 });
140
141 if (children.iterator().hasNext()) {
142 log.debug("Content found in [{}].", logicalWorkspace);
143 return true;
144 }
145 return false;
146 }
147
148 @Override
149 public void reload() {
150
151
152
153 log.info("Reloading JCR");
154 init();
155 }
156
157 private void loadRepositories() throws Exception {
158 final String path = SystemProperty.getProperty(SystemProperty.MAGNOLIA_REPOSITORIES_CONFIG);
159 if (path == null) {
160 throw new RepositoryNotInitializedException("No value found for property " + SystemProperty.MAGNOLIA_REPOSITORIES_CONFIG + ": can not start repository.");
161 }
162 final String tokenizedConfig = ConfigUtil.getTokenizedConfigFile(path);
163 InputStream stream = IOUtils.toInputStream(tokenizedConfig);
164
165 RepositoryMappingDefinitionReader reader = new RepositoryMappingDefinitionReader();
166 RepositoryMappingDefinition mapping = reader.read(stream);
167
168 for (RepositoryDefinition repositoryDefinition : mapping.getRepositories()) {
169 if (repositoryDefinition.getWorkspaces().isEmpty()) {
170 repositoryDefinition.addWorkspace("default");
171 }
172 workspaceMapping.addRepositoryDefinition(repositoryDefinition);
173 loadRepository(repositoryDefinition);
174 }
175
176 for (WorkspaceMappingDefinition workspaceMapping : mapping.getWorkspaceMappings()) {
177 this.workspaceMapping.addWorkspaceMappingDefinition(workspaceMapping);
178 }
179 }
180
181 @Override
182 public void loadRepository(RepositoryDefinition definition) throws RepositoryNotInitializedException, InstantiationException, IllegalAccessException, ClassNotFoundException {
183 log.info("Loading JCR {}", definition.getName());
184
185 Class<? extends Provider> providerClass = Classes.getClassFactory().forName(definition.getProvider());
186 Provider provider = Components.getComponentProvider().newInstance(providerClass);
187 provider.init(definition);
188 Repository repository = provider.getUnderlyingRepository();
189 workspaceMapping.setRepository(definition.getName(), repository);
190 workspaceMapping.setRepositoryProvider(definition.getName(), provider);
191
192 if (definition.isLoadOnStartup()) {
193 for (String workspaceId : definition.getWorkspaces()) {
194 registerNameSpacesAndNodeTypes(workspaceId, definition, provider);
195 }
196 }
197 }
198
199 @Override
200 public void loadWorkspace(String repositoryId, String physicalWorkspaceName) throws RepositoryException {
201 log.info("Loading workspace {}", physicalWorkspaceName);
202
203 workspaceMapping.addWorkspaceMapping(new WorkspaceMappingDefinition(physicalWorkspaceName, repositoryId, physicalWorkspaceName));
204
205 Provider provider = getRepositoryProvider(repositoryId);
206 provider.registerWorkspace(physicalWorkspaceName);
207 RepositoryDefinition repositoryDefinition = workspaceMapping.getRepositoryDefinition(repositoryId);
208
209 registerNameSpacesAndNodeTypes(physicalWorkspaceName, repositoryDefinition, provider);
210 }
211
212 private void registerNameSpacesAndNodeTypes(String physicalWorkspaceName, RepositoryDefinition repositoryDefinition, Provider provider) {
213 try {
214 Session session = provider.getSystemSession(physicalWorkspaceName);
215 try {
216 provider.registerNamespace(RepositoryConstants.NAMESPACE_PREFIX, RepositoryConstants.NAMESPACE_URI, session.getWorkspace());
217 provider.registerNodeTypes();
218 } finally {
219 session.logout();
220 }
221 } catch (RepositoryException e) {
222 log.error("Failed to initialize workspace " + physicalWorkspaceName + " in repository " + repositoryDefinition.getName(), e);
223 }
224 }
225
226 @Override
227 public Session getSession(String logicalWorkspaceName, Credentials credentials) throws RepositoryException {
228 WorkspaceMappingDefinition mapping = this.workspaceMapping.getWorkspaceMapping(logicalWorkspaceName);
229 if (mapping == null) throw new NoSuchWorkspaceException(logicalWorkspaceName);
230 Repository repository = getRepository(mapping.getRepositoryName());
231 String physicalWorkspaceName = mapping.getPhysicalWorkspaceName();
232
233 Session session = repository.login(credentials, physicalWorkspaceName);
234 return wrapSession(session, logicalWorkspaceName);
235 }
236
237 @Override
238 public Session getSystemSession(String logicalWorkspaceName) throws RepositoryException {
239 WorkspaceMappingDefinition mapping = this.workspaceMapping.getWorkspaceMapping(logicalWorkspaceName);
240 if (mapping == null) throw new NoSuchWorkspaceException(logicalWorkspaceName);
241 Provider provider = getRepositoryProvider(mapping.getRepositoryName());
242 return wrapSession(provider.getSystemSession(mapping.getPhysicalWorkspaceName()), logicalWorkspaceName);
243 }
244
245 private Session wrapSession(Session session, String logicalWorkspaceName) {
246 session = new TrackingSessionWrapper(session, JCRStats.getInstance());
247 if ("imaging".equals(logicalWorkspaceName) || "Expressions".equals(logicalWorkspaceName) || "Store".equals(logicalWorkspaceName) || "mgnlSystem".equals(logicalWorkspaceName)) {
248
249
250 return new MgnlVersioningSession(session);
251 }
252 if (!RepositoryConstants.VERSION_STORE.equals(logicalWorkspaceName)) {
253
254 session = new MgnlVersioningSession(session);
255 }
256
257
258 session = new MgnlPropertySettingContentDecorator().wrapSession(session);
259 return new MgnlAuditLoggingContentDecoratorSessionWrapper(session, new MgnlAuditLoggingContentDecorator());
260 }
261
262 @Override
263 public boolean hasRepository(String repositoryId) {
264 return workspaceMapping.getRepositoryDefinition(repositoryId) != null;
265 }
266
267 @Override
268 public RepositoryDefinition getRepositoryDefinition(String repositoryId) {
269 return workspaceMapping.getRepositoryDefinition(repositoryId);
270 }
271
272 @Override
273 public Provider getRepositoryProvider(String repositoryId) {
274 return workspaceMapping.getRepositoryProvider(repositoryId);
275 }
276
277 @Override
278 public Repository getRepository(String repositoryId) {
279 return workspaceMapping.getRepository(repositoryId);
280 }
281
282 @Override
283 public void addWorkspaceMapping(WorkspaceMappingDefinition mapping) {
284 workspaceMapping.addWorkspaceMapping(mapping);
285 }
286
287 @Override
288 public boolean hasWorkspace(String logicalWorkspaceName) {
289 return workspaceMapping.getWorkspaceMapping(logicalWorkspaceName) != null;
290 }
291
292 @Override
293 public Collection<WorkspaceMappingDefinition> getWorkspaceMappings() {
294 return workspaceMapping.getWorkspaceMappings();
295 }
296
297 @Override
298 public WorkspaceMappingDefinition getWorkspaceMapping(String logicalWorkspaceName) {
299 return workspaceMapping.getWorkspaceMapping(logicalWorkspaceName);
300 }
301
302 @Override
303 public Collection<String> getWorkspaceNames() {
304 return workspaceMapping.getLogicalWorkspaceNames();
305 }
306 }