zookeeper-cpp
ZooKeeper Client for C++
 All Classes Files Functions Variables Typedefs Enumerations Enumerator Friends Groups
classpath.cpp
1 #include "classpath.hpp"
2 
3 #include <zk/string_view.hpp>
4 
5 #include <algorithm>
6 #include <array>
7 #include <cerrno>
8 #include <cstdio>
9 #include <ostream>
10 #include <sstream>
11 #include <system_error>
12 
13 #include <sys/types.h>
14 #include <sys/stat.h>
15 #include <unistd.h>
16 
17 namespace zk::server
18 {
19 
20 template <typename TContainer, typename TSep>
21 void join(std::ostream& os, const TContainer& src, TSep sep)
22 {
23  bool first = true;
24  for (const auto& x : src)
25  {
26  if (!std::exchange(first, false))
27  os << sep;
28  os << x;
29  }
30 }
31 
32 static bool file_exists(ptr<const char> path)
33 {
34  struct ::stat s;
35  if (::stat(path, &s))
36  {
37  if (errno == ENOENT)
38  return false;
39  else
40  throw std::system_error(errno, std::system_category());
41  }
42  else
43  {
44  return true;
45  }
46 }
47 
48 static classpath find_system_default()
49 {
50  string_view locations[] =
51  {
52  "/usr/share/java",
53  "/usr/local/share/java",
54  };
55  string_view requirements[] =
56  {
57  "zookeeper.jar",
58  "slf4j-api.jar",
59  "slf4j-simple.jar",
60  };
61 
62  std::vector<std::string> components;
63  std::vector<string_view> unfound;
64  for (auto jar : requirements)
65  {
66  bool found = false;
67  for (auto base_loc : locations)
68  {
69  auto potential_sz = base_loc.size() + jar.size() + 4;
70  char potential[potential_sz];
71  std::snprintf(potential, potential_sz, "%s/%s", base_loc.data(), jar.data());
72 
73  if (file_exists(potential))
74  {
75  found = true;
76  components.emplace_back(std::string(potential));
77  break;
78  }
79  }
80 
81  if (!found)
82  unfound.emplace_back(jar);
83  }
84 
85  if (unfound.empty())
86  {
87  return classpath(std::move(components));
88  }
89  else
90  {
91  std::ostringstream os;
92  os << "Could not find requirement" << ((unfound.size() == 1U) ? "" : "s") << ": ";
93  join(os, unfound, ", ");
94  os << ". Searched paths: ";
95  join(os, locations, ", ");
96  throw std::runtime_error(os.str());
97  }
98 
99 }
100 
102 {
103  static const auto instance = find_system_default();
104  return instance;
105 }
106 
107 classpath::classpath(std::vector<std::string> components) noexcept :
108  _components(std::move(components))
109 { }
110 
111 std::string classpath::command_line() const
112 {
113  std::ostringstream os;
114  os << *this;
115  return os.str();
116 }
117 
118 std::ostream& operator<<(std::ostream& os, const classpath& self)
119 {
120  join(os, self._components, ':');
121  return os;
122 }
123 
124 }
Represents a collection of JARs or other Java entities that should be provided as the --classpath to ...
Definition: classpath.hpp:18
Imports the string_view type as std::string_view.
classpath(std::vector< std::string > components) noexcept
Create a classpath specification from the provided components.
Definition: classpath.cpp:107
std::string command_line() const
Get the command-line representation of this classpath. This puts ':' characters between the component...
Definition: classpath.cpp:111
static classpath system_default()
Load the system-default classpath for ZooKeeper.
Definition: classpath.cpp:101