Extract specific token out of ANTLR Parse Tree - java

i'm trying to extract data from the ANTLR parse tree, but not fully grasping how this should be done correctly
Let's say i have the following two SQL queries:
// language=SQL
val sql3 = """
CREATE TABLE session(
id uuid not null
constraint account_pk
primary key,
created timestamp default now() not null
)
""".trimIndent()
// language=SQL
val sql4 = """
CREATE TABLE IF NOT EXISTS blah(
id uuid not null
constraint account_pk
primary key,
created timestamp default now() not null
)
""".trimIndent()
Now i parse both of them:
val visitor = Visitor()
listOf(sql3, sql4).forEach { sql ->
val lexer = SQLLexer(CharStreams.fromString(sql))
val parser = SQLParser(CommonTokenStream(lexer))
visitor.visit(parser.sql())
println(visitor.tableName)
}
In my visitor if i visit the tableCreateStatement, i get the parse tree, but obviously just grabbing child1 will work for sql3, but not for sql4 since child1 in sql4 is IF NOT EXISTS
class Visitor : SQLParserBaseVisitor<Unit>() {
var tableName = ""
override fun visitCreate_table_statement(ctx: SQLParser.Create_table_statementContext?) {
tableName = ctx?.getChild(1)?.text ?: ""
super.visitCreate_table_statement(ctx)
}
}
Is there a way to find a specific token in the parse tree?
I'm assuming the payload has something to do with it, but since it's of type Any, i'm not sure what to check it against
override fun visitCreate_table_statement(ctx: SQLParser.Create_table_statementContext?) {
ctx?.children?.forEach {
if (it.payload.javaClass == SQLParser::Schema_qualified_nameContext) {
tableName = it.text
}
}
super.visitCreate_table_statement(ctx)
}
EDIT: the .g4 files are from
https://github.com/pgcodekeeper/pgcodekeeper/tree/master/apgdiff/antlr-src

this seems to work
override fun visitCreate_table_statement(ctx: SQLParser.Create_table_statementContext?) {
ctx?.children?.forEach {
if (it.payload.javaClass == Schema_qualified_nameContext::class.java) {
tableName = it.text
}
}
super.visitCreate_table_statement(ctx)
}
For branching trees
fun walkLeaves(
childTree: ParseTree = internalTree,
leave: (childTree: ParseTree) -> Unit) {
if (childTree.childCount == 0) {
if (!childTree.text?.trim().isNullOrBlank()) {
leave(childTree)
}
} else {
for (i in 0 until childTree.childCount) {
walkLeaves(childTree = childTree.getChild(i), leave = leave)
}
}
}
fun extractSQL(
childTree: ParseTree,
tokens: MutableList<String> = mutableListOf()
): String {
walkLeaves(childTree = childTree) { leave ->
tokens.add(leave.text)
}
...
}

Related

Convert DDL String to Spark structType?

