/****************************************************************************
* Copyright 2019 Nreal Techonology Limited.All rights reserved.
*
* This file is part of NRSDK.
*
* https://www.nreal.ai/
*
*****************************************************************************/
namespace NRKernal
{
using System;
using System.Text;
using System.Xml;
using System.IO;
using System.Linq.Expressions;
using System.Collections.Generic;
using UnityEngine;
/// A list of the android.
internal class AndroidGradleTemplate
{
private enum EPatcherType
{
EPT_NONE = 0,
EPT_PLUGIN_VERSION = 1,
EPT_ADD_DEPENDENCIES = 2,
EPT_REMOVE_DEPENDENCIES = 3,
EPT_ADD_SUPPORT = 4,
}
private interface IGradlePatcher
{
void PreprocessLine(string line);
bool ProcessLine(string line, ref string result);
}
private class GradlePluginVersionPatcher : IGradlePatcher
{
const string PLUGIN_VERSION_TOKEN = "com.android.tools.build:gradle:";
private int mMajorVersionNum;
private int mMiddleVersionNum;
private int mMinorVersionNum;
public GradlePluginVersionPatcher()
{
mMajorVersionNum = 0;
mMiddleVersionNum = 0;
mMinorVersionNum = 0;
}
public void SetMinPluginVersion(int major, int middle, int minor)
{
mMajorVersionNum = major;
mMiddleVersionNum = middle;
mMinorVersionNum = minor;
}
public void PreprocessLine(string line)
{
}
public bool ProcessLine(string line, ref string result)
{
bool updateVersion = false;
var idx = line.IndexOf(PLUGIN_VERSION_TOKEN);
if (idx > 0)
{
string subLine = line.Substring(idx + PLUGIN_VERSION_TOKEN.Length);
string subVersion = subLine.Substring(0, subLine.IndexOf('\''));
Debug.LogFormat("subVersion : {0}", subVersion);
string[] versions = subVersion.Split('.');
if (versions.Length == 3)
{
int.TryParse(versions[0], out int vMain);
int.TryParse(versions[1], out int vMiddle);
int.TryParse(versions[2], out int vMin);
if (vMain < mMajorVersionNum)
{
updateVersion = true;
}
else if(vMain == mMajorVersionNum)
{
if(vMiddle < mMiddleVersionNum)
{
updateVersion = true;
}
else if(vMiddle == mMiddleVersionNum)
{
if(vMin < mMinorVersionNum)
{
updateVersion = true;
}
}
}
if (updateVersion)
{
result = line.Replace(subVersion, "3.4.3");
Debug.LogFormat("update gradle setting : {0} --> {1}", subVersion, "3.4.3");
}
}
}
return updateVersion;
}
}
private class GradleAddDependenciesPatcher : IGradlePatcher
{
const string DEPS_MARK = "**DEPS**";
private List mDependencies;
public GradleAddDependenciesPatcher()
{
mDependencies = new List();
}
public void AddDependency(string dependency)
{
mDependencies.Add(dependency);
}
public void PreprocessLine(string line)
{
for(int i = mDependencies.Count - 1; i >= 0; i--)
{
if(line.Contains(mDependencies[i]))
{
//this dependency is already in the gradle file
mDependencies.RemoveAt(i);
}
}
}
public bool ProcessLine(string line, ref string result)
{
if(mDependencies.Count > 0 && line.Contains(DEPS_MARK))
{
result = " " + string.Join("\n ", mDependencies);
result = result + "\n" + line;
return true;
}
return false;
}
}
private class GradleRemoveDependenciesPatcher : IGradlePatcher
{
private List mDependencies;
public GradleRemoveDependenciesPatcher()
{
mDependencies = new List();
}
public void RemoveDependency(string dependency)
{
mDependencies.Add(dependency);
}
public void PreprocessLine(string line)
{
}
public bool ProcessLine(string line, ref string result)
{
bool includeDeps = false;
for (int i = 0; i < mDependencies.Count; i++)
{
if (line.Contains(mDependencies[i]))
{
includeDeps = true;
//remove this line
result = null;
break;
}
}
return includeDeps;
}
}
private class GradleAddSupportPatcher : IGradlePatcher
{
private Dictionary mKeyTokenAlreadyInFile = new Dictionary();
private bool mIsFirst = true;
private List mTokenList = new List();
public void PreprocessLine(string line)
{
for(int i = 0; i < mTokenList.Count; i++)
{
var token = mTokenList[i];
if (line.Contains(token))
{
mKeyTokenAlreadyInFile[token] = true;
}
}
}
public bool ProcessLine(string line, ref string result)
{
string tempLine = "";
if (mIsFirst)
{
tempLine = GetSupportStringNotInFile();
mIsFirst = false;
}
foreach (var pair in mKeyTokenAlreadyInFile)
{
if (pair.Value)
{
if (line.Contains(pair.Key))
{
result = tempLine + pair.Key + "=true";
return true;
}
}
}
result = tempLine + line;
return false;
}
private string GetSupportStringNotInFile()
{
string line = "";
foreach (var pair in mKeyTokenAlreadyInFile)
{
if (!pair.Value)
{
line = string.Format("{0}=true\n{1}", pair.Key, line);
}
}
return line;
}
public void AddSupport(string keyToken)
{
mKeyTokenAlreadyInFile.Add(keyToken, false);
mTokenList.Add(keyToken);
}
}
Dictionary mPatchers = null;
string m_Path;
public AndroidGradleTemplate(string path)
{
m_Path = path;
mPatchers = new Dictionary();
}
private T GetOrAddPatcher(EPatcherType type) where T : IGradlePatcher, new()
{
if (!mPatchers.TryGetValue(type, out IGradlePatcher patcher))
{
patcher = new T();
mPatchers.Add(type, patcher);
}
return (T)patcher;
}
public void SetMinPluginVersion(int major, int middle, int minor)
{
GradlePluginVersionPatcher pluginVersionPatcher = GetOrAddPatcher(
EPatcherType.EPT_PLUGIN_VERSION);
pluginVersionPatcher.SetMinPluginVersion(major, middle, minor);
}
public void AddDenpendency(string dependency)
{
GradleAddDependenciesPatcher addDepPatcher = GetOrAddPatcher(
EPatcherType.EPT_ADD_DEPENDENCIES);
addDepPatcher.AddDependency(dependency);
}
public void RemoveDependency(string dependency)
{
GradleRemoveDependenciesPatcher removeDepPatcher = GetOrAddPatcher(
EPatcherType.EPT_REMOVE_DEPENDENCIES);
removeDepPatcher.RemoveDependency(dependency);
}
public void AddSupport(string keyToken)
{
GradleAddSupportPatcher addSupportPatcher = GetOrAddPatcher(
EPatcherType.EPT_ADD_SUPPORT);
addSupportPatcher.AddSupport(keyToken);
}
public void PreprocessGradleFile()
{
if (mPatchers.Count <= 0)
return;
try
{
List content = new List();
var lines = File.ReadAllLines(m_Path);
string newLine = null;
foreach (string line in lines)
{
foreach (var pair in mPatchers)
{
pair.Value.PreprocessLine(line);
}
}
foreach (string line in lines)
{
newLine = line;
foreach (var pair in mPatchers)
{
if(pair.Value.ProcessLine(line, ref newLine))
{
break;
}
}
//Original line may be empty, not null
if (newLine != null)
{
content.Add(newLine);
}
}
File.WriteAllLines(m_Path, content);
}
catch (Exception ex)
{
Debug.LogErrorFormat("PreprocessGradleFile exception : {0}", ex.Message);
}
}
}
}