001// --------------------------------------------------------------------------------
002// Copyright 2002-2024 Echo Three, LLC
003//
004// Licensed under the Apache License, Version 2.0 (the "License");
005// you may not use this file except in compliance with the License.
006// You may obtain a copy of the License at
007//
008//     http://www.apache.org/licenses/LICENSE-2.0
009//
010// Unless required by applicable law or agreed to in writing, software
011// distributed under the License is distributed on an "AS IS" BASIS,
012// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013// See the License for the specific language governing permissions and
014// limitations under the License.
015// --------------------------------------------------------------------------------
016
017package com.echothree.model.control.security.server.logic;
018
019import com.echothree.model.control.security.server.control.SecurityControl;
020import com.echothree.model.control.training.server.control.TrainingControl;
021import com.echothree.model.control.training.server.logic.PartyTrainingClassLogic;
022import com.echothree.model.control.training.server.logic.PartyTrainingClassLogic.PreparedPartyTrainingClass;
023import com.echothree.model.control.training.common.training.PartyTrainingClassStatusConstants;
024import com.echothree.model.data.party.server.entity.Party;
025import com.echothree.model.data.security.server.entity.PartySecurityRoleTemplate;
026import com.echothree.model.data.security.server.entity.PartySecurityRoleTemplateRole;
027import com.echothree.model.data.security.server.entity.PartySecurityRoleTemplateTrainingClass;
028import com.echothree.model.data.security.server.entity.PartySecurityRoleTemplateUse;
029import com.echothree.model.data.security.server.entity.SecurityRole;
030import com.echothree.model.data.training.server.entity.PartyTrainingClass;
031import com.echothree.model.data.training.server.entity.TrainingClass;
032import com.echothree.util.common.persistence.BasePK;
033import com.echothree.util.server.message.ExecutionErrorAccumulator;
034import com.echothree.util.server.persistence.Session;
035import java.util.HashSet;
036import java.util.List;
037import java.util.Set;
038
039public class PartySecurityRoleTemplateLogic {
040
041    private PartySecurityRoleTemplateLogic() {
042        super();
043    }
044
045    private static class PartySecurityRoleTemplateLogicHolder {
046        static PartySecurityRoleTemplateLogic instance = new PartySecurityRoleTemplateLogic();
047    }
048
049    public static PartySecurityRoleTemplateLogic getInstance() {
050        return PartySecurityRoleTemplateLogicHolder.instance;
051    }
052
053    // --------------------------------------------------------------------------------
054    //   Party Security Role Template Roles
055    // --------------------------------------------------------------------------------
056
057    public PartySecurityRoleTemplateRole createPartySecurityRoleTemplateRole(final PartySecurityRoleTemplate partySecurityRoleTemplate,
058            final SecurityRole securityRole, final BasePK createdBy) {
059        var securityControl = Session.getModelController(SecurityControl.class);
060        PartySecurityRoleTemplateRole partySecurityRoleTemplateRole = securityControl.createPartySecurityRoleTemplateRole(partySecurityRoleTemplate,
061                securityRole, createdBy);
062
063        // Add SecurityRole to any Parties that are currently assigned to the PartySecurityRoleTemplate.
064        List<PartySecurityRoleTemplateUse> partySecurityRoleTemplateUses = securityControl.getPartySecurityRoleTemplateUsesByPartySecurityRoleTemplate(partySecurityRoleTemplate);
065        partySecurityRoleTemplateUses.stream().map((partySecurityRoleTemplateUse) -> partySecurityRoleTemplateUse.getParty()).filter((party) -> (securityControl.getPartySecurityRole(party, securityRole) == null)).forEach((party) -> {
066            securityControl.createPartySecurityRole(party, securityRole, createdBy);
067        });
068
069        return partySecurityRoleTemplateRole;
070    }
071
072    public void deletePartySecurityRoleTemplateRole(final PartySecurityRoleTemplateRole partySecurityRoleTemplateRole, final BasePK deletedBy) {
073        var securityControl = Session.getModelController(SecurityControl.class);
074        PartySecurityRoleTemplate partySecurityRoleTemplate = partySecurityRoleTemplateRole.getPartySecurityRoleTemplate();
075
076        securityControl.deletePartySecurityRoleTemplateRole(partySecurityRoleTemplateRole, deletedBy);
077
078        // Remove SecurityRole from any Parties that may be assigned to its PartySecurityRoleTemplate.
079        List<PartySecurityRoleTemplateUse> partySecurityRoleTemplateUses = securityControl.getPartySecurityRoleTemplateUsesByPartySecurityRoleTemplate(partySecurityRoleTemplate);
080        if(partySecurityRoleTemplateUses.size() > 0) {
081            SecurityRole securityRole = partySecurityRoleTemplateRole.getSecurityRole();
082
083            partySecurityRoleTemplateUses.stream().map((partySecurityRoleTemplateUse) -> partySecurityRoleTemplateUse.getParty()).map((party) -> securityControl.getPartySecurityRoleForUpdate(party, securityRole)).filter((partySecurityRole) -> (partySecurityRole != null)).forEach((partySecurityRole) -> {
084                securityControl.deletePartySecurityRole(partySecurityRole, deletedBy);
085            });
086        }
087    }
088    
089    public void deletePartySecurityRoleTemplateRoles(final List<PartySecurityRoleTemplateRole> partySecurityRoleTemplateRoles, final BasePK deletedBy) {
090        partySecurityRoleTemplateRoles.forEach((partySecurityRoleTemplateRole) -> 
091                deletePartySecurityRoleTemplateRole(partySecurityRoleTemplateRole, deletedBy)
092        );
093    }
094
095    public void deletePartySecurityRoleTemplateRoleByPartySecurityRoleTemplate(final PartySecurityRoleTemplate partySecurityRoleTemplate, final BasePK deletedBy) {
096        var securityControl = Session.getModelController(SecurityControl.class);
097
098        deletePartySecurityRoleTemplateRoles(securityControl.getPartySecurityRoleTemplateRolesForUpdate(partySecurityRoleTemplate), deletedBy);
099    }
100
101    public void deletePartySecurityRoleTemplateRolesBySecurityRole(final SecurityRole securityRole, final BasePK deletedBy) {
102        var securityControl = Session.getModelController(SecurityControl.class);
103
104        deletePartySecurityRoleTemplateRoles(securityControl.getPartySecurityRoleTemplateRolesBySecurityRoleForUpdate(securityRole), deletedBy);
105    }
106
107    // --------------------------------------------------------------------------------
108    //   Party Security Role Template Training Classes
109    // --------------------------------------------------------------------------------
110
111    public static class PreparedPartySecurityRoleTemplateTrainingClass {
112
113        private PartySecurityRoleTemplate partySecurityRoleTemplate;
114        private TrainingClass trainingClass;
115        private Set<PreparedPartyTrainingClass> preparedPartyTrainingClasses;
116
117        public PartySecurityRoleTemplate getPartySecurityRoleTemplate() {
118            return partySecurityRoleTemplate;
119        }
120
121        public void setPartySecurityRoleTemplate(PartySecurityRoleTemplate partySecurityRoleTemplate) {
122            this.partySecurityRoleTemplate = partySecurityRoleTemplate;
123        }
124
125        public TrainingClass getTrainingClass() {
126            return trainingClass;
127        }
128
129        public void setTrainingClass(TrainingClass trainingClass) {
130            this.trainingClass = trainingClass;
131        }
132
133        public Set<PreparedPartyTrainingClass> getPreparedPartyTrainingClasses() {
134            return preparedPartyTrainingClasses;
135        }
136
137        public void setPreparedPartyTrainingClasses(Set<PreparedPartyTrainingClass> preparedPartyTrainingClasses) {
138            this.preparedPartyTrainingClasses = preparedPartyTrainingClasses;
139        }
140
141    }
142
143    public PreparedPartySecurityRoleTemplateTrainingClass preparePartySecurityRoleTemplateTrainingClass(final ExecutionErrorAccumulator eea,
144            final PartySecurityRoleTemplate partySecurityRoleTemplate, final TrainingClass trainingClass) {
145        var securityControl = Session.getModelController(SecurityControl.class);
146        PreparedPartySecurityRoleTemplateTrainingClass preparedPartySecurityRoleTemplateTrainingClass = new PreparedPartySecurityRoleTemplateTrainingClass();
147
148        preparedPartySecurityRoleTemplateTrainingClass.setPartySecurityRoleTemplate(partySecurityRoleTemplate);
149        preparedPartySecurityRoleTemplateTrainingClass.setTrainingClass(trainingClass);
150
151        // If Party does not have a PartyTrainingClass for this TrainingClass in either ASSIGNED or TRAINING, then assign it to them.
152        List<PartySecurityRoleTemplateUse> partySecurityRoleTemplateUses = securityControl.getPartySecurityRoleTemplateUsesByPartySecurityRoleTemplate(partySecurityRoleTemplate);
153        Set<PreparedPartyTrainingClass> preparedPartyTrainingClasses = new HashSet<>();
154        if(partySecurityRoleTemplateUses.size() > 0) {
155            var trainingControl = Session.getModelController(TrainingControl.class);
156
157            for(var partySecurityRoleTemplateUse : partySecurityRoleTemplateUses) {
158                Party party = partySecurityRoleTemplateUse.getParty();
159                Set<PartyTrainingClass> partyTrainingClasses = trainingControl.getPartyTrainingClassesByStatuses(party, trainingClass,
160                        PartyTrainingClassStatusConstants.WorkflowStep_ASSIGNED, PartyTrainingClassStatusConstants.WorkflowStep_TRAINING);
161
162                if(partyTrainingClasses.isEmpty()) {
163                    preparedPartyTrainingClasses.add(PartyTrainingClassLogic.getInstance().preparePartyTrainingClass(eea, party, trainingClass, null, null));
164                }
165
166                if(eea.hasExecutionErrors()) {
167                    break;
168                }
169            }
170        }
171
172        preparedPartySecurityRoleTemplateTrainingClass.setPreparedPartyTrainingClasses(preparedPartyTrainingClasses);
173
174        return preparedPartySecurityRoleTemplateTrainingClass;
175    }
176
177    public PartySecurityRoleTemplateTrainingClass createPartySecurityRoleTemplateTrainingClass(final Session session,
178            final PreparedPartySecurityRoleTemplateTrainingClass preparedPartySecurityRoleTemplateTrainingClass, final BasePK createdBy) {
179        var securityControl = Session.getModelController(SecurityControl.class);
180        TrainingClass trainingClass = preparedPartySecurityRoleTemplateTrainingClass.getTrainingClass();
181        PartySecurityRoleTemplateTrainingClass partySecurityRoleTemplateTrainingClass = securityControl.createPartySecurityRoleTemplateTrainingClass(preparedPartySecurityRoleTemplateTrainingClass.partySecurityRoleTemplate,
182            trainingClass, createdBy);
183
184        // If Party does not have a PartyTrainingClass for this TrainingClass in either ASSIGNED or TRAINING, then assign it to them.
185        preparedPartySecurityRoleTemplateTrainingClass.getPreparedPartyTrainingClasses().stream().forEach((preparedPartyTrainingClass) -> {
186            PartyTrainingClassLogic.getInstance().createPartyTrainingClass(session, preparedPartyTrainingClass, createdBy);
187        });
188
189        return partySecurityRoleTemplateTrainingClass;
190    }
191
192    public void deletePartySecurityRoleTemplateTrainingClass(final PartySecurityRoleTemplateTrainingClass partySecurityRoleTemplateTrainingClass,
193            final BasePK deletedBy) {
194        var securityControl = Session.getModelController(SecurityControl.class);
195        PartySecurityRoleTemplate partySecurityRoleTemplate = partySecurityRoleTemplateTrainingClass.getPartySecurityRoleTemplate();
196
197        securityControl.deletePartySecurityRoleTemplateTrainingClass(partySecurityRoleTemplateTrainingClass, deletedBy);
198
199        // If Party has a PartyTrainingClass in ASSIGNED status for this TrainingClass, then delete it.
200        List<PartySecurityRoleTemplateUse> partySecurityRoleTemplateUses = securityControl.getPartySecurityRoleTemplateUsesByPartySecurityRoleTemplate(partySecurityRoleTemplate);
201        if(partySecurityRoleTemplateUses.size() > 0) {
202            var trainingControl = Session.getModelController(TrainingControl.class);
203            TrainingClass trainingClass = partySecurityRoleTemplateTrainingClass.getTrainingClass();
204
205            partySecurityRoleTemplateUses.stream().map((partySecurityRoleTemplateUse) -> partySecurityRoleTemplateUse.getParty()).map((party) -> trainingControl.getPartyTrainingClassesByStatusesForUpdate(party, trainingClass,
206                    PartyTrainingClassStatusConstants.WorkflowStep_ASSIGNED)).filter((partyTrainingClasses) -> (partyTrainingClasses.size() > 0)).forEach((partyTrainingClasses) -> {
207                        partyTrainingClasses.forEach((partyTrainingClass) -> {
208                            PartyTrainingClassLogic.getInstance().deletePartyTrainingClass(partyTrainingClass, deletedBy);
209                });
210            });
211        }
212    }
213
214    public void deletePartySecurityRoleTemplateTrainingClasses(final List<PartySecurityRoleTemplateTrainingClass> partySecurityRoleTemplateTrainingClasses,
215            final BasePK deletedBy) {
216        partySecurityRoleTemplateTrainingClasses.forEach((partySecurityRoleTemplateTrainingClass) -> 
217                deletePartySecurityRoleTemplateTrainingClass(partySecurityRoleTemplateTrainingClass, deletedBy)
218        );
219    }
220
221    public void deletePartySecurityRoleTemplateTrainingClassByPartySecurityRoleTemplate(final PartySecurityRoleTemplate partySecurityRoleTemplate,
222            final BasePK deletedBy) {
223        var securityControl = Session.getModelController(SecurityControl.class);
224
225        deletePartySecurityRoleTemplateTrainingClasses(securityControl.getPartySecurityRoleTemplateTrainingClassesForUpdate(partySecurityRoleTemplate), deletedBy);
226    }
227
228    public void deletePartySecurityRoleTemplateTrainingClassesByTrainingClass(final TrainingClass trainingClass, final BasePK deletedBy) {
229        var securityControl = Session.getModelController(SecurityControl.class);
230
231        deletePartySecurityRoleTemplateTrainingClasses(securityControl.getPartySecurityRoleTemplateTrainingClassesByTrainingClassForUpdate(trainingClass), deletedBy);
232    }
233
234}