]> git.argeo.org Git - lgpl/argeo-commons.git/blob - org.argeo.node.api/src/org/argeo/node/NodeUtils.java
[maven-release-plugin] prepare release argeo-commons-2.1.82
[lgpl/argeo-commons.git] / org.argeo.node.api / src / org / argeo / node / NodeUtils.java
1 /*
2 * Copyright (C) 2007-2012 Argeo GmbH
3 *
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
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
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.
15 */
16 package org.argeo.node;
17
18 import java.security.PrivilegedAction;
19 import java.util.HashMap;
20 import java.util.Map;
21
22 import javax.jcr.NoSuchWorkspaceException;
23 import javax.jcr.Node;
24 import javax.jcr.NodeIterator;
25 import javax.jcr.Repository;
26 import javax.jcr.RepositoryException;
27 import javax.jcr.RepositoryFactory;
28 import javax.jcr.Session;
29 import javax.jcr.query.Query;
30 import javax.jcr.query.QueryResult;
31 import javax.jcr.query.qom.Constraint;
32 import javax.jcr.query.qom.DynamicOperand;
33 import javax.jcr.query.qom.QueryObjectModelFactory;
34 import javax.jcr.query.qom.Selector;
35 import javax.jcr.query.qom.StaticOperand;
36 import javax.security.auth.AuthPermission;
37 import javax.security.auth.Subject;
38 import javax.security.auth.login.LoginContext;
39 import javax.security.auth.login.LoginException;
40
41 /** Utilities related to Argeo model in JCR */
42 public class NodeUtils {
43 /**
44 * Wraps the call to the repository factory based on parameter
45 * {@link NodeConstants#CN} in order to simplify it and protect against future
46 * API changes.
47 */
48 public static Repository getRepositoryByAlias(RepositoryFactory repositoryFactory, String alias) {
49 try {
50 Map<String, String> parameters = new HashMap<String, String>();
51 parameters.put(NodeConstants.CN, alias);
52 return repositoryFactory.getRepository(parameters);
53 } catch (RepositoryException e) {
54 throw new RuntimeException("Unexpected exception when trying to retrieve repository with alias " + alias,
55 e);
56 }
57 }
58
59 /**
60 * Wraps the call to the repository factory based on parameter
61 * {@link NodeConstants#LABELED_URI} in order to simplify it and protect against
62 * future API changes.
63 */
64 public static Repository getRepositoryByUri(RepositoryFactory repositoryFactory, String uri) {
65 return getRepositoryByUri(repositoryFactory, uri, null);
66 }
67
68 /**
69 * Wraps the call to the repository factory based on parameter
70 * {@link NodeConstants#LABELED_URI} in order to simplify it and protect against
71 * future API changes.
72 */
73 public static Repository getRepositoryByUri(RepositoryFactory repositoryFactory, String uri, String alias) {
74 try {
75 Map<String, String> parameters = new HashMap<String, String>();
76 parameters.put(NodeConstants.LABELED_URI, uri);
77 if (alias != null)
78 parameters.put(NodeConstants.CN, alias);
79 return repositoryFactory.getRepository(parameters);
80 } catch (RepositoryException e) {
81 throw new RuntimeException("Unexpected exception when trying to retrieve repository with uri " + uri, e);
82 }
83 }
84
85 /**
86 * Returns the home node of the user or null if none was found.
87 *
88 * @param session the session to use in order to perform the search, this can
89 * be a session with a different user ID than the one searched,
90 * typically when a system or admin session is used.
91 * @param username the username of the user
92 */
93 public static Node getUserHome(Session session, String username) {
94 try {
95 QueryObjectModelFactory qomf = session.getWorkspace().getQueryManager().getQOMFactory();
96 Selector sel = qomf.selector(NodeTypes.NODE_USER_HOME, "sel");
97 DynamicOperand dop = qomf.propertyValue(sel.getSelectorName(), NodeNames.LDAP_UID);
98 StaticOperand sop = qomf.literal(session.getValueFactory().createValue(username));
99 Constraint constraint = qomf.comparison(dop, QueryObjectModelFactory.JCR_OPERATOR_EQUAL_TO, sop);
100 Query query = qomf.createQuery(sel, constraint, null, null);
101 return querySingleNode(query);
102 } catch (RepositoryException e) {
103 throw new RuntimeException("Cannot find home for user " + username, e);
104 }
105 }
106
107 /**
108 * Returns the home node of the user or null if none was found.
109 *
110 * @param session the session to use in order to perform the search, this can be
111 * a session with a different user ID than the one searched,
112 * typically when a system or admin session is used.
113 * @param cn the name of the group
114 */
115 public static Node getGroupHome(Session session, String cn) {
116 try {
117 QueryObjectModelFactory qomf = session.getWorkspace().getQueryManager().getQOMFactory();
118 Selector sel = qomf.selector(NodeTypes.NODE_GROUP_HOME, "sel");
119 DynamicOperand dop = qomf.propertyValue(sel.getSelectorName(), NodeNames.LDAP_CN);
120 StaticOperand sop = qomf.literal(session.getValueFactory().createValue(cn));
121 Constraint constraint = qomf.comparison(dop, QueryObjectModelFactory.JCR_OPERATOR_EQUAL_TO, sop);
122 Query query = qomf.createQuery(sel, constraint, null, null);
123 return querySingleNode(query);
124 } catch (RepositoryException e) {
125 throw new RuntimeException("Cannot find home for user " + cn, e);
126 }
127 }
128
129 /**
130 * Queries one single node.
131 *
132 * @return one single node or null if none was found
133 * @throws ArgeoJcrException if more than one node was found
134 */
135 private static Node querySingleNode(Query query) {
136 NodeIterator nodeIterator;
137 try {
138 QueryResult queryResult = query.execute();
139 nodeIterator = queryResult.getNodes();
140 } catch (RepositoryException e) {
141 throw new RuntimeException("Cannot execute query " + query, e);
142 }
143 Node node;
144 if (nodeIterator.hasNext())
145 node = nodeIterator.nextNode();
146 else
147 return null;
148
149 if (nodeIterator.hasNext())
150 throw new RuntimeException("Query returned more than one node.");
151 return node;
152 }
153
154 /** Returns the home node of the session user or null if none was found. */
155 public static Node getUserHome(Session session) {
156 String userID = session.getUserID();
157 return getUserHome(session, userID);
158 }
159
160 /**
161 * Translate the path to this node into a path containing the name of the
162 * repository and the name of the workspace.
163 */
164 public static String getDataPath(String cn, Node node) throws RepositoryException {
165 assert node != null;
166 StringBuilder buf = new StringBuilder(NodeConstants.PATH_DATA);
167 return buf.append('/').append(cn).append('/').append(node.getSession().getWorkspace().getName())
168 .append(node.getPath()).toString();
169 }
170
171 /**
172 * Open a JCR session with full read/write rights on the data, as
173 * {@link NodeConstants#ROLE_USER_ADMIN}, using the
174 * {@link NodeConstants#LOGIN_CONTEXT_DATA_ADMIN} login context. For security
175 * hardened deployement, use {@link AuthPermission} on this login context.
176 */
177 public static Session openDataAdminSession(Repository repository, String workspaceName) {
178 ClassLoader currentCl = Thread.currentThread().getContextClassLoader();
179 LoginContext loginContext;
180 try {
181 loginContext = new LoginContext(NodeConstants.LOGIN_CONTEXT_DATA_ADMIN);
182 loginContext.login();
183 } catch (LoginException e1) {
184 throw new RuntimeException("Could not login as data admin", e1);
185 } finally {
186 Thread.currentThread().setContextClassLoader(currentCl);
187 }
188 return Subject.doAs(loginContext.getSubject(), new PrivilegedAction<Session>() {
189
190 @Override
191 public Session run() {
192 try {
193 return repository.login(workspaceName);
194 } catch (NoSuchWorkspaceException e) {
195 throw new IllegalArgumentException("No workspace " + workspaceName + " available", e);
196 } catch (RepositoryException e) {
197 throw new RuntimeException("Cannot open data admin session", e);
198 }
199 }
200
201 });
202 }
203
204 /** Singleton. */
205 private NodeUtils() {
206 }
207
208 }