]> git.argeo.org Git - gpl/argeo-jcr.git/blob - org.argeo.cms.jcr/src/org/argeo/maintenance/AbstractMaintenanceService.java
Improve writing to a JCR Content
[gpl/argeo-jcr.git] / org.argeo.cms.jcr / src / org / argeo / maintenance / AbstractMaintenanceService.java
1 package org.argeo.maintenance;
2
3 import java.io.IOException;
4 import java.util.EnumSet;
5 import java.util.HashSet;
6 import java.util.Set;
7
8 import javax.jcr.NoSuchWorkspaceException;
9 import javax.jcr.Repository;
10 import javax.jcr.RepositoryException;
11 import javax.jcr.Session;
12
13 import org.argeo.api.acr.ldap.Distinguished;
14 import org.argeo.api.acr.spi.ProvidedRepository;
15 import org.argeo.api.cms.CmsLog;
16 import org.argeo.api.cms.transaction.WorkTransaction;
17 import org.argeo.cms.jcr.CmsJcrUtils;
18 import org.argeo.jcr.Jcr;
19 import org.argeo.jcr.JcrUtils;
20 import org.osgi.service.useradmin.Group;
21 import org.osgi.service.useradmin.Role;
22 import org.osgi.service.useradmin.UserAdmin;
23
24 /** Make sure roles and access rights are properly configured. */
25 public abstract class AbstractMaintenanceService {
26 private final static CmsLog log = CmsLog.getLog(AbstractMaintenanceService.class);
27
28 private Repository repository;
29 // private UserAdminService userAdminService;
30 private UserAdmin userAdmin;
31 private WorkTransaction userTransaction;
32
33 private ProvidedRepository contentRepository;
34
35 public void init() {
36 makeSureRolesExists(getRequiredRoles());
37 configureStandardRoles();
38
39 Set<String> workspaceNames = getWorkspaceNames();
40 if (workspaceNames == null || workspaceNames.isEmpty()) {
41 configureJcr(repository, null);
42 } else {
43 for (String workspaceName : workspaceNames)
44 configureJcr(repository, workspaceName);
45 }
46 }
47
48 /** Configures a workspace. */
49 protected void configureJcr(Repository repository, String workspaceName) {
50 Session adminSession;
51 try {
52 adminSession = CmsJcrUtils.openDataAdminSession(repository, workspaceName);
53 } catch (RuntimeException e1) {
54 if (e1.getCause() != null && e1.getCause() instanceof NoSuchWorkspaceException) {
55 Session defaultAdminSession = CmsJcrUtils.openDataAdminSession(repository, null);
56 try {
57 defaultAdminSession.getWorkspace().createWorkspace(workspaceName);
58 log.info("Created JCR workspace " + workspaceName);
59 } catch (RepositoryException e) {
60 throw new IllegalStateException("Cannot create workspace " + workspaceName, e);
61 } finally {
62 Jcr.logout(defaultAdminSession);
63 }
64 adminSession = CmsJcrUtils.openDataAdminSession(repository, workspaceName);
65 } else
66 throw e1;
67 }
68 try {
69 if (prepareJcrTree(adminSession)) {
70 configurePrivileges(adminSession);
71 }
72 } catch (RepositoryException | IOException e) {
73 throw new IllegalStateException("Cannot initialise JCR data layer.", e);
74 } finally {
75 JcrUtils.logoutQuietly(adminSession);
76 }
77 }
78
79 /** To be overridden. */
80 protected Set<String> getWorkspaceNames() {
81 return null;
82 }
83
84 /**
85 * To be overridden in order to programmatically set relationships between
86 * roles. Does nothing by default.
87 */
88 protected void configureStandardRoles() {
89 }
90
91 /**
92 * Creates the base JCR tree structure expected for this app if necessary.
93 *
94 * Expects a clean session ({@link Session#hasPendingChanges()} should return
95 * false) and saves it once the changes have been done. Thus the session can be
96 * rolled back if an exception occurs.
97 *
98 * @return true if something as been updated
99 */
100 public boolean prepareJcrTree(Session adminSession) throws RepositoryException, IOException {
101 return false;
102 }
103
104 /**
105 * Adds app specific default privileges.
106 *
107 * Expects a clean session ({@link Session#hasPendingChanges()} should return
108 * false} and saves it once the changes have been done. Thus the session can be
109 * rolled back if an exception occurs.
110 *
111 * Warning: no check is done and corresponding privileges are always added, so
112 * only call this when necessary
113 */
114 public void configurePrivileges(Session session) throws RepositoryException {
115 }
116
117 /** The system roles that must be available in the system. */
118 protected Set<String> getRequiredRoles() {
119 return new HashSet<>();
120 }
121
122 public void destroy() {
123
124 }
125
126 /*
127 * UTILITIES
128 */
129
130 /** Create these roles as group if they don't exist. */
131 protected void makeSureRolesExists(EnumSet<? extends Distinguished> enumSet) {
132 makeSureRolesExists(Distinguished.enumToDns(enumSet));
133 }
134
135 /** Create these roles as group if they don't exist. */
136 protected void makeSureRolesExists(Set<String> requiredRoles) {
137 if (requiredRoles == null)
138 return;
139 if (getUserAdmin() == null) {
140 log.warn("No user admin service available, cannot make sure that role exists");
141 return;
142 }
143 for (String role : requiredRoles) {
144 Role systemRole = getUserAdmin().getRole(role);
145 if (systemRole == null) {
146 try {
147 getUserTransaction().begin();
148 getUserAdmin().createRole(role, Role.GROUP);
149 getUserTransaction().commit();
150 log.info("Created role " + role);
151 } catch (Exception e) {
152 try {
153 getUserTransaction().rollback();
154 } catch (Exception e1) {
155 // silent
156 }
157 throw new IllegalStateException("Cannot create role " + role, e);
158 }
159 }
160 }
161 }
162
163 /** Add a user or group to a group. */
164 protected void addToGroup(String groupToAddDn, String groupDn) {
165 if (groupToAddDn.contentEquals(groupDn)) {
166 if (log.isTraceEnabled())
167 log.trace("Ignore adding group " + groupDn + " to itself");
168 return;
169 }
170
171 if (getUserAdmin() == null) {
172 log.warn("No user admin service available, cannot add group " + groupToAddDn + " to " + groupDn);
173 return;
174 }
175 Group groupToAdd = (Group) getUserAdmin().getRole(groupToAddDn);
176 if (groupToAdd == null)
177 throw new IllegalArgumentException("Group " + groupToAddDn + " not found");
178 Group group = (Group) getUserAdmin().getRole(groupDn);
179 if (group == null)
180 throw new IllegalArgumentException("Group " + groupDn + " not found");
181 try {
182 getUserTransaction().begin();
183 if (group.addMember(groupToAdd))
184 log.info("Added " + groupToAddDn + " to " + group);
185 getUserTransaction().commit();
186 } catch (Exception e) {
187 try {
188 getUserTransaction().rollback();
189 } catch (Exception e1) {
190 // silent
191 }
192 throw new IllegalStateException("Cannot add " + groupToAddDn + " to " + groupDn);
193 }
194 }
195
196 /*
197 * DEPENDENCY INJECTION
198 */
199 public void setRepository(Repository repository) {
200 this.repository = repository;
201 }
202
203 // public void setUserAdminService(UserAdminService userAdminService) {
204 // this.userAdminService = userAdminService;
205 // }
206
207 protected WorkTransaction getUserTransaction() {
208 return userTransaction;
209 }
210
211 protected UserAdmin getUserAdmin() {
212 return userAdmin;
213 }
214
215 public void setUserAdmin(UserAdmin userAdmin) {
216 this.userAdmin = userAdmin;
217 }
218
219 public void setUserTransaction(WorkTransaction userTransaction) {
220 this.userTransaction = userTransaction;
221 }
222
223 public void setContentRepository(ProvidedRepository contentRepository) {
224 this.contentRepository = contentRepository;
225 }
226
227 protected ProvidedRepository getContentRepository() {
228 return contentRepository;
229 }
230
231
232 }