mirror of
https://gitee.com/zhangsken/AndroidIDE.git
synced 2026-10-16 07:49:44 +08:00
Added log filter feature (#74)
This commit is contained in:
@@ -933,7 +933,7 @@ public class EditorActivity extends StudioActivity
|
||||
initialSetup();
|
||||
setStatus(getString(R.string.msg_project_initialized));
|
||||
mBinding.buildProgressIndicator.setVisibility(View.GONE);
|
||||
|
||||
|
||||
if (mFindInProjectDialog != null && mFindInProjectDialog.isShowing()) {
|
||||
mFindInProjectDialog.dismiss();
|
||||
}
|
||||
@@ -961,8 +961,8 @@ public class EditorActivity extends StudioActivity
|
||||
@SuppressWarnings("UnusedReturnValue")
|
||||
@NonNull
|
||||
public CompletableFuture<TaskExecutionResult> execTasks(
|
||||
Consumer<TaskExecutionResult> resultHandler, String... tasks) {
|
||||
saveAll(false);
|
||||
Consumer<TaskExecutionResult> resultHandler, String... tasks) {
|
||||
saveAll(false);
|
||||
runOnUiThread(() -> appendBuildOut("Executing tasks: " + TextUtils.join(", ", tasks)));
|
||||
return mBuildService
|
||||
.executeTasks(tasks)
|
||||
@@ -1348,7 +1348,8 @@ public class EditorActivity extends StudioActivity
|
||||
@Override
|
||||
public void onTabSelected(TabLayout.Tab tab) {
|
||||
final var fragment = bottomSheetTabAdapter.getFragmentAtIndex(tab.getPosition());
|
||||
if (fragment instanceof NonEditableEditorFragment) {
|
||||
if (fragment instanceof NonEditableEditorFragment
|
||||
|| fragment instanceof LogViewFragment) {
|
||||
mBinding.bottomSheet.clearFab.show();
|
||||
mBinding.bottomSheet.shareOutputFab.show();
|
||||
} else {
|
||||
@@ -1376,6 +1377,11 @@ public class EditorActivity extends StudioActivity
|
||||
if (editor.getEditor() != null) {
|
||||
editor.getEditor().setText("");
|
||||
}
|
||||
} else if (fragment instanceof LogViewFragment) {
|
||||
final var editor = (LogViewFragment) fragment;
|
||||
if (editor.getEditor() != null) {
|
||||
editor.getEditor().setText("");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1384,18 +1390,23 @@ public class EditorActivity extends StudioActivity
|
||||
final var fragment =
|
||||
bottomSheetTabAdapter.getFragmentAtIndex(
|
||||
mBinding.bottomSheet.tabs.getSelectedTabPosition());
|
||||
if (fragment instanceof NonEditableEditorFragment) {
|
||||
final var editor = (NonEditableEditorFragment) fragment;
|
||||
if (editor.getEditor() != null) {
|
||||
final var text = editor.getEditor().getText();
|
||||
final var type =
|
||||
editor instanceof SimpleOutputFragment
|
||||
? "build_output"
|
||||
: editor instanceof IDELogFragment
|
||||
? "ide_logs"
|
||||
: editor instanceof LogViewFragment ? "app_logs" : "unknown_type";
|
||||
shareText(text, type);
|
||||
if (fragment instanceof Fragment) {
|
||||
CharSequence text = "";
|
||||
String type = "unknown_type";
|
||||
if (fragment instanceof SimpleOutputFragment) {
|
||||
var editor = (SimpleOutputFragment) fragment;
|
||||
text = editor.getEditor().getText();
|
||||
type = "build_output";
|
||||
} else if (fragment instanceof IDELogFragment) {
|
||||
var editor = (IDELogFragment) fragment;
|
||||
text = editor.getEditor().getText();
|
||||
type = "ide_logs";
|
||||
} else if (fragment instanceof LogViewFragment) {
|
||||
var editor = (IDELogFragment) fragment;
|
||||
text = editor.getEditor().getText();
|
||||
type = "app_logs";
|
||||
}
|
||||
shareText(text, type);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -1520,18 +1531,14 @@ public class EditorActivity extends StudioActivity
|
||||
try {
|
||||
//noinspection ConstantConditions
|
||||
final var rootProject = ProjectManager.INSTANCE.getRootProject();
|
||||
|
||||
var projectName = rootProject.getName().get();
|
||||
if(projectName.isEmpty())
|
||||
{
|
||||
projectName = new File(ProjectManager.INSTANCE.getProjectDirPath()).getName();
|
||||
getSupportActionBar()
|
||||
.setSubtitle(projectName);
|
||||
}
|
||||
else{
|
||||
getSupportActionBar()
|
||||
.setSubtitle(projectName);
|
||||
}
|
||||
|
||||
var projectName = rootProject.getName().get();
|
||||
if (projectName.isEmpty()) {
|
||||
projectName = new File(ProjectManager.INSTANCE.getProjectDirPath()).getName();
|
||||
getSupportActionBar().setSubtitle(projectName);
|
||||
} else {
|
||||
getSupportActionBar().setSubtitle(projectName);
|
||||
}
|
||||
} catch (Throwable th) {
|
||||
// ignored
|
||||
}
|
||||
@@ -1575,7 +1582,7 @@ public class EditorActivity extends StudioActivity
|
||||
}
|
||||
|
||||
initializeLanguageServers();
|
||||
|
||||
|
||||
// Actually, we don't need to start FileOptionsHandler
|
||||
// Because it would work anyway
|
||||
// But still we do...
|
||||
|
||||
@@ -22,32 +22,32 @@ import androidx.annotation.NonNull;
|
||||
import com.itsaky.androidide.models.LogLine;
|
||||
import com.itsaky.androidide.utils.ILogger;
|
||||
|
||||
public class IDELogFragment extends LogViewFragment {
|
||||
|
||||
private final ILogger.LogListener listener = this::log;
|
||||
|
||||
public IDELogFragment() {
|
||||
ILogger.addLogListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String onCreateLogString(@NonNull LogLine line) {
|
||||
return line.toSimpleString();
|
||||
}
|
||||
|
||||
private void log(int priority, String tag, @NonNull String message) {
|
||||
if (message.contains("\n")) {
|
||||
final var split = message.split("\n");
|
||||
for (var line : split) {
|
||||
logLine(priority, tag, line);
|
||||
}
|
||||
} else {
|
||||
logLine(priority, tag, message);
|
||||
}
|
||||
}
|
||||
|
||||
private void logLine(int priority, String tag, String message) {
|
||||
final var line = new LogLine(ILogger.priorityChar(priority), tag, message);
|
||||
appendLog(line);
|
||||
}
|
||||
}
|
||||
public class IDELogFragment extends LogViewFragment {
|
||||
|
||||
private final ILogger.LogListener listener = this::log;
|
||||
|
||||
public IDELogFragment() {
|
||||
ILogger.addLogListener(listener);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected String onCreateLogString(@NonNull LogLine line) {
|
||||
return line.toSimpleString();
|
||||
}
|
||||
|
||||
private void log(int priority, String tag, @NonNull String message) {
|
||||
if (message.contains("\n")) {
|
||||
final var split = message.split("\n");
|
||||
for (var line : split) {
|
||||
logLine(priority, tag, line);
|
||||
}
|
||||
} else {
|
||||
logLine(priority, tag, message);
|
||||
}
|
||||
}
|
||||
|
||||
private void logLine(int priority, String tag, String message) {
|
||||
final var line = new LogLine(ILogger.priorityChar(priority), tag, message);
|
||||
appendLog(line);
|
||||
}
|
||||
}
|
||||
@@ -18,57 +18,147 @@
|
||||
package com.itsaky.androidide.fragments;
|
||||
|
||||
import android.os.Bundle;
|
||||
import android.text.Editable;
|
||||
import android.text.TextUtils;
|
||||
import android.view.LayoutInflater;
|
||||
import android.view.View;
|
||||
import android.view.ViewGroup;
|
||||
import android.widget.AdapterView;
|
||||
import android.widget.ArrayAdapter;
|
||||
|
||||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import androidx.fragment.app.Fragment;
|
||||
|
||||
import com.blankj.utilcode.util.StringUtils;
|
||||
import com.blankj.utilcode.util.ThreadUtils;
|
||||
|
||||
import com.itsaky.androidide.R;
|
||||
import com.itsaky.androidide.databinding.FragmentLogViewBinding;
|
||||
import com.itsaky.androidide.language.logs.LogLanguageImpl;
|
||||
import com.itsaky.androidide.models.LogLine;
|
||||
import com.itsaky.androidide.syntax.colorschemes.SchemeAndroidIDE;
|
||||
import com.itsaky.androidide.utils.TypefaceUtils;
|
||||
import com.itsaky.androidide.views.editor.IDEEditor;
|
||||
import com.itsaky.androidide.utils.SingleTextWatcher;
|
||||
import io.github.rosemoe.sora.lang.Language;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import io.github.rosemoe.sora.lang.Language;
|
||||
public class LogViewFragment extends Fragment {
|
||||
|
||||
public class LogViewFragment extends NonEditableEditorFragment {
|
||||
private FragmentLogViewBinding binding;
|
||||
|
||||
private final Language language = getLanguage();
|
||||
private final List<LogLine> unsavedLines = new ArrayList<>();
|
||||
|
||||
private char priority;
|
||||
private String tag;
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public View onCreateView(
|
||||
@NonNull LayoutInflater inflater,
|
||||
@Nullable ViewGroup container,
|
||||
@Nullable Bundle savedInstanceState) {
|
||||
binding = FragmentLogViewBinding.inflate(inflater, container, false);
|
||||
return binding.getRoot();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onViewCreated(@NonNull View view, @Nullable Bundle savedInstanceState) {
|
||||
super.onViewCreated(view, savedInstanceState);
|
||||
Objects.requireNonNull(getEditor()).setEditorLanguage(language);
|
||||
final var editor = getEditor();
|
||||
editor.setEditable(false);
|
||||
editor.setDividerWidth(0);
|
||||
editor.setWordwrap(false);
|
||||
editor.setUndoEnabled(false);
|
||||
editor.setTypefaceLineNumber(TypefaceUtils.jetbrainsMono());
|
||||
editor.setTypefaceText(TypefaceUtils.jetbrainsMono());
|
||||
editor.setTextSize(12);
|
||||
editor.setColorScheme(new SchemeAndroidIDE());
|
||||
editor.setEditorLanguage(language);
|
||||
|
||||
final var arr = requireContext().getResources().getStringArray(R.array.logcat_units);
|
||||
binding.logPrioritySpinner.setAdapter(
|
||||
new ArrayAdapter<>(
|
||||
requireContext(),
|
||||
androidx.appcompat.R.layout.support_simple_spinner_dropdown_item,
|
||||
arr));
|
||||
|
||||
binding.logPrioritySpinner.setOnItemSelectedListener(
|
||||
new AdapterView.OnItemSelectedListener() {
|
||||
@Override
|
||||
public void onItemSelected(AdapterView<?> parent, View view, int position, long id) {
|
||||
priority = parent.getSelectedItem().toString().charAt(0);
|
||||
getEditor().setText("");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onNothingSelected(AdapterView<?> parent) {}
|
||||
});
|
||||
|
||||
binding
|
||||
.tagFilterInput
|
||||
.getEditText()
|
||||
.addTextChangedListener(
|
||||
new SingleTextWatcher() {
|
||||
@Override
|
||||
public void afterTextChanged(Editable editable) {
|
||||
tag = editable.toString();
|
||||
getEditor().setText("");
|
||||
}
|
||||
});
|
||||
|
||||
if (!unsavedLines.isEmpty()) {
|
||||
for (var line : unsavedLines) {
|
||||
applyToLanguage(line);
|
||||
getEditor().append(line.toString().trim() + "\n");
|
||||
applyToLanguage(line);
|
||||
}
|
||||
unsavedLines.clear();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean filterLog(char priority, String tag, LogLine l) {
|
||||
return 'V' == priority
|
||||
|| (l.priorityChar == priority)
|
||||
&& (TextUtils.isEmpty(tag)
|
||||
|| (!TextUtils.isEmpty(tag) && (l.tag.toLowerCase().contains(tag.toLowerCase()))));
|
||||
}
|
||||
|
||||
private void applyToLanguage(LogLine line) {
|
||||
if (language instanceof LogLanguageImpl) {
|
||||
((LogLanguageImpl) this.language).addLine(line);
|
||||
}
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public IDEEditor getEditor() {
|
||||
return binding.editor;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onDestroyView() {
|
||||
super.onDestroyView();
|
||||
binding = null;
|
||||
}
|
||||
|
||||
public void appendLog(LogLine line) {
|
||||
if (getEditor() == null) {
|
||||
unsavedLines.add(line);
|
||||
return;
|
||||
if (filterLog(priority, tag, line)) {
|
||||
if (getEditor() == null) {
|
||||
unsavedLines.add(line);
|
||||
return;
|
||||
}
|
||||
|
||||
final var lineString = onCreateLogString(line);
|
||||
final var msg = lineString.endsWith("\n") ? lineString : lineString + "\n";
|
||||
|
||||
ThreadUtils.runOnUiThread(() -> getEditor().append(msg));
|
||||
applyToLanguage(line);
|
||||
}
|
||||
|
||||
applyToLanguage(line);
|
||||
|
||||
final var lineString = onCreateLogString(line);
|
||||
final var msg = lineString.endsWith("\n") ? lineString : lineString + "\n";
|
||||
ThreadUtils.runOnUiThread(() -> getEditor().append(msg));
|
||||
}
|
||||
|
||||
protected String onCreateLogString(@NonNull LogLine line) {
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
xmlns:app="http://schemas.android.com/apk/res-auto"
|
||||
android:id="@+id/root"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:orientation="vertical" >
|
||||
|
||||
<LinearLayout
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal"
|
||||
android:padding="8dp" >
|
||||
|
||||
<androidx.appcompat.widget.AppCompatSpinner
|
||||
android:id="@+id/log_priority_spinner"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_weight="1"
|
||||
android:entries="@array/logcat_units" />
|
||||
|
||||
<com.google.android.material.textfield.TextInputLayout
|
||||
android:id="@+id/tag_filter_input"
|
||||
style="@style/AppTheme.TextInputLayout.Outlined"
|
||||
android:layout_width="0dp"
|
||||
android:layout_height="wrap_content"
|
||||
android:layout_marginStart="8dp"
|
||||
android:layout_weight="1"
|
||||
android:hint="@string/hint_log_tag_filter"
|
||||
app:hintEnabled="true"
|
||||
app:hintTextColor="@color/secondaryColor" >
|
||||
|
||||
<com.google.android.material.textfield.TextInputEditText
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent"
|
||||
android:singleLine="true" />
|
||||
</com.google.android.material.textfield.TextInputLayout>
|
||||
</LinearLayout>
|
||||
|
||||
<com.itsaky.androidide.views.editor.IDEEditor
|
||||
android:id="@+id/editor"
|
||||
android:layout_width="match_parent"
|
||||
android:layout_height="match_parent" />
|
||||
|
||||
</LinearLayout>
|
||||
@@ -1,4 +1,5 @@
|
||||
<?xml version="1.0" encoding="utf-8"?><!--
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<!--
|
||||
~ This file is part of AndroidIDE.
|
||||
~
|
||||
~ AndroidIDE is free software: you can redistribute it and/or modify
|
||||
@@ -13,8 +14,9 @@
|
||||
~
|
||||
~ You should have received a copy of the GNU General Public License
|
||||
~ along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
-->
|
||||
-->
|
||||
<resources>
|
||||
|
||||
<string-array name="dimension_units">
|
||||
<item>dp</item>
|
||||
<item>sp</item>
|
||||
@@ -23,4 +25,14 @@
|
||||
<item>in</item>
|
||||
<item>mm</item>
|
||||
</string-array>
|
||||
|
||||
<string-array name="logcat_units">
|
||||
<item>Verbose</item>
|
||||
<item>Debug</item>
|
||||
<item>Info</item>
|
||||
<item>Warning</item>
|
||||
<item>Error</item>
|
||||
<item>Fatal</item>
|
||||
</string-array>
|
||||
|
||||
</resources>
|
||||
@@ -380,6 +380,7 @@
|
||||
<string name="wizard_loading">Templates loading...</string>
|
||||
<string name="next">Next</string>
|
||||
<string name="exit">Exit</string>
|
||||
<string name="hint_log_tag_filter">Log tags filter</string>
|
||||
|
||||
<string name="idepref_title_tpFix">JDK 11 tag pointers fix</string>
|
||||
<string name="idepref_msg_tpFix">Set LD_PRELOAD to libhook.so to fix tag pointers issue for JDK 11 in Android 11 [DEPRECATED - Prefer using JDK 17].</string>
|
||||
|
||||
@@ -1,179 +1,161 @@
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.itsaky.androidide.models;
|
||||
|
||||
public class LogLine {
|
||||
|
||||
// It makes things easier in LogLanguageImpl
|
||||
public static int INFO;
|
||||
public static int DEBUG;
|
||||
public static int ERROR;
|
||||
public static int WARNING;
|
||||
|
||||
static {
|
||||
try {
|
||||
final var klass = Class.forName("com.itsaky.androidide.syntax.colorschemes.SchemeAndroidIDE");
|
||||
INFO = klass.getField("LOG_INFO").getInt(null);
|
||||
DEBUG = klass.getField("LOG_DEBUG").getInt(null);
|
||||
ERROR = klass.getField("LOG_ERROR").getInt(null);
|
||||
WARNING = klass.getField("LOG_WARNING").getInt(null);
|
||||
} catch (Throwable err) {
|
||||
INFO = 0;
|
||||
DEBUG = 1;
|
||||
ERROR = 2;
|
||||
WARNING = 3;
|
||||
}
|
||||
}
|
||||
|
||||
public String unformatted;
|
||||
public String date;
|
||||
public String time;
|
||||
public String pid;
|
||||
public String tid;
|
||||
public String tag;
|
||||
public String message;
|
||||
public char priorityChar;
|
||||
public int priority;
|
||||
public boolean formatted;
|
||||
|
||||
// For JSONRpc
|
||||
@SuppressWarnings("unused")
|
||||
private LogLine() {}
|
||||
|
||||
public LogLine(char priorityChar, String tag, String message) {
|
||||
this("", "", "", "", priorityChar, tag, message);
|
||||
}
|
||||
|
||||
public LogLine(
|
||||
String date,
|
||||
String time,
|
||||
String pid,
|
||||
String tid,
|
||||
char priorityChar,
|
||||
String tag,
|
||||
String message) {
|
||||
this(date, time, pid, tid, priorityChar, tag, message, true);
|
||||
}
|
||||
|
||||
public LogLine(
|
||||
String date,
|
||||
String time,
|
||||
String pid,
|
||||
String tid,
|
||||
char priorityChar,
|
||||
String tag,
|
||||
String message,
|
||||
boolean formatted) {
|
||||
this.date = date;
|
||||
this.time = time;
|
||||
this.pid = pid;
|
||||
this.tid = tid;
|
||||
this.priorityChar = priorityChar;
|
||||
this.tag = tag;
|
||||
this.message = message;
|
||||
this.priority = parsePriority(priorityChar);
|
||||
this.formatted = formatted;
|
||||
|
||||
if (tag.length() > 25) {
|
||||
this.tag = "...".concat(tag.substring(tag.length() - 25));
|
||||
}
|
||||
}
|
||||
|
||||
private int parsePriority(char s) {
|
||||
final var c = Character.toLowerCase(s);
|
||||
if (c == 'w') {
|
||||
return WARNING;
|
||||
} else if (c == 'e') {
|
||||
return ERROR;
|
||||
} else if (c == 'i') {
|
||||
return INFO;
|
||||
} else {
|
||||
return DEBUG;
|
||||
}
|
||||
}
|
||||
|
||||
public LogLine(String unformatted) {
|
||||
this.unformatted = unformatted;
|
||||
this.formatted = false;
|
||||
}
|
||||
|
||||
public static LogLine forLogString(final String log) {
|
||||
try {
|
||||
final var split = log.split("\\s", 7);
|
||||
return new LogLine(
|
||||
split[0], // date
|
||||
split[1], // time
|
||||
split[2], // process id
|
||||
split[3], // thread id
|
||||
split[4].charAt(0), // priority
|
||||
split[5], // tag
|
||||
split[6] // message
|
||||
);
|
||||
} catch (Throwable th) {
|
||||
return new LogLine(log);
|
||||
}
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
int id = 0xffffffff;
|
||||
if (priority == WARNING) {
|
||||
id = 0xffff7043;
|
||||
} else if (priority == ERROR) {
|
||||
id = 0xffc50e29;
|
||||
} else if (priority == INFO) {
|
||||
id = 0xff4caf50;
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.formatted
|
||||
? String.format(
|
||||
"%-6s %-13s %-6s %-6s %-2s %-35s %s",
|
||||
date, time, pid, tid, priorityChar, trimIfNeeded(tag, 35), message)
|
||||
: this.unformatted;
|
||||
}
|
||||
|
||||
private String trimIfNeeded(String tag, int maxLength) {
|
||||
final var sb = new StringBuilder(tag);
|
||||
final var length = tag.length();
|
||||
if (length > maxLength) {
|
||||
final var start = length - maxLength;
|
||||
sb.delete(0, start);
|
||||
|
||||
// When the tag is long enough, prefix the tag with '..'
|
||||
sb.setCharAt(0, '.');
|
||||
sb.setCharAt(1, '.');
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String toSimpleString() {
|
||||
return this.formatted
|
||||
? String.format("%-25s %-2s %s", trimIfNeeded(tag, 25), priorityChar, message)
|
||||
: this.unformatted;
|
||||
}
|
||||
|
||||
public String formattedTagAndMessage() {
|
||||
return this.formatted
|
||||
? String.format("%-25s %s", trimIfNeeded(tag, 25), message)
|
||||
: this.unformatted;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* This file is part of AndroidIDE.
|
||||
*
|
||||
* AndroidIDE is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* AndroidIDE is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with AndroidIDE. If not, see <https://www.gnu.org/licenses/>.
|
||||
*
|
||||
*/
|
||||
package com.itsaky.androidide.models;
|
||||
|
||||
public class LogLine {
|
||||
|
||||
// It makes things easier in LogLanguageImpl
|
||||
public static int INFO;
|
||||
public static int DEBUG;
|
||||
public static int ERROR;
|
||||
public static int WARNING;
|
||||
|
||||
static {
|
||||
try {
|
||||
final var klass = Class.forName("com.itsaky.androidide.syntax.colorschemes.SchemeAndroidIDE");
|
||||
INFO = klass.getField("LOG_INFO").getInt(null);
|
||||
DEBUG = klass.getField("LOG_DEBUG").getInt(null);
|
||||
ERROR = klass.getField("LOG_ERROR").getInt(null);
|
||||
WARNING = klass.getField("LOG_WARNING").getInt(null);
|
||||
} catch (Throwable err) {
|
||||
INFO = 0;
|
||||
DEBUG = 1;
|
||||
ERROR = 2;
|
||||
WARNING = 3;
|
||||
}
|
||||
}
|
||||
|
||||
public String unformatted;
|
||||
public String date;
|
||||
public String time;
|
||||
public String pid;
|
||||
public String tid;
|
||||
public String tag;
|
||||
public String message;
|
||||
public char priorityChar;
|
||||
public int priority;
|
||||
public boolean formatted;
|
||||
|
||||
// For JSONRpc
|
||||
@SuppressWarnings("unused")
|
||||
private LogLine() {}
|
||||
|
||||
public LogLine(char priorityChar, String tag, String message) {
|
||||
this("", "", "", "", priorityChar, tag, message);
|
||||
}
|
||||
|
||||
public LogLine(
|
||||
String date,
|
||||
String time,
|
||||
String pid,
|
||||
String tid,
|
||||
char priorityChar,
|
||||
String tag,
|
||||
String message) {
|
||||
this(date, time, pid, tid, priorityChar, tag, message, true);
|
||||
}
|
||||
|
||||
public LogLine(
|
||||
String date,
|
||||
String time,
|
||||
String pid,
|
||||
String tid,
|
||||
char priorityChar,
|
||||
String tag,
|
||||
String message,
|
||||
boolean formatted) {
|
||||
this.date = date;
|
||||
this.time = time;
|
||||
this.pid = pid;
|
||||
this.tid = tid;
|
||||
this.priorityChar = priorityChar;
|
||||
this.tag = tag;
|
||||
this.message = message;
|
||||
this.priority = parsePriority(priorityChar);
|
||||
this.formatted = formatted;
|
||||
}
|
||||
|
||||
private int parsePriority(char s) {
|
||||
final var c = Character.toLowerCase(s);
|
||||
if (c == 'w') {
|
||||
return WARNING;
|
||||
} else if (c == 'e') {
|
||||
return ERROR;
|
||||
} else if (c == 'i') {
|
||||
return INFO;
|
||||
} else {
|
||||
return DEBUG;
|
||||
}
|
||||
}
|
||||
|
||||
public LogLine(String unformatted) {
|
||||
this.unformatted = unformatted;
|
||||
this.formatted = false;
|
||||
}
|
||||
|
||||
public static LogLine forLogString(final String log) {
|
||||
try {
|
||||
final var split = log.split("\\s", 7);
|
||||
return new LogLine(
|
||||
split[0], // date
|
||||
split[1], // time
|
||||
split[2], // process id
|
||||
split[3], // thread id
|
||||
split[4].charAt(0), // priority
|
||||
split[5], // tag
|
||||
split[6] // message
|
||||
);
|
||||
} catch (Throwable th) {
|
||||
return new LogLine(log);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.formatted
|
||||
? String.format("%s %s %s/%s %s/%s %s", date, time, pid, tid, priorityChar, tag, message)
|
||||
: this.unformatted;
|
||||
}
|
||||
|
||||
private String trimIfNeeded(String tag, int maxLength) {
|
||||
final var sb = new StringBuilder(tag);
|
||||
final var length = tag.length();
|
||||
if (length > maxLength) {
|
||||
final var start = length - maxLength;
|
||||
sb.delete(0, start);
|
||||
|
||||
// When the tag is long enough, prefix the tag with '..'
|
||||
sb.setCharAt(0, '.');
|
||||
sb.setCharAt(1, '.');
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
public String toSimpleString() {
|
||||
return this.formatted
|
||||
? String.format("%-25s %-2s %s", trimIfNeeded(tag, 25), priorityChar, message)
|
||||
: this.unformatted;
|
||||
}
|
||||
|
||||
public String formattedTagAndMessage() {
|
||||
return this.formatted
|
||||
? String.format("%-25s %s", trimIfNeeded(tag, 25), message)
|
||||
: this.unformatted;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user