View Javadoc
1   /*
2    * Copyright 2009 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.ole.sys.batch;
17  
18  import java.io.File;
19  import java.util.ArrayList;
20  import java.util.List;
21  
22  import org.apache.commons.lang.StringUtils;
23  import org.kuali.ole.sys.OLEConstants;
24  import org.kuali.ole.sys.context.SpringContext;
25  import org.kuali.rice.core.api.config.property.ConfigurationService;
26  import org.kuali.rice.core.api.util.KeyValue;
27  import org.kuali.rice.kns.service.DataDictionaryService;
28  import org.kuali.rice.krad.keyvalues.KeyValuesFinder;
29  
30  public class BatchFileUtils {
31      public static List<File> retrieveBatchFileLookupRootDirectories() {
32          ConfigurationService kualiConfigurationService = SpringContext.getBean(ConfigurationService.class);
33          List<File> directories = new ArrayList<File>();
34          String configProperty = kualiConfigurationService.getPropertyValueAsString(OLEConstants.BATCH_FILE_LOOKUP_ROOT_DIRECTORIES);
35  
36          String[] directoryNames = StringUtils.split(configProperty, ";");
37          for (String directoryName : directoryNames) {
38              File rootDirectory = new File(directoryName).getAbsoluteFile();
39              directories.add(rootDirectory);
40          }
41  
42          // sanity check: make sure directories are set up so that they will not present problems for pathRelativeToRootDirectory and
43          // resolvePathToAbsolutePath methods
44          for (int i = 0; i < directories.size(); i++) {
45              for (int j = i + 1; j < directories.size(); j++) {
46                  File directoryI = directories.get(i);
47                  File directoryJ = directories.get(j);
48  
49                  if (isPrefixOfAnother(directoryI.getAbsolutePath(), directoryJ.getAbsolutePath())) {
50                      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");
51                  }
52                  if (isPrefixOfAnother(directoryI.getName(), directoryJ.getName())) {
53                      throw new RuntimeException("Cannot have any two directories in config property batch.file.lookup.root.directories that have names that are prefix of another");
54                  }
55              }
56          }
57          return directories;
58      }
59  
60      private static boolean isPrefixOfAnother(String str1, String str2) {
61          return str1.startsWith(str2) || str2.startsWith(str1);
62      }
63  
64      /**
65       * returns a path relative to the appropriate lookup root directory, while including the name of the root directory for example,
66       * if the parameter is "c:\opt\staging\gl\somefile.txt" and the roots are "c:\opt\reports;c:\opt\staging", it will return
67       * "staging\gl\somefile.txt" (the system-specific path separator will be used). If there are multiple matching roots, then the
68       * first one to be matched will take precedence
69       * 
70       * @param absolutePath an absolute path for a file/directory
71       */
72      public static String pathRelativeToRootDirectory(String absolutePath) {
73          for (File rootDirectory : retrieveBatchFileLookupRootDirectories()) {
74              if (absolutePath.startsWith(rootDirectory.getAbsolutePath())) {
75                  return StringUtils.replaceOnce(absolutePath, rootDirectory.getAbsolutePath(), rootDirectory.getName());
76              }
77          }
78          throw new RuntimeException("Unable to find appropriate root directory)");
79      }
80  
81  
82      /**
83       * @param path a path string that was generated by {@link #pathRelativeToRootDirectory(String)}
84       * @return an absolute path, including the root directory
85       */
86      public static String resolvePathToAbsolutePath(String path) {
87          for (File rootDirectory : retrieveBatchFileLookupRootDirectories()) {
88              if (path.startsWith(rootDirectory.getName())) {
89                  return new File(StringUtils.replaceOnce(path, rootDirectory.getName(), rootDirectory.getAbsolutePath())).getAbsolutePath();
90              }
91          }
92          throw new RuntimeException("Cannot resolve to absolute path");
93      }
94  
95      public static boolean isDirectoryAccessible(String directory) {
96          List<String> pathNames = null;
97  
98          Class<? extends KeyValuesFinder> keyValuesFinderClass = SpringContext.getBean(DataDictionaryService.class).getAttributeValuesFinderClass(BatchFile.class, "path");
99          try {
100             if (keyValuesFinderClass != null) {
101                 KeyValuesFinder valuesGenerator = keyValuesFinderClass.newInstance();
102                 pathNames = new ArrayList<String>();
103 
104                 List<KeyValue> keyValues = valuesGenerator.getKeyValues();
105                 for (KeyValue keyValue : keyValues) {
106                     pathNames.add(new File(resolvePathToAbsolutePath((String) keyValue.getKey())).getAbsolutePath());
107                 }
108             }
109         }
110         catch (IllegalAccessException e) {
111             throw new RuntimeException("can't instiantiate class " + keyValuesFinderClass, e);
112         }
113         catch (InstantiationException e) {
114             throw new RuntimeException("can't instiantiate class " + keyValuesFinderClass, e);
115         }
116 
117         File directoryAbsolute = new File(directory).getAbsoluteFile();
118         String directoryAbsolutePath = directoryAbsolute.getAbsolutePath();
119         if (pathNames != null) {
120             if (!pathNames.contains(directoryAbsolutePath)) {
121                 return false;
122             }
123         }
124 
125         List<File> rootDirectories = retrieveBatchFileLookupRootDirectories();
126         for (File rootDirectory : rootDirectories) {
127             if (isSuperDirectoryOf(rootDirectory, directoryAbsolute)) {
128                 return true;
129             }
130         }
131         return false;
132     }
133 
134     public static boolean isSuperDirectoryOf(File superDirectory, File directory) {
135         superDirectory = superDirectory.getAbsoluteFile();
136 
137         while (directory != null) {
138             directory = directory.getAbsoluteFile();
139             if (directory.equals(superDirectory)) {
140                 return true;
141             }
142             directory = directory.getParentFile();
143         }
144         return false;
145     }
146 }