1 package org.kuali.student.common.ui.server.gwt;
2
3 import java.util.HashMap;
4 import java.util.LinkedHashMap;
5 import java.util.List;
6 import java.util.Map;
7 import java.util.UUID;
8
9 import java.net.URLDecoder;
10 import org.apache.commons.lang.StringUtils;
11 import org.apache.log4j.Logger;
12 import org.kuali.rice.kew.api.document.DocumentDetail;
13 import org.kuali.rice.kew.api.document.WorkflowDocumentService;
14 import org.kuali.rice.kim.api.permission.PermissionService;
15 import org.kuali.student.common.ui.client.service.DataSaveResult;
16 import org.kuali.student.common.ui.server.gwt.DataService;
17 import org.kuali.student.common.ui.shared.IdAttributes;
18 import org.kuali.student.common.util.security.SecurityUtils;
19 import org.kuali.student.core.assembly.transform.ProposalWorkflowFilter;
20 import org.kuali.student.r1.common.assembly.data.Data;
21 import org.kuali.student.r1.common.assembly.data.Metadata;
22 import org.kuali.student.r1.common.assembly.transform.AuthorizationFilter;
23 import org.kuali.student.r1.common.assembly.transform.MetadataFilter;
24 import org.kuali.student.r1.common.assembly.transform.TransformFilter;
25 import org.kuali.student.r1.common.assembly.transform.TransformFilter.TransformFilterAction;
26 import org.kuali.student.r1.common.assembly.transform.TransformationManager;
27 import org.kuali.student.r2.common.dto.DtoConstants;
28 import org.kuali.student.r1.common.rice.StudentIdentityConstants;
29 import org.kuali.student.r1.common.rice.authorization.PermissionType;
30 import org.kuali.student.r2.common.dto.ContextInfo;
31 import org.kuali.student.r2.common.dto.ValidationResultInfo;
32 import org.kuali.student.r2.common.exceptions.DataValidationErrorException;
33 import org.kuali.student.r2.common.exceptions.DoesNotExistException;
34 import org.kuali.student.r2.common.exceptions.OperationFailedException;
35 import org.kuali.student.r2.common.exceptions.VersionMismatchException;
36 import org.kuali.student.r1.core.proposal.dto.ProposalInfo;
37 import org.kuali.student.r1.core.proposal.service.ProposalService;
38 import org.springframework.transaction.annotation.Transactional;
39
40 @Transactional(readOnly=true,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
41 public abstract class AbstractDataService implements DataService{
42
43 private static final long serialVersionUID = 1L;
44
45 final Logger LOG = Logger.getLogger(AbstractDataService.class);
46
47 private TransformationManager transformationManager;
48
49 private PermissionService permissionService;
50
51
52 private ProposalService proposalService;
53
54 private WorkflowDocumentService workflowDocumentService;
55
56 @Override
57 public Data getData(String id, ContextInfo contextInfo) throws OperationFailedException {
58 Map<String, Object> filterProperties = getDefaultFilterProperties(contextInfo);
59 filterProperties.put(TransformFilter.FILTER_ACTION, TransformFilterAction.GET);
60 filterProperties.put(MetadataFilter.METADATA_ID_VALUE, id);
61
62 String dtoId = URLDecoder.decode(id);
63
64
65 try{
66 if (proposalService != null){
67 ProposalInfo proposalInfo = proposalService.getProposal(dtoId);
68 filterProperties.put(ProposalWorkflowFilter.PROPOSAL_INFO, proposalInfo);
69 dtoId = proposalInfo.getProposalReference().get(0);
70 }
71
72 Object dto = get(dtoId, contextInfo);
73 if (dto != null){
74 return transformationManager.transform(dto, getDtoClass().getName(), filterProperties);
75 }
76 } catch(DoesNotExistException e){
77 return null;
78 } catch (Exception e) {
79 LOG.error("Error getting data",e);
80 throw new OperationFailedException("Error getting data",e);
81 }
82 return null;
83 }
84
85 @Override
86 public Metadata getMetadata(String id, Map<String, String> attributes,ContextInfo contextInfo) {
87 Map<String, Object> filterProperties = getDefaultFilterProperties(contextInfo);
88 filterProperties.put(MetadataFilter.METADATA_ID_VALUE, id);
89
90
91 String idType = (attributes != null? attributes.get(IdAttributes.ID_TYPE):null);
92 String docType = (attributes != null ? attributes.get(StudentIdentityConstants.DOCUMENT_TYPE_NAME):null);
93 String dtoState = (attributes != null ? attributes.get(DtoConstants.DTO_STATE):null);
94 String dtoNextState = (attributes != null ? attributes.get(DtoConstants.DTO_NEXT_STATE):null);
95 String workflowNode = (attributes != null ? attributes.get(DtoConstants.DTO_WORKFLOW_NODE):null);
96
97 if (idType == null){
98 filterProperties.remove(MetadataFilter.METADATA_ID_TYPE);
99 } else {
100 filterProperties.put(MetadataFilter.METADATA_ID_TYPE, idType);
101 }
102
103 if (docType == null){
104 filterProperties.put(ProposalWorkflowFilter.WORKFLOW_DOC_TYPE, getDefaultWorkflowDocumentType());
105 } else {
106 filterProperties.put(ProposalWorkflowFilter.WORKFLOW_DOC_TYPE, docType);
107 }
108
109 if (dtoState != null){
110 filterProperties.put(DtoConstants.DTO_STATE, dtoState);
111 }
112
113 if (dtoNextState != null){
114 filterProperties.put(DtoConstants.DTO_NEXT_STATE, dtoNextState);
115 }
116
117 if (workflowNode != null){
118 filterProperties.put(DtoConstants.DTO_WORKFLOW_NODE, workflowNode);
119 }
120
121 if (checkDocumentLevelPermissions()){
122 filterProperties.put(AuthorizationFilter.DOC_LEVEL_PERM_CHECK, Boolean.TRUE.toString());
123 }
124
125 Metadata metadata = transformationManager.getMetadata(getDtoClass().getName(), filterProperties);
126 return metadata;
127 }
128
129 @Override
130 @Transactional(readOnly=false,noRollbackFor={DoesNotExistException.class},rollbackFor={Throwable.class})
131 public DataSaveResult saveData(Data data, ContextInfo contextInfo) throws OperationFailedException, DataValidationErrorException, VersionMismatchException{
132 Map<String, Object> filterProperties = getDefaultFilterProperties(contextInfo);
133 filterProperties.put(TransformFilter.FILTER_ACTION, TransformFilterAction.SAVE);
134
135 DataSaveResult saveResult = new DataSaveResult();
136 try {
137
138 Object dto = transformationManager.transform(data, getDtoClass(), filterProperties);
139
140
141
142
143 dto = save(dto, filterProperties, contextInfo);
144
145
146 List<ValidationResultInfo> validationResults = validate(dto, contextInfo);
147
148
149 Data persistedData = transformationManager.transform(dto, getDtoClass().getName(), filterProperties);
150
151 saveResult.setValue(persistedData);
152 saveResult.setValidationResults(validationResults);
153 }catch (DataValidationErrorException dvee){
154
155 throw dvee;
156 }catch (OperationFailedException ofe){
157 throw ofe;
158 }catch (VersionMismatchException vme){
159 throw vme;
160 }catch (Exception e) {
161 LOG.error("Failed to save data",e);
162 throw new OperationFailedException("Failed to save data",e);
163 }
164
165 return saveResult;
166 }
167
168
169
170 @Override
171 public List<ValidationResultInfo> validateData(Data data, ContextInfo contextInfo) throws OperationFailedException {
172 List<ValidationResultInfo> validationResults;
173
174 try {
175 Metadata metadata = transformationManager.getUnfilteredMetadata(getDtoClass().getName());
176 Object dto = null;
177 dto = transformationManager.getMapper().convertFromData(data, getDtoClass(), metadata);
178 validationResults = validate(dto, contextInfo);
179 } catch (Exception e) {
180 throw new OperationFailedException("Unable to validate data", e);
181 }
182
183 return validationResults;
184 }
185
186 @Override
187 public Boolean isAuthorized(PermissionType type, Map<String,String> attributes, ContextInfo contextInfo) {
188 String user = SecurityUtils.getCurrentUserId();
189 boolean result = false;
190 if (checkDocumentLevelPermissions()) {
191 if (type == null) {
192 return null;
193 }
194 String namespaceCode = type.getPermissionNamespace();
195 String permissionTemplateName = type.getPermissionTemplateName();
196
197 Map<String,String> roleQuals = new LinkedHashMap<String,String>();
198 if (attributes != null) {
199
200
201
202 if (proposalService != null){
203 ProposalInfo proposalInfo = null;
204 try {
205
206 if (attributes.containsKey(IdAttributes.IdType.KS_KEW_OBJECT_ID.toString())){
207 proposalInfo = proposalService.getProposal(attributes.get(IdAttributes.IdType.KS_KEW_OBJECT_ID.toString()));
208 } else if (attributes.containsKey(IdAttributes.IdType.DOCUMENT_ID.toString())){
209 proposalInfo = proposalService.getProposalByWorkflowId(attributes.get(IdAttributes.IdType.DOCUMENT_ID.toString()));
210 }
211
212
213 DocumentDetail docDetail = getWorkflowDocumentService().getDocumentDetail(proposalInfo.getWorkflowId());
214 String docStatusCode = getWorkflowDocumentService().getDocumentStatus(proposalInfo.getWorkflowId()).getCode();
215
216
217 if (proposalInfo != null){
218 attributes.put(IdAttributes.IdType.KS_KEW_OBJECT_ID.toString(), proposalInfo.getId());
219 attributes.put(StudentIdentityConstants.QUALIFICATION_DATA_ID, proposalInfo.getId());
220 attributes.put(IdAttributes.IdType.DOCUMENT_ID.toString(), proposalInfo.getWorkflowId());
221 attributes.put(StudentIdentityConstants.DOCUMENT_TYPE_NAME, proposalInfo.getType());
222 attributes.put(StudentIdentityConstants.ROUTE_STATUS_CODE, docStatusCode);
223
224
225 addAdditionalAttributes(attributes,proposalInfo,docDetail);
226 }
227 } catch (Exception e){
228 LOG.error("Could not retrieve proposal to determine permission qualifiers:" + e.toString());
229 }
230 }
231
232
233
234 attributes.put("RAND_NO_CACHE", UUID.randomUUID().toString());
235 roleQuals.putAll(attributes);
236 }
237 if (StringUtils.isNotBlank(namespaceCode) && StringUtils.isNotBlank(permissionTemplateName)) {
238 LOG.info("Checking Permission '" + namespaceCode + "/" + permissionTemplateName + "' for user '" + user + "'");
239 result = getPermissionService().isAuthorizedByTemplate(user, namespaceCode, permissionTemplateName, new LinkedHashMap<String,String>(), roleQuals);
240 }
241 else {
242 LOG.info("Can not check Permission with namespace '" + namespaceCode + "' and template name '" + permissionTemplateName + "' for user '" + user + "'");
243 return Boolean.TRUE;
244 }
245 }
246 else {
247 LOG.info("Will not check for document level permissions. Defaulting authorization to true.");
248 result = true;
249 }
250 LOG.info("Result of authorization check for user '" + user + "': " + result);
251 return Boolean.valueOf(result);
252 }
253
254 protected void addAdditionalAttributes(Map<String, String> attributes,
255 ProposalInfo proposalInfo, DocumentDetail docDetail) {
256 return;
257 }
258
259 public Map<String, Object> getDefaultFilterProperties(ContextInfo contextInfo){
260 Map<String, Object> filterProperties = new HashMap<String,Object>();
261 filterProperties.put(MetadataFilter.METADATA_ID_TYPE, StudentIdentityConstants.QUALIFICATION_KEW_OBJECT_ID);
262 filterProperties.put(ProposalWorkflowFilter.WORKFLOW_USER, SecurityUtils.getCurrentUserId());
263
264 return filterProperties;
265 }
266
267 protected DataSaveResult _saveData(Data data, Map<String, Object> filterProperties, ContextInfo contextInfo) throws OperationFailedException{
268 try {
269 filterProperties.put(MetadataFilter.METADATA_ID_VALUE, (String)data.query("id"));
270
271 Object dto = transformationManager.transform(data, getDtoClass(),filterProperties);
272 dto = save(dto, filterProperties, contextInfo);
273
274 Data persistedData = transformationManager.transform(dto,getDtoClass().getName(), filterProperties);
275 return new DataSaveResult(null, persistedData);
276 } catch (DataValidationErrorException dvee){
277 return new DataSaveResult(dvee.getValidationResults(), null);
278 } catch (Exception e) {
279 LOG.error("Unable to save", e);
280 throw new OperationFailedException("Unable to save");
281 }
282 }
283
284 protected boolean checkDocumentLevelPermissions() {
285 return false;
286 }
287
288
289
290 public TransformationManager getTransformationManager() {
291 return transformationManager;
292 }
293
294 public void setTransformationManager(TransformationManager transformationManager) {
295 this.transformationManager = transformationManager;
296 }
297
298 public PermissionService getPermissionService() {
299 return permissionService;
300 }
301
302 public void setPermissionService(PermissionService permissionService) {
303 this.permissionService = permissionService;
304 }
305
306 public ProposalService getProposalService() {
307 return proposalService;
308 }
309
310 public void setProposalService(ProposalService proposalService) {
311 this.proposalService = proposalService;
312 }
313
314 public WorkflowDocumentService getWorkflowDocumentService() {
315 return workflowDocumentService;
316 }
317
318 public void setWorkflowDocumentService(WorkflowDocumentService workflowDocumentService) {
319 this.workflowDocumentService = workflowDocumentService;
320 }
321
322 protected abstract String getDefaultWorkflowDocumentType();
323
324 protected abstract String getDefaultMetaDataState();
325
326
327
328
329
330
331
332
333
334
335 protected abstract Object get(String id, ContextInfo contextInfo) throws Exception;
336
337
338
339
340
341
342
343
344
345
346 protected abstract Object save(Object dto, Map<String, Object> properties, ContextInfo contextInfo) throws Exception;
347
348
349
350
351
352
353
354
355
356 protected abstract List<ValidationResultInfo> validate(Object dto, ContextInfo contextInfo) throws Exception;
357
358
359
360
361
362
363 protected abstract Class<?> getDtoClass();
364
365 }