name.remal.gradle_plugins.dsl.utils.registerCloseable.kt Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of gradle-plugins-kotlin-dsl Show documentation
Show all versions of gradle-plugins-kotlin-dsl Show documentation
Remal Gradle plugins: gradle-plugins-kotlin-dsl
package name.remal.gradle_plugins.dsl.utils
import com.google.common.base.FinalizablePhantomReference
import com.google.common.base.FinalizableReferenceQueue
import name.remal.concurrentSetOf
import name.remal.gradle_plugins.dsl.extensions.GRADLE
import org.gradle.BuildListener
import org.gradle.BuildResult
import org.gradle.api.initialization.Settings
import org.gradle.api.invocation.Gradle
import java.io.Closeable
import java.lang.ref.Reference
import java.lang.ref.WeakReference
import java.util.concurrent.atomic.AtomicBoolean
private val closeableReferences = concurrentSetOf>()
private val finalizableReferenceQueue = FinalizableReferenceQueue().also { queue ->
Runtime.getRuntime().addShutdownHook(Thread { queue.close() })
}
private val gradleHolder: Gradle? by lazy { GRADLE }
fun registerCloseable(closeable: T): T {
val isClosed = AtomicBoolean(false)
val buildListener = object : BuildListener {
private val weakReference = WeakReference(closeable)
override fun buildFinished(result: BuildResult?) {
if (isClosed.compareAndSet(false, true)) {
weakReference.get()?.apply {
getGradleLogger(javaClass.name).debug("Closing {}: {}", javaClass.name, this)
try {
close()
} catch (e: Exception) {
getGradleLogger(javaClass.name).error("Error occurred while closing ${javaClass.name}: $this: $e", e)
}
}
}
}
override fun settingsEvaluated(settings: Settings?) {
// do nothing
}
override fun projectsLoaded(gradle: Gradle?) {
// do nothing
}
override fun buildStarted(gradle: Gradle?) {
// do nothing
}
override fun projectsEvaluated(gradle: Gradle?) {
// do nothing
}
}
gradleHolder?.addListener(buildListener)
closeableReferences.add(object : FinalizablePhantomReference(closeable, finalizableReferenceQueue) {
override fun finalizeReferent() {
gradleHolder?.removeListener(buildListener)
if (isClosed.compareAndSet(false, true)) {
closeable.apply {
getGradleLogger(javaClass.name).debug("Closing {}: {}", javaClass.name, this)
try {
close()
} catch (e: Exception) {
getGradleLogger(javaClass.name).error("Error occurred while closing ${javaClass.name}: $this: $e", e)
}
}
}
closeableReferences.remove(this)
}
})
return closeable
}
fun registerIfCloseable(obj: T): T {
if (obj is Closeable) {
registerCloseable(obj)
}
return obj
}