Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions assemblies/static/src/main/resources/hop-gui.bat
Original file line number Diff line number Diff line change
Expand Up @@ -74,8 +74,8 @@ REM
REM If the user passes in DEBUG as the first parameter, it starts Hop in debugger mode and opens port 5005
REM to allow attaching a debugger to step code.
if [%1]==[DEBUG] (
REM # optional line for attaching a debugger
set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005)
REM # optional line for attaching a debugger + turning on GUI debug logging
set HOP_OPTIONS=%HOP_OPTIONS% -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005 -DHOP_LOG_LEVEL=Debug)

REM Pass HOP variables if they're set.
if not "%HOP_AUDIT_FOLDER%"=="" (
Expand Down
3 changes: 2 additions & 1 deletion assemblies/static/src/main/resources/hop-gui.sh
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,11 @@ if [ -z "${HOP_OPTIONS}" ]; then
HOP_OPTIONS="-Xmx2048m"
fi

# optional line for attaching a debugger
# optional line for attaching a debugger + turning on GUI debug logging
#
if [ "$1" = "debug" ] || [ "$1" = "DEBUG" ]; then
HOP_OPTIONS="${HOP_OPTIONS} -Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=n,address=5005"
HOP_OPTIONS="${HOP_OPTIONS} -DHOP_LOG_LEVEL=Debug"
fi

# Add HOP variables if they're set:
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.StringTokenizer;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;
import java.util.concurrent.CountDownLatch;
Expand Down Expand Up @@ -218,7 +219,10 @@ private void execProcess(String[] process, ProcessResult processresult) throws H
// execute process
try {
if (!meta.isArgumentsInFields()) {
p = data.runtime.exec(new String[] {process[0]});
// Match historical Runtime.exec(String) whitespace tokenization without using the
// deprecated String overload. A single-element String[] would treat the whole command
// line (e.g. "/bin/echo hop-single") as the executable name.
p = data.runtime.exec(tokenizeCommandLine(process[0]));
} else {
p = data.runtime.exec(process);
}
Expand Down Expand Up @@ -323,6 +327,19 @@ private void execProcess(String[] process, ProcessResult processresult) throws H
}
}

/**
* Tokenize a command line the same way Runtime.exec(String) historically did (whitespace via
* {@link StringTokenizer}).
*/
static String[] tokenizeCommandLine(String command) {
StringTokenizer st = new StringTokenizer(command);
String[] cmdArray = new String[st.countTokens()];
for (int i = 0; st.hasMoreTokens(); i++) {
cmdArray[i] = st.nextToken();
}
return cmdArray;
}

