Skip to content

Commit

Permalink
Merge branch 'private-release/v1.2.1-221' into zowe-release/v1.2.1-221
Browse files Browse the repository at this point in the history
Signed-off-by: Uladzislau <[email protected]>
  • Loading branch information
KUGDev committed Jun 3, 2024
2 parents 3b1e91e + 2fe96fb commit f198604
Show file tree
Hide file tree
Showing 12 changed files with 127 additions and 85 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,20 @@

package org.zowe.explorer.dataops.content.synchronizer

import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.application.runReadAction
import com.intellij.openapi.diagnostic.logger
import com.intellij.openapi.progress.ProgressIndicator
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.openapi.vfs.newvfs.events.VFileDeleteEvent
import com.intellij.openapi.vfs.newvfs.events.VFileEvent
import org.zowe.explorer.dataops.DataOpsManager
import org.zowe.explorer.dataops.attributes.FileAttributes
import org.zowe.explorer.dataops.attributes.RemoteUssAttributes
import org.zowe.explorer.editor.FileContentChangeListener
import org.zowe.explorer.utils.*
import org.zowe.explorer.vfs.MFBulkFileListener
import org.zowe.explorer.vfs.MFVirtualFileSystem
import java.io.IOException
import java.util.concurrent.ConcurrentHashMap

