Scala XML Elem Not Showing Up - scala

I have a class where I want a conditional Elem in xml to be added, but I am unable to do this. Please help.
The ShortName block is supposed to be conditional.
While debugging I see that get shortname gets executed. In fact if I try wrapping that in a dummy tag (<dummy>{getShortName().get}</dummy> ) everything works. But I need the condition outside.
Here's my class:
import scala.xml.Elem
class MyClass(rob: ROB, scalaDTO: ScalaDTO, robStatus: Status) {
val myRob =
<FeatureNames>
{val allPoiNames = rob.Identity.Names.get.ROB_Name
allPoiNames.map(robName => {
if (!robName.Type.contains("Shortened")) {
<FeatureName CaseAutoCorrectionEnabled="true">
{robName.Text.map(text => {
val transType = text.Trans_Type
transType match {
case None => {
{
<Name>
{text.value}
</Name>
{
//Executes but does not get added
getShortName().getOrElse(null)
}
<Language>
{robName.Language_Code}
</Language>
}
}
case _ => {
<OtherName>
{text.value}
</OtherName>
}
}
})}
</FeatureName>
}
})}
</FeatureNames>
private def getShortName(): Option[Elem] = {
val condition = true
if (condition) {
Some(
<ShortName>ShortName</ShortName>
)
} else {
None
}
}
override def toString: String = {
val prettyPrinter = new scala.xml.PrettyPrinter(150, 2)
prettyPrinter.format(scala.xml.Utility.trim(myRob))
}
}
My output looks like:
<FeatureNames>
<FeatureName CaseAutoCorrectionEnabled="true">
<Language>ENF</Language>
<OtherName>The Name</OtherName>
</FeatureName>
</FeatureNames>
Note the Missing Name Tag,moving it below the getShortName() line prints it fine

For this kind of logic, you can express it as a NodeSeq instead of mixing it in with xml literals.
Something like:
case None =>
NodeSeq.fromSeq(Seq(<Name>{text.value}</Name>, getShortName().orNull, <Language>{robName.Language_Code}</Language>))

Related

How to skip "ArrayIndexOutOfBoundsException: 0" from a Scala function (return type: Iterator String Array)?

