app/drivers/objectmatrix/MxsMetadata.scala (65 lines of code) (raw):

package drivers.objectmatrix import java.time.{Instant, LocalDateTime, ZoneOffset, ZonedDateTime} import com.om.mxs.client.japi.Attribute import org.slf4j.LoggerFactory case class MxsMetadata (stringValues:Map[String,String], boolValues:Map[String,Boolean], longValues:Map[String,Long], intValues:Map[String,Int]) { private val logger = LoggerFactory.getLogger(getClass) /** * converts the data to a Seq[com.om.mxs.client.japi.Attribute], suitable for passing to ObjectMatrix API calls * @return sequence of Attributes. */ def toAttributes:Seq[Attribute] = { stringValues.map(entry=> Option(entry._2).map(realValue=>Attribute.createTextAttribute(entry._1,realValue,true)) ).toSeq.collect({case Some(attrib)=>attrib}) ++ boolValues.map(entry=>new Attribute(entry._1,entry._2,true)) ++ longValues.map(entry=>new Attribute(entry._1, entry._2, true)) ++ intValues.map(entry=>new Attribute(entry._1, entry._2, true)) } /** * convenience function to set a string value. Internally calls `withValue`. * @param key key to set * @param value string value to set it to * @return and updated [[MxsMetadata]] object */ def withString(key:String, value:String):MxsMetadata = { withValue[String](key,value) } /** * sets the given value for the given key and returns an updated [[MxsMetadata]] object. * if the type of `value` is not supported, then it emits a warning and returns the original [[MxsMetadata]] * @param key key to identify the metadata * @param value value to set. This must be either Boolean, String, Int, Long or ZonedDateTime. ZonedDateTime is converted * to epoch millisenconds and stored as a long * @tparam T the data type of `value`. Normally the compiler can infer this from the argument * @return an updated [[MxsMetadata]] object */ def withValue[T](key:String, value:T):MxsMetadata = { value match { case boolValue: Boolean => this.copy(boolValues = this.boolValues ++ Map(key -> boolValue)) case stringValue: String => this.copy(stringValues = this.stringValues ++ Map(key -> stringValue)) case intValue: Int => this.copy(intValues = this.intValues ++ Map(key -> intValue)) case longValue: Long => this.copy(longValues = this.longValues ++ Map(key -> longValue)) case timeValue: ZonedDateTime => this.copy(longValues = this.longValues ++ Map(key -> timeValue.toInstant.toEpochMilli)) case timeValue: LocalDateTime => this.copy(longValues = this.longValues ++ Map(key -> timeValue.toInstant(ZoneOffset.UTC).toEpochMilli)) case instant: Instant => this.copy(longValues = this.longValues ++ Map(key -> instant.toEpochMilli)) case _ => logger.warn(s"Could not set key $key to value $value (type ${value.getClass.toGenericString}), type not recognised") this } } def toSymbolMap:Map[Symbol,String] = stringValues.map(tuple=>(Symbol(tuple._1), tuple._2)) ++ boolValues.map(tuple=>(Symbol(tuple._1), tuple._2.toString)) ++ longValues.map(tuple=>(Symbol(tuple._1), tuple._2.toString)) ++ intValues.map(tuple=>(Symbol(tuple._1), tuple._2.toString)) def dumpString(fieldNames:Seq[String]) = { val kv = fieldNames.map(fieldName=>{ val maybeString = stringValues.get(fieldName) val maybeBool = boolValues.get(fieldName) val maybeLong = longValues.get(fieldName) val maybeInt = intValues.get(fieldName) val v = if(maybeString.isDefined){ maybeString.get } else if(maybeBool.isDefined){ if(maybeBool.get){ "true" } else { "false" } } else if(maybeLong.isDefined){ maybeLong.get.toString } else if(maybeInt.isDefined){ maybeInt.get.toString } else { "(none)" } s"$fieldName=$v" }) kv.mkString(", ") } } object MxsMetadata { def apply(stringValues: Map[String, String], boolValues: Map[String, Boolean], longValues: Map[String, Long], intValues: Map[String, Int]): MxsMetadata = new MxsMetadata(stringValues, boolValues, longValues, intValues) }