Hi! I'm going to port haystack-java to Dart. We making a web application for SkySpark. We think it's better to port exist client library for haystack instead write own implementation, right?
So, I have a questions. Can I just copy all this repo to Dart or task is not trivial? Should I port all java files or I need in a part if this?
Port will be published on https://pub.dartlang.org as open source.
Thank you.
Brian FrankTue 20 Jan 2015
Porting to Dart would really only require the client portions of the Java library. Plus you would probably want to make use of the Browser's XMLHttpRequest.
org.projecthaystack: APIs to model core data values, grids, dicts
org.projecthaystack.io: grid encoders/decoders (just really need Zinc)
org.projecthaystack.client: really want to make HClient work in browser
If do get a working Dart client library, please let us know!
Mike JarmyTue 20 Jan 2015
Sounds like a really interesting project, please post us a link once you've got it working. As Brian said, it shouldn't be that hard.
Dmitriy VasilyevTue 20 Jan 2015
Thank you for answer! Sure I'll get you know when I'm done. With Dart language you'll get JavaScript library automatically (I'll publish it on github)
Alper ÜzmezlerTue 20 Jan 2015
That will be our open source push to the community.
Dmitriy VasilyevFri 23 Jan 2015
Hi, guys. Working on HStr class and have a questions about split method.
Do I need really port your split algorithm or I can use common Dart String.split() method?
If I do need so can you tell me what the last string of method is doing:
public static String[] split(String str, int separator, boolean trim)
{
ArrayList toks = new ArrayList(16);
//...
return (String[])toks.toArray(new String[toks.size()]);
}
Mike JarmyFri 23 Jan 2015
It looks like that method is only used for splitting up mime types in the Accept header of an HTTP request. So you basically just need to do whatever works properly for that. If there is any easier way to do it with Dart, then thats fine.
FYI the last line is the standard java idiom for turning a List into an Array of a given type.
Dmitriy VasilyevFri 23 Jan 2015
Thank you. What about this:
In HNum.hashCode():
long bits = Double.doubleToLongBits(val);
int hash = (int)(bits ^ (bits >>> 32));
This code cuts number to 32 bit. Is it really need? Or this operation servers for convert to int type only?
Can I just convert double to int without this operations?
Dmitriy VasilyevMon 26 Jan 2015
I have one idea. In all val objects (extends HVal) there are equals method. Can I just override == operator instead use equals methods?
Brian FrankMon 26 Jan 2015
In Java you use equals and hashCode overrides to manage equality so that you could use a class like HRef as a key in a hash map. I have never programmed in Dart, but I believe you do this by overriding the == operator.
Dmitriy VasilyevTue 27 Jan 2015
ok, got it. Thank you.
Dmitriy VasilyevTue 3 Feb 2015
Hi again. Now I'm working on HZincReader class. It works on StringStream as I understand, and reads string char by char.
I have a working project (ActionScript3) where I split response on strings, than split by commas (and/or by space if needed). It works with regexp. Just split, than convert to real values and types. It works well on our project.
So, what is do you think better way to do it in Dart: split by regexp or read char by char? May be regexp takes a lot of time compare it with one-char reading?
Mike JarmyTue 3 Feb 2015
That really depends on Dart itself, or rather the performance of its libraries. I myself have no first-hand experience with Dart.
Brian FrankTue 3 Feb 2015
Now I'm working on HZincReader class. It works on StringStream as I understand, and reads string char by char.
If you are porting that code, then you have to handle it char by char. If you split by comma or anything, then your code won't handle commas inside quoted strings for example. Given that very similar code is already running successfully in JavaScript, I wouldn't worry too much about performance (assuming Dart does good job to compile into JS).
Dmitriy VasilyevTue 3 Feb 2015
I wrote this in AS3:
var spaceRE:RegExp = /(?:\s|^)(?:(?:"[^"]*")|(?:\([^\(\)]*\))|(?:[^\s\(\)"]*))*(?=\s|$)/g;
var commaRE:RegExp = /(?:,|^)(?:(?:"[^"]*")|(?:\([^\(\)]*\))|(?:[^,\(\)"]*))*(?=,|$)/g;
It's dumb expresses: lefts commas(spaces) in match start. Need to clean it after. Also need make together parts like haystackCur:@S.EnergyDVRDemo.AHU_3.Fan and "EnergyDVRDemo AHU_3 Fan".
I split body by \n char, then I search matches in rows with commas or space chars using this reg exps. It works well in our project. What do you think?
Brian FrankTue 3 Feb 2015
What do you think?
Well I personally find that code difficult to understand, but then again I'm not a huge fan of regex :) So its really a personal thing as long it works. Just make sure when you test suite you try out complicated combinations like:
foo,"bar \", baz"
I would recommend you port the Java test suite in its entirety which has tons of boundary conditions to test
Dmitriy VasilyevTue 3 Feb 2015
Yes, I understand. I'll try to port code as is, as I did it for model core data values, grids, dicts (with all tests). Thank you.
Dmitriy VasilyevMon 9 Feb 2015
May be bug in HZincReader/Writer classes with null values:
There is string in your ZincTest.java in grid (5th test):
"Bin(text/plain),N\n"
So, it reads ok, as null value. But then ZincWriter makes this string:
"Bin(text/plain),\n"
And now new body can't be parsed, because there isn't value after comma, so in a row values less than columns (1 < 2).
Reader works this way(HZincReader.java 86-96):
for (int i=0; i<numCols; ++i)
{
skipSpace();
if (cur != ',' && cur != '\n') cells[i] = readVal();
skipSpace();
if (i+1 < numCols)
{
if (cur != ',') throw errChar("Expecting comma in row");
consume();
}
}
Writes works this way (HZincWriter.java 122-130):
if (i > 0) out.write(',');
if (val == null)
{
if (i == 0) out.write('N');
}
else
{
out.write(val.toZinc());
}
I met this bug after run ported zinc tests.
So, what to do: add null values if commas meets or always write N for nulls? Do your tests works in java well?
P.S. I have met zinc responses where was ,,, rows, so I did first way in Dart now.
Brian FrankTue 10 Feb 2015
An empty cell is always treated the same as N - both resulting in null for that cell. The Java code works both ways, but I believe the writer always prefers the empty cell to the N cell. I just tested it a couple different ways and it looks like the Java code handles both cases just fine.
However, remember that there is one special case - a single column grid. In this case you must use N and can't leave the entire row empty, because otherwise you end up with an empty line which is considered end of grid.
Dmitriy VasilyevTue 10 Feb 2015
Oh, sorry, understood. You have pre-filled array with nulls.
HVal[] cells = new HVal[numCols];
I never do it like this and miss.
Dmitriy VasilyevWed 11 Feb 2015
I'm making HClient class. How can I try and test calls to a haystack?
I have installed skyspark locally in my laptop. I run it and can login into it with web form, can see some information in demo project.
Then I have started simple http server to host html page with dart code. But when I try making a simple request from dart to skyspark (/api/demo/about) I catch cross domain error.
So, I don't understand: how I can reach skyspark? How I can test and use haystack-dart library?
Brian FrankWed 11 Feb 2015
So, I don't understand: how I can reach skyspark?
Everything has to be be loaded in the browser from the same domain. Simplest way to load JS code into the browser from SkySpark is to put all your files into the {home}/pub/ directory which is then available in browser under /pub/.
Also remember that to access a project you will need to be logged into that project, or more simply for testing just run with -noAuth flag
Dmitriy VasilyevFri 13 Feb 2015
So, looks like I haven't way to retrieve Folio-Auth-Api-Uri HTTP header (because browser always follows redirect). I have to hardcode auth api uri in code or skip it.
What is most appropriate way to implement auth? In other words:
Should I make Basic auth?
Should I make Folio auth?
Which ones uri I should hardcode for Folio auth? I know follows cases:
/auth/project/api?username (EnergyDvr)
/auth/project/salt?username and /auth/project/login (SkySpark Login form)
Brian FrankFri 13 Feb 2015
We don't really have a standard authentication mechanism, I guess if we just always required https we could stick with Basic. You really want both for now though. I would suggest just copying the logic in the Java HClient which is well tested for various servers.
For folio nothing is hardcoded, you just look for the Folio-Auth-Api-Uri HTTP header.
Dmitriy VasilyevFri 13 Feb 2015
I can't just copy java. When I try to get api/project/about server answer with 303 status (redirect) and Folio-Auth-Api-Uri HTTP header. Dart (as JavaScript) works in browser and using for Html requests browser's XMLHttpRequest object which always follows redirect. This is W3C standard. After redirect I got html login page which doesn't contain Folio-Auth-Api-Uri HTTP header. This is why I can't use java's way.
By the way, your login form page doesn't read this header too. Paths are included in html's javascript (may be with template engine).
Just wanted to ask your opinion for best solution in this problem.
Brian FrankFri 13 Feb 2015
In the browser, you are going to be served up from the server system already most likely for cross-domain reasons. So typically you will defer to the authentication mechanism and login pages of the source system. For example in SkySpark, any URIs to an authenticated realm will redirect to the login page, then back to the original URI after login.
Dmitriy VasilyevFri 13 Feb 2015
Understood. Now I have skipped auth part of HClient.
Alper ÜzmezlerMon 16 Feb 2015
Hi Brian and community,
Haystack dart port is written and community feedback would be essential.
Dmitry will be publishing the open source toolkit (client side only) today.
Dmitriy VasilyevMon 16 Feb 2015
Hi, guys. It's almost done. I ommited all server parts. And now still exists one annoyed bug with timezone, but it's only as I know.
Can you preview it and make few comments? Bitbucket rep
Brian FrankMon 16 Feb 2015
Until someone actually tries to use in practice, you probably won't get the feedback you really need. But just looking thru the code and having only a superficial knowledge of Dart it looks like a very straight forward port of the Java code which should make for solid design. It looks like you have the key tests for HVal, HDict, and zinc stuff all duplicated too - so if those tests are fully passing then you should have a pretty solid start.
Pretty awesome guys, thanks for your contributions. I will update the Downloads section to port to this repo too ok?
Alper ÜzmezlerMon 16 Feb 2015
Thank you Brian.
Posting on download section would be great start to get more community attention.
I think all asynchronous testings are working. We just need to improve the timezone classes.
Dmitriy VasilyevThu 19 Feb 2015
Project published. Use this link: https://pub.dartlang.org/packages/haystack.
Tell me, if something is wrong in descriptions.
Brian FrankFri 20 Feb 2015
Link will be in next upgrade of website (whenever I post that)
Dmitriy Vasilyev Tue 20 Jan 2015
Hi! I'm going to port haystack-java to Dart. We making a web application for SkySpark. We think it's better to port exist client library for haystack instead write own implementation, right?
So, I have a questions. Can I just copy all this repo to Dart or task is not trivial? Should I port all java files or I need in a part if this?
Port will be published on https://pub.dartlang.org as open source.
Thank you.
Brian Frank Tue 20 Jan 2015
Porting to Dart would really only require the client portions of the Java library. Plus you would probably want to make use of the Browser's XMLHttpRequest.
If do get a working Dart client library, please let us know!
Mike Jarmy Tue 20 Jan 2015
Sounds like a really interesting project, please post us a link once you've got it working. As Brian said, it shouldn't be that hard.
Dmitriy Vasilyev Tue 20 Jan 2015
Thank you for answer! Sure I'll get you know when I'm done. With Dart language you'll get JavaScript library automatically (I'll publish it on github)
Alper Üzmezler Tue 20 Jan 2015
That will be our open source push to the community.
Dmitriy Vasilyev Fri 23 Jan 2015
Hi, guys. Working on
HStr
class and have a questions aboutsplit
method.Do I need really port your
split
algorithm or I can use common DartString.split()
method?If I do need so can you tell me what the last string of method is doing:
Mike Jarmy Fri 23 Jan 2015
It looks like that method is only used for splitting up mime types in the Accept header of an HTTP request. So you basically just need to do whatever works properly for that. If there is any easier way to do it with Dart, then thats fine.
FYI the last line is the standard java idiom for turning a List into an Array of a given type.
Dmitriy Vasilyev Fri 23 Jan 2015
Thank you. What about this:
In HNum.hashCode():
This code cuts number to 32 bit. Is it really need? Or this operation servers for convert to
int
type only?Can I just convert double to int without this operations?
Dmitriy Vasilyev Mon 26 Jan 2015
I have one idea. In all val objects (extends
HVal
) there areequals
method. Can I just override==
operator instead useequals
methods?Brian Frank Mon 26 Jan 2015
In Java you use equals and hashCode overrides to manage equality so that you could use a class like HRef as a key in a hash map. I have never programmed in Dart, but I believe you do this by overriding the == operator.
Dmitriy Vasilyev Tue 27 Jan 2015
ok, got it. Thank you.
Dmitriy Vasilyev Tue 3 Feb 2015
Hi again. Now I'm working on HZincReader class. It works on StringStream as I understand, and reads string char by char.
I have a working project (ActionScript3) where I split response on strings, than split by commas (and/or by space if needed). It works with regexp. Just split, than convert to real values and types. It works well on our project.
So, what is do you think better way to do it in Dart: split by regexp or read char by char? May be regexp takes a lot of time compare it with one-char reading?
Mike Jarmy Tue 3 Feb 2015
That really depends on Dart itself, or rather the performance of its libraries. I myself have no first-hand experience with Dart.
Brian Frank Tue 3 Feb 2015
If you are porting that code, then you have to handle it char by char. If you split by comma or anything, then your code won't handle commas inside quoted strings for example. Given that very similar code is already running successfully in JavaScript, I wouldn't worry too much about performance (assuming Dart does good job to compile into JS).
Dmitriy Vasilyev Tue 3 Feb 2015
I wrote this in AS3:
var spaceRE:RegExp = /(?:\s|^)(?:(?:"[^"]*")|(?:\([^\(\)]*\))|(?:[^\s\(\)"]*))*(?=\s|$)/g;
var commaRE:RegExp = /(?:,|^)(?:(?:"[^"]*")|(?:\([^\(\)]*\))|(?:[^,\(\)"]*))*(?=,|$)/g;
It's dumb expresses: lefts commas(spaces) in match start. Need to clean it after. Also need make together parts like
haystackCur:@S.EnergyDVRDemo.AHU_3.Fan
and"EnergyDVRDemo AHU_3 Fan"
.I split body by
\n
char, then I search matches in rows with commas or space chars using this reg exps. It works well in our project. What do you think?Brian Frank Tue 3 Feb 2015
Well I personally find that code difficult to understand, but then again I'm not a huge fan of regex :) So its really a personal thing as long it works. Just make sure when you test suite you try out complicated combinations like:
I would recommend you port the Java test suite in its entirety which has tons of boundary conditions to test
Dmitriy Vasilyev Tue 3 Feb 2015
Yes, I understand. I'll try to port code as is, as I did it for model core data values, grids, dicts (with all tests). Thank you.
Dmitriy Vasilyev Mon 9 Feb 2015
May be bug in HZincReader/Writer classes with null values:
There is string in your ZincTest.java in grid (5th test):
So, it reads ok, as null value. But then ZincWriter makes this string:
And now new body can't be parsed, because there isn't value after comma, so in a row values less than columns (1 < 2).
Reader works this way(HZincReader.java 86-96):
Writes works this way (HZincWriter.java 122-130):
I met this bug after run ported zinc tests.
So, what to do: add null values if commas meets or always write
N
for nulls? Do your tests works in java well?P.S. I have met zinc responses where was
,,,
rows, so I did first way in Dart now.Brian Frank Tue 10 Feb 2015
An empty cell is always treated the same as N - both resulting in null for that cell. The Java code works both ways, but I believe the writer always prefers the empty cell to the N cell. I just tested it a couple different ways and it looks like the Java code handles both cases just fine.
However, remember that there is one special case - a single column grid. In this case you must use N and can't leave the entire row empty, because otherwise you end up with an empty line which is considered end of grid.
Dmitriy Vasilyev Tue 10 Feb 2015
Oh, sorry, understood. You have pre-filled array with nulls.
I never do it like this and miss.
Dmitriy Vasilyev Wed 11 Feb 2015
I'm making HClient class. How can I try and test calls to a haystack?
I have installed skyspark locally in my laptop. I run it and can login into it with web form, can see some information in demo project.
Then I have started simple http server to host html page with dart code. But when I try making a simple request from dart to skyspark (
/api/demo/about
) I catch cross domain error.So, I don't understand: how I can reach skyspark? How I can test and use haystack-dart library?
Brian Frank Wed 11 Feb 2015
Everything has to be be loaded in the browser from the same domain. Simplest way to load JS code into the browser from SkySpark is to put all your files into the {home}/pub/ directory which is then available in browser under /pub/.
Also remember that to access a project you will need to be logged into that project, or more simply for testing just run with -noAuth flag
Dmitriy Vasilyev Fri 13 Feb 2015
So, looks like I haven't way to retrieve
Folio-Auth-Api-Uri
HTTP header (because browser always follows redirect). I have to hardcode auth api uri in code or skip it.What is most appropriate way to implement auth? In other words:
/auth/project/api?username
(EnergyDvr)/auth/project/salt?username
and/auth/project/login
(SkySpark Login form)Brian Frank Fri 13 Feb 2015
We don't really have a standard authentication mechanism, I guess if we just always required https we could stick with Basic. You really want both for now though. I would suggest just copying the logic in the Java HClient which is well tested for various servers.
For folio nothing is hardcoded, you just look for the Folio-Auth-Api-Uri HTTP header.
Dmitriy Vasilyev Fri 13 Feb 2015
I can't just copy java. When I try to get
api/project/about
server answer with 303 status (redirect) and Folio-Auth-Api-Uri HTTP header. Dart (as JavaScript) works in browser and using for Html requests browser's XMLHttpRequest object which always follows redirect. This is W3C standard. After redirect I got html login page which doesn't contain Folio-Auth-Api-Uri HTTP header. This is why I can't use java's way.By the way, your login form page doesn't read this header too. Paths are included in html's javascript (may be with template engine).
Just wanted to ask your opinion for best solution in this problem.
Brian Frank Fri 13 Feb 2015
In the browser, you are going to be served up from the server system already most likely for cross-domain reasons. So typically you will defer to the authentication mechanism and login pages of the source system. For example in SkySpark, any URIs to an authenticated realm will redirect to the login page, then back to the original URI after login.
Dmitriy Vasilyev Fri 13 Feb 2015
Understood. Now I have skipped auth part of HClient.
Alper Üzmezler Mon 16 Feb 2015
Hi Brian and community,
Haystack dart port is written and community feedback would be essential.
Dmitry will be publishing the open source toolkit (client side only) today.
Dmitriy Vasilyev Mon 16 Feb 2015
Hi, guys. It's almost done. I ommited all server parts. And now still exists one annoyed bug with timezone, but it's only as I know.
Can you preview it and make few comments? Bitbucket rep
Brian Frank Mon 16 Feb 2015
Until someone actually tries to use in practice, you probably won't get the feedback you really need. But just looking thru the code and having only a superficial knowledge of Dart it looks like a very straight forward port of the Java code which should make for solid design. It looks like you have the key tests for HVal, HDict, and zinc stuff all duplicated too - so if those tests are fully passing then you should have a pretty solid start.
Pretty awesome guys, thanks for your contributions. I will update the Downloads section to port to this repo too ok?
Alper Üzmezler Mon 16 Feb 2015
Thank you Brian.
Posting on download section would be great start to get more community attention.
I think all asynchronous testings are working. We just need to improve the timezone classes.
Dmitriy Vasilyev Thu 19 Feb 2015
Project published. Use this link: https://pub.dartlang.org/packages/haystack.
Tell me, if something is wrong in descriptions.
Brian Frank Fri 20 Feb 2015
Link will be in next upgrade of website (whenever I post that)