1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16 package org.kuali.student.lum.lu.assembly;
17
18 import java.util.ArrayList;
19 import java.util.List;
20
21 import org.apache.log4j.Logger;
22 import org.kuali.rice.kim.bo.types.dto.AttributeSet;
23 import org.kuali.student.common.assembly.data.AssemblyException;
24 import org.kuali.student.common.assembly.data.Data;
25 import org.kuali.student.common.assembly.data.Metadata;
26 import org.kuali.student.common.assembly.dictionary.MetadataServiceImpl;
27 import org.kuali.student.common.assembly.old.BaseAssembler;
28 import org.kuali.student.common.assembly.old.data.SaveResult;
29 import org.kuali.student.common.dto.MetaInfo;
30 import org.kuali.student.common.dto.RichTextInfo;
31 import org.kuali.student.common.exceptions.DoesNotExistException;
32 import org.kuali.student.common.exceptions.MissingParameterException;
33 import org.kuali.student.common.search.dto.SearchRequest;
34 import org.kuali.student.common.search.dto.SearchResult;
35 import org.kuali.student.common.search.dto.SearchResultCell;
36 import org.kuali.student.common.search.dto.SearchResultRow;
37 import org.kuali.student.common.validation.dto.ValidationResultInfo;
38 import org.kuali.student.common.validation.dto.ValidationResultInfo.ErrorLevel;
39 import org.kuali.student.common.versionmanagement.dto.VersionDisplayInfo;
40 import org.kuali.student.lum.common.client.lo.MetaInfoHelper;
41 import org.kuali.student.lum.common.client.widgets.CluSetHelper;
42 import org.kuali.student.lum.common.client.widgets.CluSetRangeHelper;
43 import org.kuali.student.lum.common.client.widgets.CluSetRangeModelUtil;
44 import org.kuali.student.lum.lu.dto.CluInfo;
45 import org.kuali.student.lum.lu.dto.CluSetInfo;
46 import org.kuali.student.lum.lu.dto.MembershipQueryInfo;
47 import org.kuali.student.lum.lu.service.LuService;
48 import org.kuali.student.lum.lu.service.LuServiceConstants;
49 import org.springframework.transaction.annotation.Transactional;
50
51 @Transactional(readOnly=true,rollbackFor={Throwable.class})
52 public class CluSetManagementAssembler extends BaseAssembler<Data, Void> {
53
54
55 final Logger LOG = Logger.getLogger(CluSetManagementAssembler.class);
56
57 public static final String JOINT_RELATION_TYPE = "kuali.lu.relation.type.co-located";
58
59 public static final String FORMAT_LU_TYPE = "kuali.lu.type.CreditCourseFormatShell";
60
61 public static final String FORMAT_RELATION_TYPE = "luLuRelationType.hasCourseFormat";
62 public static final String ACTIVITY_RELATION_TYPE = "luLuRelationType.contains";
63
64 public static final String PROPOSAL_REFERENCE_TYPE = "kuali.proposal.referenceType.clu";
65
66 public static final String CLUSET_DATA_TYPE = "cluset";
67
68 private LuService luService;
69 private MetadataServiceImpl metadataService;
70
71 public MetadataServiceImpl getMetadataService() {
72 return metadataService;
73 }
74
75 public void setMetadataService(MetadataServiceImpl metadataService) {
76 this.metadataService = metadataService;
77 }
78
79 @Override
80 public Data get(String id) throws AssemblyException {
81
82 CluSetHelper resultCluSetHelper = null;
83 Data resultData = null;
84
85 try {
86 CluSetInfo cluSetInfo = getCluSetInfo(id);
87 resultCluSetHelper = toCluSetHelper(cluSetInfo);
88 if (resultCluSetHelper == null) {
89 resultData = null;
90 } else {
91
92
93 resultData = resultCluSetHelper.getData();
94 }
95 } catch (Exception e) {
96 throw new AssemblyException("Could not retrive cluSet with id " + id, e);
97 }
98
99 return resultData;
100 }
101
102 public CluSetInfo getCluSetInfo(String cluSetId) throws Exception {
103 List<String> cluIds = null;
104 CluSetInfo cluSetInfo = null;
105
106
107
108 cluSetInfo = luService.getCluSetInfo(cluSetId);
109 cluSetInfo.setCluIds(null);
110 cluIds = luService.getCluIdsFromCluSet(cluSetId);
111 cluSetInfo.setCluIds(cluIds);
112 upWrap(cluSetInfo);
113 return cluSetInfo;
114 }
115
116 public MetaInfoHelper toMetaInfoHelper(MetaInfo metaInfo) {
117 MetaInfoHelper metaInfoHelper = null;
118 Data metaData = new Data();
119 if (metaInfo == null) return null;
120 metaInfoHelper = MetaInfoHelper.wrap(metaData);
121 metaInfoHelper.setCreateId(metaInfo.getCreateId());
122 metaInfoHelper.setCreateTime(metaInfo.getCreateTime());
123 metaInfoHelper.setUpdateId(metaInfo.getUpdateId());
124 metaInfoHelper.setUpdateTime(metaInfo.getUpdateTime());
125 metaInfoHelper.setVersionInd(metaInfo.getVersionInd());
126 return metaInfoHelper;
127 }
128
129 public MetaInfo toMetaInfo(MetaInfoHelper metaInfoHelper) {
130 MetaInfo metaInfo = null;
131 if (metaInfoHelper == null) return null;
132 metaInfo = new MetaInfo();
133 metaInfo.setCreateId(metaInfoHelper.getCreateId());
134 metaInfo.setCreateTime(metaInfoHelper.getCreateTime());
135 metaInfo.setUpdateId(metaInfoHelper.getUpdateId());
136 metaInfo.setUpdateTime(metaInfoHelper.getUpdateTime());
137 metaInfo.setVersionInd(metaInfoHelper.getVersionInd());
138 return metaInfo;
139 }
140
141 public String richTextToString(RichTextInfo richTextInfo) {
142 String result = null;
143 if (richTextInfo == null) return null;
144 result = richTextInfo.getPlain();
145 return result;
146 }
147
148 @Override
149 @Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
150 public SaveResult<Data> save(Data input) throws AssemblyException {
151
152 try {
153 SaveResult<Data> result = new SaveResult<Data>();
154 List<ValidationResultInfo> validationResults = validate(input);
155 if (hasValidationErrors(validationResults)) {
156 result.setValidationResults(validationResults);
157 result.setValue(input);
158 return result;
159 }
160
161 SaveResult<Data> clusetResult = saveCluSet(input);
162 result.setValidationResults(clusetResult.getValidationResults());
163 result.setValue(clusetResult.getValue());
164 return result;
165 } catch (Exception e) {
166 throw new AssemblyException("Unable to save ....", e);
167 }
168 }
169
170 private void upWrap(CluSetInfo cluSetInfo) throws AssemblyException {
171 List<String> cluSetIds = (cluSetInfo == null)? null : cluSetInfo.getCluSetIds();
172 List<String> unWrappedCluSetIds = null;
173 List<CluSetInfo> wrappedCluSets = null;
174 List<CluSetInfo> subCluSets = null;
175
176 try {
177 if (cluSetIds != null && !cluSetIds.isEmpty()) {
178 subCluSets = luService.getCluSetInfoByIdList(cluSetIds);
179 }
180 } catch (Exception e) {
181 LOG.error(e.getMessage(), e);
182 throw new AssemblyException("Failed to retrieve the sub clusets of cluset " +
183 cluSetInfo.getId());
184 }
185
186 if (subCluSets != null) {
187 for (CluSetInfo subCluSet : subCluSets) {
188 if (subCluSet.getIsReusable()) {
189 unWrappedCluSetIds = (unWrappedCluSetIds == null)?
190 new ArrayList<String>() : unWrappedCluSetIds;
191 unWrappedCluSetIds.add(subCluSet.getId());
192 } else {
193 wrappedCluSets = (wrappedCluSets == null)?
194 new ArrayList<CluSetInfo>() : wrappedCluSets;
195 wrappedCluSets.add(subCluSet);
196 }
197 }
198 }
199 cluSetInfo.setCluSetIds(unWrappedCluSetIds);
200 if (wrappedCluSets != null) {
201 for (CluSetInfo wrappedCluSet : wrappedCluSets) {
202 MembershipQueryInfo mqInfo = wrappedCluSet.getMembershipQuery();
203 if (wrappedCluSet.getCluIds() != null && !wrappedCluSet.getCluIds().isEmpty()) {
204 cluSetInfo.setCluIds(wrappedCluSet.getCluIds());
205 }
206 if (mqInfo != null && mqInfo.getSearchTypeKey() != null && !mqInfo.getSearchTypeKey().isEmpty()) {
207 cluSetInfo.setMembershipQuery(mqInfo);
208 }
209 }
210 }
211 }
212
213 private void wrap(CluSetInfo cluSetInfo) throws AssemblyException {
214 int numCluSetElementTypes = 0;
215 boolean hasCluIds = false;
216 boolean hasCluSetIds = false;
217 boolean hasMembershipQuery = false;
218 List<String> wrapperCluSetIds = new ArrayList<String>();
219 MembershipQueryInfo mqInfo = null;
220 if (cluSetInfo.getCluIds() != null && !cluSetInfo.getCluIds().isEmpty()) {
221 numCluSetElementTypes++;
222 hasCluIds = true;
223 }
224 if (cluSetInfo.getCluSetIds() != null && !cluSetInfo.getCluSetIds().isEmpty()) {
225 numCluSetElementTypes++;
226 hasCluSetIds = true;
227 }
228 mqInfo = cluSetInfo.getMembershipQuery();
229 if (mqInfo != null && mqInfo.getSearchTypeKey() != null && !mqInfo.getSearchTypeKey().isEmpty()) {
230 numCluSetElementTypes++;
231 hasMembershipQuery = true;
232 }
233
234 if (numCluSetElementTypes > 1) {
235 if (hasCluIds) {
236 CluSetInfo wrapperCluSet = new CluSetInfo();
237 setWrapperCluSetInfoValues(wrapperCluSet, cluSetInfo);
238
239 wrapperCluSet.setCluIds(cluSetInfo.getCluIds());
240 cluSetInfo.setCluIds(null);
241 try {
242 if (wrapperCluSet.getType() == null) {
243 wrapperCluSet.setType("kuali.cluSet.type.CreditCourse");
244 }
245 wrapperCluSet = luService.createCluSet(wrapperCluSet.getType(), wrapperCluSet);
246 } catch (Exception e) {
247 LOG.error("Failed to create wrapper cluset",e);
248 throw new AssemblyException(e);
249 }
250 wrapperCluSetIds.add(wrapperCluSet.getId());
251 }
252 if (hasMembershipQuery) {
253 CluSetInfo wrapperCluSet = new CluSetInfo();
254 setWrapperCluSetInfoValues(wrapperCluSet, cluSetInfo);
255
256 wrapperCluSet.setMembershipQuery(mqInfo);
257 cluSetInfo.setMembershipQuery(null);
258 try {
259 wrapperCluSet = luService.createCluSet(wrapperCluSet.getType(), wrapperCluSet);
260 } catch (Exception e) {
261 LOG.error("Failed to create wrapper cluset",e);
262 throw new AssemblyException(e);
263 }
264 wrapperCluSetIds.add(wrapperCluSet.getId());
265 }
266 if (hasCluSetIds) {
267 wrapperCluSetIds.addAll(cluSetInfo.getCluSetIds());
268 }
269 cluSetInfo.setCluSetIds(wrapperCluSetIds);
270 }
271 }
272
273 private void setWrapperCluSetInfoValues(CluSetInfo wrapperCluSet, CluSetInfo cluSetInfo) {
274 wrapperCluSet.setAdminOrg(cluSetInfo.getAdminOrg());
275 wrapperCluSet.setEffectiveDate(cluSetInfo.getEffectiveDate());
276 wrapperCluSet.setExpirationDate(cluSetInfo.getExpirationDate());
277 wrapperCluSet.setIsReusable(false);
278 wrapperCluSet.setIsReferenceable(false);
279 wrapperCluSet.setName(cluSetInfo.getName());
280 wrapperCluSet.setState(cluSetInfo.getState());
281 wrapperCluSet.setType(cluSetInfo.getType());
282 }
283
284 private SaveResult<Data> saveCluSet(Data input) throws AssemblyException {
285 SaveResult<Data> result = new SaveResult<Data>();
286
287 List<ValidationResultInfo> saveValidationResults = null;
288 CluSetHelper cluSetHelper = new CluSetHelper(input);
289 CluSetInfo cluSetInfo = toCluSetInfo(cluSetHelper);
290 CluSetInfo updatedCluSetInfo = null;
291 CluSetHelper resultCluSetHelper = null;
292 Data resultData = null;
293 wrap(cluSetInfo);
294
295 if ((cluSetInfo.getCluIds() == null || cluSetInfo.getCluIds().isEmpty()) &&
296 (cluSetInfo.getCluSetIds() == null || cluSetInfo.getCluSetIds().isEmpty()) &&
297 (cluSetInfo.getMembershipQuery() == null)){
298 ValidationResultInfo cluSetCannotBeEmpty = new ValidationResultInfo();
299 saveValidationResults = (saveValidationResults == null)? new ArrayList<ValidationResultInfo>() :
300 saveValidationResults;
301 result.setValue(null);
302 cluSetCannotBeEmpty.setElement("");
303 cluSetCannotBeEmpty.setMessage("Clu set cannot be empty");
304 cluSetCannotBeEmpty.setError("Clu set cannot be empty");
305 cluSetCannotBeEmpty.setLevel(ErrorLevel.ERROR);
306 saveValidationResults.add(cluSetCannotBeEmpty);
307 result.setValidationResults(saveValidationResults);
308 return result;
309 }
310
311 if (cluSetInfo.getId() != null && cluSetInfo.getId().trim().length() > 0) {
312 try {
313 updatedCluSetInfo = luService.updateCluSet(cluSetInfo.getId(), cluSetInfo);
314 } catch (Exception e) {
315 LOG.error("Failed to update cluset",e);
316 throw new AssemblyException(e);
317 }
318 } else {
319 try {
320 if (cluSetInfo.getType() == null) {
321 cluSetInfo.setType("kuali.cluSet.type.CreditCourse");
322 }
323 updatedCluSetInfo = luService.createCluSet(cluSetInfo.getType(), cluSetInfo);
324 } catch (Exception e) {
325 LOG.error("Failed to create cluset",e);
326 throw new AssemblyException(e);
327 }
328 }
329 try {
330 resultCluSetHelper = toCluSetHelper(updatedCluSetInfo);
331 } catch (Exception e) {
332 throw new AssemblyException(e);
333 }
334 if (resultCluSetHelper == null) {
335 resultData = null;
336 } else {
337
338
339 resultData = resultCluSetHelper.getData();
340 }
341 result.setValue(resultData);
342 return result;
343 }
344
345 private List<String> getMembershipQuerySearchResult(MembershipQueryInfo query) throws MissingParameterException {
346 if(query == null) {
347 return null;
348 }
349 SearchRequest sr = new SearchRequest();
350 sr.setSearchKey(query.getSearchTypeKey());
351 sr.setParams(query.getQueryParamValueList());
352
353 SearchResult result = luService.search(sr);
354
355 List<String> cluIds = new ArrayList<String>();
356 List<SearchResultRow> rows = result.getRows();
357 for(SearchResultRow row : rows) {
358 List<SearchResultCell> cells = row.getCells();
359 for(SearchResultCell cell : cells) {
360 if(cell.getKey().equals("lu.resultColumn.cluId")) {
361 cluIds.add(cell.getValue());
362 }
363 }
364 }
365 return cluIds;
366 }
367
368 private CluSetHelper toCluSetHelper(CluSetInfo cluSetInfo) throws Exception {
369 Data data = new Data();
370 Data cluSetDetailData = new Data();
371 data.set("cluset", cluSetDetailData);
372 CluSetHelper result = CluSetHelper.wrap(cluSetDetailData);
373 if (cluSetInfo != null) {
374 if (cluSetInfo.getCluIds() != null && !cluSetInfo.getCluIds().isEmpty()) {
375 List<CluInfo> cluInfos = new ArrayList<CluInfo>();
376 for(String id:cluSetInfo.getCluIds()){
377 VersionDisplayInfo versionInfo = luService.getCurrentVersion(LuServiceConstants.CLU_NAMESPACE_URI, id);
378 cluInfos.add(luService.getClu(versionInfo.getId()));
379 }
380 result.setApprovedClus(new Data());
381 for (CluInfo cluInfo : cluInfos) {
382 if (cluInfo.getState().equals("Active")) {
383 result.getApprovedClus().add(cluInfo.getVersionInfo().getVersionIndId());
384 } else {
385 result.getProposedClus().add(cluInfo.getVersionInfo().getVersionIndId());
386 }
387 result.getAllClus().add(cluInfo.getVersionInfo().getVersionIndId());
388 }
389 }
390 if (cluSetInfo.getCluSetIds() != null && !cluSetInfo.getCluSetIds().isEmpty()) {
391 result.setCluSets(new Data());
392 for (String cluSetId : cluSetInfo.getCluSetIds()) {
393 result.getCluSets().add(cluSetId);
394 }
395 }
396 if (cluSetInfo.getMembershipQuery() != null) {
397 MembershipQueryInfo mq = cluSetInfo.getMembershipQuery();
398 List<String> cluRangeCluIds = getMembershipQuerySearchResult(mq);
399 if (cluRangeCluIds != null) {
400 result.setCluRangeViewDetails(new Data());
401 for (String cluRangeCluId : cluRangeCluIds) {
402 result.getCluRangeViewDetails().add(cluRangeCluId);
403 }
404 }
405 }
406 result.setDescription(richTextToString(cluSetInfo.getDescr()));
407 result.setEffectiveDate(cluSetInfo.getEffectiveDate());
408 result.setExpirationDate(cluSetInfo.getExpirationDate());
409 result.setId(cluSetInfo.getId());
410 result.setMetaInfo(toMetaInfoHelper(cluSetInfo.getMetaInfo()));
411 result.setName(cluSetInfo.getName());
412 result.setOrganization(cluSetInfo.getAdminOrg());
413 result.setState(cluSetInfo.getState());
414 result.setType(cluSetInfo.getType());
415 result.setCluRangeParams(CluSetRangeModelUtil.INSTANCE.toData(
416 cluSetInfo.getMembershipQuery()));
417 }
418 return result;
419 }
420
421 private void addToCluIds(Data clusData, final List<String> cluIds) {
422 if (clusData != null) {
423 for (Data.Property p : clusData) {
424 if(!"_runtimeData".equals(p.getKey())){
425 String cluId = p.getValue();
426 cluIds.add(cluId);
427 }
428 }
429 }
430 }
431
432 private CluSetInfo toCluSetInfo(CluSetHelper cluSetHelper) {
433 CluSetInfo cluSetInfo = new CluSetInfo();
434 Data approvedClusData = cluSetHelper.getApprovedClus();
435 Data proposedClusData = cluSetHelper.getProposedClus();
436 Data cluSetsData = cluSetHelper.getCluSets();
437 final List<String> cluIds = new ArrayList<String>();
438 List<String> cluSetIds = null;
439
440 cluSetInfo.setId(cluSetHelper.getId());
441 if (approvedClusData != null) {
442 addToCluIds(approvedClusData, cluIds);
443 }
444 if (proposedClusData != null) {
445 addToCluIds(proposedClusData, cluIds);
446 }
447 if (cluIds != null && !cluIds.isEmpty()) {
448 cluSetInfo.setCluIds(cluIds);
449 }
450 if (cluSetsData != null) {
451 for (Data.Property p : cluSetsData) {
452 if(!"_runtimeData".equals(p.getKey())){
453 String cluSetId = p.getValue();
454 cluSetIds = (cluSetIds == null)? new ArrayList<String>(3) :
455 cluSetIds;
456 cluSetIds.add(cluSetId);
457 }
458 }
459 }
460 if (cluSetIds != null) {
461 cluSetInfo.setCluSetIds(cluSetIds);
462 }
463 cluSetInfo.setAdminOrg(cluSetHelper.getOrganization());
464 cluSetInfo.setDescr(toRichTextInfo(cluSetHelper.getDescription()));
465 cluSetInfo.setEffectiveDate(cluSetHelper.getEffectiveDate());
466 cluSetInfo.setExpirationDate(cluSetHelper.getExpirationDate());
467 cluSetInfo.setMembershipQuery(toMembershipQueryInfo(cluSetHelper.getCluRangeParams()));
468
469 cluSetInfo.setMetaInfo(toMetaInfo(cluSetHelper.getMetaInfo()));
470 cluSetInfo.setName(cluSetHelper.getName());
471 cluSetInfo.setState(cluSetHelper.getState());
472 if (cluSetInfo.getState() == null) {
473 cluSetInfo.setState("active");
474 }
475 cluSetInfo.setType(cluSetHelper.getType());
476 cluSetInfo.setIsReusable(cluSetHelper.getReusable());
477 cluSetInfo.setIsReferenceable(cluSetHelper.getReferenceable());
478 return cluSetInfo;
479 }
480
481 private MembershipQueryInfo toMembershipQueryInfo(CluSetRangeHelper cluSetRangeHelper) {
482 return CluSetRangeModelUtil.INSTANCE.toMembershipQueryInfo(cluSetRangeHelper.getData());
483 }
484
485 private RichTextInfo toRichTextInfo(String text) {
486 RichTextInfo result = new RichTextInfo();
487 if (text == null) return null;
488 result.setPlain(text);
489 result.setFormatted(text);
490 return result;
491 }
492
493 @Override
494 public Data assemble(Void input) throws AssemblyException {
495 throw new UnsupportedOperationException("Data assembly not supported");
496 }
497
498 @Override
499 public Void disassemble(Data input) throws AssemblyException {
500 throw new UnsupportedOperationException("Data disassembly not supported");
501 }
502
503 public LuService getLuService() {
504 return luService;
505 }
506
507 public void setLuService(LuService luService) {
508 this.luService = luService;
509 }
510
511 @Override
512 protected String getDataType() {
513 return CLUSET_DATA_TYPE;
514 }
515
516 @Override
517 public Metadata getDefaultMetadata() {
518
519 return metadataService.getMetadata(getDataType());
520 }
521
522 @Override
523 protected String getDocumentPropertyName() {
524 return "course";
525 }
526
527 @Override
528 protected String getDtoName() {
529 return "kuali.lu.type.CreditCourse";
530 }
531
532 @Override
533 protected AttributeSet getQualification(String idType, String id) {
534 String DOCUMENT_TYPE_NAME = "documentTypeName";
535 AttributeSet qualification = new AttributeSet();
536 qualification.put(DOCUMENT_TYPE_NAME, "CluCreditCourse");
537
538
539
540
541
542
543 qualification.put(idType, id);
544 return qualification;
545 }
546
547 }