NOISSUE reorganize and document libraries

This commit is contained in:
Petr Mrázek
2016-04-10 15:53:05 +02:00
parent 47e37635f5
commit b6d455a02b
368 changed files with 159 additions and 275 deletions

View File

@ -0,0 +1,159 @@
#include "JavaChecker.h"
#include <FileSystem.h>
#include <Commandline.h>
#include <QFile>
#include <QProcess>
#include <QMap>
#include <QCoreApplication>
#include <QDebug>
JavaChecker::JavaChecker(QObject *parent) : QObject(parent)
{
}
void JavaChecker::performCheck()
{
QString checkerJar = FS::PathCombine(QCoreApplication::applicationDirPath(), "jars", "JavaCheck.jar");
QStringList args;
process.reset(new QProcess());
if(m_args.size())
{
auto extraArgs = Commandline::splitArgs(m_args);
args.append(extraArgs);
}
if(m_minMem != 0)
{
args << QString("-Xms%1m").arg(m_minMem);
}
if(m_maxMem != 0)
{
args << QString("-Xmx%1m").arg(m_maxMem);
}
if(m_permGen != 64)
{
args << QString("-XX:PermSize=%1m").arg(m_permGen);
}
args.append({"-jar", checkerJar});
process->setArguments(args);
process->setProgram(m_path);
process->setProcessChannelMode(QProcess::SeparateChannels);
qDebug() << "Running java checker: " + m_path + args.join(" ");;
connect(process.get(), SIGNAL(finished(int, QProcess::ExitStatus)), this, SLOT(finished(int, QProcess::ExitStatus)));
connect(process.get(), SIGNAL(error(QProcess::ProcessError)), this, SLOT(error(QProcess::ProcessError)));
connect(process.get(), SIGNAL(readyReadStandardOutput()), this, SLOT(stdoutReady()));
connect(process.get(), SIGNAL(readyReadStandardError()), this, SLOT(stderrReady()));
connect(&killTimer, SIGNAL(timeout()), SLOT(timeout()));
killTimer.setSingleShot(true);
killTimer.start(15000);
process->start();
}
void JavaChecker::stdoutReady()
{
QByteArray data = process->readAllStandardOutput();
QString added = QString::fromLocal8Bit(data);
added.remove('\r');
m_stdout += added;
}
void JavaChecker::stderrReady()
{
QByteArray data = process->readAllStandardError();
QString added = QString::fromLocal8Bit(data);
added.remove('\r');
m_stderr += added;
}
void JavaChecker::finished(int exitcode, QProcess::ExitStatus status)
{
killTimer.stop();
QProcessPtr _process;
_process.swap(process);
JavaCheckResult result;
{
result.path = m_path;
result.id = m_id;
}
result.errorLog = m_stderr;
qDebug() << "STDOUT" << m_stdout;
qWarning() << "STDERR" << m_stderr;
qDebug() << "Java checker finished with status " << status << " exit code " << exitcode;
if (status == QProcess::CrashExit || exitcode == 1)
{
qDebug() << "Java checker failed!";
emit checkFinished(result);
return;
}
bool success = true;
QMap<QString, QString> results;
QStringList lines = m_stdout.split("\n", QString::SkipEmptyParts);
for(QString line : lines)
{
line = line.trimmed();
auto parts = line.split('=', QString::SkipEmptyParts);
if(parts.size() != 2 || parts[0].isEmpty() || parts[1].isEmpty())
{
success = false;
}
else
{
results.insert(parts[0], parts[1]);
}
}
if(!results.contains("os.arch") || !results.contains("java.version") || !success)
{
qDebug() << "Java checker failed - couldn't extract required information.";
emit checkFinished(result);
return;
}
auto os_arch = results["os.arch"];
auto java_version = results["java.version"];
bool is_64 = os_arch == "x86_64" || os_arch == "amd64";
result.valid = true;
result.is_64bit = is_64;
result.mojangPlatform = is_64 ? "64" : "32";
result.realPlatform = os_arch;
result.javaVersion = java_version;
qDebug() << "Java checker succeeded.";
emit checkFinished(result);
}
void JavaChecker::error(QProcess::ProcessError err)
{
if(err == QProcess::FailedToStart)
{
killTimer.stop();
qDebug() << "Java checker has failed to start.";
JavaCheckResult result;
{
result.path = m_path;
result.id = m_id;
}
emit checkFinished(result);
return;
}
}
void JavaChecker::timeout()
{
// NO MERCY. NO ABUSE.
if(process)
{
qDebug() << "Java checker has been killed by timeout.";
process->kill();
}
}

