1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  package org.kuali.student.lum.kim;
20  
21  import java.util.ArrayList;
22  import java.util.HashMap;
23  import java.util.HashSet;
24  import java.util.Iterator;
25  import java.util.List;
26  import java.util.Map;
27  import java.util.Set;
28  
29  import javax.xml.namespace.QName;
30  
31  import org.apache.commons.lang.StringUtils;
32  import org.apache.log4j.Logger;
33  import org.kuali.rice.core.resourceloader.GlobalResourceLoader;
34  import org.kuali.rice.kew.dto.DocumentDetailDTO;
35  import org.kuali.rice.kew.dto.DocumentTypeDTO;
36  import org.kuali.rice.kew.service.KEWServiceLocator;
37  import org.kuali.rice.kew.service.WorkflowUtility;
38  import org.kuali.rice.kim.bo.impl.KimAttributes;
39  import org.kuali.rice.kim.bo.types.dto.AttributeSet;
40  import org.kuali.rice.kim.service.support.impl.KimTypeAttributeValidationException;
41  import org.kuali.student.common.rice.StudentIdentityConstants;
42  import org.kuali.student.core.proposal.dto.ProposalInfo;
43  import org.kuali.student.core.proposal.service.ProposalService;
44  
45  
46  
47  
48  
49  public class KimQualificationHelper {
50      protected static final Logger LOG = Logger.getLogger(KimQualificationHelper.class);
51  
52  	private static UniqueMap translationMap = new UniqueMap();
53  
54  	{
55  	    
56  	    
57  	}
58  
59  	protected static WorkflowUtility getWorkflowUtility() {
60  		return KEWServiceLocator.getWorkflowUtilityService();
61  	}
62  
63      public static void validateRequiredAttributesAgainstReceived(Set<List<String>> requiredAttributes, AttributeSet receivedAttributes, boolean checkRequiredAttributes, String commaSeparatorString) {
64  		
65  		if ( !checkRequiredAttributes ) {
66  			return;
67  		}
68  		
69  		if ( requiredAttributes == null || requiredAttributes.isEmpty() ) {
70  			return;
71  		}
72  		
73  		if ( receivedAttributes == null || receivedAttributes.isEmpty() ) {
74  			return;		
75  		}
76  		
77  		Set<List<String>> totalMissingAttributes = new HashSet<List<String>>();
78  		for (List<String> currentReqAttributes : requiredAttributes) {
79  			List<String> missingAttributes = new ArrayList<String>();
80  			for( String requiredAttribute : currentReqAttributes ) {
81  				if( !receivedAttributes.containsKey(requiredAttribute) ) {
82  					missingAttributes.add(requiredAttribute);
83  				}
84  			}
85  			if (missingAttributes.isEmpty()) {
86  				
87  				return;
88  			}
89  			totalMissingAttributes.add(missingAttributes);
90          }
91  
92  		int i = 1;
93      	StringBuffer errorMessage = new StringBuffer("Missing Required Attributes from lists - ");
94      	for (List<String> missingAttributes : totalMissingAttributes) {
95              if(missingAttributes.size()>0) {
96              	errorMessage.append("List " + i + ": (");
97              	i++;
98              	Iterator<String> attribIter = missingAttributes.iterator();
99              	while ( attribIter.hasNext() ) {
100             		errorMessage.append( attribIter.next() );
101             		if( attribIter.hasNext() ) {
102             			errorMessage.append( commaSeparatorString );
103             		}
104             	}
105             	errorMessage.append(")");
106             }
107         }
108 		LOG.info("Found missing attributes: " + errorMessage.toString());
109         throw new KimTypeAttributeValidationException(errorMessage.toString());
110     }
111 
112     protected static String getProposalId(AttributeSet qualification) {
113         for (String proposalReferenceType : StudentIdentityConstants.QUALIFICATION_PROPOSAL_ID_REF_TYPES) {
114             if (qualification.containsKey(proposalReferenceType)) {
115                 return qualification.get(proposalReferenceType);
116             }
117         }
118         return null;
119     }
120 
121     public static AttributeSet translateInputAttributeSet(AttributeSet qualification) {
122 		try {
123 			DocumentDetailDTO docDetail = null;
124 			
125 			String documentNumber = qualification.get(KimAttributes.DOCUMENT_NUMBER);
126 			String proposalId = getProposalId(qualification);
127 			if (StringUtils.isBlank(documentNumber)) {
128 			    
129 	            if (StringUtils.isNotBlank(proposalId)) {
130 	                ProposalInfo propInfo = getProposalService().getProposal(proposalId);
131 	                documentNumber = propInfo.getWorkflowId();
132 	            }
133 			}
134 			if (StringUtils.isNotBlank(documentNumber)) {
135 				
136 				docDetail = getWorkflowUtility().getDocumentDetail(Long.valueOf(documentNumber));
137 			}
138 			else {
139 				
140 				String appId = qualification.get( StudentIdentityConstants.QUALIFICATION_KEW_OBJECT_ID );
141 				if (StringUtils.isNotBlank(appId)) {
142 					String documentTypeName = qualification.get( KimAttributes.DOCUMENT_TYPE_NAME );
143 					if (StringUtils.isBlank(documentTypeName)) {
144 						
145 						String ksObjectType = qualification.get( StudentIdentityConstants.QUALIFICATION_KEW_OBJECT_TYPE );
146 						if (StringUtils.isNotBlank(ksObjectType)) {
147 							documentTypeName = translationMap.get(ksObjectType);
148 						}
149 					}
150 					
151 					if (StringUtils.isNotBlank(documentTypeName)) {
152 						
153 						docDetail = getWorkflowUtility().getDocumentDetailFromAppId(documentTypeName, appId);
154 					}
155 					else {
156 						
157 						LOG.warn("Could not find valid document type name or KS object type using qualifications: " + qualification);
158 					}
159 				}
160 				else {
161 					
162 					LOG.warn("Could not find valid document id or application id using qualifications: " + qualification);
163 				}
164 			}
165 			translateQualifications(docDetail, proposalId, qualification);
166 		    return qualification;
167 	    }
168 		catch (Exception e) {
169             LOG.error(e.getLocalizedMessage(), e);
170             throw new RuntimeException(e);
171 		}
172 	}
173 
174 	protected static void translateQualifications(DocumentDetailDTO docDetail, String proposalId, AttributeSet qualifications) {
175 		if (docDetail != null) {
176 			
177 			if (!qualifications.containsKey(KimAttributes.DOCUMENT_NUMBER)) {
178 				qualifications.put(KimAttributes.DOCUMENT_NUMBER, docDetail.getRouteHeaderId().toString());
179 			}
180 			
181 			if (!qualifications.containsKey(StudentIdentityConstants.QUALIFICATION_KS_PROPOSAL_ID) && StringUtils.isNotBlank(proposalId)) {
182 			    qualifications.put(StudentIdentityConstants.QUALIFICATION_KS_PROPOSAL_ID, proposalId);
183 			}
184 			
185 			if (!qualifications.containsKey(StudentIdentityConstants.QUALIFICATION_KEW_OBJECT_ID)) {
186 				qualifications.put(StudentIdentityConstants.QUALIFICATION_KEW_OBJECT_ID, docDetail.getAppDocId());
187 			}
188 			DocumentTypeDTO docType = KEWServiceLocator.getDocumentTypeService().getDocumentTypeVO(docDetail.getDocTypeId());
189 			if (docType != null) {
190 				String documentTypeName = docType.getName();
191 				
192 				if (!qualifications.containsKey(KimAttributes.DOCUMENT_TYPE_NAME)) {
193 					qualifications.put(KimAttributes.DOCUMENT_TYPE_NAME, documentTypeName);
194 				}
195 				
196 				if (!qualifications.containsKey(StudentIdentityConstants.QUALIFICATION_KEW_OBJECT_TYPE)) {
197 					qualifications.put(StudentIdentityConstants.QUALIFICATION_KEW_OBJECT_TYPE, translationMap.getKeyForValue(documentTypeName));
198 				}
199 			}
200 			else {
201 				String errorMsg = "Could not find valid KEW document type for document id " + docDetail.getRouteHeaderId(); 
202 				LOG.error(errorMsg);
203 				throw new RuntimeException(errorMsg);
204 			}
205 		}
206 		else {
207 			LOG.warn("Could not find KEW document instance for qualifications: " + qualifications);
208 			
209 			if ((!qualifications.containsKey(StudentIdentityConstants.QUALIFICATION_KEW_OBJECT_TYPE)) && 
210 					qualifications.containsKey(KimAttributes.DOCUMENT_TYPE_NAME)) {
211 				qualifications.put(StudentIdentityConstants.QUALIFICATION_KEW_OBJECT_TYPE, translationMap.getKeyForValue(qualifications.get(KimAttributes.DOCUMENT_TYPE_NAME)));
212 			}
213 			else if ((!qualifications.containsKey(KimAttributes.DOCUMENT_TYPE_NAME)) && 
214 					qualifications.containsKey(StudentIdentityConstants.QUALIFICATION_KEW_OBJECT_TYPE)) {
215 				qualifications.put(KimAttributes.DOCUMENT_TYPE_NAME, translationMap.get(qualifications.get(StudentIdentityConstants.QUALIFICATION_KEW_OBJECT_TYPE)));
216 			}
217 		}
218 	}
219 
220     protected static ProposalService getProposalService() {
221         return (ProposalService) GlobalResourceLoader.getService(new QName("http://student.kuali.org/wsdl/proposal","ProposalService"));
222     }
223 
224 	private static class UniqueMap extends HashMap<String,String> {
225 
226         private static final long serialVersionUID = 1L;
227 
228 		@Override
229         public String put(String key, String value) {
230 			if (this.containsValue(value)) {
231 				throw new UnsupportedOperationException("Map already contains an entry with value: " + value);
232 			}
233 	        return super.put(key, value);
234         }
235 
236 		public String getKeyForValue(String value) {
237 			for (Map.Entry<String, String> mapEntry : this.entrySet()) {
238 	            if (StringUtils.equals(value, mapEntry.getValue())) {
239 	            	return mapEntry.getKey();
240 	            }
241             }
242 			return null;
243 		}
244 	}
245 
246 }