source: launchers/macosx/JavaHelper.h @ 281c5f57

Last change on this file since 281c5f57 was 281c5f57, checked in by meeh <meeh@…>, 21 months ago

Bugfixes, improvements, more error handling and stability to the osx launcher.

  • Property mode set to 100644
File size: 4.5 KB
Line 
1#pragma once
2
3#ifdef __cplusplus
4
5#include <memory.h>
6#include <string.h>
7#include <stdlib.h>
8
9#include <Foundation/Foundation.h>
10#include <CoreFoundation/CoreFoundation.h>
11#include <CoreFoundation/CFStream.h>
12#include <CoreFoundation/CFPropertyList.h>
13#include <CoreFoundation/CFDictionary.h>
14#include <CoreFoundation/CFArray.h>
15#include <CoreFoundation/CFString.h>
16
17#include "RouterTask.h"
18
19
20#define DEF_MIN_JVM_VER "1.7+"
21
22#include "include/strutil.hpp"
23
24#include <functional>
25#include <memory>
26#include <list>
27
28
29class JvmVersion
30{
31public:
32  std::string JVMName;
33  std::string JVMHomePath;
34  std::string JVMPlatformVersion;
35
36  inline const char * ToCString()
37  {
38    std::stringstream ss;
39    ss << "JvmVersion(name=" << JVMName.c_str() << ",version=";
40    ss << JVMPlatformVersion.c_str() << ",home=" << JVMHomePath.c_str() << ")";
41    std::string s = ss.str();
42    return s.c_str();
43  }
44
45  inline bool HasContent()
46  {
47    return (
48      std::strlen(JVMName.c_str()) > 0 &&
49      std::strlen(JVMHomePath.c_str()) > 0 &&
50      std::strlen(JVMPlatformVersion.c_str()) > 0
51    );
52  }
53};
54
55
56typedef std::shared_ptr<JvmVersion> JvmVersionPtr;
57typedef std::shared_ptr<std::list<JvmVersionPtr> > JvmListPtr;
58typedef std::shared_ptr<std::list<std::shared_ptr<JvmVersion> > > JvmListSharedPtr;
59typedef void(^MenuBarControllerActionBlock)(BOOL active);
60
61extern JvmListSharedPtr gRawJvmList;
62
63class JvmHomeContext : public std::enable_shared_from_this<JvmHomeContext>
64{
65public:
66
67  inline void setJvm(JvmVersionPtr* current)
68  {
69    mCurrent = *current;
70  }
71
72  inline JvmListPtr getJvmList()
73  {
74    return gRawJvmList;
75  }
76
77  inline std::shared_ptr<JvmHomeContext> getContext()
78  {
79    return shared_from_this();
80  }
81
82  inline std::string getJavaHome()
83  {
84    if (mCurrent)
85    {
86      return mCurrent->JVMHomePath;
87    }
88    return gRawJvmList->back()->JVMHomePath;
89  }
90private:
91  JvmVersionPtr mCurrent;
92};
93
94static void processJvmEntry (const void* key, const void* value, void* context) {
95  //CFShow(key);
96  //CFShow(value);
97
98  // The reason for using strprintf is to "force" a copy of the values,
99  // since local variables gets deleted once this function returns.
100  auto currentJvm = reinterpret_cast<JvmVersion*>(context);
101  if (CFEqual((CFStringRef)key,CFSTR("JVMName"))) {
102    auto strVal = extractString((CFStringRef)value);
103    currentJvm->JVMName = strprintf("%s",strVal.c_str());
104  }
105  if (CFEqual((CFStringRef)key,CFSTR("JVMHomePath"))) {
106    auto strVal = extractString((CFStringRef)value);
107    currentJvm->JVMHomePath = strprintf("%s",strVal.c_str());
108  }
109  if (CFEqual((CFStringRef)key,CFSTR("JVMPlatformVersion"))) {
110    auto strVal = extractString((CFStringRef)value);
111    currentJvm->JVMPlatformVersion = strprintf("%s",strVal.c_str());
112  }
113}
114
115
116
117static void processJvmPlistEntries (const void* item, void* context) {
118  CFDictionaryRef dict = CFDictionaryCreateCopy(kCFAllocatorDefault, (CFDictionaryRef)item);
119
120  JvmVersionPtr currentJvmPtr = std::shared_ptr<JvmVersion>(new JvmVersion());
121  struct CFunctional
122  {
123    static void applier(const void* key, const void* value, void* context){
124      // The reason for using strprintf is to "force" a copy of the values,
125      // since local variables gets deleted once this function returns.
126      auto currentJvm = static_cast<JvmVersion*>(context);
127      if (CFEqual((CFStringRef)key,CFSTR("JVMName"))) {
128        auto d = extractString((CFStringRef)value);
129        currentJvm->JVMName = trim_copy(d);
130      }
131      if (CFEqual((CFStringRef)key,CFSTR("JVMHomePath"))) {
132        auto d = extractString((CFStringRef)value);
133        currentJvm->JVMHomePath = trim_copy(d);
134      }
135      if (CFEqual((CFStringRef)key,CFSTR("JVMPlatformVersion"))) {
136        auto d = extractString((CFStringRef)value);
137        currentJvm->JVMPlatformVersion = trim_copy(d);
138      }
139
140    }
141  };
142
143  CFDictionaryApplyFunction(dict, CFunctional::applier, (void*)currentJvmPtr.get());
144
145  if (currentJvmPtr->HasContent())
146  {
147    printf("Found JVM: %s\n\n", currentJvmPtr->ToCString());
148    gRawJvmList->push_back(currentJvmPtr);
149  }
150}
151
152static void listAllJavaInstallsAvailable()
153{
154  auto javaHomeRes = check_output({"/usr/libexec/java_home","-v",DEF_MIN_JVM_VER,"-X"});
155  CFDataRef javaHomes = CFDataCreate(NULL, (const UInt8 *)javaHomeRes.buf.data(), strlen(javaHomeRes.buf.data()));
156
157  CFPropertyListRef propertyList = CFPropertyListCreateWithData(kCFAllocatorDefault, javaHomes, kCFPropertyListImmutable, NULL, NULL);
158
159
160
161  auto jCount = CFArrayGetCount((CFArrayRef)propertyList);
162
163  CFArrayApplyFunction((CFArrayRef)propertyList, CFRangeMake(0, jCount), processJvmPlistEntries, NULL);
164  //CFShow(propertyList);
165}
166
167#endif
Note: See TracBrowser for help on using the repository browser.