I have hive/redshift tables and I want to create a spark data frame with precisely the DDL of the original tables, written in JAVA. Is there an option to achieve that?
I think maybe is better to convert the DDL string to Spark schema json, and from that create a df struct type. I started to investiage the spark parser api
String ddlString = "CREATE TABLE data.baab (" +
"id STRING, " +
"test STRING, " +
"test2 STRING, " +
"audit STRUCT<createdDate: TIMESTAMP, createdBy: STRING, lastModifiedDate: TIMESTAMP, lastModifiedBy: STRING>) " +
"USING parquet " +
"LOCATION 's3://test.com' " +
"TBLPROPERTIES ('transient_lastDdlTime' = '1676593278')";
SparkSqlParser parser = new SparkSqlParser();
and I cant see anything that related to ddl parser:
override def parseDataType(sqlText : _root_.scala.Predef.String) : org.apache.spark.sql.types.DataType = { /* compiled code */ }
override def parseExpression(sqlText : _root_.scala.Predef.String) : org.apache.spark.sql.catalyst.expressions.Expression = { /* compiled code */ }
override def parseTableIdentifier(sqlText : _root_.scala.Predef.String) : org.apache.spark.sql.catalyst.TableIdentifier = { /* compiled code */ }
override def parseFunctionIdentifier(sqlText : _root_.scala.Predef.String) : org.apache.spark.sql.catalyst.FunctionIdentifier = { /* compiled code */ }
override def parseMultipartIdentifier(sqlText : _root_.scala.Predef.String) : scala.Seq[_root_.scala.Predef.String] = { /* compiled code */ }
override def parseTableSchema(sqlText : _root_.scala.Predef.String) : org.apache.spark.sql.types.StructType = { /* compiled code */ }
override def parsePlan(sqlText : _root_.scala.Predef.String) : org.apache.spark.sql.catalyst.plans.logical.LogicalPlan = { /* compiled code */ }
protected def astBuilder : org.apache.spark.sql.catalyst.parser.AstBuilder
protected def parse[T](command : _root_.scala.Predef.String)(toResult : scala.Function1[org.apache.spark.sql.catalyst.parser.SqlBaseParser, T]) : T = { /* compiled code */ }
this is what I tried:
StructType struct = null;
Pattern pattern = Pattern.compile("\\(([^()]*)\\)");
Matcher matcher = pattern.matcher(ddlString);
if (matcher.find()) {
String result = matcher.group(1);
struct = StructType.fromDDL(result);
}
return struct;
this is work, but I afraid that this solution will not covert all the cases.
Any suggestions?

Bluetooth LE - How do i get Advertisement Interval in milliseconds?

I have to get the Advertisement Interval in milliseconds. I used result.periodicAdvertisingInterval but this returns 0. I have to implement something like this:
private val scanCallback = object : ScanCallback(){
#RequiresApi(Build.VERSION_CODES.N)
#SuppressLint("MissingPermission", "NotifyDataSetChanged")
override fun onScanResult(callbackType: Int, result: ScanResult) {
val scanJob = CoroutineScope(Dispatchers.Main).launch {
val tag = deviceMap.computeIfAbsent(result.device.address) {
val newTag = BleTag(result.device.name ?: "Unbekannt", result.device.address, result.rssi , result.scanRecord?.bytes, "")
deviceList.add(newTag)
newTag
}
tag.name = result.device.name ?: "Unbekannt"
tag.rssi = result.rssi
tag.advertisementData = result.scanRecord?.bytes
}
deviceList.sortBy {result.rssi }
recyclerView.adapter?.notifyDataSetChanged()
menu.findItem(R.id.count).title = "Geräte: " + deviceList.size
super.onScanResult(callbackType, result)
}
override fun onScanFailed(errorCode: Int) {
super.onScanFailed(errorCode)
Log.e("Scan failed","")
}
}
This result is obtained by subtracting the timestamps of two consecutive advertisements of the same device.

How to truncate HTML string, to be used as a "preview" version of the original?