View File

@ -0,0 +1,54 @@
#pragma once
#include <QProcess>
#include <QTimer>
#include <memory>
#include "multimc_logic_export.h"
#include "JavaVersion.h"
class JavaChecker;
struct MULTIMC_LOGIC_EXPORT JavaCheckResult
{
QString path;
QString mojangPlatform;
QString realPlatform;
JavaVersion javaVersion;
QString errorLog;
bool valid = false;
bool is_64bit = false;
int id;
};
typedef std::shared_ptr<QProcess> QProcessPtr;
typedef std::shared_ptr<JavaChecker> JavaCheckerPtr;
class MULTIMC_LOGIC_EXPORT JavaChecker : public QObject
{
Q_OBJECT
public:
explicit JavaChecker(QObject *parent = 0);
void performCheck();
QString m_path;
QString m_args;
int m_id = 0;
int m_minMem = 0;
int m_maxMem = 0;
int m_permGen = 64;
signals:
void checkFinished(JavaCheckResult result);
private:
QProcessPtr process;
QTimer killTimer;
QString m_stdout;
QString m_stderr;
public
slots:
void timeout();
void finished(int exitcode, QProcess::ExitStatus);
void error(QProcess::ProcessError);
void stdoutReady();
void stderrReady();
};

View File

@ -0,0 +1,45 @@
/* Copyright 2013-2015 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include "JavaCheckerJob.h"
#include <QDebug>
void JavaCheckerJob::partFinished(JavaCheckResult result)
{
num_finished++;
qDebug() << m_job_name.toLocal8Bit() << "progress:" << num_finished << "/"
<< javacheckers.size();
emit progress(num_finished, javacheckers.size());
javaresults.replace(result.id, result);
if (num_finished == javacheckers.size())
{
emit finished(javaresults);
}
}
void JavaCheckerJob::executeTask()
{
qDebug() << m_job_name.toLocal8Bit() << " started.";
m_running = true;
for (auto iter : javacheckers)
{
javaresults.append(JavaCheckResult());
connect(iter.get(), SIGNAL(checkFinished(JavaCheckResult)), SLOT(partFinished(JavaCheckResult)));
iter->performCheck();
}
}

View File

@ -0,0 +1,84 @@
/* Copyright 2013-2015 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <QtNetwork>
#include "JavaChecker.h"
#include "tasks/Task.h"
class JavaCheckerJob;
typedef std::shared_ptr<JavaCheckerJob> JavaCheckerJobPtr;
class JavaCheckerJob : public Task
{
Q_OBJECT
public:
explicit JavaCheckerJob(QString job_name) : Task(), m_job_name(job_name) {};
bool addJavaCheckerAction(JavaCheckerPtr base)
{
javacheckers.append(base);
total_progress++;
// if this is already running, the action needs to be started right away!
if (isRunning())
{
setProgress(current_progress, total_progress);
connect(base.get(), SIGNAL(checkFinished(JavaCheckResult)), SLOT(partFinished(JavaCheckResult)));
base->performCheck();
}
return true;
}
JavaCheckerPtr operator[](int index)
{
return javacheckers[index];
}
;
JavaCheckerPtr first()
{
if (javacheckers.size())
return javacheckers[0];
return JavaCheckerPtr();
}
int size() const
{
return javacheckers.size();
}
virtual bool isRunning() const override
{
return m_running;
}
signals:
void started();
void finished(QList<JavaCheckResult>);
private slots:
void partFinished(JavaCheckResult result);
protected:
virtual void executeTask() override;
private:
QString m_job_name;
QList<JavaCheckerPtr> javacheckers;
QList<JavaCheckResult> javaresults;
qint64 current_progress = 0;
qint64 total_progress = 0;
int num_finished = 0;
bool m_running = false;
};

View File

@ -0,0 +1,28 @@
#include "JavaInstall.h"
#include <MMCStrings.h>
bool JavaInstall::operator<(const JavaInstall &rhs)
{
auto archCompare = Strings::naturalCompare(arch, rhs.arch, Qt::CaseInsensitive);
if(archCompare != 0)
return archCompare < 0;
if(id < rhs.id)
{
return true;
}
if(id > rhs.id)
{
return false;
}
return Strings::naturalCompare(path, rhs.path, Qt::CaseInsensitive) < 0;
}
bool JavaInstall::operator==(const JavaInstall &rhs)
{
return arch == rhs.arch && id == rhs.id && path == rhs.path;
}
bool JavaInstall::operator>(const JavaInstall &rhs)
{
return (!operator<(rhs)) && (!operator==(rhs));
}

View File

@ -0,0 +1,38 @@
#pragma once
#include "BaseVersion.h"
#include "JavaVersion.h"
struct JavaInstall : public BaseVersion
{
JavaInstall(){}
JavaInstall(QString id, QString arch, QString path)
: id(id), arch(arch), path(path)
{
}
virtual QString descriptor()
{
return id.toString();
}
virtual QString name()
{
return id.toString();
}
virtual QString typeString() const
{
return arch;
}
bool operator<(const JavaInstall & rhs);
bool operator==(const JavaInstall & rhs);
bool operator>(const JavaInstall & rhs);
JavaVersion id;
QString arch;
QString path;
bool recommended = false;
};
typedef std::shared_ptr<JavaInstall> JavaInstallPtr;

View File

@ -0,0 +1,186 @@
/* Copyright 2013-2015 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <QtNetwork>
#include <QtXml>
#include <QRegExp>
#include <QDebug>
#include "java/JavaInstallList.h"
#include "java/JavaCheckerJob.h"
#include "java/JavaUtils.h"
#include "MMCStrings.h"
#include "minecraft/VersionFilterData.h"
JavaInstallList::JavaInstallList(QObject *parent) : BaseVersionList(parent)
{
}
Task *JavaInstallList::getLoadTask()
{
return new JavaListLoadTask(this);
}
const BaseVersionPtr JavaInstallList::at(int i) const
{
return m_vlist.at(i);
}
bool JavaInstallList::isLoaded()
{
return m_loaded;
}
int JavaInstallList::count() const
{
return m_vlist.count();
}
QVariant JavaInstallList::data(const QModelIndex &index, int role) const
{
if (!index.isValid())
return QVariant();
if (index.row() > count())
return QVariant();
auto version = std::dynamic_pointer_cast<JavaInstall>(m_vlist[index.row()]);
switch (role)
{
case VersionPointerRole:
return qVariantFromValue(m_vlist[index.row()]);
case VersionIdRole:
return version->descriptor();
case VersionRole:
return version->id.toString();
case RecommendedRole:
return version->recommended;
case PathRole:
return version->path;
case ArchitectureRole:
return version->arch;
default:
return QVariant();
}
}
BaseVersionList::RoleList JavaInstallList::providesRoles() const
{
return {VersionPointerRole, VersionIdRole, VersionRole, RecommendedRole, PathRole, ArchitectureRole};
}
void JavaInstallList::updateListData(QList<BaseVersionPtr> versions)
{
beginResetModel();
m_vlist = versions;
m_loaded = true;
sortVersions();
if(m_vlist.size())
{
auto best = std::dynamic_pointer_cast<JavaInstall>(m_vlist[0]);
best->recommended = true;
}
endResetModel();
}
bool sortJavas(BaseVersionPtr left, BaseVersionPtr right)
{
auto rleft = std::dynamic_pointer_cast<JavaInstall>(left);
auto rright = std::dynamic_pointer_cast<JavaInstall>(right);
return (*rleft) > (*rright);
}
void JavaInstallList::sortVersions()
{
beginResetModel();
std::sort(m_vlist.begin(), m_vlist.end(), sortJavas);
endResetModel();
}
JavaListLoadTask::JavaListLoadTask(JavaInstallList *vlist) : Task()
{
m_list = vlist;
m_currentRecommended = NULL;
}
JavaListLoadTask::~JavaListLoadTask()
{
}
void JavaListLoadTask::executeTask()
{
setStatus(tr("Detecting Java installations..."));
JavaUtils ju;
QList<QString> candidate_paths = ju.FindJavaPaths();
m_job = std::shared_ptr<JavaCheckerJob>(new JavaCheckerJob("Java detection"));
connect(m_job.get(), SIGNAL(finished(QList<JavaCheckResult>)), this, SLOT(javaCheckerFinished(QList<JavaCheckResult>)));
connect(m_job.get(), &Task::progress, this, &Task::setProgress);
qDebug() << "Probing the following Java paths: ";
int id = 0;
for(QString candidate : candidate_paths)
{
qDebug() << " " << candidate;
auto candidate_checker = new JavaChecker();
candidate_checker->m_path = candidate;
candidate_checker->m_id = id;
m_job->addJavaCheckerAction(JavaCheckerPtr(candidate_checker));
id++;
}
m_job->start();
}
void JavaListLoadTask::javaCheckerFinished(QList<JavaCheckResult> results)
{
QList<JavaInstallPtr> candidates;
qDebug() << "Found the following valid Java installations:";
for(JavaCheckResult result : results)
{
if(result.valid)
{
JavaInstallPtr javaVersion(new JavaInstall());
javaVersion->id = result.javaVersion;
javaVersion->arch = result.mojangPlatform;
javaVersion->path = result.path;
candidates.append(javaVersion);
qDebug() << " " << javaVersion->id.toString() << javaVersion->arch << javaVersion->path;
}
}
QList<BaseVersionPtr> javas_bvp;
for (auto java : candidates)
{
//qDebug() << java->id << java->arch << " at " << java->path;
BaseVersionPtr bp_java = std::dynamic_pointer_cast<BaseVersion>(java);
if (bp_java)
{
javas_bvp.append(java);
}
}
m_list->updateListData(javas_bvp);
emitSucceeded();
}

View File

@ -0,0 +1,71 @@
/* Copyright 2013-2015 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <QObject>
#include <QAbstractListModel>
#include "BaseVersionList.h"
#include "tasks/Task.h"
#include "JavaCheckerJob.h"
#include "JavaInstall.h"
#include "multimc_logic_export.h"
class JavaListLoadTask;
class MULTIMC_LOGIC_EXPORT JavaInstallList : public BaseVersionList
{
Q_OBJECT
public:
explicit JavaInstallList(QObject *parent = 0);
virtual Task *getLoadTask() override;
virtual bool isLoaded() override;
virtual const BaseVersionPtr at(int i) const override;
virtual int count() const override;
virtual void sortVersions() override;
virtual QVariant data(const QModelIndex &index, int role) const override;
virtual RoleList providesRoles() const override;
public slots:
virtual void updateListData(QList<BaseVersionPtr> versions) override;
protected:
QList<BaseVersionPtr> m_vlist;
bool m_loaded = false;
};
class JavaListLoadTask : public Task
{
Q_OBJECT
public:
explicit JavaListLoadTask(JavaInstallList *vlist);
~JavaListLoadTask();
virtual void executeTask();
public slots:
void javaCheckerFinished(QList<JavaCheckResult> results);
protected:
std::shared_ptr<JavaCheckerJob> m_job;
JavaInstallList *m_list;
JavaInstall *m_currentRecommended;
};

View File

@ -0,0 +1,219 @@
/* Copyright 2013-2015 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#include <QStringList>
#include <QString>
#include <QDir>
#include <QStringList>
#include <settings/Setting.h>
#include <QDebug>
#include "java/JavaUtils.h"
#include "java/JavaCheckerJob.h"
#include "java/JavaInstallList.h"
#include "FileSystem.h"
JavaUtils::JavaUtils()
{
}
JavaInstallPtr JavaUtils::MakeJavaPtr(QString path, QString id, QString arch)
{
JavaInstallPtr javaVersion(new JavaInstall());
javaVersion->id = id;
javaVersion->arch = arch;
javaVersion->path = path;
return javaVersion;
}
JavaInstallPtr JavaUtils::GetDefaultJava()
{
JavaInstallPtr javaVersion(new JavaInstall());
javaVersion->id = "java";
javaVersion->arch = "unknown";
javaVersion->path = "java";
return javaVersion;
}
#if defined(Q_OS_WIN32)
QList<JavaInstallPtr> JavaUtils::FindJavaFromRegistryKey(DWORD keyType, QString keyName)
{
QList<JavaInstallPtr> javas;
QString archType = "unknown";
if (keyType == KEY_WOW64_64KEY)
archType = "64";
else if (keyType == KEY_WOW64_32KEY)
archType = "32";
HKEY jreKey;
if (RegOpenKeyExA(HKEY_LOCAL_MACHINE, keyName.toStdString().c_str(), 0,
KEY_READ | keyType | KEY_ENUMERATE_SUB_KEYS, &jreKey) == ERROR_SUCCESS)
{
// Read the current type version from the registry.
// This will be used to find any key that contains the JavaHome value.
char *value = new char[0];
DWORD valueSz = 0;
if (RegQueryValueExA(jreKey, "CurrentVersion", NULL, NULL, (BYTE *)value, &valueSz) ==
ERROR_MORE_DATA)
{
value = new char[valueSz];
RegQueryValueExA(jreKey, "CurrentVersion", NULL, NULL, (BYTE *)value, &valueSz);
}
QString recommended = value;
TCHAR subKeyName[255];
DWORD subKeyNameSize, numSubKeys, retCode;
// Get the number of subkeys
RegQueryInfoKey(jreKey, NULL, NULL, NULL, &numSubKeys, NULL, NULL, NULL, NULL, NULL,
NULL, NULL);
// Iterate until RegEnumKeyEx fails
if (numSubKeys > 0)
{
for (int i = 0; i < numSubKeys; i++)
{
subKeyNameSize = 255;
retCode = RegEnumKeyEx(jreKey, i, subKeyName, &subKeyNameSize, NULL, NULL, NULL,
NULL);
if (retCode == ERROR_SUCCESS)
{
// Now open the registry key for the version that we just got.
QString newKeyName = keyName + "\\" + subKeyName;
HKEY newKey;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, newKeyName.toStdString().c_str(), 0,
KEY_READ | KEY_WOW64_64KEY, &newKey) == ERROR_SUCCESS)
{
// Read the JavaHome value to find where Java is installed.
value = new char[0];
valueSz = 0;
if (RegQueryValueEx(newKey, "JavaHome", NULL, NULL, (BYTE *)value,
&valueSz) == ERROR_MORE_DATA)
{
value = new char[valueSz];
RegQueryValueEx(newKey, "JavaHome", NULL, NULL, (BYTE *)value,
&valueSz);
// Now, we construct the version object and add it to the list.
JavaInstallPtr javaVersion(new JavaInstall());
javaVersion->id = subKeyName;
javaVersion->arch = archType;
javaVersion->path =
QDir(FS::PathCombine(value, "bin")).absoluteFilePath("javaw.exe");
javas.append(javaVersion);
}
RegCloseKey(newKey);
}
}
}
}
RegCloseKey(jreKey);
}
return javas;
}
QList<QString> JavaUtils::FindJavaPaths()
{
QList<JavaInstallPtr> java_candidates;
QList<JavaInstallPtr> JRE64s = this->FindJavaFromRegistryKey(
KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment");
QList<JavaInstallPtr> JDK64s = this->FindJavaFromRegistryKey(
KEY_WOW64_64KEY, "SOFTWARE\\JavaSoft\\Java Development Kit");
QList<JavaInstallPtr> JRE32s = this->FindJavaFromRegistryKey(
KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Runtime Environment");
QList<JavaInstallPtr> JDK32s = this->FindJavaFromRegistryKey(
KEY_WOW64_32KEY, "SOFTWARE\\JavaSoft\\Java Development Kit");
java_candidates.append(JRE64s);
java_candidates.append(MakeJavaPtr("C:/Program Files/Java/jre7/bin/javaw.exe"));
java_candidates.append(MakeJavaPtr("C:/Program Files/Java/jre6/bin/javaw.exe"));
java_candidates.append(JDK64s);
java_candidates.append(JRE32s);
java_candidates.append(MakeJavaPtr("C:/Program Files (x86)/Java/jre7/bin/javaw.exe"));
java_candidates.append(MakeJavaPtr("C:/Program Files (x86)/Java/jre6/bin/javaw.exe"));
java_candidates.append(JDK32s);
java_candidates.append(MakeJavaPtr(this->GetDefaultJava()->path));
QList<QString> candidates;
for(JavaInstallPtr java_candidate : java_candidates)
{
if(!candidates.contains(java_candidate->path))
{
candidates.append(java_candidate->path);
}
}
return candidates;
}
#elif defined(Q_OS_MAC)
QList<QString> JavaUtils::FindJavaPaths()
{
QList<QString> javas;
javas.append(this->GetDefaultJava()->path);
javas.append("/Applications/Xcode.app/Contents/Applications/Application Loader.app/Contents/MacOS/itms/java/bin/java");
javas.append("/Library/Internet Plug-Ins/JavaAppletPlugin.plugin/Contents/Home/bin/java");
javas.append("/System/Library/Frameworks/JavaVM.framework/Versions/Current/Commands/java");
QDir libraryJVMDir("/Library/Java/JavaVirtualMachines/");
QStringList libraryJVMJavas = libraryJVMDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
foreach (const QString &java, libraryJVMJavas) {
javas.append(libraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/bin/java");
javas.append(libraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/jre/bin/java");
}
QDir systemLibraryJVMDir("/System/Library/Java/JavaVirtualMachines/");
QStringList systemLibraryJVMJavas = systemLibraryJVMDir.entryList(QDir::Dirs | QDir::NoDotAndDotDot);
foreach (const QString &java, systemLibraryJVMJavas) {
javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Home/bin/java");
javas.append(systemLibraryJVMDir.absolutePath() + "/" + java + "/Contents/Commands/java");
}
return javas;
}
#elif defined(Q_OS_LINUX)
QList<QString> JavaUtils::FindJavaPaths()
{
qDebug() << "Linux Java detection incomplete - defaulting to \"java\"";
QList<QString> javas;
javas.append(this->GetDefaultJava()->path);
javas.append("/opt/java/bin/java");
javas.append("/usr/bin/java");
return javas;
}
#else
QList<QString> JavaUtils::FindJavaPaths()
{
qDebug() << "Unknown operating system build - defaulting to \"java\"";
QList<QString> javas;
javas.append(this->GetDefaultJava()->path);
return javas;
}
#endif

View File

@ -0,0 +1,43 @@
/* Copyright 2013-2015 MultiMC Contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#pragma once
#include <QStringList>
#include "JavaCheckerJob.h"
#include "JavaChecker.h"
#include "JavaInstallList.h"
#ifdef Q_OS_WIN
#include <windows.h>
#endif
#include "multimc_logic_export.h"
class MULTIMC_LOGIC_EXPORT JavaUtils : public QObject
{
Q_OBJECT
public:
JavaUtils();
JavaInstallPtr MakeJavaPtr(QString path, QString id = "unknown", QString arch = "unknown");
QList<QString> FindJavaPaths();
JavaInstallPtr GetDefaultJava();
#ifdef Q_OS_WIN
QList<JavaInstallPtr> FindJavaFromRegistryKey(DWORD keyType, QString keyName);
#endif
};

View File

@ -0,0 +1,112 @@
#include "JavaVersion.h"
#include <MMCStrings.h>
#include <QRegularExpression>
#include <QString>
JavaVersion & JavaVersion::operator=(const QString & javaVersionString)
{
string = javaVersionString;
auto getCapturedInteger = [](const QRegularExpressionMatch & match, const QString &what) -> int
{
auto str = match.captured(what);
if(str.isEmpty())
{
return 0;
}
return str.toInt();
};
QRegularExpression pattern;
if(javaVersionString.startsWith("1."))
{
pattern = QRegularExpression ("1[.](?<major>[0-9]+)([.](?<minor>[0-9]+))?(_(?<security>[0-9]+)?)?(-(?<prerelease>[a-zA-Z0-9]+))?");
}
else
{
pattern = QRegularExpression("(?<major>[0-9]+)([.](?<minor>[0-9]+))?([.](?<security>[0-9]+))?(-(?<prerelease>[a-zA-Z0-9]+))?");
}
auto match = pattern.match(string);
parseable = match.hasMatch();
major = getCapturedInteger(match, "major");
minor = getCapturedInteger(match, "minor");
security = getCapturedInteger(match, "security");
prerelease = match.captured("prerelease");
return *this;
}
JavaVersion::JavaVersion(const QString &rhs)
{
operator=(rhs);
}
QString JavaVersion::toString()
{
return string;
}
bool JavaVersion::requiresPermGen()
{
if(parseable)
{
return major < 8;
}
return true;
}
bool JavaVersion::operator<(const JavaVersion &rhs)
{
if(parseable && rhs.parseable)
{
if(major < rhs.major)
return true;
if(major > rhs.major)
return false;
if(minor < rhs.minor)
return true;
if(minor > rhs.minor)
return false;
if(security < rhs.security)
return true;
if(security > rhs.security)
return false;
// everything else being equal, consider prerelease status
bool thisPre = !prerelease.isEmpty();
bool rhsPre = !rhs.prerelease.isEmpty();
if(thisPre && !rhsPre)
{
// this is a prerelease and the other one isn't -> lesser
return true;
}
else if(!thisPre && rhsPre)
{
// this isn't a prerelease and the other one is -> greater
return false;
}
else if(thisPre && rhsPre)
{
// both are prereleases - use natural compare...
return Strings::naturalCompare(prerelease, rhs.prerelease, Qt::CaseSensitive) < 0;
}
// neither is prerelease, so they are the same -> this cannot be less than rhs
return false;
}
else return Strings::naturalCompare(string, rhs.string, Qt::CaseSensitive) < 0;
}
bool JavaVersion::operator==(const JavaVersion &rhs)
{
if(parseable && rhs.parseable)
{
return major == rhs.major && minor == rhs.minor && security == rhs.security && prerelease == rhs.prerelease;
}
return string == rhs.string;
}
bool JavaVersion::operator>(const JavaVersion &rhs)
{
return (!operator<(rhs)) && (!operator==(rhs));
}

View File

@ -0,0 +1,30 @@
#pragma once
#include "multimc_logic_export.h"
#include <QString>
class MULTIMC_LOGIC_EXPORT JavaVersion
{
friend class JavaVersionTest;
public:
JavaVersion() {};
JavaVersion(const QString & rhs);
JavaVersion & operator=(const QString & rhs);
bool operator<(const JavaVersion & rhs);
bool operator==(const JavaVersion & rhs);
bool operator>(const JavaVersion & rhs);
bool requiresPermGen();
QString toString();
private:
QString string;
int major = 0;
int minor = 0;
int security = 0;
bool parseable = false;
QString prerelease;
};