I have a Scala function as shown below. Input neighborhood is array of strings. However, sometimes it (i.e. neighborhood) can be empty. In that case I get "ArrayIndexOutOfBoundsException", which is understandable. I want to avoid this exception. I mean, my code has to skip this error and move on to the next job (not shown here).
I tried this:
if(neighborhood.isEmpty){
true
} else {
val key = neighborhood(0)
neighborhood
.filterNot { _.equals(key) }
.combinations(k - 1)
}
But IntelliJ shows 'type mismatch between iterator and boolean.'
How to deal with this? I am newbie in Scala. Thanks!
Here is original function:
private def scanData(neighborhood: Array[String], k: Int): Iterator[Array[String]] = {
val key = neighborhood(0)
neighborhood
.filterNot { _.equals(key) }
.combinations(k - 1)
}
```scala
You can make use of headOption for a clean approach.
neighborhood.headOption.map { key =>
neighborhood.tail
.filterNot(_ == key)
.combinations(k-1)
}.getOrElse(Iterator.empty)
Use Option. You may find information here. Here you are en example :
object Run {
def main(args:Array[String]):Unit = {
val neighborhood:Array[String] = Array("1", "2","3")
val k = 1
val isa = geta(emptyArray) match {
case Some(isa) => scanData(neighborhood,k)
case None => Array.empty
}
}
def scanData(neighborhood: Array[String], k: Int): Iterator[Array[String]] = {
val key = neighborhood(0)
neighborhood
.filterNot { _.equals(key) }
.combinations(k - 1)
}
def geta(neighborhood:Array[String]):Option[Array[String]] = {
if(neighborhood.isEmpty){
return None;
} else {
return Some(neighborhood)
}
}
}

Scala missing parameter type for expanded function The argument types of an anonymous function must be fully known. (SLS 8.5)

I have the following snippet I need to complete for an assignment. To fulfill the asignment I have to correctly replace the comments /*fulfill ...*/. However I tried my best and I am still getting an
missing parameter type for expanded function The argument types of an anonymous function must be fully known. (SLS 8.5) error.
I found similar questions related to this error. However I could not derive a solution for my paticular problem of those answers.
So the target is to check whether the events fulfill the properties.
I am glad for every hint.
This is the code I need to complete:
import scala.collection.mutable.MutableList
abstract class Event
case class Command(cmdName: String) extends Event
case class Succeed(cmdName: String) extends Event
case class Fail(cmdName: String) extends Event
class Property(val name: String, val func: () => Boolean)
class Monitor[T] {
val properties = MutableList.empty[Property]
// (propName: String)(formula: => Boolean) was inserted by me
def property(propName: String)(formula: => Boolean) /* fulfill declaration here */ {
properties += new Property(propName, formula _)
}
var eventsToBeProcessed = List[T]()
def check(events: List[T]) {
for (prop <- properties) {
eventsToBeProcessed = events
println(prop.func())
}
}
def require(func: PartialFunction[T, Boolean]):Boolean = {
/* Fulfill body */
// This is what I came up with and what throws the compilation error
// case event:T => if (func.isDefinedAt(event)) Some(func(event)) else None
// Edit 1: Now I tried this but it prints that properties evaluate to false
var result = true
for (event <- eventsToBeProcessed){
if (func.isDefinedAt(event)){
result = result && func(event)
}
}
return result
}
}
class EventMonitor extends Monitor[Event] {
property("The first command should succeed or fail before it is received again") {
require {
case Command(c) =>
require {
case Succeed(`c`) => true
case Fail(`c`) => true
case Command(`c`) => false
}
}
}
property("The first command should not get two results") {
require {
case Succeed(c) =>
require {
case Succeed(`c`) => false
case Fail(`c`) => false
case Command(`c`) => true
}
case Fail(c) =>
require {
case Succeed(`c`) => false
case Fail(`c`) => false
case Command(`c`) => true
}
}
}
property("The first command should succeed") {
/* Add a property definition here which requires that the first command does not fail.
* It should yield OK with the events listed in the main method.
*/
// This is what I came up with
require{
case Command(c) =>
require{
case Succeed(`c`)=> true
case Fail(`c`) => false
}
}
}
}
object Checker {
def main(args: Array[String]) {
val events = List(
Command("take_picture"),
Command("get_position"),
Succeed("take_picture"),
Fail("take_picture")
)
val monitor = new EventMonitor
monitor.check(events)
// Desired output should be "true false true"
}
}
You wrote require function that returns T => Option[Boolean] intead of Boolean.
You should rewrite it on something like this:
def require(func: PartialFunction[T, Boolean]):Boolean = {
val left = eventsToBeProcessed.dropWhile(!func.isDefinedAt(_))
left.headOption.forall(head => {
eventsToBeProcessed = left.tail
func(head)
})
}

closing file pointer in Scala in Finally

In the following code, I am reading no. of lines from a file. If something goes wrong, I'll like to close the file pointer. But how can I find out if f contains valid pointer or not?
def countLines(filename:String):Option[Int] = {
try{
val f = Source.fromFile(filename)
println(s"no. of lines ${f.getLines().size}")
Some(f.getLines.size)
} catch {
case ex: FileNotFoundException => {
println(s"file ${filename} not found")
None
}
} finally {
//f might not be a valid pointer depending on when the error occured
}
}
The book I am reading uses var to maintain state (if f is valid or not) but I am trying to avoid it for sake of using only immutable variables.
def countLines(filename:String):Option[Int] = {
var f:Option[Source] = None
try{
f = Some(Source.fromFile(filename))
println(s"no. of lines ${f.get.getLines().size}")
Some(f.get.getLines.size)
} catch {
case ex: FileNotFoundException => {
println(s"file ${filename} not found")
None
}
} finally {
for(i<-f){
println("closing file")
i.close()
}
}
}
A double Try(). This closes the io resource even if the getLines() fails, but only if the fromFile() succeeds.
import scala.util.Try
def countLines(filename: String): Option[Int] =
Try(io.Source.fromFile(filename)).fold(_ => None, {f =>
val count = Try(f.getLines().length)
f.close()
count.toOption
})
What do you think about this?
If you want Scala-way - i think it's good example for your task:
def countLines(filename: String): Try[Int] = Try(Source.fromFile(filename).getLines.toList.size)
def test() = {
val filename = "/etc/passwd"
countLines(filename) match {
case Success(n) => println(n)
case Failure(f) => println(f)
}
}
When n - is a number of our lines, and f - is a Throwable.
How about this:
def countLines(filename: String): Option[Int] = {
val file = Try(Source.fromFile(filename))
val count = file.map(_.getLines().size)
(for {
_ <- count.recoverWith { case _ => file.map(_.close()) }
lineCount <- count
} yield lineCount).toOption
}
Let's analyze it:
If file does not exist we will have failed Try instance and method returns None. In this case you do not need to clear any resources as no actual stream was created.
If getLines fails for any reason or anything else during processing goes south we will close created stream in first line of for comprehension
Hope it helps
Simply, how about this:
def numLines(fileName:String):Option[Int] = {
try {
val f = scala.io.Source.fromFile(fileName)
try { Some(f.getLines.size) }
catch { case ex: IOException =>
Console.err.println("i/o excetion")
None
}
finally { f.close() }
}
catch {
case ex: FileNotFoundException =>
Console.err.println("file not found")
None
}
}

In scala, check non nullity and apply method directly?

With the following definitions:
class Test {
var activated: Boolean = false
}
def maybeTest(): Test = {
if(...) {
val res = new Test
if(...) res.activated = true
} else null
}
I am having a lot of if structures like this one:
val myobject = maybeTest()
if(myobject != null && myobject.activated) {
// Do something that does not care about the object
}
I would like to condensate it a little bit. Is there a nice way to define/write something like this to avoid a nullPointerException:
if(maybeTest() &&> (_.activated)) {
...
}
What is a best way of achieving this in scala?
You can wrap such code in Option like this:
class Test(num: Int) {
def someNum = num
}
val test: Test = null
Option(test).map(t => t.someNum)
In this example if your variable is null then you will get None, otherwise just work with Some(value)
Update
If you don't want to use Option, then you can define such function
class Test(num: Int) {
def give = num
}
def ifDefAndTrue[T, K](obj: T)(ifTrue: T => Boolean)(then: => K) {
if (obj != null && ifTrue(obj))
then
}
In your case this look like this:
val test = new Test // assuming that activated is false
ifDefAndTrue(test)(_.activate) {
println("results in unit")
}
But it contains side effect and not functional
How about
for {m <- Option(maybeTest())
if m.activated
}
{
... // do something with non-null, activated, m
}
Found the best way with implicit classes, which properly handles the null case (although it might not be the most efficient way).
implicit class CheckNull[T](obj: T) {
def call(f: T => Unit): Unit = if(obj != null) f(obj) else ()
def is(f: T => Boolean): Boolean = if(obj != null) f(obj) else false
}
So I can write a type safe method and even calls:
if(maybeTest() is (_.activated)) {
...
}
myObjectMaybeNull call (_.pause())
Note that parenthesis around (_.activated) are necessary.

How to generalize a method?

I'm trying to generalize the following code:
def fetchUrl = {
try {
val lineList = Source.fromURL(url).getLines.toList
process(lineList)
}
catch {
case ex: java.net.UnknownHostException => ex.printStackTrace()
}
}
I want to be able to fetch URL's (fromURL) and files (fromFile) with the same method. Is it possible to generalize this code to archive this?
I figured I could use pattern matching for this but I don't know how.
def fetchSource(src: Source, str: String) = src match {
case ??? => Source.fromURL(url).getLines.toList
case ??? => Source.fromFile(str).getLines.toList
}
Is there a way to get this right?
Thanks in advance.
You could check if a string is a Url (for this example I'm using java.net.URL, but you can do it with UrlValidator as well)
Something like this:
def isUrl(url: String) = try {
new java.net.URL(url)
true
} catch {
case _ => false
}
import scala.io.Source
def fetchSource(src:String) = if(isUrl(src)) {
Source.fromURL(src).getLines.toList
} else {
Source.fromFile(src).getLines.toList
}
The simplest solution is to have one method that will fetch a given Source, and two wrapper methods that build Source from File or URL.
def fetchSource(source: io.Source) =
try {
val lineList = source.getLines.toList
process(lineList)
} catch {
case ex: java.net.UnknownHostException => ex.printStackTrace()
}
def fetchFile(file: java.io.File) = fetchSource(io.Source.fromFile(file))
def fetchUrl(url: java.net.URL) = fetchSource(io.Source.fromURL(url))