1 /**
2 * Copyright 2010 The Kuali Foundation Licensed under the
3 * Educational Community License, Version 2.0 (the "License"); you may
4 * not use this file except in compliance with the License. You may
5 * obtain a copy of the License at
6 *
7 * http://www.osedu.org/licenses/ECL-2.0
8 *
9 * Unless required by applicable law or agreed to in writing,
10 * software distributed under the License is distributed on an "AS IS"
11 * BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express
12 * or implied. See the License for the specific language governing
13 * permissions and limitations under the License.
14 */
15
16 package org.kuali.student.r2.lum.lo.dao.impl;
17
18 import java.util.List;
19
20 import javax.persistence.EntityManager;
21 import javax.persistence.PersistenceContext;
22 import javax.persistence.Query;
23
24 import org.kuali.student.r1.common.dao.impl.AbstractCrudDaoImpl;
25 import org.kuali.student.r2.common.exceptions.DependentObjectsExistException;
26 import org.kuali.student.r2.common.exceptions.DoesNotExistException;
27 import org.kuali.student.r2.common.exceptions.UnsupportedActionException;
28 import org.kuali.student.r2.lum.lo.dao.LoDao;
29 import org.kuali.student.r2.lum.lo.entity.Lo;
30 import org.kuali.student.r2.lum.lo.entity.LoCategory;
31 import org.kuali.student.r2.lum.lo.entity.LoLoCategoryJoin;
32 import org.kuali.student.r2.lum.lo.entity.LoLoRelation;
33
34 /**
35 * @author Kuali Student Team
36 *
37 */
38 public class LoDaoImpl extends AbstractCrudDaoImpl implements LoDao {
39 @PersistenceContext(unitName = "Lo")
40 @Override
41 public void setEm(EntityManager em) {
42 super.setEm(em);
43 }
44
45 /* (non-Javadoc)
46 * @see org.kuali.student.lum.lo.dao.LoDao#addLoCategoryToLo(java.lang.String, java.lang.String)
47 */
48 @Override
49 public boolean addLoCategoryToLo(String loCategoryId, String loId) throws UnsupportedActionException, DoesNotExistException {
50 Lo lo = fetch(Lo.class, loId);
51 LoCategory loCategory = fetch(LoCategory.class, loCategoryId);
52 String loRepoId = lo.getLoRepository().getId();
53 String loCategoryRepoId = loCategory.getLoRepository().getId();
54
55 if ( ! loRepoId.equals(loCategoryRepoId) ) {
56 throw new UnsupportedActionException("The learning objective category is not associated with the learning objective's repository");
57 }
58 LoLoCategoryJoin join = new LoLoCategoryJoin();
59 join.setLo(lo);
60 join.setLoCategory(loCategory);
61 create(join);
62 return true;
63 }
64
65 /* (non-Javadoc)
66 * @see org.kuali.student.lum.lo.dao.LoDao#removeLoCategoryFromLo(java.lang.String, java.lang.String)
67 */
68 @Override
69 public boolean removeLoCategoryFromLo(String loCategoryId, String loId) throws DoesNotExistException {
70 Query query = em.createNamedQuery("Lo.getLoCategoryJoin");
71 query.setParameter("loCategoryId", loCategoryId);
72 query.setParameter("loId", loId);
73 LoLoCategoryJoin join = (LoLoCategoryJoin) query.getSingleResult();
74 delete(join);
75 return true;
76 }
77
78 /* (non-Javadoc)
79 * @see org.kuali.student.lum.lo.dao.LoDao#getLoByIdList(java.util.List)
80 */
81 @Override
82 public List<Lo> getLoByIdList(List<String> loIds) {
83 Query query = em.createNamedQuery("Lo.findLosByIdList");
84 query.setParameter("idList", loIds);
85 @SuppressWarnings("unchecked")
86 List<Lo> resultList = query.getResultList();
87 return resultList;
88 }
89
90 /* (non-Javadoc)
91 * @see org.kuali.student.lum.lo.dao.LoDao#deleteLo(java.lang.String)
92 */
93 @Override
94 public boolean deleteLo(String loId) throws DoesNotExistException, DependentObjectsExistException {
95 //Lo child = fetch(Lo.class, loId);
96 if ( ! getIncludedLos(loId).isEmpty() ) {
97 throw new DependentObjectsExistException("Lo(" +
98 loId+
99 ") cannot be deleted without orphaning child Lo(s).");
100 }
101 // TODO - will need more general logic here when we have relationships other than "includes"
102 // hopefully dictionary-driven
103 // List<Lo> parents = getIncludingLos(loId);
104 // for (Lo parent : parents) {
105 // parent.getRelatedLos().remove(child);
106 // update(parent);
107 // }
108 delete(Lo.class, loId);
109 return true;
110 }
111
112 /* (non-Javadoc)
113 * @see org.kuali.student.lum.lo.dao.LoDao#getLoChildren(java.lang.String)
114 */
115 private List<Lo> getIncludedLos(String loId) throws DoesNotExistException {
116 return getRelatedLosByLoId(loId, "kuali.lo.relation.type.includes"); // TODO - gotta be a constant somewhere, or perhaps pull from dictionary
117 }
118
119 /* (non-Javadoc)
120 * @see org.kuali.student.lum.lo.dao.LoDao#getLoParents(java.lang.String)
121 */
122 private List<Lo> getIncludingLos(String loId) throws DoesNotExistException {
123 return getLosByRelatedLoId(loId, "kuali.lo.relation.type.includes"); // TODO - gotta be a constant somewhere, or perhaps pull from dictionary
124 }
125
126 /* (non-Javadoc)
127 * @see org.kuali.student.lum.lo.dao.LoDao#getLosByLoCategory(java.lang.String)
128 */
129 @Override
130 public List<Lo> getLosByLoCategory(String loCategoryId) {
131 Query query = em.createNamedQuery("Lo.getLosByLoCategory");
132 query.setParameter("loCategoryId", loCategoryId);
133 @SuppressWarnings("unchecked")
134 List<Lo> resultList = query.getResultList();
135 return resultList;
136 }
137
138 /* (non-Javadoc)
139 * @see org.kuali.student.lum.lo.dao.LoDao#getLoCategories(java.lang.String)
140 */
141 @Override
142 public List<LoCategory> getLoCategories(String loRepositoryKey) {
143 Query query = em.createNamedQuery("Lo.getLoCategories");
144 query.setParameter("repositoryId", loRepositoryKey);
145 @SuppressWarnings("unchecked")
146 List<LoCategory> resultList = query.getResultList();
147 return resultList;
148 }
149
150 /* (non-Javadoc)
151 * @see org.kuali.student.lum.lo.dao.LoDao#deleteLoCategory(java.lang.String)
152 */
153 @Override
154 public boolean deleteLoCategory(String loCategoryId) throws DoesNotExistException, DependentObjectsExistException {
155 List<Lo> los = getLosByLoCategory(loCategoryId);
156 if (null != los && !los.isEmpty()) {
157 throw new DependentObjectsExistException("LoCategory(" + loCategoryId + ") still has " + los.size() + " Learning Objective(s) associated with it.");
158 }
159 delete(LoCategory.class, loCategoryId);
160 return true;
161 }
162
163 @Override
164 public List<Lo> getRelatedLosByLoId(String loId, String loLoRelationTypeId)
165 throws DoesNotExistException {
166 Query query = em.createNamedQuery("Lo.getRelatedLosByLoId");
167 query.setParameter("loId", loId);
168 query.setParameter("loLoRelationTypeId", loLoRelationTypeId);
169 @SuppressWarnings("unchecked")
170 List<Lo> resultList = query.getResultList();
171 return resultList;
172 }
173
174 @Override
175 public List<Lo> getLosByRelatedLoId(String relatedLoId,
176 String loLoRelationTypeId) throws DoesNotExistException {
177 Query query = em.createNamedQuery("Lo.getLosByRelatedLoId");
178 query.setParameter("relatedLoId", relatedLoId);
179 query.setParameter("loLoRelationTypeId", loLoRelationTypeId);
180 @SuppressWarnings("unchecked")
181 List<Lo> resultList = query.getResultList();
182 return resultList;
183 }
184
185 @Override
186 public void deleteLoLoRelation(String loLoRelationId) throws DoesNotExistException {
187
188 // // make sure we don't orphan an LO (and potentially its children)
189 // LoLoRelation llRelation = fetch(LoLoRelation.class, loLoRelationId);
190 // if (getIncludingLos(llRelation.getRelatedLo().getId()).size() == 1) {
191 // // TODO - "&& [not a top-level LO for another CLU]" when LO's are reused
192 // throw new DependentObjectsExistException("LoLoRelation(" +
193 // loLoRelationId +
194 // ") cannot be deleted without orphaning Lo(s).");
195 // }
196 delete(LoLoRelation.class, loLoRelationId);
197 }
198
199 @Override
200 public List<LoCategory> getLoCategoriesForLo(String loId) {
201 Query query = em.createNamedQuery("Lo.getLoCategoriesForLo");
202 query.setParameter("loId", loId);
203 // @SuppressWarnings("unchecked")
204 List<LoCategory> resultList = query.getResultList();
205 return resultList;
206 }
207
208 @Override
209 public List<String> getAllowedLoLoRelationTypesForLoType(String loTypeKey, String relatedLoTypeKey) {
210 Query query = em.createNamedQuery("Lo.getAllowedLoLoRelationTypes");
211 query.setParameter("loTypeKey", loTypeKey);
212 query.setParameter("relatedLoTypeKey", relatedLoTypeKey);
213 @SuppressWarnings("unchecked")
214 List<String> resultList = query.getResultList();
215 return resultList;
216 }
217
218 @Override
219 public List<Lo> getLosByRepository(String loRepositoryId) {
220 Query query = em.createNamedQuery("Lo.getLosByRepository");
221 query.setParameter("loRepositoryId", loRepositoryId);
222 @SuppressWarnings("unchecked")
223 List<Lo> resultList = query.getResultList();
224 return resultList;
225 }
226
227 @Override
228 public List<LoLoRelation> getLoLoRelationsByLoId(String loId) {
229 Query query = em.createNamedQuery("Lo.getLoLoRelationsByLoId");
230 query.setParameter("loId", loId);
231 @SuppressWarnings("unchecked")
232 List<LoLoRelation> resultList = query.getResultList();
233 return resultList;
234 }
235
236 // These are left over from when Lo's were in parent-child hierarchies, and there
237 // was a concept of 'equivalent' LO's
238 // TODO - remove when logic has been completely pilfered as appropriate
239 /* (non-Javadoc)
240 * @see org.kuali.student.lum.lo.dao.LoDao#getAllDescendantLoIds(java.lang.String)
241 @Override
242 public List<String> getAllDescendantLoIds(String loId) {
243 Query query = em.createNamedQuery("Lo.getLoChildrenIds");
244 query.setParameter("parentId", loId);
245 return getAllLevels(query, "parentId", loId);
246 }
247
248 /* (non-Javadoc)
249 * @see org.kuali.student.lum.lo.dao.LoDao#getAncestors(java.lang.String)
250 *
251 * Get the id's of _all_ ancestors of the specified Lo
252 @Override
253 public List<String> getAncestors(String loId) {
254 Query query = em.createNamedQuery("Lo.getAncestors");
255 query.setParameter("childId", loId);
256 return getAllLevels(query, "childId", loId);
257 }
258
259 /* Recurse a query
260 private List<String> getAllLevels(Query query, String paramName, String paramValue) {
261 // Eliminate dup's by using a set
262 Set<String> valSet = new TreeSet<String>();
263 query.setParameter(paramName, paramValue);
264 @SuppressWarnings("unchecked")
265 List<String> nextLevelList = query.getResultList();
266 valSet.addAll(nextLevelList);
267 for (String resultStr : nextLevelList) {
268 valSet.addAll(getAllLevels(query, paramName, resultStr));
269 }
270 return new ArrayList<String>(valSet);
271 }
272
273 /* (non-Javadoc)
274 * @see org.kuali.student.lum.lo.dao.LoDao#getLoEquivalents(java.lang.String)
275 * Retrieves all learning objectives that have an equivalence reference to the specified LO.
276 * Note: Equivalency of learning objectives is uni-directional, and we're navigating to those
277 * LO's pointing to loId's
278 @Override
279 public List<Lo> getLoEquivalents(String loId) {
280 Query query = em.createNamedQuery("Lo.getLoEquivalents");
281 query.setParameter("loId", loId);
282 @SuppressWarnings("unchecked")
283 List<Lo> los = query.getResultList();
284 return los;
285 }
286
287 /* (non-Javadoc)
288 * @see org.kuali.student.lum.lo.dao.LoDao#getEquivalentLos(java.lang.String)
289 * /**
290 * Retrieves all equivalent learning objectives of a learning objective.
291 * Note: Equivalency of learning objectives is uni-directional, and we're navigating to those
292 * LO's that loId's LO points to as equivalent
293 @Override
294 public List<Lo> getEquivalentLos(String loId) {
295 Query query = em.createNamedQuery("Lo.getEquivalentLos");
296 query.setParameter("loId", loId);
297 @SuppressWarnings("unchecked")
298 List<Lo> los = query.getResultList();
299 return los;
300 }
301
302 /* (non-Javadoc)
303 * @see org.kuali.student.lum.lo.dao.LoDao#isEquivalent(java.lang.String, java.lang.String)
304 @Override
305 public boolean isEquivalent(String equivLoId, String loId) {
306 Query query = em.createNamedQuery("Lo.getEquivalentLosIds");
307 query.setParameter("loId", loId);
308 @SuppressWarnings("unchecked")
309 List<String> losIds = query.getResultList();
310 return losIds.contains(equivLoId);
311 }
312
313 /* (non-Javadoc)
314 * @see org.kuali.student.lum.lo.dao.LoDao#removeChildLoFromLo(java.lang.String, java.lang.String)
315 @Override
316 public boolean removeChildLoFromLo(String loId, String parentLoId) throws DependentObjectsExistException, DoesNotExistException {
317 Lo parentLo = null;
318 Lo lo = null;
319 if (getLoParents(loId).size() <= 1) {
320 throw new DependentObjectsExistException();
321 }
322 try {
323 parentLo = fetch(Lo.class, parentLoId);
324 lo = fetch(Lo.class, loId);
325 } catch (DoesNotExistException e) {
326 return false;
327 }
328 List<Lo> children = parentLo.getChildLos();
329 int index = children.indexOf(lo);
330 if (-1 == index) {
331 throw new DoesNotExistException("Lo(" + loId + ") is not a child of Lo(" + parentLoId + ").");
332 }
333 children.remove(index);
334 // TODO - null out hierarchy
335 return true;
336 }
337
338 /* (non-Javadoc)
339 * @see org.kuali.student.lum.lo.dao.LoDao#removeEquivalentLoFromLo(java.lang.String, java.lang.String)
340 @Override
341 public boolean removeEquivalentLoFromLo(String loId, String equivalentLoId) {
342 Lo lo = null;
343 Lo equivLo = null;
344 try {
345 lo = fetch(Lo.class, loId);
346 equivLo = fetch(Lo.class, equivalentLoId);
347 } catch (DoesNotExistException e) {
348 return false;
349 }
350 List<Lo> equivs = lo.getEquivalentLos();
351 int index = equivs.indexOf(equivLo);
352 equivs.remove(index);
353 return true;
354 }
355
356 /* (non-Javadoc)
357 * @see org.kuali.student.lum.lo.dao.LoDao#isDescendant(java.lang.String, java.lang.String)
358 @Override
359 public boolean isDescendant(String loId, String descendantLoId) {
360 List<Lo> los = getLoChildren(loId);
361 Lo child = null;
362 try {
363 child = fetch(Lo.class, descendantLoId);
364 } catch (DoesNotExistException e) {
365 return false;
366 }
367 return los.contains(child);
368 }
369 */
370 }