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 }