Medical Imaging Interaction Toolkit  2018.4.99-389bf124
Medical Imaging Interaction Toolkit
mitkStandardFileLocations.cpp
Go to the documentation of this file.
1 /*============================================================================
2 
3 The Medical Imaging Interaction Toolkit (MITK)
4 
5 Copyright (c) German Cancer Research Center (DKFZ)
6 All rights reserved.
7 
8 Use of this source code is governed by a 3-clause BSD license that can be
9 found in the LICENSE file.
10 
11 ============================================================================*/
12 
14 
15 #include <itkMacro.h>
16 #include <itkObject.h>
17 #include <itksys/SystemTools.hxx>
18 #include <mitkConfig.h>
19 
20 #include <algorithm>
21 
23 {
24 }
25 
27 {
28 }
29 
31 {
32  static StandardFileLocations::Pointer m_Instance = nullptr;
33 
34  if (m_Instance.IsNull())
35  m_Instance = StandardFileLocations::New();
36  return m_Instance;
37 }
38 
39 void mitk::StandardFileLocations::AddDirectoryForSearch(const char *dir, bool insertInFrontOfSearchList)
40 {
41  // Do nothing if directory is already included into search list (TODO more clever: search only once!)
42  FileSearchVectorType::iterator iter;
43  if (m_SearchDirectories.size() > 0)
44  {
45  iter = std::find(m_SearchDirectories.begin(), m_SearchDirectories.end(), std::string(dir));
46  if (iter != m_SearchDirectories.end())
47  return;
48  }
49  // insert dir into queue
50  if (insertInFrontOfSearchList)
51  {
52  auto it = m_SearchDirectories.begin();
53  m_SearchDirectories.insert(it, std::string(dir));
54  }
55  else
56  m_SearchDirectories.push_back(std::string(dir));
57 }
58 
60 {
61  FileSearchVectorType::iterator it;
62  // background layers
63  if (m_SearchDirectories.size() > 0)
64  {
65  it = std::find(m_SearchDirectories.begin(), m_SearchDirectories.end(), std::string(dir));
66  if (it != m_SearchDirectories.end())
67  {
68  m_SearchDirectories.erase(it);
69  return;
70  }
71  }
72 }
73 
75 {
76  FileSearchVectorType::iterator it;
77 
78  for (it = m_SearchDirectories.begin(); it != m_SearchDirectories.end(); ++it)
79  {
80  std::string currDir = (*it);
81 
82  // Perhaps append "/" before appending filename
83  if (currDir.find_last_of("\\") + 1 != currDir.size() || currDir.find_last_of("/") + 1 != currDir.size())
84  currDir += "/";
85 
86  // Append filename
87  currDir += filename;
88 
89  // Perhaps remove "/" after filename
90  if (currDir.find_last_of("\\") + 1 == currDir.size() || currDir.find_last_of("/") + 1 == currDir.size())
91  currDir.erase(currDir.size() - 1, currDir.size());
92 
93  // convert to OS dependent path schema
94  currDir = itksys::SystemTools::ConvertToOutputPath(currDir.c_str());
95 
96  // On windows systems, the ConvertToOutputPath method quotes pathes that contain empty spaces.
97  // These quotes are not expected by the FileExists method and therefore removed, if existing.
98  if (currDir.find_last_of("\"") + 1 == currDir.size())
99  currDir.erase(currDir.size() - 1, currDir.size());
100  if (currDir.find_last_of("\"") == 0)
101  currDir.erase(0, 1);
102 
103  // Return first found path
104  if (itksys::SystemTools::FileExists(currDir.c_str()))
105  return currDir;
106  }
107  return std::string("");
108 }
109 
110 std::string mitk::StandardFileLocations::FindFile(const char *filename, const char *pathInSourceDir)
111 {
112  std::string directoryPath;
113 
114  // 1. look for MITKCONF environment variable
115  const char *mitkConf = itksys::SystemTools::GetEnv("MITKCONF");
116  if (mitkConf != nullptr)
117  AddDirectoryForSearch(mitkConf, false);
118 
119 // 2. use .mitk-subdirectory in home directory of the user
120 #if defined(_WIN32) && !defined(__CYGWIN__)
121  const char *homeDrive = itksys::SystemTools::GetEnv("HOMEDRIVE");
122  const char *homePath = itksys::SystemTools::GetEnv("HOMEPATH");
123 
124  if ((homeDrive != nullptr) || (homePath != nullptr))
125  {
126  directoryPath = homeDrive;
127  directoryPath += homePath;
128  directoryPath += "/.mitk/";
129  AddDirectoryForSearch(directoryPath.c_str(), false);
130  }
131 
132 #else
133  const char *homeDirectory = itksys::SystemTools::GetEnv("HOME");
134  if (homeDirectory != nullptr)
135  {
136  directoryPath = homeDirectory;
137  directoryPath += "/.mitk/";
138  AddDirectoryForSearch(directoryPath.c_str(), false);
139  }
140 
141 #endif // defined(_WIN32) && !defined(__CYGWIN__)
142 
143  // 3. look in the current working directory
144  directoryPath = "";
145  AddDirectoryForSearch(directoryPath.c_str());
146 
147  directoryPath = itksys::SystemTools::GetCurrentWorkingDirectory();
148  AddDirectoryForSearch(directoryPath.c_str(), false);
149 
150  std::string directoryBinPath = directoryPath + "/bin";
151  AddDirectoryForSearch(directoryBinPath.c_str(), false);
152  // 4. use a source tree location from compile time
153  directoryPath = MITK_ROOT;
154  if (pathInSourceDir)
155  {
156  directoryPath += pathInSourceDir;
157  }
158  directoryPath += '/';
159  AddDirectoryForSearch(directoryPath.c_str(), false);
160 
161  return SearchDirectoriesForFile(filename);
162 }
163 
165 {
166  const char *mitkoptions = itksys::SystemTools::GetEnv("MITKOPTIONS");
167  std::string optionsDirectory;
168 
169  if (mitkoptions != nullptr)
170  {
171  // 1. look for MITKOPTIONS environment variable
172  optionsDirectory = mitkoptions;
173  optionsDirectory += "/";
174  }
175  else
176  {
177  // 2. use .mitk-subdirectory in home directory of the user
178  std::string homeDirectory;
179 #if defined(_WIN32) && !defined(__CYGWIN__)
180  const char *homeDrive = itksys::SystemTools::GetEnv("HOMEDRIVE");
181  const char *homePath = itksys::SystemTools::GetEnv("HOMEPATH");
182  if ((homeDrive == nullptr) || (homePath == nullptr))
183  {
184  itkGenericOutputMacro(<< "Environment variables HOMEDRIVE and/or HOMEPATH not set"
185  << ". Using current working directory as home directory: "
186  << itksys::SystemTools::GetCurrentWorkingDirectory());
187  homeDirectory = itksys::SystemTools::GetCurrentWorkingDirectory();
188  }
189  else
190  {
191  homeDirectory = homeDrive;
192  homeDirectory += homePath;
193  }
194  if (itksys::SystemTools::FileExists(homeDirectory.c_str()) == false)
195  {
196  itkGenericOutputMacro(<< "Could not find home directory at " << homeDirectory
197  << ". Using current working directory as home directory: "
198  << itksys::SystemTools::GetCurrentWorkingDirectory());
199  homeDirectory = itksys::SystemTools::GetCurrentWorkingDirectory();
200  }
201 #else
202  const char *home = itksys::SystemTools::GetEnv("HOME");
203  if (home == nullptr)
204  {
205  itkGenericOutputMacro(<< "Environment variable HOME not set"
206  << ". Using current working directory as home directory: "
207  << itksys::SystemTools::GetCurrentWorkingDirectory());
208  homeDirectory = itksys::SystemTools::GetCurrentWorkingDirectory();
209  }
210  else
211  homeDirectory = home;
212  if (itksys::SystemTools::FileExists(homeDirectory.c_str()) == false)
213  {
214  itkGenericOutputMacro(<< "Could not find home directory at " << homeDirectory
215  << ". Using current working directory as home directory: "
216  << itksys::SystemTools::GetCurrentWorkingDirectory());
217  homeDirectory = itksys::SystemTools::GetCurrentWorkingDirectory();
218  }
219 #endif // defined(_WIN32) && !defined(__CYGWIN__)
220 
221  optionsDirectory = homeDirectory;
222  optionsDirectory += "/.mitk";
223  }
224 
225  optionsDirectory = itksys::SystemTools::ConvertToOutputPath(optionsDirectory.c_str());
226  if (itksys::SystemTools::CountChar(optionsDirectory.c_str(), '"') > 0)
227  {
228  char *unquoted = itksys::SystemTools::RemoveChars(optionsDirectory.c_str(), "\"");
229  optionsDirectory = unquoted;
230  delete[] unquoted;
231  }
232 
233  if (itksys::SystemTools::MakeDirectory(optionsDirectory.c_str()) == false)
234  {
235  itkGenericExceptionMacro(<< "Could not create .mitk directory at " << optionsDirectory);
236  }
237  return optionsDirectory;
238 }
FileSearchVectorType m_SearchDirectories
void RemoveDirectoryForSearch(const char *dir)
Remove a directory from the search queue: \ Use this function in combination with FindFile()...
std::string GetOptionDirectory()
Return directory of/for option files.
void AddDirectoryForSearch(const char *dir, bool insertInFrontOfSearchList=true)
Adds a directory into the search queue: \ Use this function in combination with FindFile(), after adding some \ directories, they will also be searched for the requested file.
#define MITK_ROOT
Definition: mitkConfig.h:9
std::string FindFile(const char *filename, const char *pathInSourceDir=nullptr)
looks for a file in several standard locations
static StandardFileLocations * GetInstance()
std::string SearchDirectoriesForFile(const char *filename)
Provides a method to look for configuration and option files etc.