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.Date;
019import java.util.GregorianCalendar;
020
021import javax.jcr.Node;
022import javax.jcr.PathNotFoundException;
023import javax.jcr.RepositoryException;
024
025import org.ametys.core.user.UserIdentity;
026import org.ametys.plugins.bpm.WorkflowProcess;
027import org.ametys.plugins.explorer.resources.ResourceCollection;
028import org.ametys.plugins.repository.AmetysObject;
029import org.ametys.plugins.repository.AmetysRepositoryException;
030import org.ametys.plugins.repository.RepositoryConstants;
031import org.ametys.plugins.repository.jcr.DefaultTraversableAmetysObject;
032import org.ametys.plugins.workflow.repository.WorkflowAwareAmetysObject;
033
034/**
035 * Class representing of workflow's process, backed by a JCR node.<br>
036 */
037public class JCRWorkflowProcess extends DefaultTraversableAmetysObject<JCRWorkflowProcessFactory> implements WorkflowProcess, WorkflowAwareAmetysObject
038{
039    /** Constants for workflowId Metadata* */
040    public static final String METADATA_WORKFLOW_ID = "workflowId";
041    
042    /** Constants for currentStepId Metadata* */
043    public static final String METADATA_CURRENT_STEP_ID = "currentStepId";
044    
045    private static final String PROPERTY_DESCRIPTION = RepositoryConstants.NAMESPACE_PREFIX + ":description";
046    private static final String PROPERTY_TITLE = RepositoryConstants.NAMESPACE_PREFIX + ":title";
047    private static final String PROPERTY_WORKFLOW = RepositoryConstants.NAMESPACE_PREFIX + ":workflow";
048    private static final String PROPERTY_SITE = RepositoryConstants.NAMESPACE_PREFIX + ":site";
049    private static final String PROPERTY_CREATION_DATE = RepositoryConstants.NAMESPACE_PREFIX + ":creationDate";
050
051    private static final String NODE_NAME_CREATOR = RepositoryConstants.NAMESPACE_PREFIX + ":creator";
052    private static final String ATTACHMENTS_NODE_NAME = RepositoryConstants.NAMESPACE_PREFIX + ":attachments";
053    
054    /**
055     * Creates an {@link JCRWorkflowProcess}.
056     * @param node the node backing this {@link AmetysObject}
057     * @param parentPath the parentPath in the Ametys hierarchy
058     * @param factory the JCRWorkflowProcessFactory which created the AmetysObject
059     */
060    public JCRWorkflowProcess(Node node, String parentPath, JCRWorkflowProcessFactory factory)
061    {
062        super(node, parentPath, factory);
063    }
064
065    @Override
066    public String getTitle() throws AmetysRepositoryException
067    {
068        try
069        {
070            return getNode().getProperty(PROPERTY_TITLE).getString();
071        }
072        catch (PathNotFoundException e)
073        {
074            return null;
075        }
076        catch (RepositoryException e)
077        {
078            throw new AmetysRepositoryException("Error getting the title property.", e);
079        }
080    }
081
082    public void setTitle(String title)
083    {
084        try
085        {
086            getNode().setProperty(PROPERTY_TITLE, title);
087        }
088        catch (RepositoryException e)
089        {
090            throw new AmetysRepositoryException("Error setting the title property.", e);
091        }
092        
093    }
094
095    @Override
096    public String getWorkflow() throws AmetysRepositoryException
097    {
098        try
099        {
100            return getNode().getProperty(PROPERTY_WORKFLOW).getString();
101        }
102        catch (PathNotFoundException e)
103        {
104            return null;
105        }
106        catch (RepositoryException e)
107        {
108            throw new AmetysRepositoryException("Error getting the workflow property.", e);
109        }
110    }
111
112    public void setWorkflow(String workflowId)
113    {
114        try
115        {
116            getNode().setProperty(PROPERTY_WORKFLOW, workflowId);
117        }
118        catch (RepositoryException e)
119        {
120            throw new AmetysRepositoryException("Error setting the workflow property.", e);
121        }
122        
123    }
124
125    @Override
126    public String getDescription() throws AmetysRepositoryException
127    {
128        try
129        {
130            return getNode().getProperty(PROPERTY_DESCRIPTION).getString();
131        }
132        catch (PathNotFoundException e)
133        {
134            return null;
135        }
136        catch (RepositoryException e)
137        {
138            throw new AmetysRepositoryException("Error getting the description property.", e);
139        }
140    }
141
142    public void setDescription(String description)
143    {
144        try
145        {
146            getNode().setProperty(PROPERTY_DESCRIPTION, description);
147        }
148        catch (RepositoryException e)
149        {
150            throw new AmetysRepositoryException("Error setting the description property.", e);
151        }
152        
153    }
154
155    @Override
156    public UserIdentity getCreator() throws AmetysRepositoryException
157    {
158        try
159        {
160            Node creator = getNode().getNode(NODE_NAME_CREATOR);
161            String login = creator.getProperty(RepositoryConstants.NAMESPACE_PREFIX + ":login").getString();
162            String populationId = creator.getProperty(RepositoryConstants.NAMESPACE_PREFIX + ":population").getString();
163            return new UserIdentity(login, populationId);
164        }
165        catch (PathNotFoundException e)
166        {
167            return null;
168        }
169        catch (RepositoryException e)
170        {
171            throw new AmetysRepositoryException("Error getting the creator property.", e);
172        }
173    }
174
175    public void setCreator(UserIdentity creator)
176    {
177        try
178        {
179            Node currentNode = getNode();
180            if (currentNode.hasNode(NODE_NAME_CREATOR))
181            {
182                currentNode.getNode(NODE_NAME_CREATOR).remove();
183            }
184            if (creator != null)
185            {
186                Node userNode = currentNode.addNode(NODE_NAME_CREATOR, "ametys:user");
187                userNode.setProperty(RepositoryConstants.NAMESPACE_PREFIX + ":login", creator.getLogin());
188                userNode.setProperty(RepositoryConstants.NAMESPACE_PREFIX + ":population", creator.getPopulationId());
189            }
190        }
191        catch (RepositoryException e)
192        {
193            throw new AmetysRepositoryException("Error setting the creator property.", e);
194        }
195        
196    }
197    
198    public String getSite() throws AmetysRepositoryException
199    {
200        try
201        {
202            return getNode().getProperty(PROPERTY_SITE).getString();
203        }
204        catch (PathNotFoundException e)
205        {
206            return null;
207        }
208        catch (RepositoryException e)
209        {
210            throw new AmetysRepositoryException("Error getting the site property.", e);
211        }
212    }
213    
214    public void setSite(String site)
215    {
216        try
217        {
218            getNode().setProperty(PROPERTY_SITE, site);
219        }
220        catch (RepositoryException e)
221        {
222            throw new AmetysRepositoryException("Error setting the site property.", e);
223        }
224    }
225    
226    @Override
227    public Date getCreationDate() throws AmetysRepositoryException
228    {
229        try
230        {
231            return getNode().getProperty(PROPERTY_CREATION_DATE).getDate().getTime();
232        }
233        catch (PathNotFoundException e)
234        {
235            return null;
236        }
237        catch (RepositoryException e)
238        {
239            throw new AmetysRepositoryException("Error getting the date property.", e);
240        }
241    }
242
243    public void setCreationDate(Date creationDate)
244    {
245        try
246        {
247            GregorianCalendar cal = new GregorianCalendar();
248            cal.setTime(creationDate);
249            getNode().setProperty(PROPERTY_CREATION_DATE, cal);
250        }
251        catch (RepositoryException e)
252        {
253            throw new AmetysRepositoryException("Error setting the date property.", e);
254        }
255        
256    }
257    
258    @Override
259    public ResourceCollection getRootAttachments(boolean create) throws AmetysRepositoryException
260    {
261        if (hasChild(ATTACHMENTS_NODE_NAME))
262        {
263            return getChild(ATTACHMENTS_NODE_NAME);
264        }
265        else
266        {
267            return create ? createChild(ATTACHMENTS_NODE_NAME, "ametys:resources-collection") : null;
268        }
269    }
270
271    public long getWorkflowId() throws AmetysRepositoryException
272    {
273        try
274        {
275            return getNode().getProperty(RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ':' + METADATA_WORKFLOW_ID).getLong();
276        }
277        catch (RepositoryException e)
278        {
279            throw new AmetysRepositoryException("Unable to get workflowId property", e);
280        }
281    }
282
283    public void setWorkflowId(long workflowId) throws AmetysRepositoryException
284    {
285        try
286        {
287            if (getNode().hasProperty(RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ':' + METADATA_WORKFLOW_ID))
288            {
289                throw new AmetysRepositoryException("Cannot call setWorkflowId on an already persisted Ametys Object");
290            }
291            
292            getNode().setProperty(RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ':' + METADATA_WORKFLOW_ID, workflowId);
293        }
294        catch (RepositoryException e)
295        {
296            throw new AmetysRepositoryException("Unable to set workflowId property", e);
297        }
298    }
299
300    public long getCurrentStepId() throws AmetysRepositoryException
301    {
302        try
303        {
304            return getNode().getProperty(RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ':' + METADATA_CURRENT_STEP_ID).getLong();
305        }
306        catch (RepositoryException e)
307        {
308            throw new AmetysRepositoryException("Unable to get currentStepId property", e);
309        }
310    }
311
312    public void setCurrentStepId(long stepId) throws AmetysRepositoryException
313    {
314        try
315        {
316            getNode().setProperty(RepositoryConstants.NAMESPACE_PREFIX_INTERNAL + ':' + METADATA_CURRENT_STEP_ID, stepId);
317        }
318        catch (RepositoryException e)
319        {
320            throw new AmetysRepositoryException("Unable to set currentStepId property", e);
321        }
322    }
323
324}