View Javadoc
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 }