Background
We allow the user to create some text that will get converted to HTML, using a rich-text editor library (called Android-RTEditor).
The output HTML text is saved as is on the server and the device.
Because on some end cases, there is a need to show a lot of this content (multiple instances), we wish to also save a "preview" version of this content, meaning it will be much shorter in length (say 120 of normal characters, excluding the extra characters for the HTML tags, which are not counted).
What we want is a minimized version of the HTML. Some tags might optionally be removed, but we still want to see lists (numbered/bullets), no matter what we choose to do, because lists do show like text to the user (the bullet is a character, and so do the numbers with the dot).
The tag of going to next line should also be handled , as it's important to go to the next line.
The problem
As opposed to a normal string, where I can just call substring with the required number of characters, on HTML it might ruin the tags.
What I've tried
I've thought of 2 possible solutions for this:
Convert to plain text (while having some tags handled), and then truncate : Parse the HTML, and replacing some tags with Unicode alternatives, while removing the others. For example, instead of a bullet-list, put the bullet character (maybe this), and same for numbered list (put numbers instead). All the other tags would be removed. Same goes for the tag of going to the next line (""), which should be replaced with "\n". After that, I could safely truncate the normal text, because there are no more tags that could be ruined.
Truncate nicely inside the HTML : Parse the HTML, while identifying the text within it, and truncate it there and closing all tags when reaching the truncation position. This might even be harder.
I'm not sure which is easier, but I can think of possible disadvantages for each. It is just a preview though, so I don't think it matters much.
I've searched the Internet for such solutions, to see if others have made it.
I've found some links that talk about "cleaning" or "optimizing" HTML, but I don't see they can handle replacing them or truncating them. Not only that, but since it's HTML, most are not related to Android, and use PHP, C#, Angular and others as their language.
Here are some links that I've found:
Java Library to truncate html strings?
how to truncate HTML string without leaving it malformated?
The questions
Are those solutions that I've written possible? If so, is there maybe a known way to implement them? Or even a Java/Kotlin/Android library? How hard would it be to make such a solution?
Maybe other solution I haven't thought about?
EDIT:
I've also tried using an old code I've made in the past (here), which parses XML. Maybe it will work. I also try now to investigate some third party libraries for parsing HTML, such as Jsoup. I think it can help with the truncating, while supporting "faulty" HTML inputs.
OK, I think I got it, using my old code for converting XML string into an object . It would still be great to see more robust solutions, but I think what I got is good enough, at least for now.
Below code uses it (origininal XmlTag class available here) :
XmlTagTruncationHelper.kt
object XmlTagTruncationHelper {
/**#param maxLines max lines to permit. If <0, means there is no restriction
* #param maxTextCharacters max text characters to permit. If <0, means there is no restriction*/
class Restriction(val maxTextCharacters: Int, val maxLines: Int) {
var currentTextCharactersCount: Int = 0
var currentLinesCount: Int = 0
}
#JvmStatic
fun truncateXmlTag(xmlTag: XmlTag, restriction: Restriction): String {
if (restriction.maxLines == 0 || (restriction.maxTextCharacters >= 0 && restriction.currentTextCharactersCount >= restriction.maxTextCharacters))
return ""
val sb = StringBuilder()
sb.append("<").append(xmlTag.tagName)
val numberOfAttributes = if (xmlTag.tagAttributes != null) xmlTag.tagAttributes!!.size else 0
if (numberOfAttributes != 0)
for ((key, value) in xmlTag.tagAttributes!!)
sb.append(" ").append(key).append("=\"").append(value).append("\"")
val numberOfInnerContent = if (xmlTag.innerTagsAndContent != null) xmlTag.innerTagsAndContent!!.size else 0
if (numberOfInnerContent == 0)
sb.append("/>")
else {
sb.append(">")
for (innerItem in xmlTag.innerTagsAndContent!!) {
if (restriction.maxTextCharacters >= 0 && restriction.currentTextCharactersCount >= restriction.maxTextCharacters)
break
if (innerItem is XmlTag) {
if (restriction.maxLines < 0)
sb.append(truncateXmlTag(innerItem, restriction))
else {
// Log.d("AppLog", "xmlTag:" + innerItem.tagName + " " + innerItem.innerTagsAndContent?.size)
var needToBreak = false
when {
innerItem.tagName == "br" -> {
++restriction.currentLinesCount
needToBreak = restriction.currentLinesCount >= restriction.maxLines
}
innerItem.tagName == "li" -> {
++restriction.currentLinesCount
needToBreak = restriction.currentLinesCount >= restriction.maxLines
}
}
if (needToBreak)
break
sb.append(truncateXmlTag(innerItem, restriction))
}
} else if (innerItem is String) {
if (restriction.maxTextCharacters < 0)
sb.append(innerItem)
else
if (restriction.currentTextCharactersCount < restriction.maxTextCharacters) {
val str = innerItem
val extraCharactersAllowedToAdd = restriction.maxTextCharacters - restriction.currentTextCharactersCount
val strToAdd = str.substring(0, Math.min(str.length, extraCharactersAllowedToAdd))
if (strToAdd.isNotEmpty()) {
sb.append(strToAdd)
restriction.currentTextCharactersCount += strToAdd.length
}
}
}
}
sb.append("</").append(xmlTag.tagName).append(">")
}
return sb.toString()
}
}
XmlTag.kt
//based on https://stackoverflow.com/a/19115036/878126
/**
* an xml tag , includes its name, value and attributes
* #param tagName the name of the xml tag . for example : <a>b</a> . the name of the tag is "a"
*/
class XmlTag(val tagName: String) {
/** a hashmap of all of the tag attributes. example: <a c="d" e="f">b</a> . attributes: {{"c"="d"},{"e"="f"}} */
#JvmField
var tagAttributes: HashMap<String, String>? = null
/**list of inner text and xml tags*/
#JvmField
var innerTagsAndContent: ArrayList<Any>? = null
companion object {
#JvmStatic
fun getXmlFromString(input: String): XmlTag? {
val factory = XmlPullParserFactory.newInstance()
factory.isNamespaceAware = true
val xpp = factory.newPullParser()
xpp.setInput(StringReader(input))
return getXmlRootTagOfXmlPullParser(xpp)
}
#JvmStatic
fun getXmlRootTagOfXmlPullParser(xmlParser: XmlPullParser): XmlTag? {
var currentTag: XmlTag? = null
var rootTag: XmlTag? = null
val tagsStack = Stack<XmlTag>()
xmlParser.next()
var eventType = xmlParser.eventType
var doneParsing = false
while (eventType != XmlPullParser.END_DOCUMENT && !doneParsing) {
when (eventType) {
XmlPullParser.START_DOCUMENT -> {
}
XmlPullParser.START_TAG -> {
val xmlTagName = xmlParser.name
currentTag = XmlTag(xmlTagName)
if (tagsStack.isEmpty())
rootTag = currentTag
tagsStack.push(currentTag)
val numberOfAttributes = xmlParser.attributeCount
if (numberOfAttributes > 0) {
val attributes = HashMap<String, String>(numberOfAttributes)
for (i in 0 until numberOfAttributes) {
val attrName = xmlParser.getAttributeName(i)
val attrValue = xmlParser.getAttributeValue(i)
attributes[attrName] = attrValue
}
currentTag.tagAttributes = attributes
}
}
XmlPullParser.END_TAG -> {
currentTag = tagsStack.pop()
if (!tagsStack.isEmpty()) {
val parentTag = tagsStack.peek()
parentTag.addInnerXmlTag(currentTag)
currentTag = parentTag
} else
doneParsing = true
}
XmlPullParser.TEXT -> {
val innerText = xmlParser.text
if (currentTag != null)
currentTag.addInnerText(innerText)
}
}
eventType = xmlParser.next()
}
return rootTag
}
/**returns the root xml tag of the given xml resourceId , or null if not succeeded . */
fun getXmlRootTagOfXmlFileResourceId(context: Context, xmlFileResourceId: Int): XmlTag? {
val res = context.resources
val xmlParser = res.getXml(xmlFileResourceId)
return getXmlRootTagOfXmlPullParser(xmlParser)
}
}
private fun addInnerXmlTag(tag: XmlTag) {
if (innerTagsAndContent == null)
innerTagsAndContent = ArrayList()
innerTagsAndContent!!.add(tag)
}
private fun addInnerText(str: String) {
if (innerTagsAndContent == null)
innerTagsAndContent = ArrayList()
innerTagsAndContent!!.add(str)
}
/**formats the xmlTag back to its string format,including its inner tags */
override fun toString(): String {
val sb = StringBuilder()
sb.append("<").append(tagName)
val numberOfAttributes = if (tagAttributes != null) tagAttributes!!.size else 0
if (numberOfAttributes != 0)
for ((key, value) in tagAttributes!!)
sb.append(" ").append(key).append("=\"").append(value).append("\"")
val numberOfInnerContent = if (innerTagsAndContent != null) innerTagsAndContent!!.size else 0
if (numberOfInnerContent == 0)
sb.append("/>")
else {
sb.append(">")
for (innerItem in innerTagsAndContent!!)
sb.append(innerItem.toString())
sb.append("</").append(tagName).append(">")
}
return sb.toString()
}
}
Sample usage:
build.grade
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
}
...
dependencies{
implementation 'com.1gravity:android-rteditor:1.6.7'
...
}
...
MainActivity.kt
class MainActivity : AppCompatActivity() {
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
// val inputXmlString = "<zz>Zhshs<br/>ABC</zz>"
val inputXmlString = "Aaa<br/><b>Bbb<br/></b>Ccc<br/><ul><li>Ddd</li><li>eee</li></ul>fff<br/><ol><li>ggg</li><li>hhh</li></ol>"
// XML must have a root tag
val xmlString = if (!inputXmlString.startsWith("<"))
"<html>$inputXmlString</html>" else inputXmlString
val rtApi = RTApi(this, RTProxyImpl(this), RTMediaFactoryImpl(this, true))
val mRTManager = RTManager(rtApi, savedInstanceState)
mRTManager.registerEditor(beforeTruncationTextView, true)
mRTManager.registerEditor(afterTruncationTextView, true)
beforeTruncationTextView.setRichTextEditing(true, inputXmlString)
val xmlTag = XmlTag.getXmlFromString(xmlString)
Log.d("AppLog", "xml parsed: " + xmlTag.toString())
val maxTextCharacters = 10
val maxLines = 20
val output = XmlTagTruncationHelper.truncateXmlTag(xmlTag!!, XmlTagTruncationHelper.Restriction(maxTextCharacters, maxLines))
afterTruncationTextView.setRichTextEditing(true, output)
Log.d("AppLog", "xml with truncation : maxTextCharacters: $maxTextCharacters , maxLines: $maxLines output: " + output)
}
}
activity_main.xml
<LinearLayout
xmlns:android="http://schemas.android.com/apk/res/android" xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools" android:layout_width="match_parent"
android:layout_height="match_parent" android:gravity="center" android:orientation="vertical"
tools:context=".MainActivity">
<com.onegravity.rteditor.RTEditText
android:id="#+id/beforeTruncationTextView" android:layout_width="match_parent"
android:layout_height="wrap_content" android:background="#11ff0000" tools:text="beforeTruncationTextView"/>
<com.onegravity.rteditor.RTEditText
android:id="#+id/afterTruncationTextView" android:layout_width="match_parent"
android:layout_height="wrap_content" android:background="#1100ff00" tools:text="afterTruncationTextView"/>
</LinearLayout>
And the result:

