Skip to content

Commit 37edb36

Browse files
committed
Remove uses of ReflectiveCalls from Code
- remove need for reflection by using traits instead of structural typing since scala 3 has a different import scala.reflect.Selectables... from scala 2.13 which uses scala.language.reflectiveCalls. Neither import exist in the other version and are therefore incompatible, so the easiest approach was to get rid of structural typing in lieu of traits. - add comments for 2.12 phaseout - remove JDOMUtils DAFFODIL-2975
1 parent 3a8d6ba commit 37edb36

File tree

11 files changed

+43
-173
lines changed

11 files changed

+43
-173
lines changed

daffodil-io/src/main/scala/org/apache/daffodil/io/processors/charset/BitsCharsetDefinition.scala

+6-1
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,18 @@
1616
*/
1717
package org.apache.daffodil.io.processors.charset
1818

19+
import org.apache.daffodil.lib.util.SimpleNamedLoadableService
20+
1921
/**
2022
* These are the classes which must be dynamically loaded in order to add a charset implementation
2123
* to Daffodil. All charsets must implement this class and be added to the
2224
* org.apache.daffodil.runtime1.processors.charset.BitsCharsetDefinition file in
2325
* daffodil-io/src/main/resources/META-INF/services. name() must return a fully capitalized string
2426
*/
25-
abstract class BitsCharsetDefinition(charset: BitsCharset, alias: Option[String] = None) {
27+
abstract class BitsCharsetDefinition(
28+
charset: BitsCharset,
29+
alias: Option[String] = None
30+
) extends SimpleNamedLoadableService {
2631
final def name(): String = alias.getOrElse(charset.name).toUpperCase()
2732

2833
final def charset(): BitsCharset = charset

daffodil-lib/src/main/scala/org/apache/daffodil/lib/Implicits.scala

+3-4
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package org.apache.daffodil.lib
1919

2020
import java.io.{ BufferedInputStream, ByteArrayInputStream }
2121
import scala.language.implicitConversions
22-
import scala.language.reflectiveCalls
2322

2423
import org.apache.daffodil.lib.exceptions.Assert
2524
import org.apache.daffodil.lib.xml.NS
@@ -47,10 +46,10 @@ object Implicits {
4746

4847
/**
4948
* Used for reading/writing to database, files, etc.
50-
* Code From the book "Beginning Scala"
51-
* http://www.amazon.com/Beginning-Scala-David-Pollak/dp/1430219890
49+
* Code without reflection
50+
* TODO: scala 2.12 Phaseout. Replace with scala.util.Using
5251
*/
53-
def using[A <: { def close(): Unit }, B](param: A)(f: A => B): B =
52+
def using[A <: AutoCloseable, B](param: A)(f: A => B): B =
5453
try { f(param) }
5554
finally { param.close() }
5655

daffodil-lib/src/main/scala/org/apache/daffodil/lib/api/Validator.scala

+3-1
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717

1818
package org.apache.daffodil.lib.api
1919

20+
import org.apache.daffodil.lib.util.SimpleNamedLoadableService
21+
2022
import com.typesafe.config.Config
2123

2224
/**
@@ -35,7 +37,7 @@ trait Validator {
3537
*
3638
* The factory implementations are expected to be thread safe
3739
*/
38-
trait ValidatorFactory {
40+
trait ValidatorFactory extends SimpleNamedLoadableService {
3941

4042
/**
4143
* Unique name of this Validator service

daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/Misc.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -638,11 +638,11 @@ object Misc {
638638
}
639639
}
640640

641-
import scala.language.reflectiveCalls // scala 2.10 creates warning unless we have this.
642641
/**
643642
* Convenient I/O tools
643+
* TODO: scala 2.12 Phaseout. Replace with scala.util.Using
644644
*/
645-
def using[A <: { def close(): Unit }, B](param: A)(f: A => B): B =
645+
def using[A <: AutoCloseable, B](param: A)(f: A => B): B =
646646
try { f(param) }
647647
finally { param.close() }
648648

daffodil-lib/src/main/scala/org/apache/daffodil/lib/util/SimpleNamedServiceLoader.scala

+3-2
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ package org.apache.daffodil.lib.util
1919
import java.util.ServiceConfigurationError
2020
import java.util.ServiceLoader
2121
import scala.collection.mutable.ArrayBuffer
22-
import scala.language.reflectiveCalls
22+
23+
trait SimpleNamedLoadableService { def name(): String }
2324

2425
/**
2526
* Contains methods for dynamic loading of classes from the class path.
@@ -39,7 +40,7 @@ object SimpleNamedServiceLoader {
3940
* It must have a name member returning a string. It must have a default (no-arg) constructor.
4041
* @return A map from the name (string) to the corresponding instance of the class.
4142
*/
42-
def loadClass[T <: { def name(): String }](clazz: Class[T]): Map[String, T] = {
43+
def loadClass[T <: SimpleNamedLoadableService](clazz: Class[T]): Map[String, T] = {
4344
val thingName = Misc.getNameGivenAClassObject(clazz)
4445
val iter = ServiceLoader.load(clazz).iterator()
4546
val instanceBuf = new ArrayBuffer[T]

daffodil-lib/src/main/scala/org/apache/daffodil/lib/xml/JDOMUtils.scala

-117
This file was deleted.

daffodil-lib/src/main/scala/org/apache/daffodil/lib/xml/QNameBase.scala

-18
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ package org.apache.daffodil.lib.xml
1919

2020
import java.net.URI
2121
import java.net.URISyntaxException
22-
import scala.language.reflectiveCalls
2322
import scala.util.Try
2423

2524
import org.apache.daffodil.lib.api.UnqualifiedPathStepPolicy
@@ -486,23 +485,6 @@ final case class StepQName(prefix: Option[String], local: String, namespace: NS)
486485
case _ => Assert.usageError("other must be a NamedQName")
487486
}
488487
}
489-
490-
/**
491-
* Finds the matches in a list of things that have QNames.
492-
* Used for finding if a named path step has corresponding element declaration.
493-
*
494-
* Handles local or global matches
495-
*
496-
*/
497-
def findMatches[T <: { def namedQName: NamedQName }](candidates: Seq[T]): Seq[T] = {
498-
val matched = candidates.filter { x =>
499-
val other = x.namedQName
500-
val res = matches(other)
501-
res
502-
}
503-
matched
504-
}
505-
506488
}
507489

508490
protected trait RefQNameFactoryBase[T] {

daffodil-lib/src/test/scala/org/apache/daffodil/lib/util/TestXMLCatalogAndValidate.scala

+1-15
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ package org.apache.daffodil.lib.util
2020
import java.io.File
2121
import javax.xml.XMLConstants
2222
import javax.xml.parsers.SAXParser
23-
import scala.language.reflectiveCalls
2423
import scala.xml.Attribute
2524
import scala.xml.Elem
2625
import scala.xml.MetaData
@@ -31,8 +30,8 @@ import scala.xml.SAXParseException
3130
import scala.xml.Text
3231
import scala.xml.parsing.NoBindingFactoryAdapter
3332

33+
import org.apache.daffodil.lib.Implicits.using
3434
import org.apache.daffodil.lib.exceptions.Assert
35-
import org.apache.daffodil.lib.util.Implicits.using
3635
import org.apache.daffodil.lib.util.collections.Stack
3736
import org.apache.daffodil.lib.xml.DaffodilSAXParserFactory
3837
import org.apache.daffodil.lib.xml.NS
@@ -53,19 +52,6 @@ import org.xml.sax.InputSource
5352
import org.xml.sax.XMLReader
5453
import org.xml.sax.helpers.XMLFilterImpl
5554

56-
object Implicits {
57-
58-
/**
59-
* Used for reading/writing to database, files, etc.
60-
* Code From the book "Beginning Scala"
61-
* http://www.amazon.com/Beginning-Scala-David-Pollak/dp/1430219890
62-
*/
63-
def using[A <: { def close(): Unit }, B](param: A)(f: A => B): B =
64-
try { f(param) }
65-
finally { param.close() }
66-
67-
}
68-
6955
/**
7056
* The goal here is to integrate XML Catalog with XSD Validation, so that both
7157
* the DFDL Schema references to other DFDL Schema namespaces would be resolved via

daffodil-lib/src/test/scala/org/apache/daffodil/lib/xml/test/unit/TestXMLUtils.scala

-8
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import java.nio.file.StandardOpenOption
2424
import scala.xml._
2525

2626
import org.apache.daffodil.lib.util.Misc
27-
import org.apache.daffodil.lib.xml.JDOMUtils
2827
import org.apache.daffodil.lib.xml.NS
2928
import org.apache.daffodil.lib.xml.XMLUtils
3029

@@ -159,13 +158,6 @@ class TestXMLUtils {
159158
assertFalse(isSame)
160159
}
161160

162-
@Test def testIsNil(): Unit = {
163-
val d1 = JDOMUtils.elem2Element(<a xmlns:xsi={XMLUtils.XSI_NAMESPACE} xsi:nil="true"/>)
164-
val d2 = JDOMUtils.elem2Element(<a xmlns:xsi={XMLUtils.XSI_NAMESPACE}>foo</a>)
165-
assertTrue(JDOMUtils.isNil(d1))
166-
assertFalse(JDOMUtils.isNil(d2))
167-
}
168-
169161
@Test def testWalkUnicodeString1(): Unit = {
170162
val s = "abc"
171163
val Seq((ab, 'a', 'b'), ('a', 'b', 'c'), ('b', 'c', ca)) =

daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/dsom/CompiledExpression1.scala

+23-4
Original file line numberDiff line numberDiff line change
@@ -459,12 +459,31 @@ class DPathElementCompileInfo(
459459
matches(0)
460460
}
461461

462+
/**
463+
* Finds the matches in a list of DPathElementCompileInfo.
464+
* Used for finding if a named path step has corresponding element declaration.
465+
*
466+
* Handles local or global matches
467+
*
468+
*/
469+
def findMatches(
470+
step: StepQName,
471+
candidates: Seq[DPathElementCompileInfo]
472+
): Seq[DPathElementCompileInfo] = {
473+
val matched = candidates.filter { x =>
474+
val other = x.namedQName
475+
val res = step.matches(other)
476+
res
477+
}
478+
matched
479+
}
480+
462481
private def findNamedMatches(
463482
step: StepQName,
464483
possibles: Seq[DPathElementCompileInfo],
465484
expr: ImplementsThrowsOrSavesSDE
466485
): Seq[DPathElementCompileInfo] = {
467-
val matchesERD: Seq[DPathElementCompileInfo] = step.findMatches(possibles)
486+
val matchesERD: Seq[DPathElementCompileInfo] = findMatches(step, possibles)
468487

469488
val retryMatchesERD =
470489
if (
@@ -476,7 +495,7 @@ class DPathElementCompileInfo(
476495
// default namespace was assumed but didn't match, the unqualified path
477496
// step policy allows us to try to match NoNamespace elements.
478497
val noNamespaceStep = step.copy(namespace = NoNamespace)
479-
noNamespaceStep.findMatches(possibles)
498+
findMatches(noNamespaceStep, possibles)
480499
} else {
481500
matchesERD
482501
}
@@ -493,7 +512,7 @@ class DPathElementCompileInfo(
493512
step: StepQName,
494513
possibles: Seq[DPathElementCompileInfo]
495514
): Seq[DPathElementCompileInfo] = {
496-
val matchesERD = step.findMatches(possibles)
515+
val matchesERD = findMatches(step, possibles)
497516
val retryMatchesERD =
498517
if (
499518
matchesERD.isEmpty &&
@@ -504,7 +523,7 @@ class DPathElementCompileInfo(
504523
// default namespace was assumed but didn't match, the unqualified path
505524
// step policy allows us to try to match NoNamespace elements.
506525
val noNamespaceStep = step.copy(namespace = NoNamespace)
507-
noNamespaceStep.findMatches(possibles)
526+
findMatches(noNamespaceStep, possibles)
508527
} else {
509528
matchesERD
510529
}

daffodil-runtime1/src/main/scala/org/apache/daffodil/runtime1/layers/api/Layer.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
*/
1717
package org.apache.daffodil.runtime1.layers.api;
1818

19+
import org.apache.daffodil.lib.util.SimpleNamedLoadableService;
1920
import org.apache.daffodil.runtime1.layers.LayerRuntime;
2021
import org.apache.daffodil.runtime1.layers.LayerUtils;
2122

@@ -257,7 +258,7 @@
257258
* <p>
258259
* Unhandled exceptions thrown by the layer code are treated as fatal errors.
259260
*/
260-
public abstract class Layer {
261+
public abstract class Layer implements SimpleNamedLoadableService {
261262

262263
private final String localName;
263264
private final String targetNamespace;

0 commit comments

Comments
 (0)