I have code written in Scala that reads annotations decorating other Scala classes. These annotations are written in Java. The sticking point is that annotations don't allow advanced data structures, and one of these annotations is a wrapper that contains an array of other annotations. This is where Scala starts throwing a fit. The following is my solution:

import java.util

import scala.collection.JavaConversions._
import scala.collection.mutable
import scala.io.Source

val line = "package.structure.leading.to.annotated.Class"
val anns = AnnotationUtils.getAllAnnotationsInheritted(Class.forName(line).newInstance.getClass)

var attributesMap = mutable.Map[String, Map[String, String]]()

for (ann <- anns) {
    if (ann.annotationType == classOf[Attributes]) {
      for (attr <- List(ann.asInstanceOf[Attributes].value)) {

        val i = new util.ArrayList[Attribute](asJavaCollection(attr))
        for (a <- i) {
          attributesMap += a.attributeName -> Map(
            "type" -> a.attributeType,
            "description" -> a.attributeDescription,
            "optional" -> a.attributeDescription(),
            "pattern" -> a.valueMatchPattern,
            "default" -> a.defaultValue,
            "options" -> asJavaCollection(a.attributeOptions).mkString(", "),
            "excludes" -> asJavaCollection(a.excludesAttributes).mkString(", "),
            "requires" -> asJavaCollection(a.requiresAttributes).mkString(", "),
            "someOf" -> asJavaCollection(a.someOfTheseAttributes).mkString(", "))
          println(asJavaCollection(a.attributeOptions).mkString(", "))

Most of the actual processing has been removed to highlight the part I'm finding really ugly.

The Attributes class is the wrapper annotation, and is declared like this:

public @interface Attributes {
    Attribute[] value();

Attribute is the class with the actual information and is defined like this:

public @interface Attribute {
    String attributeName();
    String attributeType();
    String attributeDescription();
    String valueMatchPattern() default ".*";
    String optional() default "false";
    String defaultValue() default "N/A";
    String [] attributeOptions() default {};
    String [] excludesAttributes() default {};
    String [] requiresAttributes() default {};
    String [] someOfTheseAttributes() default {};

I find the constant switching back and forth between Scala and Java datatypes to be terrible code and difficult to read. Is there a better way to do this?


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.