How do I save a record in Apache Jena?

I want to create a person with nick name jd and e-mail john.doe#provider.com in a persistent Apache Jena database.
I wrote following code:
var dataSet:Dataset? = null
val Dir = "data/MyDataSet"
dataSet = TDBFactory.createDataset(Dir)
dataSet.begin(ReadWrite.WRITE)
val model = dataSet.defaultModel
createPerson("john.doe#provider.com", model, "jd")
dataSet.end()
dataSet.close()
private fun createPerson(email: String, model: Model, nick: String) {
val uuid = UUID.randomUUID()
val uri = "http://mycompany.com/data/p-${uuid}"
val person = model.createResource(uri)
person.addProperty(VCARD.EMAIL, email)
person.addProperty(VCARD.N,
model.createResource()
.addProperty(VCARD.NICKNAME, nick))
}
When I run it, I get no errors.
But when I try to read the data from the file (see code below), the query doesn't find anything.
ds.begin(ReadWrite.READ)
val query = QueryFactory.create("""SELECT ?x
WHERE { ?x <http://www.w3.org/2001/vcard-rdf/3.0#EMAIL> "john.doe#provider.com" }""")
val qexec: QueryExecution
try {
qexec = QueryExecutionFactory.create(query, ds.defaultModel)
val rs = qexec.execSelect()
while (rs.hasNext()) {
val solution = rs.nextSolution()
System.out.println("")
}
}
catch (throwable:Throwable) {
logger.error("", throwable)
}
finally {
ds.end()
}
What's wrong with my code?
You should get a warning at end because you have not committed the transaction.
dataSet.begin(ReadWrite.WRITE)
val model = dataSet.defaultModel
createPerson("john.doe#provider.com", model, "jd")
dataSet.commit()
dataSet.end()

