001    /*
002     * Copyright 2011 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     */
016    package org.kuali.kfs.sys.batch;
017    
018    import java.util.Arrays;
019    import java.util.Collection;
020    import java.util.Date;
021    import java.util.HashSet;
022    import java.util.Properties;
023    import java.util.Set;
024    
025    import org.apache.commons.lang.StringUtils;
026    import org.kuali.kfs.sys.context.SpringContext;
027    import org.kuali.rice.kns.bo.PersistableBusinessObject;
028    import org.kuali.rice.kns.service.BusinessObjectService;
029    import org.kuali.rice.kns.service.PostDataLoadEncryptionService;
030    import org.springframework.core.io.FileSystemResource;
031    
032    public class PostDataLoadEncryptionStep extends AbstractStep {
033        private static org.apache.log4j.Logger LOG = org.apache.log4j.Logger.getLogger(PostDataLoadEncryptionStep.class);
034        private PostDataLoadEncryptionService postDataLoadEncryptionService;
035        private String attributesToEncryptProperties;
036    
037        /**
038         * @see org.kuali.kfs.sys.batch.Step#execute(java.lang.String, java.util.Date)
039         */
040        public boolean execute(String jobName, Date jobRunDate) {
041            Properties attributesToEncryptProperties = new Properties();
042            try {
043                attributesToEncryptProperties.load(new FileSystemResource(this.attributesToEncryptProperties).getInputStream());
044            }
045            catch (Exception e) {
046                throw new IllegalArgumentException("PostDataLoadEncrypter requires the full, absolute path to a properties file where the keys are the names of the BusinessObject classes that should be processed and the values are the list of attributes on each that require encryption", e);
047            }
048            for (Object businessObjectClassName : attributesToEncryptProperties.keySet()) {
049                Class businessObjectClass;
050                try {
051                    businessObjectClass = Class.forName((String) businessObjectClassName);
052                }
053                catch (Exception e) {
054                    throw new IllegalArgumentException(new StringBuffer("Unable to load Class ").append(businessObjectClassName).append(" specified by name in attributesToEncryptProperties file ").append(attributesToEncryptProperties).toString(), e);
055                }
056                Set<String> attributeNames = null;
057                try {
058                    attributeNames = new HashSet(Arrays.asList(StringUtils.split((String) attributesToEncryptProperties.get(businessObjectClassName), ",")));
059                }
060                catch (Exception e) {
061                    throw new IllegalArgumentException(new StringBuffer("Unable to load attributeNames Set from comma-delimited list of attribute names specified as value for property with Class name ").append(businessObjectClassName).append(" key in attributesToEncryptProperties file ").append(attributesToEncryptProperties).toString(), e);
062                }
063                postDataLoadEncryptionService.checkArguments(businessObjectClass, attributeNames);
064                postDataLoadEncryptionService.createBackupTable(businessObjectClass);
065                try {
066                    postDataLoadEncryptionService.prepClassDescriptor(businessObjectClass, attributeNames);
067                    Collection objectsToEncrypt = SpringContext.getBean(BusinessObjectService.class).findAll(businessObjectClass);
068                    for (Object businessObject : objectsToEncrypt) {
069                        postDataLoadEncryptionService.encrypt((PersistableBusinessObject) businessObject, attributeNames);
070                    }
071                    postDataLoadEncryptionService.restoreClassDescriptor(businessObjectClass, attributeNames);
072                    LOG.info(new StringBuffer("Encrypted ").append(attributesToEncryptProperties.get(businessObjectClassName)).append(" attributes of Class ").append(businessObjectClassName));
073                }
074                catch (Exception e) {
075                    postDataLoadEncryptionService.restoreTableFromBackup(businessObjectClass);
076                    LOG.error(new StringBuffer("Caught exception, while encrypting ").append(attributesToEncryptProperties.get(businessObjectClassName)).append(" attributes of Class ").append(businessObjectClassName).append(" and restored table from backup"), e);
077                }
078                postDataLoadEncryptionService.dropBackupTable(businessObjectClass);
079            }
080            return true;
081        }
082    
083        public void setPostDataLoadEncryptionService(PostDataLoadEncryptionService postDataLoadEncryptionService) {
084            this.postDataLoadEncryptionService = postDataLoadEncryptionService;
085        }
086    
087        /**
088         * Sets the attributesToEncryptProperties attribute value.
089         * 
090         * @param attributesToEncryptProperties The attributesToEncryptProperties to set.
091         */
092        public void setAttributesToEncryptProperties(String attributesToEncryptProperties) {
093            this.attributesToEncryptProperties = attributesToEncryptProperties;
094        }
095    }