View Javadoc

1   /**
2    * Copyright 2005-2012 The Kuali Foundation
3    *
4    * Licensed under the Educational Community License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    *
8    * http://www.opensource.org/licenses/ecl2.php
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.kuali.rice.devtools.pdle;
17  
18  import org.apache.commons.beanutils.PropertyUtils;
19  import org.apache.log4j.Logger;
20  import org.apache.ojb.broker.accesslayer.conversions.FieldConversionDefaultImpl;
21  import org.apache.ojb.broker.metadata.ClassDescriptor;
22  import org.kuali.rice.core.api.encryption.EncryptionService;
23  import org.kuali.rice.core.framework.persistence.ojb.conversion.OjbKualiEncryptDecryptFieldConversion;
24  import org.kuali.rice.krad.bo.PersistableBusinessObject;
25  import org.kuali.rice.krad.exception.ClassNotPersistableException;
26  import org.kuali.rice.krad.service.BusinessObjectService;
27  import org.kuali.rice.krad.service.impl.PersistenceServiceImplBase;
28  
29  import java.util.Collections;
30  import java.util.Set;
31  
32  import java.util.ArrayList;
33  import java.util.HashMap;
34  import java.util.List;
35  import java.util.Map;
36  import java.util.Set;
37  
38  public class PostDataLoadEncryptionServiceImpl extends PersistenceServiceImplBase implements PostDataLoadEncryptionService {
39      protected Logger LOG = Logger.getLogger(PostDataLoadEncryptionServiceImpl.class);
40  
41      private BusinessObjectService businessObjectService;
42      private EncryptionService encryptionService;
43      private PostDataLoadEncryptionDao postDataLoadEncryptionDao;
44  
45      @Override
46      public void checkArguments(Class<? extends PersistableBusinessObject> businessObjectClass, Set<String> attributeNames) {
47      	checkArguments(businessObjectClass, attributeNames, true);
48      }
49  
50      @Override
51      public void checkArguments(Class<? extends PersistableBusinessObject> businessObjectClass, Set<String> attributeNames, boolean checkOjbEncryptConfig) {
52  	if ((businessObjectClass == null) || (attributeNames == null)) {
53  	    throw new IllegalArgumentException(
54  		    "PostDataLoadEncryptionServiceImpl.encrypt does not allow a null business object Class or attributeNames Set");
55  	}
56  	final ClassDescriptor classDescriptor;
57  	try {
58  	    classDescriptor = getClassDescriptor(businessObjectClass);
59  	} catch (ClassNotPersistableException e) {
60  	    throw new IllegalArgumentException(
61  		    "PostDataLoadEncryptionServiceImpl.encrypt does not handle business object classes that do not have a corresponding ClassDescriptor defined in the OJB repository",
62  		    e);
63  	}
64  	for (String attributeName : attributeNames) {
65  	    if (classDescriptor.getFieldDescriptorByName(attributeName) == null) {
66  		throw new IllegalArgumentException(
67  			new StringBuffer("Attribute ")
68  				.append(attributeName)
69  				.append(
70  					" specified to PostDataLoadEncryptionServiceImpl.encrypt is not in the OJB repository ClassDescriptor for Class ")
71  				.append(businessObjectClass).toString());
72  	    }
73  	    if (checkOjbEncryptConfig && !(classDescriptor.getFieldDescriptorByName(attributeName).getFieldConversion() instanceof OjbKualiEncryptDecryptFieldConversion)) {
74  		throw new IllegalArgumentException(
75  			new StringBuffer("Attribute ")
76  				.append(attributeName)
77  				.append(" of business object Class ")
78  				.append(businessObjectClass)
79  				.append(
80  					" specified to PostDataLoadEncryptionServiceImpl.encrypt is not configured for encryption in the OJB repository")
81  				.toString());
82  	    }
83  	}
84      }
85  
86      @Override
87      public void createBackupTable(Class<? extends PersistableBusinessObject> businessObjectClass) {
88  	postDataLoadEncryptionDao.createBackupTable(getClassDescriptor(businessObjectClass).getFullTableName());
89      }
90  
91      @Override
92      public void prepClassDescriptor(Class<? extends PersistableBusinessObject> businessObjectClass, Set<String> attributeNames) {
93  	ClassDescriptor classDescriptor = getClassDescriptor(businessObjectClass);
94  	for (String attributeName : attributeNames) {
95  	    classDescriptor.getFieldDescriptorByName(attributeName).setFieldConversionClassName(
96  		    FieldConversionDefaultImpl.class.getName());
97  	}
98      }
99  
100     @Override
101     public void truncateTable(Class<? extends PersistableBusinessObject> businessObjectClass) {
102 	postDataLoadEncryptionDao.truncateTable(getClassDescriptor(businessObjectClass).getFullTableName());
103     }
104 
105     @Override
106     public void encrypt(PersistableBusinessObject businessObject, Set<String> attributeNames) {
107 	for (String attributeName : attributeNames) {
108 	    try {
109 		PropertyUtils.setProperty(businessObject, attributeName, encryptionService.encrypt(PropertyUtils
110 			.getProperty(businessObject, attributeName)));
111 	    } catch (Exception e) {
112 		throw new RuntimeException(new StringBuffer(
113 			"PostDataLoadEncryptionServiceImpl caught exception while attempting to encrypt attribute ").append(
114 			attributeName).append(" of Class ").append(businessObject.getClass()).toString(), e);
115 	    }
116 	}
117 	businessObjectService.save(businessObject);
118     }
119 
120     @Override
121     public void restoreClassDescriptor(Class<? extends PersistableBusinessObject> businessObjectClass, Set<String> attributeNames) {
122 	ClassDescriptor classDescriptor = getClassDescriptor(businessObjectClass);
123 	for (String attributeName : attributeNames) {
124 	    classDescriptor.getFieldDescriptorByName(attributeName).setFieldConversionClassName(
125 		    OjbKualiEncryptDecryptFieldConversion.class.getName());
126 	}
127 	businessObjectService.countMatching(businessObjectClass, Collections.<String, Object>emptyMap());
128     }
129 
130     @Override
131     public void restoreTableFromBackup(Class<? extends PersistableBusinessObject> businessObjectClass) {
132 	postDataLoadEncryptionDao.restoreTableFromBackup(getClassDescriptor(businessObjectClass).getFullTableName());
133     }
134 
135     @Override
136     public void dropBackupTable(Class<? extends PersistableBusinessObject> businessObjectClass) {
137 	postDataLoadEncryptionDao.dropBackupTable(getClassDescriptor(businessObjectClass).getFullTableName());
138     }
139 
140     @Override
141     public boolean doesBackupTableExist(String tableName){
142         return postDataLoadEncryptionDao.doesBackupTableExist(tableName);
143     }
144     
145     @Override
146     public void createBackupTable(String tableName) {
147         postDataLoadEncryptionDao.createBackupTable(tableName);
148         postDataLoadEncryptionDao.addEncryptionIndicatorToBackupTable(tableName);
149     }
150     
151     @Override
152     public void truncateTable(String tableName) {
153         postDataLoadEncryptionDao.truncateTable(tableName);
154     }
155 
156     @Override
157     public List<Map<String, String>> retrieveUnencryptedColumnValuesFromBackupTable(String tableName, final List<String> columnNames, int numberOfRowsToCommitAfter) {
158         return postDataLoadEncryptionDao.retrieveUnencryptedColumnValuesFromBackupTable(tableName, columnNames, numberOfRowsToCommitAfter);
159     }
160 
161     @Override
162     public boolean performEncryption(final String tableName, final List<Map<String, String>> rowsToEncryptColumnsNameValueMap) throws Exception {
163         List<Map<String, List<String>>> rowsToEncryptColumnNameOldNewValuesMap = new ArrayList<Map<String, List<String>>>();
164         for(Map<String, String> columnsNameValueMap: rowsToEncryptColumnsNameValueMap){
165             rowsToEncryptColumnNameOldNewValuesMap.add(getColumnNamesEncryptedValues(tableName, columnsNameValueMap));
166         }
167         return postDataLoadEncryptionDao.performEncryption(tableName, rowsToEncryptColumnNameOldNewValuesMap); 
168     }
169 
170     public Map<String, List<String>> getColumnNamesEncryptedValues(String tableName, final Map<String, String> columnNamesValues) {
171         List<String> oldNewValues = new ArrayList<String>();
172         String columnOldValue;
173         Map<String, List<String>> columnNameOldNewValuesMap = new HashMap<String, List<String>>();
174         for (String columnName: columnNamesValues.keySet()) {
175             try {
176                 oldNewValues = new ArrayList<String>();
177                 columnOldValue = columnNamesValues.get(columnName);
178                 //List chosen over a java object (for old and new value) for better performance
179                 oldNewValues.add(PostDataLoadEncryptionDao.UNENCRYPTED_VALUE_INDEX, columnOldValue);
180                 oldNewValues.add(PostDataLoadEncryptionDao.ENCRYPTED_VALUE_INDEX, encryptionService.encrypt(columnOldValue));
181                 columnNameOldNewValuesMap.put(columnName, oldNewValues);
182             } catch (Exception e) {
183                 throw new RuntimeException(new StringBuffer(
184                 "PostDataLoadEncryptionServiceImpl caught exception while attempting to encrypt Column ").append(
185                 columnName).append(" of Table ").append(tableName).toString(), e);
186             }
187         }
188         return columnNameOldNewValuesMap;
189     }
190 
191     @Override
192     public void restoreTableFromBackup(String tableName) {
193         postDataLoadEncryptionDao.dropEncryptionIndicatorFromBackupTable(tableName);
194         postDataLoadEncryptionDao.restoreTableFromBackup(tableName);
195     }
196 
197     @Override
198     public void dropBackupTable(String tableName) {
199         postDataLoadEncryptionDao.dropBackupTable(tableName);
200     }    
201 
202     public void setPostDataLoadEncryptionDao(PostDataLoadEncryptionDao postDataLoadEncryptionDao) {
203 	this.postDataLoadEncryptionDao = postDataLoadEncryptionDao;
204     }
205 
206     public void setEncryptionService(EncryptionService encryptionService) {
207 	this.encryptionService = encryptionService;
208     }
209 
210     public void setBusinessObjectService(BusinessObjectService businessObjectService) {
211 	this.businessObjectService = businessObjectService;
212     }
213 }