How to convert java 8 map, filter and streams to scala?

I am very new to scala trying to understand by changing the equivalent java to scala so that I get better understanding.
How to convert java 8 map, filter and streams to scala ?
I have the following java 8 code which I am trying to convert to Scala :
public Set<String> getValidUsages(String itemId, long sNo, Date timeOfAccess) {
Set<String> itemSet = Sets.newHashSet();
TestWindows testWindows = items.get(itemId).getTestWindows();
final boolean isTV = existsEligibleTestWindow(testWindows.getTV(), timeOfAccess);
if (isTV) {
itemSet.add(TV);
} else {
final boolean isCableUseable = existsEligibleTestWindow(testWindows.getCableUse(), timeOfAccess);
final boolean isWifi = existsEligibleTestWindow(testWindows.getWifi(), timeOfAccess);
if (isCableUseable || isWifi) {
itemSet.add(MOVIE);
}
}
if (testWindows.getUsageIds() != null) {
itemSet.addAll(testWindows.getUsageIds()
.entrySet()
.stream()
.filter(entry -> existsEligibleTestWindow(entry.getValue(), timeOfAccess))
.map(Map.Entry::getKey)
.collect(Collectors.toSet()));
}
return itemSet;
}
private boolean existsEligibleTestWindow(List<TestWindow> windows, Date timeOfAccess) {
if (windows != null) {
return windows.stream()
.filter(w -> withinDateRange(timeOfAccess, w))
.findAny()
.isPresent();
}
return false;
}
private boolean withinDateRange(Date toCheck, TestWindow window) {
return toCheck.after(window.getStartTime()) && toCheck.before(window.getEndTime());
}
I tried :
def withinDateRange(toCheck: Date, window: TestWindow): Boolean = {
toCheck.after( window.getStartTime ) && toCheck.before( window.getEndTime )
}
def getValidUsages(itemId: String, sNo: Long, timeOfAccess: Date): Set[String] = {
var itemSet = Sets.newHashSet()
val testWindows = items.value(itemId).getTestWindows
val isTV = existsEligibleTestWindow(testWindows.get(0).getTV, timeOfAccess)
if (isTV) {
itemSet += TV
} else {
val isCableUseable = existsEligibleTestWindow(testWindows.get(0).getCableUse, timeOfAccess)
val isWifi = existsEligibleTestWindow(testWindows.get(0).getWifi, timeOfAccess)
if (isCableUseable || isWifi) {
itemSet += MOVIE
}
}
if (testWindows.get(0).getUsageIds != null) {
itemSet.addAll(testWindows.get(0).getUsageIds.entrySet().stream()
.filter((x) => existsEligibleTestWindow(x._2, timeOfAccess)).map(x => Map.Entry._1 )
.collect(Collectors.toSet()))
}
itemSet
}
def existsEligibleConsumptionWindow(windows: List[ConsumptionWindow], timeOfAccess: Date): Boolean = {
if (windows != null) {
return windows.exists((x) => withinDateRange(timeOfAccess, x))
}
false
}
But getting error while doing filter and stream. Can some one point to direct direction ? Any references ? I am getting error on getValidUsages :
compile error “cannot resolve reference project with such signature
This is somewhat difficult to answer since I am unfamiliar with some of the types you use. But if I guess there are types like the following:
trait Window {
def getStartTime: LocalDate
def getEndTime: LocalDate
}
trait TestWindows extends Window {
def getTV: List[Window]
def getCableUse: List[Window]
def getWifi: List[Window]
def getUsageIds: Map[String, List[Window]]
}
then you could just do this:
def withinDateRange(toCheck: LocalDate)(window: Window): Boolean =
window.getStartTime.isBefore(toCheck) && window.getEndTime.isAfter(toCheck)
// Nothing should ever be null in Scala. If it's possible you don't have any ConsumptionWindows you should either
// model it as an empty list or an Option[List[ConsumptionWindow]]
def existsEligibleTestWindow(windows: List[Window],
timeOfAccess: LocalDate): Boolean =
windows.exists(withinDateRange(timeOfAccess))
def getValidUsages(testWindows: TestWindows, timeOfAccess: LocalDate): Set[String] = {
val isTV = existsEligibleTestWindow(testWindows.getTV, timeOfAccess)
val isCableUse = existsEligibleTestWindow(testWindows.getCableUse, timeOfAccess)
val isWifi = existsEligibleTestWindow(testWindows.getWifi, timeOfAccess)
val tvOrMovie: Option[String] = if (isTV) Some("TV")
else if (isCableUse || isWifi) Some("MOVIE")
else None
val byUsageId = testWindows.getUsageIds.collect { case (key, windows) if existsEligibleTestWindow(windows, timeOfAccess) => key }.toSet
tvOrMovie.toSet ++ byUsageId
}
In your original code there was presumably some items value, but in the above I just assume you do TestWindows testWindows = items.get(itemId).getTestWindows() outside the getValidUsages function.
My example doesn't use java structures at all and just uses the scala core collections. The other main difference is that I use immutable data structures which is, I think, a little easier to follow and generally safer.
Some items of note:
1) The Option.toSet operation result in an empty set when called upon a None.
2) There is an example of function currying used for the withinDateRange method.
3) I obviously have no idea what your original types do and had to guess at the relevant parts.
The problem seems to be that you are using Java types in Scala while depending on scala's map & filter operations. This has its own troubles but if you convert the list/collections to a Scala's collections first (warning, Scala types are immutable by default), then you should be able to just use the map/filter operations without having to call java's stream() method.
def getValidUsages(itemId: String, sNo: long, timeOfAcess: Date): Set[String] = {
var itemSet: Set[String] = Sets.newHashSet()
val testWindows: TestWindows = items.get(itemId).getTestWindows()
val isTV: Boolean = existsEligibleTestWindow(testWindows.getTV(), timeOfAccess)
isTV match {
case true => itemSet.add(TV)
case false => {
val isCableUseable: Boolean = existsEligibleTestWindow(testWindows.getCableUse(), timeOfAcess)
val isWifi: Boolean = existsEligibleTestWindow(testWindows.getWifi(), timeOfAccess)
if(isCableUseable || isWifi) {
itemSet.add(MOVIE)
}
}
}
if(testWindows.getUsageIds() != null) {
itemSet.addAll(testWindows.getUsageIds()
.stream.
.filter(entry => existsEligibleTestWindow(entry._2, timeOfAccess))
.map(filteredData => Map.Entry._1)
.collect Collectors.toSet())
}
itemSet
}
def existsEligibleTestWindow(windows: List[TestWindow], timeOfAcess: Date): Boolean = {
windows match {
case null => false
case _ => windows.stream.filter(data => withinDateRange(timeOfAcess), data).findAny().isPresent
}
}
Good luck :)

Categories

Resources