nextflow.config.CascadingConfig.groovy Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of nextflow Show documentation
Show all versions of nextflow Show documentation
A DSL modelled around the UNIX pipe concept, that simplifies writing parallel and scalable pipelines in a portable manner
/*
* Copyright 2013-2024, Seqera Labs
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package nextflow.config
import java.lang.reflect.Method
import groovy.transform.CompileDynamic
import groovy.transform.CompileStatic
import groovy.transform.Memoized
/**
* Configuration object which fallback to a parent {@link CascadingConfig} object
* when an attribute value is missing.
*
* @see ConfigField
*
* @author Paolo Di Tommaso
*/
@CompileStatic
abstract class CascadingConfig {
protected Map config = [:]
protected CascadingConfig parent
CascadingConfig() {}
CascadingConfig(Map config, CascadingConfig parent) {
this.config = config
this.parent = parent
config.keySet().each { K it -> checkField(it) }
}
@CompileDynamic
private Set discoverFields(Closure accept) {
def result = new HashSet()
def clazz = this.getClass()
while( clazz != null ) {
def methods = clazz.getMethods()
def names = (methods as List)?.findResults { field ->
def annotation = field.getAnnotation(ConfigField)
if( annotation && accept(annotation) )
return annotation.value() ?: field.getName().replaceFirst('^get','').uncapitalize()
return null
}
result.addAll(names)
clazz = clazz.getSuperclass()
}
return result ?: Collections.emptySet()
}
@Memoized
protected Set validFields() {
return discoverFields({ true })
}
protected Set privateFields() {
return discoverFields({ ConfigField field -> field._private() })
}
final protected void checkField(K name) throws IllegalArgumentException {
def fields = validFields()
if( !fields.contains(name.toString()) )
throw new IllegalArgumentException("Not a valid config attribute: `$name`")
}
protected Map copyPublicAttributes() {
def skip = privateFields()
def copy = new LinkedHashMap()
this.config.each { k,v -> if(!skip.contains(k)) copy[k]=v }
return copy
}
boolean isEmpty() { config.isEmpty() }
boolean containsAttribute( K key ) {
config.containsKey(key) ?: ( parent ? parent.containsAttribute(key) : false )
}
V getAttribute(K key) {
getAttribute(key, null)
}
V getAttribute(K key, V defValue) {
checkField(key)
return config.containsKey(key) ? config.get(key) : ( parent && parent.containsAttribute(key) ? parent.getAttribute(key) : defValue )
}
V getOrCreateAttribute(K key, Closure missing) {
def result = getAttribute(key)
if( result == null ) {
result = missing.call()
config.put(key, result)
}
return result
}
void setAttribute( K key, V value ) {
checkField(key)
config.put(key,value)
}
Set getAttributeNames() {
new HashSet(config.keySet())
}
/**
* Convert this object to an equivalent {@link ConfigObject}
*
* @return A {@link ConfigObject} holding the same data
*/
ConfigObject toConfigObject() {
toConfigObject0(this.config)
}
@CompileDynamic
protected ConfigObject toConfigObject0( Map map ) {
def result = new ConfigObject()
map.each { key, value ->
if( value instanceof Map ) {
result.put( key, toConfigObject0((Map)value) )
}
else if( value instanceof CascadingConfig ) {
result.put( key, value.toConfigObject() )
}
else {
result.put( key, value )
}
}
return result
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy