001/** 002 * Copyright 2005-2017 The Kuali Foundation 003 * 004 * Licensed under the Educational Community 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.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016package org.kuali.rice.krms.impl.repository; 017 018import org.apache.commons.lang.StringUtils; 019import org.kuali.rice.krad.data.DataObjectService; 020import org.kuali.rice.krad.data.PersistenceOption; 021import org.kuali.rice.krms.api.repository.action.ActionDefinition; 022 023import java.util.ArrayList; 024import java.util.Collection; 025import java.util.Collections; 026import java.util.HashMap; 027import java.util.List; 028import java.util.Map; 029 030import static org.kuali.rice.krms.impl.repository.BusinessObjectServiceMigrationUtils.deleteMatching; 031import static org.kuali.rice.krms.impl.repository.BusinessObjectServiceMigrationUtils.findMatchingOrderBy; 032import static org.kuali.rice.krms.impl.repository.BusinessObjectServiceMigrationUtils.findSingleMatching; 033 034/** 035 * Implementation of the interface for accessing KRMS repository Action related 036 * business objects. 037 * 038 * @author Kuali Rice Team (rice.collab@kuali.org) 039 */ 040public class ActionBoServiceImpl implements ActionBoService { 041 042 private DataObjectService dataObjectService; 043 044 /** 045 * This overridden method creates a KRMS Action in the repository. 046 */ 047 @Override 048 public ActionDefinition createAction(ActionDefinition action) { 049 if (action == null) { 050 throw new IllegalArgumentException("action is null"); 051 } 052 053 final String actionNameKey = action.getName(); 054 final String actionNamespaceKey = action.getNamespace(); 055 final ActionDefinition existing = getActionByNameAndNamespace(actionNameKey, actionNamespaceKey); 056 057 if (existing != null) { 058 throw new IllegalStateException("the action to create already exists: " + action); 059 } 060 061 ActionBo bo = ActionBo.from(action); 062 RuleBo rule = new RuleBo(); 063 rule.setId(action.getRuleId()); 064 rule.getActions().add(bo); 065 bo.setRule(rule); 066 067 bo = dataObjectService.save(bo, PersistenceOption.FLUSH); 068 069 return ActionBo.to(bo); 070 } 071 072 /** 073 * This overridden method updates an existing Action in the repository. 074 */ 075 @Override 076 public ActionDefinition updateAction(ActionDefinition action) { 077 if (action == null) { 078 throw new IllegalArgumentException("action is null"); 079 } 080 081 // must already exist to be able to update 082 final String actionIdKey = action.getId(); 083 final ActionBo existing = dataObjectService.find(ActionBo.class, actionIdKey); 084 085 if (existing == null) { 086 throw new IllegalStateException("the action does not exist: " + action); 087 } 088 089 final ActionDefinition toUpdate; 090 091 if (existing.getId().equals(action.getId())) { 092 toUpdate = action; 093 } else { 094 // if passed in id does not match existing id, correct it 095 final ActionDefinition.Builder builder = ActionDefinition.Builder.create(action); 096 builder.setId(existing.getId()); 097 toUpdate = builder.build(); 098 } 099 100 // copy all updateable fields to bo 101 ActionBo boToUpdate = ActionBo.from(toUpdate); 102 103 // delete any old, existing attributes 104 deleteMatching(dataObjectService, ActionAttributeBo.class, Collections.singletonMap("action.id", 105 toUpdate.getId())); 106 107 // update the action and create new attributes 108 final ActionBo updatedData = dataObjectService.save(boToUpdate, PersistenceOption.FLUSH); 109 110 return ActionBo.to(updatedData); 111 } 112 113 /** 114 * This overridden method retrieves an Action from the repository. 115 */ 116 @Override 117 public ActionDefinition getActionByActionId(String actionId) { 118 if (StringUtils.isBlank(actionId)) { 119 throw new IllegalArgumentException("action ID is null or blank"); 120 } 121 122 ActionBo bo = dataObjectService.find(ActionBo.class, actionId); 123 124 return ActionBo.to(bo); 125 } 126 127 /** 128 * This overridden method retrieves an Action from the repository. 129 */ 130 @Override 131 public ActionDefinition getActionByNameAndNamespace(String name, String namespace) { 132 if (StringUtils.isBlank(name)) { 133 throw new IllegalArgumentException("name is blank"); 134 } 135 if (StringUtils.isBlank(namespace)) { 136 throw new IllegalArgumentException("namespace is blank"); 137 } 138 139 final Map<String, Object> map = new HashMap<String, Object>(); 140 map.put("name", name); 141 map.put("namespace", namespace); 142 143 ActionBo myAction = findSingleMatching(dataObjectService, ActionBo.class, map); 144 145 return ActionBo.to(myAction); 146 } 147 148 /** 149 * This overridden method retrieves a List of Actions associated with a Rule. 150 */ 151 @Override 152 public List<ActionDefinition> getActionsByRuleId(String ruleId) { 153 if (StringUtils.isBlank(ruleId)) { 154 throw new IllegalArgumentException("ruleId is null or blank"); 155 } 156 157 List<ActionBo> bos = findMatchingOrderBy(dataObjectService, ActionBo.class, Collections.singletonMap("ruleId", 158 ruleId), "sequenceNumber", true); 159 160 return convertListOfBosToImmutables(bos); 161 } 162 163 /** 164 * This overridden method retrieves a specific Action associated with a Rule. 165 */ 166 @Override 167 public ActionDefinition getActionByRuleIdAndSequenceNumber(String ruleId, Integer sequenceNumber) { 168 if (StringUtils.isBlank(ruleId)) { 169 throw new IllegalArgumentException("ruleId is null or blank"); 170 } 171 if (sequenceNumber == null) { 172 throw new IllegalArgumentException("sequenceNumber is null"); 173 } 174 175 final Map<String, Object> map = new HashMap<String, Object>(); 176 map.put("ruleId", ruleId); 177 map.put("sequenceNumber", sequenceNumber); 178 ActionBo bo = dataObjectService.find(ActionBo.class, map); 179 180 return ActionBo.to(bo); 181 } 182 183 /** 184 * This method retrieves an ActionAttributeBo by id 185 * 186 * @see org.kuali.rice.krms.impl.repository.ActionBoService#getActionsByRuleId(java.lang.String) 187 */ 188 public ActionAttributeBo getActionAttributeById(String attrId) { 189 if (StringUtils.isBlank(attrId)) { 190 return null; 191 } 192 193 return dataObjectService.find(ActionAttributeBo.class, attrId); 194 } 195 196 /** 197 * Sets the dataObjectService attribute value. 198 * 199 * @param dataObjectService The dataObjectService to set. 200 */ 201 public void setDataObjectService(final DataObjectService dataObjectService) { 202 this.dataObjectService = dataObjectService; 203 } 204 205 /** 206 * Converts a List<ActionBo> to an Unmodifiable List<Action> 207 * 208 * @param actionBos a mutable List<ActionBo> to made completely immutable. 209 * @return An unmodifiable List<Action> 210 */ 211 List<ActionDefinition> convertListOfBosToImmutables(final Collection<ActionBo> actionBos) { 212 if (actionBos == null) { 213 return Collections.emptyList(); 214 } 215 216 ArrayList<ActionDefinition> actions = new ArrayList<ActionDefinition>(); 217 218 for (ActionBo bo : actionBos) { 219 ActionDefinition action = ActionBo.to(bo); 220 actions.add(action); 221 } 222 223 return Collections.unmodifiableList(actions); 224 } 225}