Changes for checkstyle 8.32
[policy/apex-pdp.git] / model / model-api / src / main / java / org / onap / policy / apex / model / modelapi / impl / PolicyFacade.java
1 /*-
2  * ============LICENSE_START=======================================================
3  *  Copyright (C) 2016-2018 Ericsson. All rights reserved.
4  *  Modifications Copyright (C) 2019 Nordix Foundation.
5  * ================================================================================
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *      http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *
18  * SPDX-License-Identifier: Apache-2.0
19  * ============LICENSE_END=========================================================
20  */
21
22 package org.onap.policy.apex.model.modelapi.impl;
23
24 import java.util.Map;
25 import java.util.Map.Entry;
26 import java.util.Properties;
27 import java.util.Set;
28 import java.util.TreeSet;
29 import org.onap.policy.apex.model.basicmodel.concepts.AxArtifactKey;
30 import org.onap.policy.apex.model.basicmodel.concepts.AxKey;
31 import org.onap.policy.apex.model.basicmodel.concepts.AxReferenceKey;
32 import org.onap.policy.apex.model.basicmodel.concepts.AxValidationResult;
33 import org.onap.policy.apex.model.basicmodel.handling.ApexModelStringWriter;
34 import org.onap.policy.apex.model.contextmodel.concepts.AxContextAlbum;
35 import org.onap.policy.apex.model.eventmodel.concepts.AxEvent;
36 import org.onap.policy.apex.model.modelapi.ApexApiResult;
37 import org.onap.policy.apex.model.modelapi.ApexModel;
38 import org.onap.policy.apex.model.policymodel.concepts.AxPolicy;
39 import org.onap.policy.apex.model.policymodel.concepts.AxState;
40 import org.onap.policy.apex.model.policymodel.concepts.AxStateFinalizerLogic;
41 import org.onap.policy.apex.model.policymodel.concepts.AxStateOutput;
42 import org.onap.policy.apex.model.policymodel.concepts.AxStateTaskOutputType;
43 import org.onap.policy.apex.model.policymodel.concepts.AxStateTaskReference;
44 import org.onap.policy.apex.model.policymodel.concepts.AxTask;
45 import org.onap.policy.apex.model.policymodel.concepts.AxTaskSelectionLogic;
46 import org.onap.policy.common.utils.validation.Assertions;
47
48 /**
49  * This class acts as a facade for operations towards a policy model for policy operations.
50  *
51  * @author Liam Fallon (liam.fallon@ericsson.com)
52  */
53 public class PolicyFacade {
54     private static final String STATE_NAME_MAY_NOT_BE_NULL = "stateName may not be null";
55     private static final String DOES_NOT_EXIST_ON_STATE = " does not exist on state ";
56     private static final String STATE_FINALIZER_LOGIC = "state finalizer logic ";
57     private static final String DO_ES_NOT_EXIST = " do(es) not exist";
58     private static final String CONCEPT_S = "concept(s) ";
59     private static final String DOES_NOT_EXIST = " does not exist";
60     private static final String CONCEPT = "concept ";
61     private static final String ALREADY_EXISTS = " already exists";
62
63     // Apex model we're working towards
64     private final ApexModel apexModel;
65
66     // Properties to use for the model
67     private final Properties apexProperties;
68
69     // Facade classes for working towards the real Apex model
70     private final KeyInformationFacade keyInformationFacade;
71
72     // JSON output on list/delete if set
73     private final boolean jsonMode;
74
75     /**
76      * Constructor that creates a policy facade for the Apex Model API.
77      *
78      * @param apexModel the apex model
79      * @param apexProperties Properties for the model
80      * @param jsonMode set to true to return JSON strings in list and delete operations, otherwise
81      *        set to false
82      */
83     public PolicyFacade(final ApexModel apexModel, final Properties apexProperties, final boolean jsonMode) {
84         this.apexModel = apexModel;
85         this.apexProperties = apexProperties;
86         this.jsonMode = jsonMode;
87
88         keyInformationFacade = new KeyInformationFacade(apexModel, apexProperties, jsonMode);
89     }
90
91     /**
92      * Create a policy.
93      *
94      * @param name name of the policy
95      * @param version version of the policy, set to null to use the default version
96      * @param template template used to create the policy, set to null to use the default template
97      * @param firstState the first state of the policy
98      * @param uuid policy UUID, set to null to generate a UUID
99      * @param description policy description, set to null to generate a description
100      * @return result of the operation
101      */
102     public ApexApiResult createPolicy(final String name, final String version, final String template,
103             final String firstState, final String uuid, final String description) {
104         try {
105             final AxArtifactKey key = new AxArtifactKey();
106             key.setName(name);
107             if (version != null) {
108                 key.setVersion(version);
109             } else {
110                 key.setVersion(apexProperties.getProperty("DEFAULT_CONCEPT_VERSION"));
111             }
112
113             String templateString = template;
114             if (templateString == null) {
115                 templateString = apexProperties.getProperty("DEFAULT_POLICY_TEMPLATE");
116             }
117
118             if (apexModel.getPolicyModel().getPolicies().getPolicyMap().containsKey(key)) {
119                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS, CONCEPT + key.getId() + ALREADY_EXISTS);
120             }
121
122             final AxPolicy policy = new AxPolicy(key);
123             policy.setTemplate(templateString);
124             policy.setFirstState(firstState);
125
126             apexModel.getPolicyModel().getPolicies().getPolicyMap().put(key, policy);
127
128             if (apexModel.getPolicyModel().getKeyInformation().getKeyInfoMap().containsKey(key)) {
129                 return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
130             } else {
131                 return keyInformationFacade.createKeyInformation(name, version, uuid, description);
132             }
133         } catch (final Exception e) {
134             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
135         }
136     }
137
138     /**
139      * Update a policy.
140      *
141      * @param name name of the policy
142      * @param version version of the policy, set to null to use the latest version
143      * @param template template used to create the policy, set to null to not update
144      * @param firstState the first state of the policy
145      * @param uuid policy UUID, set to null to not update
146      * @param description policy description, set to null to not update
147      * @return result of the operation
148      */
149     public ApexApiResult updatePolicy(final String name, final String version, final String template,
150             final String firstState, final String uuid, final String description) {
151         try {
152             final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
153             if (policy == null) {
154                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
155                         CONCEPT + name + ':' + version + DOES_NOT_EXIST);
156             }
157
158             if (template != null) {
159                 policy.setTemplate(template);
160             }
161             if (firstState != null) {
162                 policy.setFirstState(firstState);
163             }
164
165             return keyInformationFacade.updateKeyInformation(name, version, uuid, description);
166         } catch (final Exception e) {
167             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
168         }
169     }
170
171     /**
172      * List policies.
173      *
174      * @param name name of the policy, set to null to list all
175      * @param version starting version of the policy, set to null to list all versions
176      * @return result of the operation
177      */
178     public ApexApiResult listPolicy(final String name, final String version) {
179         try {
180             final Set<AxPolicy> policySet = apexModel.getPolicyModel().getPolicies().getAll(name, version);
181             if (name != null && policySet.isEmpty()) {
182                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
183                         CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
184             }
185
186             final ApexApiResult result = new ApexApiResult();
187             for (final AxPolicy policy : policySet) {
188                 result.addMessage(
189                         new ApexModelStringWriter<AxPolicy>(false).writeString(policy, AxPolicy.class, jsonMode));
190             }
191             return result;
192         } catch (final Exception e) {
193             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
194         }
195     }
196
197     /**
198      * Delete a policy.
199      *
200      * @param name name of the policy
201      * @param version version of the policy, set to null to use the latest version
202      * @return result of the operation
203      */
204     public ApexApiResult deletePolicy(final String name, final String version) {
205         try {
206             if (version != null) {
207                 final AxArtifactKey key = new AxArtifactKey(name, version);
208                 final AxPolicy removedPolicy = apexModel.getPolicyModel().getPolicies().getPolicyMap().remove(key);
209                 if (removedPolicy != null) {
210                     return new ApexApiResult(ApexApiResult.Result.SUCCESS, new ApexModelStringWriter<AxPolicy>(false)
211                             .writeString(removedPolicy, AxPolicy.class, jsonMode));
212                 } else {
213                     return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
214                             CONCEPT + key.getId() + DOES_NOT_EXIST);
215                 }
216             }
217
218             final Set<AxPolicy> policySet = apexModel.getPolicyModel().getPolicies().getAll(name, version);
219             if (policySet.isEmpty()) {
220                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
221                         CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
222             }
223
224             final ApexApiResult result = new ApexApiResult();
225             for (final AxPolicy policy : policySet) {
226                 result.addMessage(
227                         new ApexModelStringWriter<AxPolicy>(false).writeString(policy, AxPolicy.class, jsonMode));
228                 apexModel.getPolicyModel().getPolicies().getPolicyMap().remove(policy.getKey());
229                 keyInformationFacade.deleteKeyInformation(name, version);
230             }
231             return result;
232         } catch (final Exception e) {
233             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
234         }
235     }
236
237     /**
238      * Validate policies.
239      *
240      * @param name name of the policy, set to null to list all
241      * @param version starting version of the policy, set to null to list all versions
242      * @return result of the operation
243      */
244     public ApexApiResult validatePolicy(final String name, final String version) {
245         try {
246             final Set<AxPolicy> policySet = apexModel.getPolicyModel().getPolicies().getAll(name, version);
247             if (policySet.isEmpty()) {
248                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
249                         CONCEPT_S + name + ':' + version + DO_ES_NOT_EXIST);
250             }
251
252             final ApexApiResult result = new ApexApiResult();
253             for (final AxPolicy policy : policySet) {
254                 final AxValidationResult validationResult = policy.validate(new AxValidationResult());
255                 result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false).writeString(policy.getKey(),
256                         AxArtifactKey.class, jsonMode));
257                 result.addMessage(validationResult.toString());
258             }
259             return result;
260         } catch (final Exception e) {
261             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
262         }
263     }
264
265     /**
266      * Create a policy state.
267      *
268      * @param name name of the policy
269      * @param version version of the policy, set to null to use the latest version
270      * @param stateName of the state
271      * @param triggerName name of the trigger event for this state
272      * @param triggerVersion version of the trigger event for this state, set to null to use the
273      *        latest version
274      * @param defaultTaskName the default task name
275      * @param defaltTaskVersion the default task version, set to null to use the latest version
276      * @return result of the operation
277      */
278     public ApexApiResult createPolicyState(final String name, final String version, final String stateName,
279             final String triggerName, final String triggerVersion, final String defaultTaskName,
280             final String defaltTaskVersion) {
281         try {
282             Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
283
284             final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
285             if (policy == null) {
286                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
287                         CONCEPT + name + ':' + version + DOES_NOT_EXIST);
288             }
289
290             final AxReferenceKey refKey = new AxReferenceKey(policy.getKey(), stateName);
291
292             if (policy.getStateMap().containsKey(refKey.getLocalName())) {
293                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS,
294                         CONCEPT + refKey.getId() + ALREADY_EXISTS);
295             }
296
297             final AxEvent triggerEvent = apexModel.getPolicyModel().getEvents().get(triggerName, triggerVersion);
298             if (triggerEvent == null) {
299                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
300                         CONCEPT + triggerName + ':' + triggerVersion + DOES_NOT_EXIST);
301             }
302
303             final AxTask defaultTask = apexModel.getPolicyModel().getTasks().get(defaultTaskName, defaltTaskVersion);
304             if (defaultTask == null) {
305                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
306                         CONCEPT + defaultTaskName + ':' + defaltTaskVersion + DOES_NOT_EXIST);
307             }
308
309             final AxState state = new AxState(refKey);
310             state.setTrigger(triggerEvent.getKey());
311             state.setDefaultTask(defaultTask.getKey());
312
313             policy.getStateMap().put(state.getKey().getLocalName(), state);
314             return new ApexApiResult();
315         } catch (final Exception e) {
316             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
317         }
318     }
319
320     /**
321      * Update a policy state.
322      *
323      * @param name name of the policy
324      * @param version version of the policy, set to null to use the latest version
325      * @param stateName of the state
326      * @param triggerName name of the trigger event for this state, set to null to not update
327      * @param triggerVersion version of the trigger event for this state, set to use latest version
328      *        of trigger event
329      * @param defaultTaskName the default task name, set to null to not update
330      * @param defaltTaskVersion the default task version, set to use latest version of default task
331      * @return result of the operation
332      */
333     public ApexApiResult updatePolicyState(final String name, final String version, final String stateName,
334             final String triggerName, final String triggerVersion, final String defaultTaskName,
335             final String defaltTaskVersion) {
336         try {
337             Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
338
339             final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
340             if (policy == null) {
341                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
342                         CONCEPT + name + ':' + version + DOES_NOT_EXIST);
343             }
344
345             final AxState state = policy.getStateMap().get(stateName);
346             if (state == null) {
347                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
348                         CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
349             }
350
351             if (triggerName != null) {
352                 final AxEvent triggerEvent = apexModel.getPolicyModel().getEvents().get(triggerName, triggerVersion);
353                 if (triggerEvent == null) {
354                     return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
355                             CONCEPT + triggerName + ':' + triggerVersion + DOES_NOT_EXIST);
356                 }
357                 state.setTrigger(triggerEvent.getKey());
358             }
359
360             if (defaultTaskName != null) {
361                 final AxTask defaultTask =
362                         apexModel.getPolicyModel().getTasks().get(defaultTaskName, defaltTaskVersion);
363                 if (defaultTask == null) {
364                     return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
365                             CONCEPT + defaultTaskName + ':' + defaltTaskVersion + DOES_NOT_EXIST);
366                 }
367                 state.setDefaultTask(defaultTask.getKey());
368             }
369
370             return new ApexApiResult();
371         } catch (final Exception e) {
372             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
373         }
374     }
375
376     /**
377      * List policy states.
378      *
379      * @param name name of the policy
380      * @param version version of the policy, set to null to use the latest version
381      * @param stateName of the state, set to null to list all states of the policy
382      * @return result of the operation
383      */
384     public ApexApiResult listPolicyState(final String name, final String version, final String stateName) {
385         try {
386             final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
387             if (policy == null) {
388                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
389                         CONCEPT + name + ':' + version + DOES_NOT_EXIST);
390             }
391
392             if (stateName != null) {
393                 final AxState state = policy.getStateMap().get(stateName);
394                 if (state != null) {
395                     return new ApexApiResult(ApexApiResult.Result.SUCCESS,
396                             new ApexModelStringWriter<AxState>(false).writeString(state, AxState.class, jsonMode));
397                 } else {
398                     return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
399                             CONCEPT + name + ':' + version + ':' + state + DOES_NOT_EXIST);
400                 }
401             } else {
402                 if (policy.getStateMap().size() == 0) {
403                     return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
404                             "no states defined on policy " + policy.getKey().getId());
405                 }
406                 final ApexApiResult result = new ApexApiResult();
407                 for (final AxState state : policy.getStateMap().values()) {
408                     result.addMessage(
409                             new ApexModelStringWriter<AxState>(false).writeString(state, AxState.class, jsonMode));
410                 }
411                 return result;
412             }
413         } catch (final Exception e) {
414             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
415         }
416     }
417
418     /**
419      * Delete a policy state.
420      *
421      * @param name name of the policy
422      * @param version version of the policy, set to null to use the latest version
423      * @param stateName of the state, set to null to delete all states
424      * @return result of the operation
425      */
426     public ApexApiResult deletePolicyState(final String name, final String version, final String stateName) {
427         try {
428             final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
429             if (policy == null) {
430                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
431                         CONCEPT + name + ':' + version + DOES_NOT_EXIST);
432             }
433
434             final ApexApiResult result = new ApexApiResult();
435             if (stateName != null) {
436                 if (policy.getStateMap().containsKey(stateName)) {
437                     result.addMessage(new ApexModelStringWriter<AxState>(false)
438                             .writeString(policy.getStateMap().get(stateName), AxState.class, jsonMode));
439                     policy.getStateMap().remove(stateName);
440                     return result;
441                 } else {
442                     return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
443                             CONCEPT + name + ':' + version + ':' + stateName + DOES_NOT_EXIST);
444                 }
445             } else {
446                 if (policy.getStateMap().size() == 0) {
447                     return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
448                             "no states defined on policy " + policy.getKey().getId());
449                 }
450                 for (final AxState state : policy.getStateMap().values()) {
451                     result.addMessage(
452                             new ApexModelStringWriter<AxState>(false).writeString(state, AxState.class, jsonMode));
453                 }
454                 policy.getStateMap().clear();
455                 return result;
456             }
457         } catch (final Exception e) {
458             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
459         }
460     }
461
462     /**
463      * Create task selection logic for a state.
464      *
465      * @param name name of the policy
466      * @param version version of the policy, set to null to use the latest version
467      * @param stateName of the state
468      * @param logicFlavour the task selection logic flavour for the state, set to null to use the
469      *        default task logic flavour
470      * @param logic the source code for the logic of the state
471      * @return result of the operation
472      */
473     public ApexApiResult createPolicyStateTaskSelectionLogic(final String name, final String version,
474             final String stateName, final String logicFlavour, final String logic) {
475         try {
476             Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
477
478             final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
479             if (policy == null) {
480                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
481                         CONCEPT + name + ':' + version + DOES_NOT_EXIST);
482             }
483
484             final AxState state = policy.getStateMap().get(stateName);
485             if (state == null) {
486                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
487                         CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
488             }
489
490             // There is only one logic item associated with a state so we use a hard coded logic
491             // name
492             final AxReferenceKey refKey = new AxReferenceKey(state.getKey(), "TaskSelectionLogic");
493
494             if (!state.getTaskSelectionLogic().getKey().getLocalName().equals(AxKey.NULL_KEY_NAME)) {
495                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS,
496                         CONCEPT + refKey.getId() + ALREADY_EXISTS);
497             }
498
499             state.setTaskSelectionLogic(new AxTaskSelectionLogic(refKey, logicFlavour, logic));
500             return new ApexApiResult();
501         } catch (final Exception e) {
502             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
503         }
504     }
505
506     /**
507      * Update task selection logic for a state.
508      *
509      * @param name name of the policy
510      * @param version version of the policy, set to null to use the latest version
511      * @param stateName of the state
512      * @param logicFlavour the task selection logic flavour for the state, set to null to not update
513      * @param logic the source code for the logic of the state, set to null to not update
514      * @return result of the operation
515      */
516     public ApexApiResult updatePolicyStateTaskSelectionLogic(final String name, final String version,
517             final String stateName, final String logicFlavour, final String logic) {
518         try {
519             Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
520
521             final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
522             if (policy == null) {
523                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
524                         CONCEPT + name + ':' + version + DOES_NOT_EXIST);
525             }
526
527             final AxState state = policy.getStateMap().get(stateName);
528             if (state == null) {
529                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
530                         CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
531             }
532
533             if (state.getTaskSelectionLogic().getKey().getLocalName().equals(AxKey.NULL_KEY_NAME)) {
534                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
535                         CONCEPT + state.getTaskSelectionLogic().getKey().getId() + DOES_NOT_EXIST);
536             }
537
538             final AxTaskSelectionLogic taskSelectionLogic = state.getTaskSelectionLogic();
539             if (logicFlavour != null) {
540                 taskSelectionLogic.setLogicFlavour(logicFlavour);
541             }
542             if (logic != null) {
543                 taskSelectionLogic.setLogic(logic);
544             }
545
546             return new ApexApiResult();
547         } catch (final Exception e) {
548             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
549         }
550     }
551
552     /**
553      * List task selection logic for a state.
554      *
555      * @param name name of the policy
556      * @param version version of the policy, set to null to use the latest version
557      * @param stateName of the state
558      * @return result of the operation
559      */
560     public ApexApiResult listPolicyStateTaskSelectionLogic(final String name, final String version,
561             final String stateName) {
562         try {
563             Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
564
565             final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
566             if (policy == null) {
567                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
568                         CONCEPT + name + ':' + version + DOES_NOT_EXIST);
569             }
570
571             final AxState state = policy.getStateMap().get(stateName);
572             if (state == null) {
573                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
574                         CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
575             }
576
577             return new ApexApiResult(ApexApiResult.Result.SUCCESS,
578                     new ApexModelStringWriter<AxTaskSelectionLogic>(false).writeString(state.getTaskSelectionLogic(),
579                             AxTaskSelectionLogic.class, jsonMode));
580         } catch (final Exception e) {
581             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
582         }
583     }
584
585     /**
586      * Delete task selection logic for a state.
587      *
588      * @param name name of the policy
589      * @param version version of the policy, set to null to use the latest version
590      * @param stateName of the state
591      * @return result of the operation
592      */
593     public ApexApiResult deletePolicyStateTaskSelectionLogic(final String name, final String version,
594             final String stateName) {
595         try {
596             Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
597
598             final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
599             if (policy == null) {
600                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
601                         CONCEPT + name + ':' + version + DOES_NOT_EXIST);
602             }
603
604             final AxState state = policy.getStateMap().get(stateName);
605             if (state == null) {
606                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
607                         CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
608             }
609
610             if (state.getTaskSelectionLogic().getKey().getLocalName().equals(AxKey.NULL_KEY_NAME)) {
611                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
612                         CONCEPT + state.getTaskSelectionLogic().getKey().getId() + DOES_NOT_EXIST);
613             }
614
615             final ApexApiResult result = new ApexApiResult();
616             result.addMessage(new ApexModelStringWriter<AxTaskSelectionLogic>(false)
617                     .writeString(state.getTaskSelectionLogic(), AxTaskSelectionLogic.class, jsonMode));
618             state.setTaskSelectionLogic(new AxTaskSelectionLogic());
619             return result;
620         } catch (final Exception e) {
621             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
622         }
623     }
624
625     /**
626      * Create a policy state output.
627      *
628      * @param name name of the policy
629      * @param version version of the policy, set to null to use the latest version
630      * @param stateName of the state
631      * @param outputName of the state output
632      * @param eventName name of the output event for this state output
633      * @param eventVersion version of the output event for this state output, set to null to use the
634      *        latest version
635      * @param nextState for this state to transition to, set to null if this is the last state that
636      *        the policy transitions to on this branch
637      * @return result of the operation
638      */
639     public ApexApiResult createPolicyStateOutput(final String name, final String version, final String stateName,
640             final String outputName, final String eventName, final String eventVersion, final String nextState) {
641         try {
642             Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
643             Assertions.argumentNotNull(outputName, "outputName may not be null");
644
645             final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
646             if (policy == null) {
647                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
648                         "Policy concept " + name + ':' + version + DOES_NOT_EXIST);
649             }
650
651             final AxState state = policy.getStateMap().get(stateName);
652             if (state == null) {
653                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
654                         "State concept " + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
655             }
656
657             final AxReferenceKey refKey = new AxReferenceKey(state.getKey(), outputName);
658             if (state.getStateOutputs().containsKey(refKey.getLocalName())) {
659                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS,
660                         "Output concept " + refKey.getId() + ALREADY_EXISTS);
661             }
662
663             final AxEvent event = apexModel.getPolicyModel().getEvents().get(eventName, eventVersion);
664             if (event == null) {
665                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
666                         "Event concept " + eventName + ':' + eventVersion + DOES_NOT_EXIST);
667             }
668
669             AxReferenceKey nextStateKey = AxReferenceKey.getNullKey();
670             if (nextState != null && !(AxReferenceKey.getNullKey().getLocalName().equals(nextState))) {
671                 if (state.getKey().getLocalName().equals(nextState)) {
672                     return new ApexApiResult(ApexApiResult.Result.FAILED,
673                             "next state " + nextState + " of a state cannot be the state itself");
674                 }
675                 nextStateKey = new AxReferenceKey(state.getKey().getParentArtifactKey(), nextState);
676
677                 if (!policy.getStateMap().containsKey(nextState)) {
678                     return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
679                             "Next state concept " + nextStateKey.getId() + DOES_NOT_EXIST);
680                 }
681             }
682
683             state.getStateOutputs().put(refKey.getLocalName(), new AxStateOutput(refKey, event.getKey(), nextStateKey));
684             return new ApexApiResult();
685         } catch (final Exception e) {
686             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
687         }
688     }
689
690     /**
691      * List policy state outputs.
692      *
693      * @param name name of the policy
694      * @param version version of the policy, set to null to use the latest version
695      * @param stateName of the state
696      * @param outputName of the state output, set to null to list all outputs of the state
697      * @return result of the operation
698      */
699     public ApexApiResult listPolicyStateOutput(final String name, final String version, final String stateName,
700             final String outputName) {
701         try {
702             Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
703
704             final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
705             if (policy == null) {
706                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
707                         CONCEPT + name + ':' + version + DOES_NOT_EXIST);
708             }
709
710             final AxState state = policy.getStateMap().get(stateName);
711             if (state == null) {
712                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
713                         CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
714             }
715
716             if (outputName != null) {
717                 final AxStateOutput stateOutput = state.getStateOutputs().get(outputName);
718                 if (stateOutput != null) {
719                     return new ApexApiResult(ApexApiResult.Result.SUCCESS,
720                             new ApexModelStringWriter<AxStateOutput>(false).writeString(stateOutput,
721                                     AxStateOutput.class, jsonMode));
722                 } else {
723                     return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
724                             CONCEPT + state.getKey().getId() + ':' + outputName + DOES_NOT_EXIST);
725                 }
726             } else {
727                 if (state.getStateOutputs().size() == 0) {
728                     return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
729                             "no state output concepts exist for state " + state.getKey().getId());
730                 }
731
732                 final ApexApiResult result = new ApexApiResult();
733
734                 for (final AxStateOutput stateOutput : state.getStateOutputs().values()) {
735                     result.addMessage(new ApexModelStringWriter<AxStateOutput>(false).writeString(stateOutput,
736                             AxStateOutput.class, jsonMode));
737                 }
738                 return result;
739             }
740         } catch (final Exception e) {
741             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
742         }
743     }
744
745     /**
746      * Delete a policy state output.
747      *
748      * @param name name of the policy
749      * @param version version of the policy, set to null to use the latest version
750      * @param stateName of the state
751      * @param outputName of the state output, set to null to delete all state outputs
752      * @return result of the operation
753      */
754     public ApexApiResult deletePolicyStateOutput(final String name, final String version, final String stateName,
755             final String outputName) {
756         try {
757             Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
758
759             final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
760             if (policy == null) {
761                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
762                         CONCEPT + name + ':' + version + DOES_NOT_EXIST);
763             }
764
765             final AxState state = policy.getStateMap().get(stateName);
766             if (state == null) {
767                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
768                         CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
769             }
770
771             if (outputName != null) {
772                 final AxStateOutput stateOutput = state.getStateOutputs().get(outputName);
773                 if (stateOutput != null) {
774                     final ApexApiResult result = new ApexApiResult(ApexApiResult.Result.SUCCESS,
775                             new ApexModelStringWriter<AxStateOutput>(false).writeString(stateOutput,
776                                     AxStateOutput.class, jsonMode));
777                     state.getStateOutputs().remove(outputName);
778                     return result;
779                 } else {
780                     return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
781                             CONCEPT + state.getKey().getId() + ':' + outputName + DOES_NOT_EXIST);
782                 }
783             } else {
784                 if (state.getStateOutputs().size() == 0) {
785                     return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
786                             "no state output concepts exist for state " + state.getKey().getId());
787                 }
788
789                 final ApexApiResult result = new ApexApiResult();
790
791                 for (final Entry<String, AxStateOutput> stateOutputEntry : state.getStateOutputs().entrySet()) {
792                     result.addMessage(new ApexModelStringWriter<AxStateOutput>(false)
793                             .writeString(stateOutputEntry.getValue(), AxStateOutput.class, jsonMode));
794                 }
795                 state.getStateOutputs().clear();
796                 return result;
797             }
798         } catch (final Exception e) {
799             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
800         }
801     }
802
803     /**
804      * Create policy finalizer logic for a state.
805      *
806      * @param name name of the policy
807      * @param version version of the policy, set to null to use the latest version
808      * @param stateName of the state
809      * @param finalizerLogicName name of the state finalizer logic
810      * @param logicFlavour the policy finalizer logic flavour for the state, set to null to use the
811      *        default task logic flavour
812      * @param logic the source code for the logic of the state
813      * @return result of the operation
814      */
815     public ApexApiResult createPolicyStateFinalizerLogic(final String name, final String version,
816             final String stateName, final String finalizerLogicName, final String logicFlavour, final String logic) {
817         try {
818             Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
819             Assertions.argumentNotNull(finalizerLogicName, "finalizerlogicName may not be null");
820
821             final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
822             if (policy == null) {
823                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
824                         CONCEPT + name + ':' + version + DOES_NOT_EXIST);
825             }
826
827             final AxState state = policy.getStateMap().get(stateName);
828             if (state == null) {
829                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
830                         CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
831             }
832
833             final AxReferenceKey refKey = new AxReferenceKey(state.getKey(), finalizerLogicName);
834
835             if (state.getStateFinalizerLogicMap().containsKey(refKey.getLocalName())) {
836                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS,
837                         CONCEPT + refKey.getId() + ALREADY_EXISTS);
838             }
839
840             state.getStateFinalizerLogicMap().put(finalizerLogicName,
841                     new AxStateFinalizerLogic(refKey, logicFlavour, logic));
842             return new ApexApiResult();
843         } catch (final Exception e) {
844             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
845         }
846     }
847
848     /**
849      * Update policy finalizer logic for a state.
850      *
851      * @param name name of the policy
852      * @param version version of the policy, set to null to use the latest version
853      * @param stateName of the state
854      * @param finalizerLogicName name of the state finalizer logic
855      * @param logicFlavour the policy finalizer logic flavour for the state, set to null to not
856      *        update
857      * @param logic the source code for the logic of the state, set to null to not update
858      * @return result of the operation
859      */
860     public ApexApiResult updatePolicyStateFinalizerLogic(final String name, final String version,
861             final String stateName, final String finalizerLogicName, final String logicFlavour, final String logic) {
862         try {
863             Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
864             Assertions.argumentNotNull(finalizerLogicName, "finalizerLogicName may not be null");
865
866             final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
867             if (policy == null) {
868                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
869                         CONCEPT + name + ':' + version + DOES_NOT_EXIST);
870             }
871
872             final AxState state = policy.getStateMap().get(stateName);
873             if (state == null) {
874                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
875                         CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
876             }
877
878             final AxReferenceKey refKey = new AxReferenceKey(state.getKey(), finalizerLogicName);
879             final AxStateFinalizerLogic stateFinalizerLogic =
880                     state.getStateFinalizerLogicMap().get(refKey.getKey().getLocalName());
881             if (stateFinalizerLogic == null) {
882                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
883                         STATE_FINALIZER_LOGIC + refKey.getId() + DOES_NOT_EXIST);
884             }
885
886             if (logicFlavour != null) {
887                 stateFinalizerLogic.setLogicFlavour(logicFlavour);
888             }
889             if (logic != null) {
890                 stateFinalizerLogic.setLogic(logic);
891             }
892
893             return new ApexApiResult();
894         } catch (final Exception e) {
895             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
896         }
897     }
898
899     /**
900      * List policy finalizer logic for a state.
901      *
902      * @param name name of the policy
903      * @param version version of the policy, set to null to use the latest version
904      * @param stateName of the state
905      * @param finalizerLogicName name of the state finalizer logic
906      * @return result of the operation
907      */
908     public ApexApiResult listPolicyStateFinalizerLogic(final String name, final String version, final String stateName,
909             final String finalizerLogicName) {
910         try {
911             Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
912
913             final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
914             if (policy == null) {
915                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
916                         CONCEPT + name + ':' + version + DOES_NOT_EXIST);
917             }
918
919             final AxState state = policy.getStateMap().get(stateName);
920             if (state == null) {
921                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
922                         CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
923             }
924
925             if (finalizerLogicName != null) {
926                 final AxReferenceKey refKey = new AxReferenceKey(state.getKey(), finalizerLogicName);
927                 final AxStateFinalizerLogic stateFinalizerLogic =
928                         state.getStateFinalizerLogicMap().get(refKey.getKey().getLocalName());
929                 if (stateFinalizerLogic == null) {
930                     return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
931                             STATE_FINALIZER_LOGIC + refKey.getId() + DOES_NOT_EXIST);
932                 }
933
934                 return new ApexApiResult(ApexApiResult.Result.SUCCESS,
935                         new ApexModelStringWriter<AxStateFinalizerLogic>(false).writeString(stateFinalizerLogic,
936                                 AxStateFinalizerLogic.class, jsonMode));
937             } else {
938                 if (state.getStateFinalizerLogicMap().size() == 0) {
939                     return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
940                             "no state finalizer logic defined on state " + state.getKey().getId());
941                 }
942                 final ApexApiResult result = new ApexApiResult();
943                 for (final AxStateFinalizerLogic stateFinalizerLogic : state.getStateFinalizerLogicMap().values()) {
944                     result.addMessage(new ApexModelStringWriter<AxStateFinalizerLogic>(false)
945                             .writeString(stateFinalizerLogic, AxStateFinalizerLogic.class, jsonMode));
946                 }
947                 return result;
948             }
949         } catch (final Exception e) {
950             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
951         }
952     }
953
954     /**
955      * Delete policy finalizer logic for a state.
956      *
957      * @param name name of the policy
958      * @param version version of the policy, set to null to use the latest version
959      * @param stateName of the state
960      * @param finalizerLogicName name of the state finalizer logic
961      * @return result of the operation
962      */
963     public ApexApiResult deletePolicyStateFinalizerLogic(final String name, final String version,
964             final String stateName, final String finalizerLogicName) {
965         try {
966             Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
967
968             final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
969             if (policy == null) {
970                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
971                         CONCEPT + name + ':' + version + DOES_NOT_EXIST);
972             }
973
974             final AxState state = policy.getStateMap().get(stateName);
975             if (state == null) {
976                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
977                         CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
978             }
979
980             if (finalizerLogicName != null) {
981                 final AxReferenceKey refKey = new AxReferenceKey(state.getKey(), finalizerLogicName);
982                 final AxStateFinalizerLogic stateFinalizerLogic =
983                         state.getStateFinalizerLogicMap().get(refKey.getKey().getLocalName());
984                 if (stateFinalizerLogic == null) {
985                     return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
986                             STATE_FINALIZER_LOGIC + refKey.getId() + DOES_NOT_EXIST);
987                 }
988
989                 final ApexApiResult result = new ApexApiResult();
990                 result.addMessage(new ApexModelStringWriter<AxStateFinalizerLogic>(false)
991                         .writeString(stateFinalizerLogic, AxStateFinalizerLogic.class, jsonMode));
992                 state.getStateFinalizerLogicMap().remove(refKey.getLocalName());
993                 return result;
994             } else {
995                 if (state.getStateFinalizerLogicMap().size() == 0) {
996                     return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
997                             "no state finalizer logic defined on state " + state.getKey().getId());
998                 }
999
1000                 final ApexApiResult result = new ApexApiResult();
1001                 for (final AxStateFinalizerLogic stateFinalizerLogic : state.getStateFinalizerLogicMap().values()) {
1002                     result.addMessage(new ApexModelStringWriter<AxStateFinalizerLogic>(false)
1003                             .writeString(stateFinalizerLogic, AxStateFinalizerLogic.class, jsonMode));
1004                 }
1005                 state.getStateFinalizerLogicMap().clear();
1006                 return result;
1007             }
1008         } catch (final Exception e) {
1009             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
1010         }
1011     }
1012
1013     /**
1014      * Create a policy state task reference.
1015      *
1016      * @param builder builder for the state task reference
1017      * @return result of the operation
1018      */
1019     public ApexApiResult createPolicyStateTaskRef(CreatePolicyStateTaskRefBuilder builder) {
1020         try {
1021             Assertions.argumentNotNull(builder.getStateName(), STATE_NAME_MAY_NOT_BE_NULL);
1022             Assertions.argumentNotNull(builder.getOutputName(), "outputName may not be null");
1023
1024             final AxPolicy policy =
1025                     apexModel.getPolicyModel().getPolicies().get(builder.getName(), builder.getVersion());
1026             if (policy == null) {
1027                 return new ApexApiResult(
1028                         ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
1029                         CONCEPT + builder.getName() + ':' + builder.getVersion() + DOES_NOT_EXIST);
1030             }
1031
1032             final AxState state = policy.getStateMap().get(builder.getStateName());
1033             if (state == null) {
1034                 return new ApexApiResult(
1035                         ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
1036                         CONCEPT + policy.getKey().getId() + ':' + builder.getStateName() + DOES_NOT_EXIST);
1037             }
1038
1039             final AxTask task =
1040                     apexModel
1041                     .getPolicyModel()
1042                     .getTasks()
1043                     .get(builder.getTaskName(), builder.getTaskVersion());
1044             if (task == null) {
1045                 return new ApexApiResult(
1046                         ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
1047                         CONCEPT + builder.getTaskName() + ':' + builder.getTaskVersion() + DOES_NOT_EXIST);
1048             }
1049
1050             if (state.getTaskReferences().containsKey(task.getKey())) {
1051                 return new ApexApiResult(
1052                         ApexApiResult.Result.CONCEPT_EXISTS,
1053                         "task "
1054                                 + task.getKey().getId()
1055                                 + " already has reference with output "
1056                                 + state.getTaskReferences().get(task.getKey()));
1057             }
1058
1059             AxReferenceKey refKey;
1060             if (builder.getTaskLocalName() == null) {
1061                 refKey = new AxReferenceKey(state.getKey(), state.getKey().getParentKeyName());
1062             } else {
1063                 refKey = new AxReferenceKey(state.getKey(), builder.getTaskLocalName());
1064             }
1065
1066             // The reference to the output we're using here
1067             final AxReferenceKey outputRefKey =
1068                     new AxReferenceKey(state.getKey(), builder.getOutputName());
1069
1070             final AxStateTaskOutputType stateTaskOutputType =
1071                     AxStateTaskOutputType.valueOf(builder.getOutputType());
1072             if (stateTaskOutputType.equals(AxStateTaskOutputType.DIRECT)) {
1073                 if (!state.getStateOutputs().containsKey(outputRefKey.getLocalName())) {
1074                     return new ApexApiResult(
1075                             ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
1076                             "state output concept " + outputRefKey.getId() + DOES_NOT_EXIST);
1077                 }
1078             } else if (stateTaskOutputType.equals(AxStateTaskOutputType.LOGIC)) {
1079                 if (!state.getStateFinalizerLogicMap().containsKey(outputRefKey.getLocalName())) {
1080                     return new ApexApiResult(
1081                             ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
1082                             "state finalizer logic concept " + outputRefKey.getId() + DOES_NOT_EXIST);
1083                 }
1084             } else {
1085                 return new ApexApiResult(
1086                         ApexApiResult.Result.FAILED, "output type " + builder.getOutputType() + " invalid");
1087             }
1088
1089             state
1090                 .getTaskReferences()
1091                 .put(task.getKey(), new AxStateTaskReference(refKey, stateTaskOutputType, outputRefKey));
1092             return new ApexApiResult();
1093         } catch (final Exception e) {
1094             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
1095         }
1096     }
1097
1098     /**
1099      * List policy state task references.
1100      *
1101      * @param name name of the policy
1102      * @param version version of the policy, set to null to use the latest version
1103      * @param stateName of the state
1104      * @param taskName name of the task, set to null to list all task references
1105      * @param taskVersion version of the task, set to null to use the latest version
1106      * @return result of the operation
1107      */
1108     public ApexApiResult listPolicyStateTaskRef(final String name, final String version, final String stateName,
1109             final String taskName, final String taskVersion) {
1110         try {
1111             Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
1112
1113             final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
1114             if (policy == null) {
1115                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
1116                         CONCEPT + name + ':' + version + DOES_NOT_EXIST);
1117             }
1118
1119             final AxState state = policy.getStateMap().get(stateName);
1120             if (state == null) {
1121                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
1122                         CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
1123             }
1124
1125             final ApexApiResult result = new ApexApiResult();
1126             boolean found = false;
1127             final Map<AxArtifactKey, AxStateTaskReference> taskReferences = state.getTaskReferences();
1128             for (final Entry<AxArtifactKey, AxStateTaskReference> taskReferenceEntry : taskReferences.entrySet()) {
1129                 final AxArtifactKey key = taskReferenceEntry.getKey();
1130                 final AxStateTaskReference value = taskReferenceEntry.getValue();
1131                 if ((taskName != null && !key.getName().equals(taskName))
1132                         || (taskVersion != null && !key.getVersion().equals(taskVersion))) {
1133                     continue;
1134                 }
1135
1136                 found = true;
1137                 result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false).writeString(key, AxArtifactKey.class,
1138                         jsonMode));
1139                 result.addMessage(new ApexModelStringWriter<AxStateTaskReference>(false).writeString(value,
1140                         AxStateTaskReference.class, jsonMode));
1141             }
1142             if (found) {
1143                 return result;
1144             } else {
1145                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
1146                         "no task references found for state " + state.getKey().getId());
1147             }
1148         } catch (final Exception e) {
1149             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
1150         }
1151     }
1152
1153     /**
1154      * Delete a policy state task reference.
1155      *
1156      * @param name name of the policy
1157      * @param version version of the policy, set to null to use the latest version
1158      * @param stateName of the state
1159      * @param taskName name of the task, set to null to delete all task references
1160      * @param taskVersion version of the task, set to null to use the latest version
1161      * @return result of the operation
1162      */
1163     public ApexApiResult deletePolicyStateTaskRef(final String name, final String version, final String stateName,
1164             final String taskName, final String taskVersion) {
1165         try {
1166             Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
1167
1168             final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
1169             if (policy == null) {
1170                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
1171                         CONCEPT + name + ':' + version + DOES_NOT_EXIST);
1172             }
1173
1174             final AxState state = policy.getStateMap().get(stateName);
1175             if (state == null) {
1176                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
1177                         CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
1178             }
1179
1180             final Set<AxArtifactKey> deleteSet = new TreeSet<>();
1181
1182             for (final AxArtifactKey taskReferenceKey : state.getTaskReferences().keySet()) {
1183                 if ((taskName != null && !taskReferenceKey.getName().equals(taskName))
1184                         || (taskVersion != null && !taskReferenceKey.getVersion().equals(taskVersion))) {
1185                     continue;
1186                 }
1187                 deleteSet.add(taskReferenceKey);
1188             }
1189             if (deleteSet.isEmpty()) {
1190                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
1191                         CONCEPT + taskName + ':' + taskVersion + DOES_NOT_EXIST_ON_STATE + state.getKey().getId());
1192             }
1193
1194             final ApexApiResult result = new ApexApiResult();
1195             for (final AxArtifactKey keyToDelete : deleteSet) {
1196                 state.getTaskReferences().remove(keyToDelete);
1197                 result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false).writeString(keyToDelete,
1198                         AxArtifactKey.class, jsonMode));
1199             }
1200             return result;
1201         } catch (final Exception e) {
1202             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
1203         }
1204     }
1205
1206     /**
1207      * Create a policy state context album reference.
1208      *
1209      * @param name name of the policy
1210      * @param version version of the policy, set to null to use the latest version
1211      * @param stateName of the state
1212      * @param contextAlbumName name of the context album for the context album reference
1213      * @param contextAlbumVersion version of the context album for the context album reference, set
1214      *        to null to use the latest version
1215      * @return result of the operation
1216      */
1217     public ApexApiResult createPolicyStateContextRef(final String name, final String version, final String stateName,
1218             final String contextAlbumName, final String contextAlbumVersion) {
1219         try {
1220             Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
1221
1222             final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
1223             if (policy == null) {
1224                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
1225                         CONCEPT + name + ':' + version + DOES_NOT_EXIST);
1226             }
1227
1228             final AxState state = policy.getStateMap().get(stateName);
1229             if (state == null) {
1230                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
1231                         CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
1232             }
1233
1234             final AxContextAlbum contextAlbum =
1235                     apexModel.getPolicyModel().getAlbums().get(contextAlbumName, contextAlbumVersion);
1236             if (contextAlbum == null) {
1237                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
1238                         CONCEPT + contextAlbumName + ':' + contextAlbumVersion + DOES_NOT_EXIST);
1239             }
1240
1241             if (state.getContextAlbumReferences().contains(contextAlbum.getKey())) {
1242                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_EXISTS, "concept album reference for concept "
1243                         + contextAlbum.getKey().getId() + " already exists in state");
1244             }
1245
1246             state.getContextAlbumReferences().add(contextAlbum.getKey());
1247             return new ApexApiResult();
1248         } catch (final Exception e) {
1249             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
1250         }
1251     }
1252
1253     /**
1254      * List policy state context album references.
1255      *
1256      * @param name name of the policy
1257      * @param version version of the policy, set to null to use the latest version
1258      * @param stateName of the state
1259      * @param contextAlbumName name of the context album for the context album reference, set to
1260      *        null to list all task context album references
1261      * @param contextAlbumVersion version of the context album for the context album reference, set
1262      *        to null to use the latest version
1263      * @return result of the operation
1264      */
1265     public ApexApiResult listPolicyStateContextRef(final String name, final String version, final String stateName,
1266             final String contextAlbumName, final String contextAlbumVersion) {
1267         try {
1268             Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
1269
1270             final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
1271             if (policy == null) {
1272                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
1273                         CONCEPT + name + ':' + version + DOES_NOT_EXIST);
1274             }
1275
1276             final AxState state = policy.getStateMap().get(stateName);
1277             if (state == null) {
1278                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
1279                         CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
1280             }
1281
1282             final ApexApiResult result = new ApexApiResult();
1283             boolean found = false;
1284             for (final AxArtifactKey albumKey : state.getContextAlbumReferences()) {
1285                 if ((contextAlbumName != null && !albumKey.getName().equals(contextAlbumName))
1286                         || (contextAlbumVersion != null && !albumKey.getVersion().equals(contextAlbumVersion))) {
1287                     continue;
1288                 }
1289                 result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false).writeString(albumKey,
1290                         AxArtifactKey.class, jsonMode));
1291                 found = true;
1292             }
1293             if (!found) {
1294                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, CONCEPT + contextAlbumName + ':'
1295                         + contextAlbumVersion + DOES_NOT_EXIST_ON_STATE + state.getKey().getId());
1296             }
1297             return result;
1298         } catch (final Exception e) {
1299             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
1300         }
1301     }
1302
1303     /**
1304      * Delete a policy state context album reference.
1305      *
1306      * @param name name of the policy
1307      * @param version version of the policy, set to null to use the default version
1308      * @param stateName of the state
1309      * @param contextAlbumName name of the context album for the context album reference, set to
1310      *        null to delete all task context album references
1311      * @param contextAlbumVersion version of the context album for the context album reference, set
1312      *        to null to use the latest version
1313      * @return result of the operation
1314      */
1315     public ApexApiResult deletePolicyStateContextRef(final String name, final String version, final String stateName,
1316             final String contextAlbumName, final String contextAlbumVersion) {
1317         try {
1318             Assertions.argumentNotNull(stateName, STATE_NAME_MAY_NOT_BE_NULL);
1319
1320             final AxPolicy policy = apexModel.getPolicyModel().getPolicies().get(name, version);
1321             if (policy == null) {
1322                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
1323                         CONCEPT + name + ':' + version + DOES_NOT_EXIST);
1324             }
1325
1326             final AxState state = policy.getStateMap().get(stateName);
1327             if (state == null) {
1328                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST,
1329                         CONCEPT + policy.getKey().getId() + ':' + stateName + DOES_NOT_EXIST);
1330             }
1331
1332             final Set<AxArtifactKey> deleteSet = new TreeSet<>();
1333
1334             for (final AxArtifactKey albumKey : state.getContextAlbumReferences()) {
1335
1336                 if ((contextAlbumName != null && !albumKey.getName().equals(contextAlbumName))
1337                         || (contextAlbumVersion != null && !albumKey.getVersion().equals(contextAlbumVersion))) {
1338
1339                     continue;
1340                 }
1341                 deleteSet.add(albumKey);
1342             }
1343             if (deleteSet.isEmpty()) {
1344                 return new ApexApiResult(ApexApiResult.Result.CONCEPT_DOES_NOT_EXIST, CONCEPT + contextAlbumName + ':'
1345                         + contextAlbumVersion + DOES_NOT_EXIST_ON_STATE + state.getKey().getId());
1346             }
1347
1348             final ApexApiResult result = new ApexApiResult();
1349             for (final AxArtifactKey keyToDelete : deleteSet) {
1350                 state.getContextAlbumReferences().remove(keyToDelete);
1351                 result.addMessage(new ApexModelStringWriter<AxArtifactKey>(false).writeString(keyToDelete,
1352                         AxArtifactKey.class, jsonMode));
1353             }
1354             return result;
1355         } catch (final Exception e) {
1356             return new ApexApiResult(ApexApiResult.Result.FAILED, e);
1357         }
1358     }
1359 }