#20 Haystack Java Toolkit

Brian Frank Thu 9 Jun 2011

I'm excited to announce the new "Haystack Java Toolkit": a small open source library to add haystack tagging to Java applications. Right now the library is pretty simple and does two things:

  • models tags and all the tag scalar values using immutable classes
  • provides simple string syntax which is easy for both humans and machines to read/write

All the code is written to work in Java 1.4/J2ME, has no dependencies, and without tests is only 16KB. So perfect even for embedded devices.

The code is all licensed under AFL 3.0 and I'll be managing it on BitBucket using Mercurial:

https://bitbucket.org/brianfrank/haystack-java

I'll be adding a few more features over the next week.

If you would like to get involved, submit patches, or use it in a downstream project, just post your feedback on this forum.

Kevin Kelley Thu 9 Jun 2011

Nice! Can't beat a well-defined interchange format.

I think I can make use of this -- I'm working on a tool to help classify the equipment in a WebCTRL installation into an appropriate tags model for skyspark.

Brian Frank Wed 5 Oct 2011

I have pushed new code for query support. I used the same filter language as SkySpark and created a new clean Java implementation. Here is an excerpt from new docs:

The toolkit includes a simple tag based query modeled by the HQuery class. You can parse a query using read and use include to check if a HTags instance matches the query:

HQuery query = HQuery.read("site and area > 15000");
boolean match = query.include(db, rec);

The simple usage is just a tag name which matches any record that has the tag (regardless of its value):

site  // query any record with the "site" tag

To match a tag value you can use any of the equality or comparison operators:

geoPostalCode == "23220"   // equal to
geoPostalCode != "23220"   // not equal to
temp < 75                  // less than
temp <= 75                 // less than or equal to
temp > 75                  // greater than
temp >= 75                 // greater than or equal to

Compare operators can use all the standard scalar from the plain text format.

You can combine filters using and, or, or not:

site or equip             // has site or equip tag
equip and hvac            // has equip and hvac tag
equip and not ahu         // has equip tag, but not the ahu tag

You use the -> to dereference a tag which has a Ref value. For example if your equip rec has a siteRef tag that references the site, you can query for equip in a given city such as:

equip and siteRef->geoCity == "Chicago"

The way to read the above expression is match a record if:

  • it has equip tag
  • and it has a siteRef tag which is a Ref
  • and what the siteRef tag points to has the geoCity tag
  • and that the site's geoCity tag is equal to "Chicago"

The formal grammar of the query langauge:

<query>      :=  <predicate>
<predicate>  :=  <condOr>
<condOr>     :=  <condAnd> ("or" <condAnd>)*
<condAnd>    :=  <term> ("and" <term>)*
<term>       :=  <parens> | <has> | <missing> | <cmp>
<parens>     :=  "(" <predicate> ")"
<has>        :=  <path>
<missing>    :=  "not" <path>
<cmp>        :=  <path> <cmpOp> <val>
<cmpOp>      :=  "=" | "!=" | "<" | "<=" | ">" | ">="
<path>       :=  <name> ("->" <name>)*
<val>        :=  same as plain text format

Login or Signup to reply.