001/* 002 * Copyright 2017 Anyware Services 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.ametys.plugins.bpm.jcr; 017 018import java.util.ArrayList; 019import java.util.List; 020 021import javax.jcr.Node; 022import javax.jcr.NodeIterator; 023import javax.jcr.PathNotFoundException; 024import javax.jcr.RepositoryException; 025 026import org.ametys.core.group.GroupIdentity; 027import org.ametys.core.user.UserIdentity; 028import org.ametys.plugins.bpm.Workflow; 029import org.ametys.plugins.explorer.resources.ResourceCollection; 030import org.ametys.plugins.explorer.resources.jcr.JCRResourcesCollectionFactory; 031import org.ametys.plugins.repository.AmetysObject; 032import org.ametys.plugins.repository.AmetysRepositoryException; 033import org.ametys.plugins.repository.RepositoryConstants; 034import org.ametys.plugins.repository.jcr.DefaultTraversableAmetysObject; 035 036/** 037 * Class representing of workflow, backed by a JCR node.<br> 038 */ 039public class JCRWorkflow extends DefaultTraversableAmetysObject<JCRWorkflowFactory> implements Workflow 040{ 041 private static final String PROPERTY_DESCRIPTION = RepositoryConstants.NAMESPACE_PREFIX + ":description"; 042 private static final String PROPERTY_TITLE = RepositoryConstants.NAMESPACE_PREFIX + ":title"; 043 private static final String NODE_NAME_OWNER = RepositoryConstants.NAMESPACE_PREFIX + ":owner"; 044 private static final String PROPERTY_WORKFLOW_DEFINITION = RepositoryConstants.NAMESPACE_PREFIX + ":workflowDef"; 045 046 private static final String NODE_NAME_ALLOWED_USERS = RepositoryConstants.NAMESPACE_PREFIX + ":allowedUsers"; 047 private static final String NODE_NAME_ALLOWED_USER = RepositoryConstants.NAMESPACE_PREFIX + ":allowedUser"; 048 private static final String NODE_NAME_ALLOWED_GROUPS = RepositoryConstants.NAMESPACE_PREFIX + ":allowedGroups"; 049 private static final String NODE_NAME_ALLOWED_GROUP = RepositoryConstants.NAMESPACE_PREFIX + ":allowedGroup"; 050 private static final String NODE_NAME_WORKFLOW_VARIABLES = RepositoryConstants.NAMESPACE_PREFIX + ":workflowVariables"; 051 private static final String NODE_NAME_ATTACHMENTS = RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ":attachments"; 052 /** 053 * Creates an {@link JCRWorkflow}. 054 * @param node the node backing this {@link AmetysObject} 055 * @param parentPath the parentPath in the Ametys hierarchy 056 * @param factory the JCRWorkflowFactory which created the AmetysObject 057 */ 058 public JCRWorkflow(Node node, String parentPath, JCRWorkflowFactory factory) 059 { 060 super(node, parentPath, factory); 061 } 062 063 @Override 064 public String getTitle() throws AmetysRepositoryException 065 { 066 try 067 { 068 return getNode().getProperty(PROPERTY_TITLE).getString(); 069 } 070 catch (PathNotFoundException e) 071 { 072 return null; 073 } 074 catch (RepositoryException e) 075 { 076 throw new AmetysRepositoryException("Error getting the title property.", e); 077 } 078 } 079 080 public void setTitle(String title) 081 { 082 try 083 { 084 getNode().setProperty(PROPERTY_TITLE, title); 085 } 086 catch (RepositoryException e) 087 { 088 throw new AmetysRepositoryException("Error setting the title property.", e); 089 } 090 091 } 092 093 @Override 094 public String getWorkflowDefinition() throws AmetysRepositoryException 095 { 096 try 097 { 098 return getNode().getProperty(PROPERTY_WORKFLOW_DEFINITION).getString(); 099 } 100 catch (PathNotFoundException e) 101 { 102 return null; 103 } 104 catch (RepositoryException e) 105 { 106 throw new AmetysRepositoryException("Error getting the workflowDefinition property.", e); 107 } 108 } 109 110 public void setWorkflowDefinition(String workflowDefId) 111 { 112 try 113 { 114 getNode().setProperty(PROPERTY_WORKFLOW_DEFINITION, workflowDefId); 115 } 116 catch (RepositoryException e) 117 { 118 throw new AmetysRepositoryException("Error setting the workflowDefinition property.", e); 119 } 120 121 } 122 123 @Override 124 public String getDescription() throws AmetysRepositoryException 125 { 126 try 127 { 128 return getNode().getProperty(PROPERTY_DESCRIPTION).getString(); 129 } 130 catch (PathNotFoundException e) 131 { 132 return null; 133 } 134 catch (RepositoryException e) 135 { 136 throw new AmetysRepositoryException("Error getting the description property.", e); 137 } 138 } 139 140 public void setDescription(String description) 141 { 142 try 143 { 144 getNode().setProperty(PROPERTY_DESCRIPTION, description); 145 } 146 catch (RepositoryException e) 147 { 148 throw new AmetysRepositoryException("Error setting the description property.", e); 149 } 150 151 } 152 153 @Override 154 public Object getVariable(String variableName) throws AmetysRepositoryException 155 { 156 try 157 { 158 return getNode().getNode(NODE_NAME_WORKFLOW_VARIABLES).getProperty(variableName).getString(); 159 } 160 catch (RepositoryException e) 161 { 162 return null; 163 } 164 } 165 166 public void setVariable(String variableName, Object value) 167 { 168 try 169 { 170 Node currentNode = getNode(); 171 if (!currentNode.hasNode(NODE_NAME_WORKFLOW_VARIABLES)) 172 { 173 currentNode.addNode(NODE_NAME_WORKFLOW_VARIABLES, "ametys:compositeMetadata"); 174 } 175 currentNode.getNode(NODE_NAME_WORKFLOW_VARIABLES).setProperty(variableName, value != null ? value.toString() : null); 176 } 177 catch (RepositoryException e) 178 { 179 throw new AmetysRepositoryException("Error setting the variable '" + variableName + "' property.", e); 180 } 181 182 } 183 184 @Override 185 public UserIdentity getOwner() throws AmetysRepositoryException 186 { 187 try 188 { 189 Node owner = getNode().getNode(NODE_NAME_OWNER); 190 String login = owner.getProperty(RepositoryConstants.NAMESPACE_PREFIX + ":login").getString(); 191 String populationId = owner.getProperty(RepositoryConstants.NAMESPACE_PREFIX + ":population").getString(); 192 return new UserIdentity(login, populationId); 193 } 194 catch (PathNotFoundException e) 195 { 196 return null; 197 } 198 catch (RepositoryException e) 199 { 200 throw new AmetysRepositoryException("Error getting the Owner property.", e); 201 } 202 } 203 204 public void setOwner(UserIdentity owner) 205 { 206 try 207 { 208 Node currentNode = getNode(); 209 if (currentNode.hasNode(NODE_NAME_OWNER)) 210 { 211 currentNode.getNode(NODE_NAME_OWNER).remove(); 212 } 213 if (owner != null) 214 { 215 Node userNode = currentNode.addNode(NODE_NAME_OWNER, "ametys:user"); 216 userNode.setProperty(RepositoryConstants.NAMESPACE_PREFIX + ":login", owner.getLogin()); 217 userNode.setProperty(RepositoryConstants.NAMESPACE_PREFIX + ":population", owner.getPopulationId()); 218 } 219 } 220 catch (RepositoryException e) 221 { 222 throw new AmetysRepositoryException("Error setting the owner property.", e); 223 } 224 225 } 226 227 @Override 228 public UserIdentity[] getAllowedUsers() throws AmetysRepositoryException 229 { 230 try 231 { 232 List<UserIdentity> grantedUsers = new ArrayList<>(); 233 234 if (getNode().hasNode(NODE_NAME_ALLOWED_USERS)) 235 { 236 NodeIterator nodeIt = getNode().getNode(NODE_NAME_ALLOWED_USERS).getNodes(NODE_NAME_ALLOWED_USER); 237 while (nodeIt.hasNext()) 238 { 239 Node allowedUser = (Node) nodeIt.next(); 240 String login = allowedUser.getProperty(RepositoryConstants.NAMESPACE_PREFIX + ":login").getString(); 241 String populationId = allowedUser.getProperty(RepositoryConstants.NAMESPACE_PREFIX + ":population").getString(); 242 243 grantedUsers.add(new UserIdentity(login, populationId)); 244 } 245 } 246 return grantedUsers.toArray(new UserIdentity[grantedUsers.size()]); 247 } 248 catch (RepositoryException e) 249 { 250 throw new AmetysRepositoryException("An error occurred while trying to get allowed users.", e); 251 } 252 } 253 254 public void setAllowedUsers(UserIdentity[] allowedUsers) 255 { 256 try 257 { 258 if (getNode().hasNode(NODE_NAME_ALLOWED_USERS)) 259 { 260 getNode().getNode(NODE_NAME_ALLOWED_USERS).remove(); 261 } 262 263 Node rootNode = getNode().addNode(NODE_NAME_ALLOWED_USERS); 264 for (UserIdentity grantedUser : allowedUsers) 265 { 266 Node userNode = rootNode.addNode(NODE_NAME_ALLOWED_USER, "ametys:user"); 267 userNode.setProperty(RepositoryConstants.NAMESPACE_PREFIX + ":login", grantedUser.getLogin()); 268 userNode.setProperty(RepositoryConstants.NAMESPACE_PREFIX + ":population", grantedUser.getPopulationId()); 269 } 270 } 271 catch (RepositoryException e) 272 { 273 throw new AmetysRepositoryException("An error occurred while setting the allowed users.", e); 274 } 275 } 276 277 @Override 278 public GroupIdentity[] getAllowedGroups() throws AmetysRepositoryException 279 { 280 try 281 { 282 List<GroupIdentity> grantedGroups = new ArrayList<>(); 283 284 Node currentNode = getNode(); 285 if (currentNode.hasNode(NODE_NAME_ALLOWED_GROUPS)) 286 { 287 NodeIterator nodeIt = currentNode.getNode(NODE_NAME_ALLOWED_GROUPS).getNodes(NODE_NAME_ALLOWED_GROUP); 288 while (nodeIt.hasNext()) 289 { 290 Node grantedGroup = (Node) nodeIt.next(); 291 String groupId = grantedGroup.getProperty(RepositoryConstants.NAMESPACE_PREFIX + ":groupId").getString(); 292 String groupDir = grantedGroup.getProperty(RepositoryConstants.NAMESPACE_PREFIX + ":groupDirectory").getString(); 293 294 grantedGroups.add(new GroupIdentity(groupId, groupDir)); 295 } 296 } 297 return grantedGroups.toArray(new GroupIdentity[grantedGroups.size()]); 298 } 299 catch (RepositoryException e) 300 { 301 throw new AmetysRepositoryException("An error occurred while trying to get allowed groups.", e); 302 } 303 } 304 305 public void setAllowedGroups(GroupIdentity[] allowedGroups) 306 { 307 try 308 { 309 Node currentNode = getNode(); 310 if (currentNode.hasNode(NODE_NAME_ALLOWED_GROUPS)) 311 { 312 currentNode.getNode(NODE_NAME_ALLOWED_GROUPS).remove(); 313 } 314 315 Node rootNode = currentNode.addNode(NODE_NAME_ALLOWED_GROUPS); 316 for (GroupIdentity allowedGroup : allowedGroups) 317 { 318 Node groupNode = rootNode.addNode(NODE_NAME_ALLOWED_GROUP, "ametys:group"); 319 groupNode.setProperty(RepositoryConstants.NAMESPACE_PREFIX + ":groupId", allowedGroup.getId()); 320 groupNode.setProperty(RepositoryConstants.NAMESPACE_PREFIX + ":groupDirectory", allowedGroup.getDirectoryId()); 321 } 322 } 323 catch (RepositoryException e) 324 { 325 throw new AmetysRepositoryException("An error occurred while setting the allowed groups.", e); 326 } 327 } 328 329 @Override 330 public ResourceCollection getRootAttachments() throws AmetysRepositoryException 331 { 332 ResourceCollection attachments; 333 if (hasChild(NODE_NAME_ATTACHMENTS)) 334 { 335 attachments = getChild(NODE_NAME_ATTACHMENTS); 336 } 337 else 338 { 339 attachments = createChild(NODE_NAME_ATTACHMENTS, JCRResourcesCollectionFactory.RESOURCESCOLLECTION_NODETYPE); 340 341 try 342 { 343 getNode().getSession().save(); 344 } 345 catch (RepositoryException e) 346 { 347 throw new AmetysRepositoryException("Unable to save session", e); 348 } 349 } 350 351 return attachments; 352 } 353 354}