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.io.File; 019 import java.security.GeneralSecurityException; 020 import java.util.ArrayList; 021 import java.util.HashMap; 022 import java.util.List; 023 024 import org.apache.commons.lang.StringUtils; 025 import org.kuali.kfs.sys.KFSConstants; 026 import org.kuali.kfs.sys.context.SpringContext; 027 import org.kuali.rice.core.service.EncryptionService; 028 import org.kuali.rice.kns.lookup.keyvalues.KeyValuesFinder; 029 import org.kuali.rice.kns.service.DataDictionaryService; 030 import org.kuali.rice.kns.service.KualiConfigurationService; 031 import org.kuali.rice.core.util.KeyLabelPair; 032 033 public class BatchFileUtils { 034 public static List<File> retrieveBatchFileLookupRootDirectories() { 035 KualiConfigurationService kualiConfigurationService = SpringContext.getBean(KualiConfigurationService.class); 036 List<File> directories = new ArrayList<File>(); 037 String configProperty = kualiConfigurationService.getPropertyString(KFSConstants.BATCH_FILE_LOOKUP_ROOT_DIRECTORIES); 038 039 String[] directoryNames = StringUtils.split(configProperty, ";"); 040 for (String directoryName : directoryNames) { 041 File rootDirectory = new File(directoryName).getAbsoluteFile(); 042 directories.add(rootDirectory); 043 } 044 045 // sanity check: make sure directories are set up so that they will not present problems for pathRelativeToRootDirectory and 046 // resolvePathToAbsolutePath methods 047 for (int i = 0; i < directories.size(); i++) { 048 for (int j = i + 1; j < directories.size(); j++) { 049 File directoryI = directories.get(i); 050 File directoryJ = directories.get(j); 051 052 if (isPrefixOfAnother(directoryI.getAbsolutePath(), directoryJ.getAbsolutePath())) { 053 throw new RuntimeException("Cannot have any two directories in config property batch.file.lookup.root.directories that have absolute paths that are prefix of another"); 054 } 055 if (isPrefixOfAnother(directoryI.getName(), directoryJ.getName())) { 056 throw new RuntimeException("Cannot have any two directories in config property batch.file.lookup.root.directories that have names that are prefix of another"); 057 } 058 } 059 } 060 return directories; 061 } 062 063 private static boolean isPrefixOfAnother(String str1, String str2) { 064 return str1.startsWith(str2) || str2.startsWith(str1); 065 } 066 067 /** 068 * returns a path relative to the appropriate lookup root directory, while including the name of the root directory for example, 069 * if the parameter is "c:\opt\staging\gl\somefile.txt" and the roots are "c:\opt\reports;c:\opt\staging", it will return 070 * "staging\gl\somefile.txt" (the system-specific path separator will be used). If there are multiple matching roots, then the 071 * first one to be matched will take precedence 072 * 073 * @param absolutePath an absolute path for a file/directory 074 */ 075 public static String pathRelativeToRootDirectory(String absolutePath) { 076 for (File rootDirectory : retrieveBatchFileLookupRootDirectories()) { 077 if (absolutePath.startsWith(rootDirectory.getAbsolutePath())) { 078 return StringUtils.replaceOnce(absolutePath, rootDirectory.getAbsolutePath(), rootDirectory.getName()); 079 } 080 } 081 throw new RuntimeException("Unable to find appropriate root directory)"); 082 } 083 084 085 /** 086 * @param path a path string that was generated by {@link #pathRelativeToRootDirectory(String)} 087 * @return an absolute path, including the root directory 088 */ 089 public static String resolvePathToAbsolutePath(String path) { 090 for (File rootDirectory : retrieveBatchFileLookupRootDirectories()) { 091 if (path.startsWith(rootDirectory.getName())) { 092 return new File(StringUtils.replaceOnce(path, rootDirectory.getName(), rootDirectory.getAbsolutePath())).getAbsolutePath(); 093 } 094 } 095 throw new RuntimeException("Cannot resolve to absolute path"); 096 } 097 098 public static boolean isDirectoryAccessible(String directory) { 099 List<String> pathNames = null; 100 101 Class<? extends KeyValuesFinder> keyValuesFinderClass = SpringContext.getBean(DataDictionaryService.class).getAttributeValuesFinderClass(BatchFile.class, "path"); 102 try { 103 if (keyValuesFinderClass != null) { 104 KeyValuesFinder valuesGenerator = keyValuesFinderClass.newInstance(); 105 pathNames = new ArrayList<String>(); 106 107 List<KeyLabelPair> keyValues = valuesGenerator.getKeyValues(); 108 for (KeyLabelPair keyValue : keyValues) { 109 pathNames.add(new File(resolvePathToAbsolutePath((String) keyValue.getKey())).getAbsolutePath()); 110 } 111 } 112 } 113 catch (IllegalAccessException e) { 114 throw new RuntimeException("can't instiantiate class " + keyValuesFinderClass, e); 115 } 116 catch (InstantiationException e) { 117 throw new RuntimeException("can't instiantiate class " + keyValuesFinderClass, e); 118 } 119 120 File directoryAbsolute = new File(directory).getAbsoluteFile(); 121 String directoryAbsolutePath = directoryAbsolute.getAbsolutePath(); 122 if (pathNames != null) { 123 if (!pathNames.contains(directoryAbsolutePath)) { 124 return false; 125 } 126 } 127 128 List<File> rootDirectories = retrieveBatchFileLookupRootDirectories(); 129 for (File rootDirectory : rootDirectories) { 130 if (isSuperDirectoryOf(rootDirectory, directoryAbsolute)) { 131 return true; 132 } 133 } 134 return false; 135 } 136 137 public static boolean isSuperDirectoryOf(File superDirectory, File directory) { 138 superDirectory = superDirectory.getAbsoluteFile(); 139 140 while (directory != null) { 141 directory = directory.getAbsoluteFile(); 142 if (directory.equals(superDirectory)) { 143 return true; 144 } 145 directory = directory.getParentFile(); 146 } 147 return false; 148 } 149 }