stevedlawrence commented on a change in pull request #431: URL: https://github.com/apache/incubator-daffodil/pull/431#discussion_r505102879
########## File path: daffodil-lib/src/main/scala/org/apache/daffodil/util/Validators.scala ########## @@ -0,0 +1,71 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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 org.apache.daffodil.util + +import java.util.ServiceLoader + +import org.apache.daffodil.api.CompiledValidator +import org.apache.daffodil.api.Validator +import org.apache.daffodil.api.Validator.CompilerOps.CheckArgs +import org.apache.daffodil.api.ValidatorNotFoundException + +import scala.collection.JavaConverters._ + +object Validators { + val default: Validator = new DefaultValidatorSPIProvider + def compiler(): ValidatorCompiler = new Compiler + + trait ValidatorCompiler { + def find(name: String): Option[CompiledValidator] + def isRegistered(name: String): Boolean + def compile(name: String, args: Validator.ArgumentList): CompiledValidator + } + + private class Compiler extends ValidatorCompiler { + private var compiled = Map.empty[String, CompiledValidator] + private lazy val impls: Map[String, Validator] = + ServiceLoader + .load(classOf[Validator]) + .iterator() + .asScala + .map(v => v.name() -> v) + .toMap + Review comment: I guess then I'm interested with how the API will get fleshed out. Based on how the CLI uses validators, it feels like it's going to end up as something like this: ```scala dp.withValidator(Validator.Custom("sch", "key1=value1 key2=value2")) ``` Which feels somewhat akward to me. Yes, you get the benefit that you don't have to recompile your app when you want to change the validator, but it's sitll not just drop in a jar and go. You still need to give your app some mechanism to provide the validator name to use and provide configuration options. And the configuration options need to be representable as key/value pairs which feels limiting. And every validator would likely have differnt key names. So even though you don't need to recompile, you still need some mechamism to pick and configure different avilable validators. To me this kind of plugability seems useful for the CLI and those limitations/awkwardness feel reasonable since it is a CLI and not an pipeline orchestration engine. But as an API user, I would rather do something like: ```scala val validator = configureAndCompileValidatorOfChoice() dp.withValidation(validator) ``` If my app needs plugablity and the validators have simple configuration options, then I could always implement it much like you have using SPI and key/value pairs. But if my app has complex Validator's that need some configuration other then key/value pair strings (e.g. an open socket to connect to a rules engine, dynamically generated validation rules) where the preferable configuration is via code, then we still have that option. Note that this feels different to me than Daffodil's UserDefinedFunctions which also use SPI. But UDFs feel different because they literally are drop and go. There's no configuration that needs to be done or selection of which ones to use. You just drop in a UDF jar on the class path and if a schema uses a UDF by that name then we use it as is. ---------------------------------------------------------------- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. For queries about this service, please contact Infrastructure at: [email protected]
