001/**
002 * Copyright 2005-2016 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.kew.impl.repository;
017
018
019import java.util.ArrayList;
020import java.util.Collection;
021import java.util.Collections;
022
023import java.util.List;
024
025import org.apache.commons.lang.StringUtils;
026import org.kuali.rice.core.api.criteria.QueryByCriteria;
027import org.kuali.rice.core.api.exception.RiceIllegalArgumentException;
028import org.kuali.rice.core.api.exception.RiceIllegalStateException;
029import org.kuali.rice.kew.api.repository.type.KewTypeAttribute;
030import org.kuali.rice.kew.api.repository.type.KewTypeDefinition;
031import org.kuali.rice.kew.api.repository.type.KewTypeRepositoryService;
032import org.kuali.rice.kew.impl.type.KewTypeAttributeBo;
033import org.kuali.rice.kew.impl.type.KewTypeBo;
034import org.kuali.rice.krad.data.DataObjectService;
035
036import static org.kuali.rice.core.api.criteria.PredicateFactory.equal;
037
038public final class KewTypeBoServiceImpl implements KewTypeRepositoryService {
039
040    private DataObjectService dataObjectService;
041
042    /**
043     * This overridden method creates a KewType if it does not already exist in the repository.
044     *
045     * @see org.kuali.rice.kew.api.repository.type.KewTypeRepositoryService#createKewType(org.kuali.rice.kew.api.repository.type.KewTypeDefinition)
046     */
047    @Override
048    public KewTypeDefinition createKewType(KewTypeDefinition kewType) {
049        if (kewType == null){
050            throw new RiceIllegalArgumentException("kewType is null");
051        }
052        final String nameKey = kewType.getName();
053        final String namespaceKey = kewType.getNamespace();
054        final KewTypeDefinition existing = getTypeByNameAndNamespace(nameKey, namespaceKey);
055        if (existing != null && existing.getName().equals(nameKey) && existing.getNamespace().equals(namespaceKey)){
056            throw new RiceIllegalStateException("The KEW Type to create already exists: " + kewType);
057        }
058
059        KewTypeBo bo = dataObjectService.save(KewTypeBo.from(kewType));
060
061        return KewTypeBo.to(bo);
062    }
063
064    /**
065     * This overridden method updates an existing KewType
066     *
067     * @see org.kuali.rice.kew.api.repository.type.KewTypeRepositoryService#updateKewType(org.kuali.rice.kew.api.repository.type.KewTypeDefinition)
068     */
069    @Override
070    public void updateKewType(KewTypeDefinition kewType) {
071        if (kewType == null) {
072            throw new RiceIllegalArgumentException("kewType is null");
073        }
074        final String idKey = kewType.getId();
075        final KewTypeBo existing = dataObjectService.find(KewTypeBo.class, idKey);
076        if (existing == null) {
077            throw new RiceIllegalStateException("The KEW type does not exist: " + kewType);
078        }
079        final KewTypeDefinition toUpdate;
080        if (!existing.getId().equals(kewType.getId())){
081            final KewTypeDefinition.Builder builder = KewTypeDefinition.Builder.create(kewType);
082            builder.setId(existing.getId());
083            toUpdate = builder.build();
084        } else {
085            toUpdate = kewType;
086        }
087
088        dataObjectService.save(KewTypeBo.from(toUpdate));
089    }
090
091    @Override
092    public KewTypeDefinition getTypeById(final String id) {
093        if (StringUtils.isBlank(id)) {
094            throw new RiceIllegalArgumentException("id is blank");
095        }
096
097        KewTypeBo kewTypeBo = dataObjectService.find(KewTypeBo.class, id);
098
099        return KewTypeBo.to(kewTypeBo);
100    }
101
102    @Override
103    public KewTypeDefinition getTypeByNameAndNamespace(final String name, final String namespace) {
104        if (StringUtils.isBlank(name)) {
105            throw new RiceIllegalArgumentException("name is blank");
106        }
107        if (StringUtils.isBlank(namespace)) {
108            throw new RiceIllegalArgumentException("namespace is blank");
109        }
110
111        QueryByCriteria.Builder criteria = QueryByCriteria.Builder.create();
112        criteria.setPredicates(equal("name", name), equal("namespace", namespace));
113        List<KewTypeBo> myTypes = dataObjectService.findMatching(KewTypeBo.class, criteria.build()).getResults();
114        if (myTypes.isEmpty()) {
115            return null;
116        } else if (myTypes.size() == 1) {
117            return KewTypeBo.to(myTypes.get(0));
118        } else {
119            throw new RiceIllegalStateException("More than one type found for the given name and namespace - (name=" +
120                    name + ", namespace=" + namespace + ").");
121        }
122
123    }
124
125    @Override
126    public List<KewTypeDefinition> findAllTypesByNamespace(final String namespace) {
127        if (StringUtils.isBlank(namespace)) {
128            throw new RiceIllegalArgumentException("namespace is blank");
129        }
130
131        QueryByCriteria.Builder criteria = QueryByCriteria.Builder.create();
132        criteria.setPredicates(equal("namespace", namespace), equal("active", Boolean.TRUE));
133        Collection<KewTypeBo> kewTypeBos = dataObjectService.findMatching(KewTypeBo.class,
134                criteria.build()).getResults();
135
136        return convertListOfBosToImmutables(kewTypeBos);
137    }
138
139    @Override
140    public List<KewTypeDefinition> findAllTypes() {
141
142        QueryByCriteria.Builder criteria = QueryByCriteria.Builder.create();
143        criteria.setPredicates(equal("active", Boolean.TRUE));
144        Collection<KewTypeBo> kewTypeBos = dataObjectService.findMatching(KewTypeBo.class,
145                criteria.build()).getResults();
146
147        return convertListOfBosToImmutables(kewTypeBos);
148    }
149
150    /**
151     * Sets the dataObjectService attribute value.
152     *
153     * @param dataObjectService The dataObjectService to set.
154     */
155    public void setDataObjectService(final DataObjectService dataObjectService) {
156        this.dataObjectService = dataObjectService;
157    }
158
159    /**
160     * Converts a List<KewTypeBo> to an Unmodifiable List<KewType>
161     *
162     * @param kewTypeBos a mutable List<KewTypeBo> to made completely immutable.
163     * @return An unmodifiable List<KewType>
164     */
165    List<KewTypeDefinition> convertListOfBosToImmutables(final Collection<KewTypeBo> kewTypeBos) {
166        ArrayList<KewTypeDefinition> kewTypes = new ArrayList<KewTypeDefinition>();
167        for (KewTypeBo bo : kewTypeBos) {
168            KewTypeDefinition kewType = KewTypeBo.to(bo);
169            kewTypes.add(kewType);
170        }
171        return Collections.unmodifiableList(kewTypes);
172    }
173
174    /**
175     * This overridden method creates a KewTypeAttribute if it does not already exist in the repository.
176     *
177     * @see org.kuali.rice.kew.api.repository.type.KewTypeRepositoryService#createKewTypeAttribute(org.kuali.rice.kew.api.repository.type.KewTypeAttribute)
178     */
179    @Override
180    public void createKewTypeAttribute(KewTypeAttribute kewTypeAttribute) {
181        if (kewTypeAttribute == null){
182            throw new RiceIllegalArgumentException("kewTypeAttribute is null");
183        }
184
185        KewTypeAttributeBo existing = dataObjectService.find(KewTypeAttributeBo.class, kewTypeAttribute);
186
187        if (null != existing && kewTypeAttribute.getTypeId().equals(existing.getTypeId()) &&
188                kewTypeAttribute.getAttributeDefinitionId().equals(existing.getAttributeDefinitionId())) {
189
190            throw new RiceIllegalStateException("The KEW Type Attribute to create already exists: " + kewTypeAttribute);
191        }
192        KewTypeBo kewType = null;
193        if (kewTypeAttribute.getTypeId() != null) {
194            kewType = dataObjectService.find(KewTypeBo.class, kewTypeAttribute.getTypeId());
195        }
196
197        dataObjectService.save(KewTypeAttributeBo.from(kewTypeAttribute, kewType));
198    }
199
200    /**
201     * This overridden method updates an existing KewTypeAttribute
202     *
203     * @see org.kuali.rice.kew.api.repository.type.KewTypeRepositoryService#updateKewTypeAttribute(org.kuali.rice.kew.api.repository.type.KewTypeAttribute)
204     */
205    @Override
206    public void updateKewTypeAttribute(KewTypeAttribute kewTypeAttribute) {
207        if (kewTypeAttribute == null) {
208            throw new RiceIllegalArgumentException("kewTypeAttribute is null");
209        }
210        final KewTypeAttributeBo existing = dataObjectService.find(KewTypeAttributeBo.class, kewTypeAttribute.getId());
211        if (existing == null) {
212            throw new RiceIllegalStateException("The KEW type Attribute does not exist: " + kewTypeAttribute);
213        }
214        final KewTypeAttribute toUpdate;
215        if (!existing.getId().equals(kewTypeAttribute.getId())){
216            final KewTypeAttribute.Builder builder = KewTypeAttribute.Builder.create(kewTypeAttribute);
217            builder.setId(existing.getId());
218            toUpdate = builder.build();
219        } else {
220            toUpdate = kewTypeAttribute;
221        }
222
223        KewTypeBo kewType = existing.getType();
224        if (!existing.getTypeId().equals(kewTypeAttribute.getTypeId())) {
225            kewType = dataObjectService.find(KewTypeBo.class, kewTypeAttribute.getTypeId());
226        }
227
228        dataObjectService.save(KewTypeAttributeBo.from(toUpdate, kewType));
229    }
230}