Skip to content

Commit 19f0d52

Browse files
committed
Merge branch 'public-release/v1.2.4-221' into public-release/v1.2.4-223
Signed-off-by: Uladzislau <[email protected]>
2 parents 9123a1e + c676a51 commit 19f0d52

17 files changed

+270
-73
lines changed

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@
33
.intellijPlatform
44
/build
55
/ide_for_launch
6+
/out
7+
/allure-results
68

79
verifier-all.jar
810

CHANGELOG.md

+14-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,19 @@
11
# IntelliJ Plugin Changelog
22

3-
All notable changes to the Zowe IntelliJ Plugin will be documented in this file.
3+
All notable changes to the For Mainframe Plugin will be documented in this file.
4+
5+
## [Unreleased]
6+
7+
### Bugfixes
8+
9+
* Bugfix: Fixed issue with cross-system folder copy with name conflicts ([c5345051](https://github.com/zowe/zowe-explorer-intellij/commit/c5345051))
10+
* Bugfix: Clarified 401 error ([f36ec547](https://github.com/zowe/zowe-explorer-intellij/commit/f36ec547))
11+
* Bugfix: Fixed issue with USS copy that would lead to incorrect encoding error ([b4cb705a](https://github.com/zowe/zowe-explorer-intellij/commit/b4cb705a))
12+
* Bugfix: Fixed issue with jobs DDs display in console ([8a75f21a](https://github.com/zowe/zowe-explorer-intellij/commit/8a75f21a))
13+
* Bugfix: Fixed issue with copying another user's folder in USS ([66676550](https://github.com/zowe/zowe-explorer-intellij/commit/66676550))
14+
* Bugfix: Some encodings are made unsupported ([080c25ab](https://github.com/zowe/zowe-explorer-intellij/commit/080c25ab))
15+
* Bugfix: Fixed issue during a file upload to a PDS ([954bf01f](https://github.com/zowe/zowe-explorer-intellij/commit/954bf01f))
16+
* Bugfix: Fixed issue with URL field when typing incorrect information, the last slash at the end of https:// is deleted ([91ab962d](https://github.com/zowe/zowe-explorer-intellij/commit/91ab962d))
417

518
## [1.2.3-223] (2024-10-02)
619

gradle.properties

+1-1
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ org.gradle.jvmargs=-Xss1M
1414
platformVersion = 2022.3
1515

1616
# SemVer format -> https://semver.org
17-
pluginVersion = 1.2.3-223
17+
pluginVersion = 1.2.4-223
1818
pluginGroup = eu.ibagroup
1919
pluginRepositoryUrl = https://github.com/for-mainframe/For-Mainframe
2020

src/main/kotlin/eu/ibagroup/formainframe/config/connect/ui/zosmf/ConnectionDialog.kt

+21-8
Original file line numberDiff line numberDiff line change
@@ -31,12 +31,17 @@ import eu.ibagroup.formainframe.config.connect.*
3131
import eu.ibagroup.formainframe.config.connect.ui.ChangePasswordDialog
3232
import eu.ibagroup.formainframe.config.connect.ui.ChangePasswordDialogState
3333
import eu.ibagroup.formainframe.dataops.DataOpsManager
34-
import eu.ibagroup.formainframe.dataops.operations.*
34+
import eu.ibagroup.formainframe.dataops.operations.ChangePasswordOperation
35+
import eu.ibagroup.formainframe.dataops.operations.InfoOperation
36+
import eu.ibagroup.formainframe.dataops.operations.ZOSInfoOperation
3537
import eu.ibagroup.formainframe.explorer.EXPLORER_NOTIFICATION_GROUP_ID
36-
import eu.ibagroup.formainframe.utils.*
3738
import eu.ibagroup.formainframe.utils.crudable.Crudable
3839
import eu.ibagroup.formainframe.utils.crudable.find
3940
import eu.ibagroup.formainframe.utils.crudable.getAll
41+
import eu.ibagroup.formainframe.utils.runTask
42+
import eu.ibagroup.formainframe.utils.validateConnectionName
43+
import eu.ibagroup.formainframe.utils.validateForBlank
44+
import eu.ibagroup.formainframe.utils.validateZosmfUrl
4045
import org.zowe.kotlinsdk.ChangePassword
4146
import org.zowe.kotlinsdk.annotations.ZVersion
4247
import java.awt.Component
@@ -59,10 +64,11 @@ class ConnectionDialog(
5964
* In case of DialogMode.UPDATE takes the last successful state from crudable, takes default state otherwise
6065
*/
6166
private val lastSuccessfulState: ConnectionDialogState =
62-
if(state.mode == DialogMode.UPDATE) crudable.find<ConnectionConfig> { it.uuid == state.connectionUuid }
67+
if (state.mode == DialogMode.UPDATE) crudable.find<ConnectionConfig> { it.uuid == state.connectionUuid }
6368
.findAny()
6469
.orElseGet { state.connectionConfig }
6570
.toDialogState(crudable) else ConnectionDialogState()
71+
6672
companion object {
6773

6874
/** Show Test connection dialog and test the connection regarding the dialog state.
@@ -81,11 +87,17 @@ class ConnectionDialog(
8187
initialState = initialState,
8288
factory = { ConnectionDialog(crudable, initialState, project) },
8389
test = { state ->
84-
val newTestedConnConfig : ConnectionConfig
90+
val newTestedConnConfig: ConnectionConfig
8591
if (initialState.mode == DialogMode.UPDATE) {
8692
val newState = state.clone()
8793
newState.initEmptyUuids(crudable)
88-
newTestedConnConfig = ConnectionConfig(newState.connectionUuid, newState.connectionName, newState.connectionUrl, newState.isAllowSsl, newState.zVersion)
94+
newTestedConnConfig = ConnectionConfig(
95+
newState.connectionUuid,
96+
newState.connectionName,
97+
newState.connectionUrl,
98+
newState.isAllowSsl,
99+
newState.zVersion
100+
)
89101
CredentialService.instance.setCredentials(
90102
connectionConfigUuid = newState.connectionUuid,
91103
username = newState.username,
@@ -97,7 +109,8 @@ class ConnectionDialog(
97109
CredentialService.instance.setCredentials(
98110
connectionConfigUuid = state.connectionUuid,
99111
username = state.username,
100-
password = state.password)
112+
password = state.password
113+
)
101114
}
102115
val throwable = runTask(title = "Testing Connection to ${newTestedConnConfig.url}", project = project) {
103116
return@runTask try {
@@ -169,7 +182,7 @@ class ConnectionDialog(
169182
EXPLORER_NOTIFICATION_GROUP_ID,
170183
"Unable to retrieve USS username",
171184
"Cannot retrieve USS username. An error happened while executing TSO request.\n" +
172-
"When working with USS files the same username will be used that was specified by the user when connecting.",
185+
"When working with USS files the same username will be used that was specified by the user when connecting.",
173186
NotificationType.WARNING
174187
).let {
175188
Notifications.Bus.notify(it, project)
@@ -215,7 +228,7 @@ class ConnectionDialog(
215228
textField()
216229
.bindText(state::connectionUrl)
217230
.validationOnApply {
218-
it.text = it.text.trim().removeTrailingSlashes()
231+
it.text = it.text.trim()
219232
validateForBlank(it) ?: validateZosmfUrl(it)
220233
}
221234
.also { urlTextField = it.component }

src/main/kotlin/eu/ibagroup/formainframe/dataops/attributes/RemoteUssAttributes.kt

+4-4
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,8 @@ data class RemoteUssAttributes(
7676
val gid: Long? = null,
7777
val groupId: String? = null,
7878
val modificationTime: String? = null,
79-
val symlinkTarget: String? = null
79+
val symlinkTarget: String? = null,
80+
var charset: Charset = DEFAULT_BINARY_CHARSET
8081
) : MFRemoteFileAttributes<ConnectionConfig, UssRequester>, Copyable {
8182

8283
/**
@@ -98,7 +99,8 @@ data class RemoteUssAttributes(
9899
gid = ussFile.gid,
99100
groupId = ussFile.groupId,
100101
modificationTime = ussFile.modificationTime,
101-
symlinkTarget = ussFile.target
102+
symlinkTarget = ussFile.target,
103+
charset = DEFAULT_BINARY_CHARSET
102104
)
103105

104106
/**
@@ -163,8 +165,6 @@ data class RemoteUssAttributes(
163165
|| mode == FileModeValue.READ_WRITE_EXECUTE.mode
164166
}
165167

166-
var charset: Charset = DEFAULT_BINARY_CHARSET
167-
168168
override var contentMode: XIBMDataType = XIBMDataType(XIBMDataType.Type.BINARY)
169169

170170
override val isCopyPossible: Boolean

src/main/kotlin/eu/ibagroup/formainframe/dataops/attributes/RemoteUssAttributesService.kt

+2-1
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,8 @@ class RemoteUssAttributesService(
8484
gid = newAttributes.gid,
8585
groupId = newAttributes.groupId,
8686
modificationTime = newAttributes.modificationTime,
87-
symlinkTarget = newAttributes.symlinkTarget
87+
symlinkTarget = newAttributes.symlinkTarget,
88+
charset = oldAttributes.charset
8889
)
8990
}
9091

src/main/kotlin/eu/ibagroup/formainframe/dataops/log/AbstractMFLoggerBase.kt

+7
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,13 @@ abstract class AbstractMFLoggerBase<PInfo: MFProcessInfo, LFetcher: LogFetcher<P
122122
this.onFinishHandler = finishHandler
123123
}
124124

125+
/**
126+
* Fetch log files
127+
*/
128+
override fun fetchLog() {
129+
logFetcher.fetchLog(mfProcessInfo)
130+
}
131+
125132
/**
126133
* Sets onNextLog handler.
127134
*/

src/main/kotlin/eu/ibagroup/formainframe/dataops/log/MFLogger.kt

+5
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,11 @@ interface MFLogger<LFetcher: LogFetcher<out MFProcessInfo>> {
3737
*/
3838
fun onLogFinished(finishHandler: () -> Unit)
3939

40+
/**
41+
* Fetch log files
42+
*/
43+
fun fetchLog()
44+
4045
/**
4146
* Sets handler for event after requesting next portion of mainframe log.
4247
* @param nextLogHandler handler that will be invoked after next request to fetching log from mainframe.

src/main/kotlin/eu/ibagroup/formainframe/dataops/operations/InfoOperationRunner.kt

+5-1
Original file line numberDiff line numberDiff line change
@@ -57,7 +57,11 @@ class InfoOperationRunner : OperationRunner<InfoOperation, SystemsResponse> {
5757
.cancelByIndicator(progressIndicator)
5858
.execute()
5959
if (!response.isSuccessful) {
60-
val headMessage = responseMessageMap[response.message()] ?: response.message()
60+
log.info("Test connection response: $response")
61+
val zosmfMessage = response.message().trim()
62+
val headMessage = if (zosmfMessage.isNotEmpty())
63+
responseMessageMap[zosmfMessage] ?: zosmfMessage
64+
else responseMessageMap["Unauthorized"] ?: zosmfMessage
6165
throw CallException(response, headMessage)
6266
}
6367
return response.body() ?: throw CallException(response, "Cannot parse z/OSMF info request body")

src/main/kotlin/eu/ibagroup/formainframe/dataops/operations/mover/CrossSystemMemberOrUssFileToPdsMover.kt

+12-5
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,8 @@ class CrossSystemMemberOrUssFileToPdsMoverFactory : OperationRunnerFactory {
4242
*/
4343
class CrossSystemMemberOrUssFileToPdsMover(val dataOpsManager: DataOpsManager) : AbstractFileMover() {
4444

45+
private val sourceContentType = "text/plain; charset=UTF-8"
46+
4547
/**
4648
* Checks that source is member or uss file, dest is partitioned data set, and they are located inside different systems.
4749
* @see OperationRunner.canRun
@@ -89,17 +91,22 @@ class CrossSystemMemberOrUssFileToPdsMover(val dataOpsManager: DataOpsManager) :
8991
else XIBMDataType(XIBMDataType.Type.TEXT)
9092

9193
val sourceContent = sourceFile.contentsToByteArray()
92-
val contentToUpload =
93-
if (sourceFile.fileType.isBinary) sourceContent
94-
else sourceContent.toString(sourceFile.charset).replace("\r\n", "\n")
95-
.toByteArray(DEFAULT_TEXT_CHARSET).addNewLine()
94+
95+
// do not convert bytes to default ISO. z/OSMF does this conversion by calling iconv and produce the desired result
96+
val contentToUpload = if (sourceFile.fileType.isBinary) sourceContent else
97+
sourceContent
98+
.toString(sourceFile.charset)
99+
.replace("\r\n", "\n")
100+
.toByteArray()
101+
.addNewLine()
96102

97103
val response = apiWithBytesConverter<DataAPI>(destConnectionConfig).writeToDatasetMember(
98104
authorizationToken = destConnectionConfig.authToken,
99105
datasetName = destAttributes.name,
100106
memberName = memberName,
101107
content = contentToUpload,
102-
xIBMDataType = xIBMDataType
108+
xIBMDataType = xIBMDataType,
109+
contentType = sourceContentType
103110
).applyIfNotNull(progressIndicator) { indicator ->
104111
cancelByIndicator(indicator)
105112
}.execute()

src/main/kotlin/eu/ibagroup/formainframe/dataops/operations/mover/CrossSystemUssDirMover.kt

+3-3
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ class CrossSystemUssDirMover(val dataOpsManager: DataOpsManager) : AbstractFileM
8686
sourceFileFetchProvider.reload(sourceQuery)
8787
}
8888

89-
val pathToDir = destAttributes.path + "/" + sourceFile.name
89+
val pathToDir = destAttributes.path + "/" + (operation.newName ?: sourceFile.name)
9090

9191
if (operation.forceOverwriting) {
9292
destFile.children.firstOrNull { it.name == sourceFile.name }?.let {
@@ -110,7 +110,7 @@ class CrossSystemUssDirMover(val dataOpsManager: DataOpsManager) : AbstractFileM
110110
val createdDirFile = attributesService.getOrCreateVirtualFile(
111111
RemoteUssAttributes(
112112
destAttributes.path,
113-
UssFile(sourceFile.name, "drwxrwxrwx"),
113+
UssFile(operation.newName ?: sourceFile.name, "drwxrwxrwx"),
114114
destConnectionConfig.url,
115115
destConnectionConfig
116116
)
@@ -153,4 +153,4 @@ class CrossSystemUssDirMover(val dataOpsManager: DataOpsManager) : AbstractFileM
153153
}
154154
log.info("USS directory has been moved successfully")
155155
}
156-
}
156+
}

src/main/kotlin/eu/ibagroup/formainframe/dataops/operations/mover/UssToUssFileMover.kt

+1-1
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ class UssToUssFileMover(private val dataOpsManager: DataOpsManager) : AbstractFi
106106
from = from,
107107
overwrite = operation.forceOverwriting,
108108
links = CopyDataUSS.Links.ALL,
109-
preserve = CopyDataUSS.Preserve.ALL,
109+
preserve = CopyDataUSS.Preserve.NONE,
110110
recursive = true
111111
),
112112
filePath = FilePath(

0 commit comments

Comments
 (0)