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.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  //  TODO Split out CluInfo assembly to its own class
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  // FIXME: should have it's own proposal types
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"; // <- what the service says, but the dictionary says: "kuali.referenceType.CLU";
65  //    public static final String CREDIT_COURSE_PROPOSAL_DATA_TYPE = "CreditCourseProposal";
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  //                resultData = new Data();
92  //                resultData.set("cluset", resultCluSetHelper.getData());
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         // note: the cluIds returned by luService.getCluSetInfo also contains the clus
106         //       that are the result of query parameter search.  Set to null here and
107         //       retrieve the clus that are direct members.
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         // goes through the list of sub clusets and ignore the ones that are not reusable
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         // if more than one type
234         if (numCluSetElementTypes > 1) {
235             if (hasCluIds) {
236                 CluSetInfo wrapperCluSet = new CluSetInfo();
237                 setWrapperCluSetInfoValues(wrapperCluSet, cluSetInfo);
238                 // copy the clus into the wrapper CluSet
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                 // copy the MembershipQuery into the wrapper CluSet
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 //        CluSetHelper cluSetHelper = new CluSetHelper((Data)input.get("cluset"));
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 //            resultData = new Data();
338 //            resultData.set("cluset", resultCluSetHelper.getData());
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         // TODO Auto-generated method stub
519         return metadataService.getMetadata(getDataType());
520     }
521 
522     @Override
523 	protected String getDocumentPropertyName() {
524         return "course";							//FIXME
525 	}
526 
527 	@Override
528 	protected String getDtoName() {
529         return "kuali.lu.type.CreditCourse";		//FIXME
530 	}
531 
532 	@Override
533 	protected AttributeSet getQualification(String idType, String id) {   //FIXME
534 		String DOCUMENT_TYPE_NAME = "documentTypeName";
535 		AttributeSet qualification = new AttributeSet();
536 		qualification.put(DOCUMENT_TYPE_NAME, "CluCreditCourse");
537 		/*
538 		 *	This commented out for permission changes
539 		 *
540 		 *         String QUALIFICATION_PROPOSAL_ID = "courseId";
541 		 *         qualification.put(QUALIFICATION_PROPOSAL_ID, id);
542 		 */
543 		qualification.put(idType, id);
544 		return qualification;
545 	}
546 
547 }