2 * Copyright (C) 2007-2012 Argeo GmbH
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
16 package org
.argeo
.cms
.internal
.kernel
;
19 import java
.net
.URISyntaxException
;
20 import java
.util
.Collection
;
21 import java
.util
.HashMap
;
24 import javax
.jcr
.Repository
;
25 import javax
.jcr
.RepositoryException
;
26 import javax
.jcr
.RepositoryFactory
;
28 import org
.apache
.commons
.logging
.Log
;
29 import org
.apache
.commons
.logging
.LogFactory
;
30 import org
.apache
.jackrabbit
.jcr2dav
.Jcr2davRepositoryFactory
;
31 import org
.argeo
.cms
.internal
.jcr
.RepoConf
;
32 import org
.argeo
.jcr
.ArgeoJcrException
;
33 import org
.argeo
.node
.NodeConstants
;
34 import org
.osgi
.framework
.BundleContext
;
35 import org
.osgi
.framework
.FrameworkUtil
;
36 import org
.osgi
.framework
.InvalidSyntaxException
;
37 import org
.osgi
.framework
.ServiceReference
;
38 import org
.springframework
.core
.io
.Resource
;
41 * OSGi-aware Jackrabbit repository factory which can retrieve/publish
42 * {@link Repository} as OSGi services.
44 class NodeRepositoryFactory
implements RepositoryFactory
{
45 private final Log log
= LogFactory
.getLog(getClass());
46 private final BundleContext bundleContext
= FrameworkUtil
.getBundle(getClass()).getBundleContext();
48 // private Resource fileRepositoryConfiguration = new ClassPathResource(
49 // "/org/argeo/cms/internal/kernel/repository-localfs.xml");
51 protected Repository
getRepositoryByAlias(String alias
) {
53 Collection
<ServiceReference
<Repository
>> srs
= bundleContext
.getServiceReferences(Repository
.class,
54 "(" + NodeConstants
.CN
+ "=" + alias
+ ")");
56 throw new ArgeoJcrException("No repository with alias " + alias
+ " found in OSGi registry");
57 else if (srs
.size() > 1)
58 throw new ArgeoJcrException(
59 srs
.size() + " repositories with alias " + alias
+ " found in OSGi registry");
60 return bundleContext
.getService(srs
.iterator().next());
61 } catch (InvalidSyntaxException e
) {
62 throw new ArgeoJcrException("Cannot find repository with alias " + alias
, e
);
66 // private void publish(String alias, Repository repository, Properties
68 // if (bundleContext != null) {
69 // // do not modify reference
70 // Hashtable<String, String> props = new Hashtable<String, String>();
71 // props.putAll(props);
72 // props.put(JCR_REPOSITORY_ALIAS, alias);
73 // bundleContext.registerService(Repository.class.getName(), repository,
78 @SuppressWarnings({ "rawtypes" })
79 public Repository
getRepository(Map parameters
) throws RepositoryException
{
80 // // check if can be found by alias
81 // Repository repository = super.getRepository(parameters);
82 // if (repository != null)
86 Repository repository
;
88 if (parameters
.containsKey(RepoConf
.labeledUri
.name()))
89 uri
= parameters
.get(NodeConstants
.LABELED_URI
).toString();
90 else if (parameters
.containsKey(KernelConstants
.JACKRABBIT_REPOSITORY_URI
))
91 uri
= parameters
.get(KernelConstants
.JACKRABBIT_REPOSITORY_URI
).toString();
94 if (uri
.startsWith("http")) {// http, https
95 Object defaultWorkspace
= parameters
.get(RepoConf
.defaultWorkspace
.name());
96 repository
= createRemoteRepository(uri
, defaultWorkspace
!= null ? defaultWorkspace
.toString() : null);
97 } else if (uri
.startsWith("file"))// http, https
98 repository
= createFileRepository(uri
, parameters
);
99 else if (uri
.startsWith("vm")) {
100 // log.warn("URI " + uri + " should have been managed by generic
101 // JCR repository factory");
102 repository
= getRepositoryByAlias(getAliasFromURI(uri
));
104 throw new ArgeoJcrException("Unrecognized URI format " + uri
);
108 else if (parameters
.containsKey(NodeConstants
.CN
)) {
109 // Properties properties = new Properties();
110 // properties.putAll(parameters);
111 String alias
= parameters
.get(NodeConstants
.CN
).toString();
112 // publish(alias, repository, properties);
113 // log.info("Registered JCR repository under alias '" + alias + "'
114 // with properties " + properties);
115 repository
= getRepositoryByAlias(alias
);
117 throw new ArgeoJcrException("Not enough information in " + parameters
);
119 if (repository
== null)
120 throw new ArgeoJcrException("Repository not found " + parameters
);
125 protected Repository
createRemoteRepository(String uri
, String defaultWorkspace
) throws RepositoryException
{
126 Map
<String
, String
> params
= new HashMap
<String
, String
>();
127 params
.put(KernelConstants
.JACKRABBIT_REPOSITORY_URI
, uri
);
128 if (defaultWorkspace
!= null)
129 params
.put(KernelConstants
.JACKRABBIT_REMOTE_DEFAULT_WORKSPACE
, defaultWorkspace
);
130 Repository repository
= new Jcr2davRepositoryFactory().getRepository(params
);
131 if (repository
== null)
132 throw new ArgeoJcrException("Remote Davex repository " + uri
+ " not found");
133 log
.info("Initialized remote Jackrabbit repository from uri " + uri
);
137 @SuppressWarnings({ "rawtypes" })
138 protected Repository
createFileRepository(final String uri
, Map parameters
) throws RepositoryException
{
139 throw new UnsupportedOperationException();
140 // InputStream configurationIn = null;
142 // Properties vars = new Properties();
143 // vars.putAll(parameters);
144 // String dirPath = uri.substring("file:".length());
145 // File homeDir = new File(dirPath);
146 // if (homeDir.exists() && !homeDir.isDirectory())
147 // throw new ArgeoJcrException("Repository home " + dirPath + " is not a
149 // if (!homeDir.exists())
151 // configurationIn = fileRepositoryConfiguration.getInputStream();
152 // vars.put(RepositoryConfigurationParser.REPOSITORY_HOME_VARIABLE,
153 // homeDir.getCanonicalPath());
154 // RepositoryConfig repositoryConfig = RepositoryConfig.create(new
155 // InputSource(configurationIn), vars);
157 // // TransientRepository repository = new
158 // // TransientRepository(repositoryConfig);
159 // final RepositoryImpl repository =
160 // RepositoryImpl.create(repositoryConfig);
161 // Session session = repository.login();
162 // // FIXME make it generic
163 // org.argeo.jcr.JcrUtils.addPrivilege(session, "/", "ROLE_ADMIN",
165 // org.argeo.jcr.JcrUtils.logoutQuietly(session);
166 // Runtime.getRuntime().addShutdownHook(new Thread("Clean JCR repository
168 // public void run() {
169 // repository.shutdown();
170 // log.info("Destroyed repository " + uri);
173 // log.info("Initialized file Jackrabbit repository from uri " + uri);
174 // return repository;
175 // } catch (Exception e) {
176 // throw new ArgeoJcrException("Cannot create repository " + uri, e);
178 // IOUtils.closeQuietly(configurationIn);
182 protected String
getAliasFromURI(String uri
) {
184 URI uriObj
= new URI(uri
);
185 String alias
= uriObj
.getPath();
186 if (alias
.charAt(0) == '/')
187 alias
= alias
.substring(1);
188 if (alias
.charAt(alias
.length() - 1) == '/')
189 alias
= alias
.substring(0, alias
.length() - 1);
191 } catch (URISyntaxException e
) {
192 throw new ArgeoJcrException("Cannot interpret URI " + uri
, e
);
197 * Called after the repository has been initialised. Does nothing by default.
199 @SuppressWarnings("rawtypes")
200 protected void postInitialization(Repository repository
, Map parameters
) {
204 public void setFileRepositoryConfiguration(Resource fileRepositoryConfiguration
) {
205 // this.fileRepositoryConfiguration = fileRepositoryConfiguration;