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
.node
;
18 import java
.security
.PrivilegedAction
;
19 import java
.util
.HashMap
;
22 import javax
.jcr
.Node
;
23 import javax
.jcr
.NodeIterator
;
24 import javax
.jcr
.Repository
;
25 import javax
.jcr
.RepositoryException
;
26 import javax
.jcr
.RepositoryFactory
;
27 import javax
.jcr
.Session
;
28 import javax
.jcr
.query
.Query
;
29 import javax
.jcr
.query
.QueryResult
;
30 import javax
.jcr
.query
.qom
.Constraint
;
31 import javax
.jcr
.query
.qom
.DynamicOperand
;
32 import javax
.jcr
.query
.qom
.QueryObjectModelFactory
;
33 import javax
.jcr
.query
.qom
.Selector
;
34 import javax
.jcr
.query
.qom
.StaticOperand
;
35 import javax
.security
.auth
.AuthPermission
;
36 import javax
.security
.auth
.Subject
;
37 import javax
.security
.auth
.login
.LoginContext
;
38 import javax
.security
.auth
.login
.LoginException
;
40 /** Utilities related to Argeo model in JCR */
41 public class NodeUtils
{
43 * Wraps the call to the repository factory based on parameter
44 * {@link NodeConstants#CN} in order to simplify it and protect against future
47 public static Repository
getRepositoryByAlias(RepositoryFactory repositoryFactory
, String alias
) {
49 Map
<String
, String
> parameters
= new HashMap
<String
, String
>();
50 parameters
.put(NodeConstants
.CN
, alias
);
51 return repositoryFactory
.getRepository(parameters
);
52 } catch (RepositoryException e
) {
53 throw new RuntimeException("Unexpected exception when trying to retrieve repository with alias " + alias
,
59 * Wraps the call to the repository factory based on parameter
60 * {@link NodeConstants#LABELED_URI} in order to simplify it and protect against
63 public static Repository
getRepositoryByUri(RepositoryFactory repositoryFactory
, String uri
) {
64 return getRepositoryByUri(repositoryFactory
, uri
, null);
68 * Wraps the call to the repository factory based on parameter
69 * {@link NodeConstants#LABELED_URI} in order to simplify it and protect against
72 public static Repository
getRepositoryByUri(RepositoryFactory repositoryFactory
, String uri
, String alias
) {
74 Map
<String
, String
> parameters
= new HashMap
<String
, String
>();
75 parameters
.put(NodeConstants
.LABELED_URI
, uri
);
77 parameters
.put(NodeConstants
.CN
, alias
);
78 return repositoryFactory
.getRepository(parameters
);
79 } catch (RepositoryException e
) {
80 throw new RuntimeException("Unexpected exception when trying to retrieve repository with uri " + uri
, e
);
85 * Returns the home node of the user or null if none was found.
87 * @param session the session to use in order to perform the search, this can
88 * be a session with a different user ID than the one searched,
89 * typically when a system or admin session is used.
90 * @param username the username of the user
92 public static Node
getUserHome(Session session
, String username
) {
94 QueryObjectModelFactory qomf
= session
.getWorkspace().getQueryManager().getQOMFactory();
95 Selector sel
= qomf
.selector(NodeTypes
.NODE_USER_HOME
, "sel");
96 DynamicOperand dop
= qomf
.propertyValue(sel
.getSelectorName(), NodeNames
.LDAP_UID
);
97 StaticOperand sop
= qomf
.literal(session
.getValueFactory().createValue(username
));
98 Constraint constraint
= qomf
.comparison(dop
, QueryObjectModelFactory
.JCR_OPERATOR_EQUAL_TO
, sop
);
99 Query query
= qomf
.createQuery(sel
, constraint
, null, null);
100 return querySingleNode(query
);
101 } catch (RepositoryException e
) {
102 throw new RuntimeException("Cannot find home for user " + username
, e
);
107 * Returns the home node of the user or null if none was found.
109 * @param session the session to use in order to perform the search, this can be
110 * a session with a different user ID than the one searched,
111 * typically when a system or admin session is used.
112 * @param cn the name of the group
114 public static Node
getGroupHome(Session session
, String cn
) {
116 QueryObjectModelFactory qomf
= session
.getWorkspace().getQueryManager().getQOMFactory();
117 Selector sel
= qomf
.selector(NodeTypes
.NODE_GROUP_HOME
, "sel");
118 DynamicOperand dop
= qomf
.propertyValue(sel
.getSelectorName(), NodeNames
.LDAP_CN
);
119 StaticOperand sop
= qomf
.literal(session
.getValueFactory().createValue(cn
));
120 Constraint constraint
= qomf
.comparison(dop
, QueryObjectModelFactory
.JCR_OPERATOR_EQUAL_TO
, sop
);
121 Query query
= qomf
.createQuery(sel
, constraint
, null, null);
122 return querySingleNode(query
);
123 } catch (RepositoryException e
) {
124 throw new RuntimeException("Cannot find home for user " + cn
, e
);
129 * Queries one single node.
131 * @return one single node or null if none was found
132 * @throws ArgeoJcrException if more than one node was found
134 private static Node
querySingleNode(Query query
) {
135 NodeIterator nodeIterator
;
137 QueryResult queryResult
= query
.execute();
138 nodeIterator
= queryResult
.getNodes();
139 } catch (RepositoryException e
) {
140 throw new RuntimeException("Cannot execute query " + query
, e
);
143 if (nodeIterator
.hasNext())
144 node
= nodeIterator
.nextNode();
148 if (nodeIterator
.hasNext())
149 throw new RuntimeException("Query returned more than one node.");
153 /** Returns the home node of the session user or null if none was found. */
154 public static Node
getUserHome(Session session
) {
155 String userID
= session
.getUserID();
156 return getUserHome(session
, userID
);
160 * Translate the path to this node into a path containing the name of the
161 * repository and the name of the workspace.
163 public static String
getDataPath(String cn
, Node node
) throws RepositoryException
{
165 StringBuilder buf
= new StringBuilder(NodeConstants
.PATH_DATA
);
166 return buf
.append('/').append(cn
).append('/').append(node
.getSession().getWorkspace().getName())
167 .append(node
.getPath()).toString();
171 * Open a JCR session with full read/write rights on the data, as
172 * {@link NodeConstants#ROLE_USER_ADMIN}, using the
173 * {@link NodeConstants#LOGIN_CONTEXT_DATA_ADMIN} login context. For security
174 * hardened deployement, use {@link AuthPermission} on this login context.
176 public static Session
openDataAdminSession(Repository repository
, String workspaceName
) {
177 ClassLoader currentCl
= Thread
.currentThread().getContextClassLoader();
178 LoginContext loginContext
;
180 loginContext
= new LoginContext(NodeConstants
.LOGIN_CONTEXT_DATA_ADMIN
);
181 loginContext
.login();
182 } catch (LoginException e1
) {
183 throw new RuntimeException("Could not login as data admin", e1
);
185 Thread
.currentThread().setContextClassLoader(currentCl
);
187 return Subject
.doAs(loginContext
.getSubject(), new PrivilegedAction
<Session
>() {
190 public Session
run() {
192 return repository
.login(workspaceName
);
193 } catch (RepositoryException e
) {
194 throw new RuntimeException("Cannot open data admin session", e
);
202 private NodeUtils() {