source: launchers/macosx/obj-cpp/JavaHelper.h @ 0b01cc5

Last change on this file since 0b01cc5 was 0b01cc5, checked in by meeh <meeh@…>, 3 years ago

Adding codebase for the Objective-C++ part of the Mac OS X launcher/wrapper.

  • Property mode set to 100644
File size: 5.2 KB
Line 
1#pragma once
2
3#include <functional>
4#include <memory>
5#include <iostream>
6#include <algorithm>
7#include <cstring>
8#include <sstream>
9#include <list>
10#include <experimental/optional>
11#include <stdlib.h>
12
13#include <Foundation/Foundation.h>
14#include <CoreFoundation/CoreFoundation.h>
15#include <CoreFoundation/CFStream.h>
16#include <CoreFoundation/CFPropertyList.h>
17#include <CoreFoundation/CFDictionary.h>
18#include <CoreFoundation/CFArray.h>
19#include <CoreFoundation/CFString.h>
20
21#include "strutil.hpp"
22#include "subprocess.hpp"
23
24using namespace subprocess;
25
26
27#define DEF_MIN_JVM_VER "1.7+"
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
55typedef std::shared_ptr<JvmVersion> JvmVersionPtr;
56typedef std::shared_ptr<std::list<JvmVersionPtr> > JvmListPtr;
57typedef std::shared_ptr<std::list<std::shared_ptr<JvmVersion> > > JvmListSharedPtr;
58typedef void(^MenuBarControllerActionBlock)(BOOL active);
59
60extern JvmListSharedPtr gRawJvmList;
61
62class JvmHomeContext : public std::enable_shared_from_this<JvmHomeContext>
63{
64public:
65
66  inline void setJvm(JvmVersionPtr* current)
67  {
68    mCurrent = *current;
69  }
70
71  inline JvmListPtr getJvmList()
72  {
73    return gRawJvmList;
74  }
75
76  inline std::shared_ptr<JvmHomeContext> getContext()
77  {
78    return shared_from_this();
79  }
80
81  inline std::string getJavaHome()
82  {
83    if (mCurrent)
84    {
85      return mCurrent->JVMHomePath;
86    }
87    return gRawJvmList->back()->JVMHomePath;
88  }
89private:
90  JvmVersionPtr mCurrent;
91};
92
93static void processJvmEntry (const void* key, const void* value, void* context) {
94  //CFShow(key);
95  //CFShow(value);
96
97  // The reason for using strprintf is to "force" a copy of the values,
98  // since local variables gets deleted once this function returns.
99  auto currentJvm = reinterpret_cast<JvmVersion*>(context);
100  if (CFEqual((CFStringRef)key,CFSTR("JVMName"))) {
101    auto strVal = extractString((CFStringRef)value);
102    currentJvm->JVMName = strprintf("%s",strVal.c_str());
103  }
104  if (CFEqual((CFStringRef)key,CFSTR("JVMHomePath"))) {
105    auto strVal = extractString((CFStringRef)value);
106    currentJvm->JVMHomePath = strprintf("%s",strVal.c_str());
107  }
108  if (CFEqual((CFStringRef)key,CFSTR("JVMPlatformVersion"))) {
109    auto strVal = extractString((CFStringRef)value);
110    currentJvm->JVMPlatformVersion = strprintf("%s",strVal.c_str());
111  }
112}
113
114static void processJvmPlistEntries (const void* item, void* context) {
115  CFDictionaryRef dict = CFDictionaryCreateCopy(kCFAllocatorDefault, (CFDictionaryRef)item);
116
117  JvmVersionPtr currentJvmPtr = std::shared_ptr<JvmVersion>(new JvmVersion());
118  struct CFunctional
119  {
120    static void applier(const void* key, const void* value, void* context){
121      // The reason for using strprintf is to "force" a copy of the values,
122      // since local variables gets deleted once this function returns.
123      auto currentJvm = static_cast<JvmVersion*>(context);
124      if (CFEqual((CFStringRef)key,CFSTR("JVMName"))) {
125        auto d = extractString((CFStringRef)value);
126        currentJvm->JVMName = trim_copy(d);
127      }
128      if (CFEqual((CFStringRef)key,CFSTR("JVMHomePath"))) {
129        auto d = extractString((CFStringRef)value);
130        currentJvm->JVMHomePath = trim_copy(d);
131      }
132      if (CFEqual((CFStringRef)key,CFSTR("JVMPlatformVersion"))) {
133        auto d = extractString((CFStringRef)value);
134        currentJvm->JVMPlatformVersion = trim_copy(d);
135      }
136     
137    }
138  };
139
140  CFDictionaryApplyFunction(dict, CFunctional::applier, (void*)currentJvmPtr.get());
141
142  if (currentJvmPtr->HasContent())
143  {
144    printf("Found JVM: %s\n\n", currentJvmPtr->ToCString());
145    gRawJvmList->push_back(currentJvmPtr);
146  }
147}
148
149static void listAllJavaInstallsAvailable()
150{
151  auto javaHomeRes = check_output({"/usr/libexec/java_home","-v",DEF_MIN_JVM_VER,"-X"});
152  CFDataRef javaHomes = CFDataCreate(NULL, (const UInt8 *)javaHomeRes.buf.data(), strlen(javaHomeRes.buf.data()));
153 
154  //CFErrorRef err;
155  CFPropertyListRef propertyList = CFPropertyListCreateWithData(kCFAllocatorDefault, javaHomes, kCFPropertyListImmutable, NULL, NULL);
156  /*if (err)
157  {
158    NSError *error = (__bridge NSError *)err;
159    NSLog(@"Failed to read property list: %@", error);
160    [NSApp presentError: error];
161    return nullptr;
162  }*/
163
164
165  //auto typeId = CFCopyTypeIDDescription(CFGetTypeID(propertyList));
166  //auto test = CFCopyDescription(propertyList);
167  //std::cout << "test: " << [test UTF8String] << " Type: " << [typeId UTF8String] << " num: " << jCount << std::endl;
168
169  // Count number of entries in the property array list.
170  // This is used to set max CRange for CFArrayApplyFunction.
171  auto jCount = CFArrayGetCount((CFArrayRef)propertyList);
172
173  CFArrayApplyFunction((CFArrayRef)propertyList, CFRangeMake(0, jCount), processJvmPlistEntries, NULL);
174  //CFShow(propertyList);
175}
Note: See TracBrowser for help on using the repository browser.