private String getOutputString(BufferedReader b) throws IOException {
StringBuilder returnValueBuffer = new StringBuilder();
String line;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,8 @@
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;

import java.util.Arrays;
import java.util.List;
import org.apache.hop.core.HopEnvironment;
import org.apache.hop.core.IRowSet;
import org.apache.hop.core.QueueRowSet;
Expand Down Expand Up @@ -215,6 +217,14 @@ void processRow_failWhenNotSuccess_setsErrors() throws HopException {
assertEquals(1, transform.getErrors());
}

@Test
void tokenizeCommandLine_splitsOnWhitespaceLikeRuntimeExecString() {
assertEquals(
Arrays.asList("/bin/echo", "hop-single"),
Arrays.asList(ExecProcess.tokenizeCommandLine("/bin/echo hop-single")));
assertEquals(List.of("cmd"), Arrays.asList(ExecProcess.tokenizeCommandLine("cmd")));
}

@Test
void processRow_emptyProcessField_throws() throws HopException {
HopEnvironment.init();
Expand Down
5 changes: 5 additions & 0 deletions ui/src/main/java/org/apache/hop/ui/core/gui/GuiResource.java
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,8 @@ public class GuiResource {
@Getter private Image imageLocation;
@Getter private Image imageMaximizePanel;
@Getter private Image imageMinimizePanel;
@Getter private Image imageDetachPanel;
@Getter private Image imageDockPanel;
@Getter private Image imageNavigateBack;
@Getter private Image imageNavigateForward;
@Getter private Image imageNavigateUp;
Expand Down Expand Up @@ -760,6 +762,9 @@ private void loadCommonImages() {
loadAsResource(display, "ui/images/maximize-panel.svg", ConstUi.SMALL_ICON_SIZE);
imageMinimizePanel =
loadAsResource(display, "ui/images/minimize-panel.svg", ConstUi.SMALL_ICON_SIZE);
imageDetachPanel =
loadAsResource(display, "ui/images/detach-panel.svg", ConstUi.SMALL_ICON_SIZE);
imageDockPanel = loadAsResource(display, "ui/images/dock-panel.svg", ConstUi.SMALL_ICON_SIZE);
imageNew = loadAsResource(display, "ui/images/new.svg", ConstUi.SMALL_ICON_SIZE);
imageNote = loadAsResource(display, "ui/images/note.svg", ConstUi.SMALL_ICON_SIZE);
imagePlugin = loadAsResource(display, "ui/images/plugin.svg", ConstUi.SMALL_ICON_SIZE);
Expand Down
19 changes: 19 additions & 0 deletions ui/src/main/java/org/apache/hop/ui/hopgui/HopGui.java
Original file line number Diff line number Diff line change
Expand Up @@ -56,10 +56,12 @@
import org.apache.hop.core.gui.plugin.key.KeyboardShortcut;
import org.apache.hop.core.gui.plugin.menu.GuiMenuElement;
import org.apache.hop.core.gui.plugin.toolbar.GuiToolbarElement;
import org.apache.hop.core.logging.DefaultLogLevel;
import org.apache.hop.core.logging.HopLogStore;
import org.apache.hop.core.logging.ILogChannel;
import org.apache.hop.core.logging.ILoggingObject;
import org.apache.hop.core.logging.LogChannel;
import org.apache.hop.core.logging.LogLevel;
import org.apache.hop.core.logging.LoggingObject;
import org.apache.hop.core.parameters.INamedParameterDefinitions;
import org.apache.hop.core.plugins.JarCache;
Expand Down Expand Up @@ -388,8 +390,25 @@ public void notifyWebThemePreferenceChanged(boolean darkMode) {
notifyWebThemePreferenceChanged(Boolean.valueOf(darkMode));
}

/**
* Apply a startup log level from the {@code HOP_LOG_LEVEL} system property (e.g. set by {@code
* hop-gui.sh debug}). Sets the default level so newly created channels inherit it, and updates
* the already-created static UI/GENERAL channels so GUI-side debug logging becomes visible.
*/
private static void applyStartupLogLevel() {
String levelCode = System.getProperty("HOP_LOG_LEVEL");
if (StringUtils.isEmpty(levelCode)) {
return;
}
LogLevel level = LogLevel.lookupCode(levelCode);
DefaultLogLevel.setLogLevel(level);
LogChannel.UI.setLogLevel(level);
LogChannel.GENERAL.setLogLevel(level);
}

public static void main(String[] arguments) {
try {
applyStartupLogLevel();
setupConsoleLogging();
if (!HopEnvironment.isInitialized()) {
HopEnvironment.init();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import org.apache.hop.ui.hopgui.perspective.metadata.MetadataPerspective;
import org.apache.hop.ui.util.SwtErrorHandler;
import org.eclipse.swt.SWT;
import org.eclipse.swt.custom.CTabFolder;

public class HopGuiAuditDelegate {

Expand Down Expand Up @@ -158,23 +159,17 @@ public void openLastFiles() {
HopFileTypeRegistry.getInstance().findHopFileType(resolvedFilename);
}

// Set target pane for Explorer split view before opening
// Route the file into its saved editor pane (restored layout tree) before opening.
if (perspective instanceof ExplorerPerspective explorerPerspective) {
AuditState auditState = auditStateMap.get(tabKey);
Object paneObj =
auditState != null ? auditState.getStateMap().get(STATE_PROPERTY_PANE) : null;
int pane = 0;
if (paneObj instanceof Number) {
pane = ((Number) paneObj).intValue();
} else if (paneObj != null) {
try {
pane = Integer.parseInt(paneObj.toString());
} catch (NumberFormatException ignored) {
pane = 0;
}
}
if (pane == 1 && explorerPerspective.getRightTabFolder() != null) {
perspective.setDropTargetFolder(explorerPerspective.getRightTabFolder());
CTabFolder targetFolder =
paneObj != null
? explorerPerspective.getTabFolderForLeafId(paneObj.toString())
: null;
if (targetFolder != null) {
perspective.setDropTargetFolder(targetFolder);
}
}

Expand Down Expand Up @@ -220,6 +215,11 @@ public void openLastFiles() {
if (activeFileTypeHandler != null) {
perspective.setActiveFileTypeHandler(activeFileTypeHandler);
}

// Drop any restored editor pane whose file(s) failed to open, so no ghost panes remain.
if (perspective instanceof ExplorerPerspective explorerPerspective) {
explorerPerspective.finishEditorLayoutRestore();
}
}
}

Expand Down Expand Up @@ -350,7 +350,10 @@ public void writeLastOpenFiles() {
stateProperties.put(STATE_PROPERTY_FILETYPE, fileType.getName());
}
if (perspective instanceof ExplorerPerspective ep) {
stateProperties.put(STATE_PROPERTY_PANE, ep.getPaneIndexForTab(tabItem.getTabItem()));
String leafId = ep.getLeafIdForTab(tabItem.getTabItem());
if (leafId != null) {
stateProperties.put(STATE_PROPERTY_PANE, leafId);
}
}

auditStateMap.add(new AuditState(tabKey, stateProperties));
Expand Down
Loading
Loading