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