Expand All @@ -44,6 +49,17 @@ abstract class RemoteAttributedContentSynchronizer<FAttributes : FileAttributes>
}
}
)
subscribe(
componentManager = ApplicationManager.getApplication(),
topic = MFVirtualFileSystem.MF_VFS_CHANGES_TOPIC,
handler = object : MFBulkFileListener {
override fun after(events: List<VFileEvent>) {
events.filterIsInstance<VFileDeleteEvent>().forEach { event ->
fetchedAtLeastOnce.removeIf { it.file == event.file }
}
}
}
)
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ class SeqDatasetContentSynchronizer(
override fun accepts(file: VirtualFile): Boolean {
val isOurVFile = super.accepts(file)
return if (isOurVFile) {
val dsAttributes = attributesService.castOrNull<RemoteDatasetAttributes>()
val dsAttributes = dataOpsManager.tryToGetAttributes(file)?.castOrNull<RemoteDatasetAttributes>()
return dsAttributes != null
&& !dsAttributes.isMigrated
&& dsAttributes.datasetInfo.datasetOrganization != DatasetOrganization.VS
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,11 +89,6 @@ class RemoteToLocalFileMover(val dataOpsManager: DataOpsManager) : AbstractFileM
contentSynchronizer.synchronizeWithRemote(syncProvider, progressIndicator)
val sourceContent = contentSynchronizer.successfulContentStorage(syncProvider)

runWriteActionInEdtAndWait {
if (operation.forceOverwriting) {
destFile.children.filter { it.name == newFileName && !it.isDirectory }.forEach { it.delete(this) }
}
}
val createdFileJava = Paths.get(destFile.path, newFileName).toFile().apply { createNewFile() }
if (!sourceFile.fileType.isBinary) {
setCreatedFileParams(createdFileJava, sourceFile)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ import com.intellij.openapi.project.Project
import com.intellij.openapi.vfs.VirtualFile
import com.intellij.util.SmartList
import org.zowe.explorer.explorer.Explorer
import java.util.*
import java.util.concurrent.ConcurrentLinkedQueue
import java.util.LinkedList
import java.util.WeakHashMap
import java.util.concurrent.locks.ReentrantLock
import kotlin.concurrent.withLock

private val PROVIDERS = SmartList(FileExplorerTreeStructureProvider())

Expand All @@ -31,46 +33,51 @@ class CommonExplorerTreeStructure<Expl : Explorer<*, *>>(
private val rootNodeProvider: (explorer: Expl, project: Project, treeStructure: ExplorerTreeStructureBase) -> ExplorerTreeNode<*, *>
) : ExplorerTreeStructureBase(explorer, project) {

private val valueToNodeMap = Collections.synchronizedMap(
WeakHashMap<Any, ConcurrentLinkedQueue<ExplorerTreeNode<*, *>>>()
)
private val fileToNodeMap = Collections.synchronizedMap(
WeakHashMap<VirtualFile, ConcurrentLinkedQueue<ExplorerTreeNode<*, *>>>()
)
private val lock = ReentrantLock()

private val valueToNodeMap = WeakHashMap<Any, MutableCollection<ExplorerTreeNode<*, *>>>()
private val fileToNodeMap = WeakHashMap<VirtualFile, MutableCollection<ExplorerTreeNode<*, *>>>()

/**
* Put the node in the value to node map queue and the file to node map queue if the virtual file is present for the node
* Put the node in the value to node map list and the file to node map list if the virtual file is present for the node
* @param node the node to be registered
*/
override fun registerNode(node: ExplorerTreeNode<*, *>) {
valueToNodeMap.getOrPut(node.value) { ConcurrentLinkedQueue() }.add(node)
val file = node.virtualFile ?: return
fileToNodeMap.getOrPut(file) { ConcurrentLinkedQueue() }.add(node)
lock.withLock {
valueToNodeMap.getOrPut(node.value) { LinkedList() }.add(node)
node.virtualFile?.let { fileToNodeMap.getOrPut(it) { LinkedList() }.add(node) }
}
}

/**
* Get the nodes queue from value to node map by the provided value. Empty set will be returned if the queue is not found
* @param value the value to get the queue by
* Get the nodes list from value to node map by the provided value. Empty list will be returned if the list is not found
* @param value the value to get the list by
*/
@Suppress("UNCHECKED_CAST")
override fun <V : Any> findByValue(value: V): Collection<ExplorerTreeNode<*, V>> {
return valueToNodeMap[value] as Collection<ExplorerTreeNode<*, V>>? ?: emptySet()
return lock.withLock {
valueToNodeMap[value] as Collection<ExplorerTreeNode<*, V>>? ?: emptyList()
}
}

/**
* Search for the values in all the value to node map queues by predicate
* Search for the values in all the value to node map lists by predicate
* @param predicate the predicate to filter by
*/
override fun findByPredicate(predicate: (ExplorerTreeNode<*, *>) -> Boolean): Collection<ExplorerTreeNode<*, *>> {
return valueToNodeMap.values.flatten().filter(predicate)
return lock.withLock {
valueToNodeMap.values.flatten().filter(predicate)
}
}

/**
* Get the nodes queue from file to node map by the provided value. Empty set will be returned if the queue is not found
* @param file the virtual file to get the queue by
* Get the nodes list from file to node map by the provided value. Empty list will be returned if the list is not found
* @param file the virtual file to get the list by
*/
override fun findByVirtualFile(file: VirtualFile): Collection<ExplorerTreeNode<*, *>> {
return fileToNodeMap[file] ?: emptySet()
return lock.withLock {
fileToNodeMap[file] ?: emptyList()
}
}

private val root by lazy { rootNodeProvider(explorer, project, this) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import org.zowe.explorer.common.ui.DialogMode
import org.zowe.explorer.common.ui.DialogState
import org.zowe.explorer.common.ui.StatefulComponent
import org.zowe.explorer.dataops.attributes.RemoteDatasetAttributes
import org.zowe.explorer.utils.UNKNOWN_PARAM_VALUE
import org.zowe.explorer.utils.getParamTextValueOrUnknown
import org.zowe.kotlinsdk.DatasetOrganization
import org.zowe.kotlinsdk.HasMigrated
import javax.swing.JComponent
Expand Down Expand Up @@ -51,31 +53,31 @@ class DatasetPropertiesDialog(val project: Project?, override var state: Dataset
label("Dataset name type: ")
.widthGroup(sameWidthGroup)
textField()
.text(dataset.dsnameType?.toString() ?: "")
.text(getParamTextValueOrUnknown(dataset.dsnameType))
.applyToComponent { isEditable = false }
.horizontalAlign(HorizontalAlign.FILL)
}
row {
label("Catalog name: ")
.widthGroup(sameWidthGroup)
textField()
.text(dataset.catalogName ?: "")
.text(getParamTextValueOrUnknown(dataset.catalogName))
.applyToComponent { isEditable = false }
.horizontalAlign(HorizontalAlign.FILL)
}
row {
label("Volume serials: ")
.widthGroup(sameWidthGroup)
textField()
.text(dataset.volumeSerials ?: "")
.text(getParamTextValueOrUnknown(dataset.volumeSerials))
.applyToComponent { isEditable = false }
.horizontalAlign(HorizontalAlign.FILL)
}
row {
label("Device type: ")
.widthGroup(sameWidthGroup)
textField()
.text(dataset.deviceType ?: "")
.text(getParamTextValueOrUnknown(dataset.deviceType))
.applyToComponent { isEditable = false }
.horizontalAlign(HorizontalAlign.FILL)
}
Expand All @@ -100,7 +102,7 @@ class DatasetPropertiesDialog(val project: Project?, override var state: Dataset
DatasetOrganization.PS -> "Sequential (PS)"
DatasetOrganization.PO -> "Partitioned (PO)"
DatasetOrganization.POE -> "Partitioned Extended (PO-E)"
else -> ""
else -> UNKNOWN_PARAM_VALUE
}
)
.applyToComponent { isEditable = false }
Expand All @@ -110,39 +112,39 @@ class DatasetPropertiesDialog(val project: Project?, override var state: Dataset
label("Record format: ")
.widthGroup(sameWidthGroup)
textField()
.text(dataset.recordFormat?.toString() ?: "")
.text(getParamTextValueOrUnknown(dataset.recordFormat))
.applyToComponent { isEditable = false }
.horizontalAlign(HorizontalAlign.FILL)
}
row {
label("Record length: ")
.widthGroup(sameWidthGroup)
textField()
.text(dataset.recordLength?.toString() ?: "")
.text(getParamTextValueOrUnknown(dataset.recordLength))
.applyToComponent { isEditable = false }
.horizontalAlign(HorizontalAlign.FILL)
}
row {
label("Block size: ")
.widthGroup(sameWidthGroup)
textField()
.text(dataset.blockSize?.toString() ?: "")
.text(getParamTextValueOrUnknown(dataset.blockSize))
.applyToComponent { isEditable = false }
.horizontalAlign(HorizontalAlign.FILL)
}
row {
label("Size in tracks: ")
.widthGroup(sameWidthGroup)
textField()
.text(dataset.sizeInTracks?.toString() ?: "")
.text(getParamTextValueOrUnknown(dataset.sizeInTracks))
.applyToComponent { isEditable = false }
.horizontalAlign(HorizontalAlign.FILL)
}
row {
label("Space units: ")
.widthGroup(sameWidthGroup)
textField()
.text(dataset.spaceUnits?.toString() ?: "")
.text(getParamTextValueOrUnknown(dataset.spaceUnits))
.applyToComponent { isEditable = false }
.horizontalAlign(HorizontalAlign.FILL)
}
Expand All @@ -165,15 +167,15 @@ class DatasetPropertiesDialog(val project: Project?, override var state: Dataset
label("Used tracks (blocks): ")
.widthGroup(sameWidthGroup)
textField()
.text(dataset.usedTracksOrBlocks?.toString() ?: "")
.text(getParamTextValueOrUnknown(dataset.usedTracksOrBlocks))
.applyToComponent { isEditable = false }
.horizontalAlign(HorizontalAlign.FILL)
}
row {
label("Used extents: ")
.widthGroup(sameWidthGroup)
textField()
.text(dataset.extendsUsed?.toString() ?: "")
.text(getParamTextValueOrUnknown(dataset.extendsUsed))
.applyToComponent { isEditable = false }
.horizontalAlign(HorizontalAlign.FILL)
}
Expand All @@ -185,23 +187,23 @@ class DatasetPropertiesDialog(val project: Project?, override var state: Dataset
label("Creation date: ")
.widthGroup(sameWidthGroup)
textField()
.text(dataset.creationDate ?: "")
.text(getParamTextValueOrUnknown(dataset.creationDate))
.applyToComponent { isEditable = false }
.horizontalAlign(HorizontalAlign.FILL)
}
row {
label("Referenced date: ")
.widthGroup(sameWidthGroup)
textField()
.text(dataset.lastReferenceDate ?: "")
.text(getParamTextValueOrUnknown(dataset.lastReferenceDate))
.applyToComponent { isEditable = false }
.horizontalAlign(HorizontalAlign.FILL)
}
row {
label("Expiration date: ")
.widthGroup(sameWidthGroup)
textField()
.text(dataset.expirationDate ?: "")
.text(getParamTextValueOrUnknown(dataset.expirationDate))
.applyToComponent { isEditable = false }
.horizontalAlign(HorizontalAlign.FILL)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import org.zowe.explorer.dataops.operations.mover.MoveCopyOperation
import org.zowe.explorer.explorer.FileExplorerContentProvider
import org.zowe.explorer.utils.castOrNull
import org.zowe.explorer.utils.getMinimalCommonParents
import org.zowe.explorer.utils.runWriteActionInEdt
import org.zowe.explorer.utils.runWriteActionInEdtAndWait
import org.zowe.explorer.vfs.MFVirtualFile
import kotlin.concurrent.withLock

Expand Down Expand Up @@ -192,6 +192,19 @@ class ExplorerPasteProvider : PasteProvider {
) {
it.isIndeterminate = false
operations.forEach { op ->
// this step is necessary to clean old file after force overwriting performed
if (op.forceOverwriting) {
val nameResolver = dataOpsManager.getNameResolver(op.source, op.destination)
op.destination.children
.filter { file ->
file == nameResolver.getConflictingChild(op.source, op.destination) && !file.isDirectory
}
.apply {
runWriteActionInEdtAndWait {
forEach { file -> file.delete(this) }
}
}
}
explorerView.ignoreVFSChangeEvents.compareAndSet(false, true)
it.text = "${op.source.name} to ${op.destination.name}"
runCatching {
Expand All @@ -204,14 +217,6 @@ class ExplorerPasteProvider : PasteProvider {
if (explorerView.isCut.get()) {
copyPasteSupport.removeFromBuffer { node -> node.file == op.source }
}

// this step is necessary to clean old file after force overwriting performed.
if (op.forceOverwriting) {
val nameResolver = dataOpsManager.getNameResolver(op.source, op.destination)
op.destination.children
.filter { file -> file == nameResolver.getConflictingChild(op.source, op.destination) }
.forEach { file -> runWriteActionInEdt { file.delete(this) } }
}
}
.onFailure { throwable ->
explorerView.explorer.reportThrowable(throwable, project)
Expand Down
Loading

0 comments on commit f198604

Please sign in to comment.