001/**
002 * Copyright 2005-2015 The Kuali Foundation
003 *
004 * Licensed under the Educational Community License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 * http://www.opensource.org/licenses/ecl2.php
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 */
016package org.kuali.rice.krad.devtools.pdle;
017
018import org.apache.commons.beanutils.PropertyUtils;
019import org.apache.log4j.Logger;
020import org.apache.ojb.broker.accesslayer.conversions.FieldConversionDefaultImpl;
021import org.apache.ojb.broker.metadata.ClassDescriptor;
022import org.kuali.rice.core.api.encryption.EncryptionService;
023import org.kuali.rice.core.framework.persistence.ojb.conversion.OjbKualiEncryptDecryptFieldConversion;
024import org.kuali.rice.krad.bo.PersistableBusinessObject;
025import org.kuali.rice.krad.exception.ClassNotPersistableException;
026import org.kuali.rice.krad.service.LegacyDataAdapter;
027import org.kuali.rice.krad.service.impl.PersistenceServiceImplBase;
028
029import java.util.Set;
030
031import java.util.ArrayList;
032import java.util.HashMap;
033import java.util.List;
034import java.util.Map;
035
036@Deprecated
037public class PostDataLoadEncryptionServiceImpl extends PersistenceServiceImplBase implements PostDataLoadEncryptionService {
038    protected Logger LOG = Logger.getLogger(PostDataLoadEncryptionServiceImpl.class);
039
040    private LegacyDataAdapter legacyDataAdapter;
041    private EncryptionService encryptionService;
042    private PostDataLoadEncryptionDao postDataLoadEncryptionDao;
043
044    @Override
045    public void checkArguments(Class<? extends PersistableBusinessObject> businessObjectClass, Set<String> attributeNames) {
046        checkArguments(businessObjectClass, attributeNames, true);
047    }
048
049    @Override
050    public void checkArguments(Class<? extends PersistableBusinessObject> businessObjectClass, Set<String> attributeNames, boolean checkOjbEncryptConfig) {
051        if ((businessObjectClass == null) || (attributeNames == null)) {
052            throw new IllegalArgumentException(
053                    "PostDataLoadEncryptionServiceImpl.encrypt does not allow a null business object Class or attributeNames Set");
054        }
055        final ClassDescriptor classDescriptor;
056        try {
057            classDescriptor = getClassDescriptor(businessObjectClass);
058        } catch (ClassNotPersistableException e) {
059            throw new IllegalArgumentException(
060                    "PostDataLoadEncryptionServiceImpl.encrypt does not handle business object classes that do not have a corresponding ClassDescriptor defined in the OJB repository",
061                    e);
062        }
063        for (String attributeName : attributeNames) {
064            if (classDescriptor.getFieldDescriptorByName(attributeName) == null) {
065                throw new IllegalArgumentException(
066                        new StringBuffer("Attribute ")
067                                .append(attributeName)
068                                .append(
069                                        " specified to PostDataLoadEncryptionServiceImpl.encrypt is not in the OJB repository ClassDescriptor for Class ")
070                                .append(businessObjectClass).toString());
071            }
072            if (checkOjbEncryptConfig && !(classDescriptor.getFieldDescriptorByName(attributeName).getFieldConversion() instanceof OjbKualiEncryptDecryptFieldConversion)) {
073                throw new IllegalArgumentException(
074                        new StringBuffer("Attribute ")
075                                .append(attributeName)
076                                .append(" of business object Class ")
077                                .append(businessObjectClass)
078                                .append(
079                                        " specified to PostDataLoadEncryptionServiceImpl.encrypt is not configured for encryption in the OJB repository")
080                                .toString());
081            }
082        }
083    }
084
085    @Override
086    public void createBackupTable(Class<? extends PersistableBusinessObject> businessObjectClass) {
087        postDataLoadEncryptionDao.createBackupTable(getClassDescriptor(businessObjectClass).getFullTableName());
088    }
089
090    @Override
091    public void prepClassDescriptor(Class<? extends PersistableBusinessObject> businessObjectClass, Set<String> attributeNames) {
092        ClassDescriptor classDescriptor = getClassDescriptor(businessObjectClass);
093        for (String attributeName : attributeNames) {
094            classDescriptor.getFieldDescriptorByName(attributeName).setFieldConversionClassName(
095                    FieldConversionDefaultImpl.class.getName());
096        }
097    }
098
099    @Override
100    public void truncateTable(Class<? extends PersistableBusinessObject> businessObjectClass) {
101        postDataLoadEncryptionDao.truncateTable(getClassDescriptor(businessObjectClass).getFullTableName());
102    }
103
104    @Override
105    public void encrypt(PersistableBusinessObject businessObject, Set<String> attributeNames) {
106        for (String attributeName : attributeNames) {
107            try {
108                PropertyUtils.setProperty(businessObject, attributeName, encryptionService.encrypt(PropertyUtils
109                        .getProperty(businessObject, attributeName)));
110            } catch (Exception e) {
111                throw new RuntimeException(new StringBuffer(
112                        "PostDataLoadEncryptionServiceImpl caught exception while attempting to encrypt attribute ").append(
113                        attributeName).append(" of Class ").append(businessObject.getClass()).toString(), e);
114            }
115        }
116        legacyDataAdapter.save(businessObject);
117    }
118
119    @Override
120    public void restoreClassDescriptor(Class<? extends PersistableBusinessObject> businessObjectClass, Set<String> attributeNames) {
121        ClassDescriptor classDescriptor = getClassDescriptor(businessObjectClass);
122        for (String attributeName : attributeNames) {
123            classDescriptor.getFieldDescriptorByName(attributeName).setFieldConversionClassName(
124                    OjbKualiEncryptDecryptFieldConversion.class.getName());
125        }
126        legacyDataAdapter.findAll(businessObjectClass);
127    }
128
129    @Override
130    public void restoreTableFromBackup(Class<? extends PersistableBusinessObject> businessObjectClass) {
131        postDataLoadEncryptionDao.restoreTableFromBackup(getClassDescriptor(businessObjectClass).getFullTableName());
132    }
133
134    @Override
135    public void dropBackupTable(Class<? extends PersistableBusinessObject> businessObjectClass) {
136        postDataLoadEncryptionDao.dropBackupTable(getClassDescriptor(businessObjectClass).getFullTableName());
137    }
138
139    @Override
140    public boolean doesBackupTableExist(String tableName){
141        return postDataLoadEncryptionDao.doesBackupTableExist(tableName);
142    }
143    
144    @Override
145    public void createBackupTable(String tableName) {
146        postDataLoadEncryptionDao.createBackupTable(tableName);
147        postDataLoadEncryptionDao.addEncryptionIndicatorToBackupTable(tableName);
148    }
149    
150    @Override
151    public void truncateTable(String tableName) {
152        postDataLoadEncryptionDao.truncateTable(tableName);
153    }
154
155    @Override
156    public List<Map<String, String>> retrieveUnencryptedColumnValuesFromBackupTable(String tableName, final List<String> columnNames, int numberOfRowsToCommitAfter) {
157        return postDataLoadEncryptionDao.retrieveUnencryptedColumnValuesFromBackupTable(tableName, columnNames, numberOfRowsToCommitAfter);
158    }
159
160    @Override
161    public boolean performEncryption(final String tableName, final List<Map<String, String>> rowsToEncryptColumnsNameValueMap) throws Exception {
162        List<Map<String, List<String>>> rowsToEncryptColumnNameOldNewValuesMap = new ArrayList<Map<String, List<String>>>();
163        for(Map<String, String> columnsNameValueMap: rowsToEncryptColumnsNameValueMap){
164            rowsToEncryptColumnNameOldNewValuesMap.add(getColumnNamesEncryptedValues(tableName, columnsNameValueMap));
165        }
166        return postDataLoadEncryptionDao.performEncryption(tableName, rowsToEncryptColumnNameOldNewValuesMap); 
167    }
168
169    public Map<String, List<String>> getColumnNamesEncryptedValues(String tableName, final Map<String, String> columnNamesValues) {
170        List<String> oldNewValues = new ArrayList<String>();
171        String columnOldValue;
172        Map<String, List<String>> columnNameOldNewValuesMap = new HashMap<String, List<String>>();
173        for (String columnName: columnNamesValues.keySet()) {
174            try {
175                oldNewValues = new ArrayList<String>();
176                columnOldValue = columnNamesValues.get(columnName);
177                //List chosen over a java object (for old and new value) for better performance
178                oldNewValues.add(PostDataLoadEncryptionDao.UNENCRYPTED_VALUE_INDEX, columnOldValue);
179                oldNewValues.add(PostDataLoadEncryptionDao.ENCRYPTED_VALUE_INDEX, encryptionService.encrypt(columnOldValue));
180                columnNameOldNewValuesMap.put(columnName, oldNewValues);
181            } catch (Exception e) {
182                throw new RuntimeException(new StringBuffer(
183                "PostDataLoadEncryptionServiceImpl caught exception while attempting to encrypt Column ").append(
184                columnName).append(" of Table ").append(tableName).toString(), e);
185            }
186        }
187        return columnNameOldNewValuesMap;
188    }
189
190    @Override
191    public void restoreTableFromBackup(String tableName) {
192        postDataLoadEncryptionDao.dropEncryptionIndicatorFromBackupTable(tableName);
193        postDataLoadEncryptionDao.restoreTableFromBackup(tableName);
194    }
195
196    @Override
197    public void dropBackupTable(String tableName) {
198        postDataLoadEncryptionDao.dropBackupTable(tableName);
199    }    
200
201    public void setPostDataLoadEncryptionDao(PostDataLoadEncryptionDao postDataLoadEncryptionDao) {
202        this.postDataLoadEncryptionDao = postDataLoadEncryptionDao;
203    }
204
205    public void setEncryptionService(EncryptionService encryptionService) {
206        this.encryptionService = encryptionService;
207    }
208
209    public void setLegacyDataAdapter(LegacyDataAdapter legacyDataAdapter) {
210        this.legacyDataAdapter = legacyDataAdapter;
211    }
212}