Parsing PList files in ActionScript

Posted in Eric Daugherty on October 9th, 2009 by admin

admin originally posted this on EricDaugherty.com.

The PList format is not one of my favorites. I've complained about it before, but Apple continues to use it for its iTunes library information, so I continue to parse it.

I've been exploring the option of porting the iTunesExport project to Flex (Air) to provide a cross platform version. The current version is written in .Net and therefore not usable on OS X. As such I needed to parse the PList file using ActionScript. I adopted the Java PList Parser written by Christoffer Lerno for his XMLWise project.

The dynamic nature of ActionScript resulted in a much smaller implementation (although I did skip over 'REAL' and 'DATA' types), and makes it easy to consume.

You can view or download my version here, released under the MIT license.

Here is a snapshot of how it is used:
var parser:PListParser = new PListParser();
var pList:Object = parser.parsePList(xml);

playlists = pList.Playlists.filter(filterPlaylists);
The last line accesses the Playlist array (dynamically created when the PList is parsed), and filters it using the specified filterPlaylists method, returning a filtered list of the playlists from the original XML file.

It provides easy structured access to an XML file that would otherwise be difficult to access in a rational manner.

BigDecimal

Posted in Jerry Andrews on October 7th, 2009 by admin

Whenever you’re working with money in Java, you should be using BigDecimal. There are other applications, but far and away the most common is monetary calculations. The biggest reason is accuracy: floating point values (stored using IEEE standard 754) can’t represent common decimal amounts. For that, you need actual arbitrary precision math–the same kind you learned in grade school. That’s what BigDecimal provides. Yes, the operations are clumsy-looking and require a lot of typing. Wouldn’t you want your bank or your tax office to have full control over the precision of the values they use to calculate your interest or taxes? You owe it to your users to provide the same precision.

The problem is illustrated simply; pick any number with multipliers other than 2, store it, then print it out.

System.out.printf(“float: %60.55f\n”,0.35f);

float: 0.3499999940395355000000000000000000000000000000000000000

Using doubles helps, but doesn’t make the problem go away–it just delays the point where you’ll see a problem. The only real solution is to use arbitrary-precision math (or switch to a CPU which works in base 10 rather than base 2).

Wherever you can, make your first conversion from user input or database storage to BigDecimal using strings. The internal conversion exposes how these values are stored in the first place:

System.out.printf(“BD by string: %60.55f\n”,new BigDecimal(“0.35″));
System.out.printf(“BD by double: %60.55f\n”,new BigDecimal(0.35d));
System.out.printf(“BD by float: %60.55f\n”,new BigDecimal(0.35f));

BD by string: 0.3500000000000000000000000000000000000000000000000000000
BD by double: 0.3499999999999999777955395074968691915273666381835937500
BD by float: 0.3499999940395355224609375000000000000000000000000000000

Once you have values stored as BigDecimals, keep all your math between two BigDecimal values. You don’t gain anything by storing a value in BigDecimal, then multiplying it by a float or a double! You introduce the same problem by doing that that you sidestepped by moving into BigDecimal. I’ve seen senior developers do the following:

public BigDecimal multiply(BigDecimal bd, double d){
return bd.multiply(new BigDecimal(d));
}

Given the “BD by double” result above, is this really going to produce the results you expect? By doing this, you just gave up whatever advantage you had using BigDecimal in the first place!

If you use division in BigDecimal, you’re going to have to round your results. To illustrate why, consider the following:

BigDecimal result = BigDecimal.ONE.divide(new BigDecimal(“3″));

Exception in thread “main” java.lang.ArithmeticException:
Non-terminating decimal expansion; no exact representable decimal result.
at java.math.BigDecimal.divide(BigDecimal.java:1594)
at BDDemo.main(BDDemo.java:12)

Any calculation which results in a repeating decimal result will throw this exception. To deal with this problem, we need to discuss the relationship between “precision”, “scale” and “rounding”. “Precision” is the number of “significant digits” we learned about in science class in high school. The following numbers all have a precision of 4:

123.4
1234
12340
12.34
0.000001234

Unfortunately, BigDecimal has no internal concept of “precision”. It stores its result as an integer of arbitrary precision, and then places the decimal point using a concept called “scale”–the number of places to the right of the decimal point. Thus, the scale of “12.34″ is 2; the scale of “0.000001234″ is 9. When you construct a BigDecimal with a given scale, you’re reducing its precision.

In order to deal with the ‘repeating’ result, you’re going to have to know enough about your problem domain to specify a scale, and a rounding mode to determine the result.

Rounding modes are discussed in detail in the BigDecimal javadoc, and I’ll discuss them in a future entry, but for now, here’s the list:

ROUND_UP round away from zero.
ROUND_DOWN round towards zero.

ROUND_CEILING round towards positive infinity.
ROUND_FLOOR round towards negative infinity.

ROUND_HALF_DOWN round towards “nearest neighbor” unless both
neighbors are equidistant, in which case round down.
ROUND_HALF_EVEN round towards the “nearest neighbor” unless both
neighbors are equidistant, in which case, round towards
the even neighbor.
ROUND_HALF_UP round towards “nearest neighbor” unless both
neighbors are equidistant, in which case round up.

ROUND_UNNECESSARY assert that the requested operation has an exact
result, hence no rounding is necessary.

Note that “ROUND_DOWN” is the same as truncating the result, and by convention, banks and accountants uses ROUND_HALF_EVEN (and has for at least the 3 decades I’ve been paying attention, if not longer).

Rules for using BigDecimals are heavily tied to your problem domain, but I do have a few rules of thumb as starting places:

1. Don’t round at all until you must (a) divide, (b) you have to store or output results.

2. BigDecimal conversion to and from a database should be done as strings. Hibernate, iBatis, and many other tools support this conversion easily and directly.

3. Standardize your representations early; put a small list of rounding mode/scale pairs for your application in an enumeration somewhere so they will be consistent across your application.

4. Talk frankly with your architects, designers, and requirements people about the use of arbitrary-precision math; make sure everyone is on the same page.

Using BigDecimal seems clumsy and wordy when you start. You’ll develop style conventions and approaches which work if you take the plunge, and you’ll have a lot more confidence in your numeric results once you do.

iTunes Export 1.6 Released

Posted in Eric Daugherty on October 4th, 2009 by admin

admin originally posted this on EricDaugherty.com.

A new version of my iTunes Export utility is available.

iTunes Export exports your iTunes playlists as M3U, WPL, ZPL, and now also MPL files, allowing you to setup playlists in iTunes and use them with other software or devices.

This release adds several fixes and enhancements that have build up in the last few months. They include:

Improved the logic for music copying. It can now handle duplicate songs and an arbitrary number of songs in a playlist (removed the 999 song limit) and handles duplicate files gracefully. Thanks to Simon Hyde for submitting the patch.

Added support for MPL playlists, used by Centrafuse (www.centrafuse.com) Car PC. Thanks for Stavros Glezakos for submitting the patch.

The new version can be downloaded from the project homepage: http://www.ericdaugherty.com/dev/itunesexport/

There have been several requests for improved file copying approaches to handle the many different usage scenarios. I have begun work on a 2.0 version and am planning to include a revamped approach to file copying in that release. Thanks for all the feedback.

Please email me with new features or bug fixes (eric@ericdaugherty.com).

Design Constraints

Posted in Jerry Andrews on October 4th, 2009 by admin

Last night a bunch of us discussed the lines between architecture, design, and implementation.

I started with a working definition John Prentice gave me–heavily paraphrased, from memory: architecture is “enough design that it’s clear the system requirements can be met”, and design is “enough design that the path code will follow is clear”. Bryan Helm suggested that architecture should also constrain design so that “good design choices will be the natural ones; bad design choices will tend to be excluded”, theory being that architects tend to be senior designers as well.

There’s a lot of good discussion of “what it is” on the web; I’ve provided some links at the end for articles I found particularly illuminating and useful.

Within the context of executable design, the group of us agreed we’d all been dealt horrible or irrelevant architectures and designs, and one hallmark of a good architecture, and also a good design, is that you could rough out code that followed the architecture, and it would execute as expected. Similarly, you could implement the design exactly, and it would execute as expected. In both cases, obviously, the system would be grossly incomplete–but the specification at the design level would be complete enough that all the functions required of the system were stubbed out and ready for detailed implementation.

I’m not sure the distinction between architecture and design is important from the point of view of a set of executable design tools. I think architecture should constrain design, and design should constrain construction. Given the way code is actually constructed, the architectural description and the design description must be maintained as the software is developed. What better way to do that than making key portions of these descriptions the armatures upon which code is developed? Code generation isn’t the way to go, because you have to keep round-tripping, and you lose the abstraction provided in the design level.

The only way I can see to allow the design to constrain the construction is to use the design itself as the runtime environment for the final code. In the Java and .NET worlds, this means custom class loaders sitting between the developed code and the design, verifying conformance to the design and allowing the design to execute directly if code hasn’t been provided to implement it. In this way, you can actually test the design as it is developed, in the same way you test code as it is developed: by running it.

There are many good articles; here’s a jumping off point:

http://www.ibm.com/developerworks/rational/library/feb06/eeles/
http://www.bredemeyer.com/whatis.htm
http://www.itarchitect.co.uk/articles/display.asp?id=358

FlowLayout in Flex 4

Posted in Justin Shacklette on October 1st, 2009 by admin

admin originally posted this on Saturnboy.

Another one of my favorite improvements that found its way into Flex 4 is the separation of layouts from containers. The fact that layouts can customized and simply plugged into any container is pretty sweet. It’s a real developer benefit because it makes me faster. I can quickly develop a custom component by leveraging a stock layout. Alternately, I can develop a “new” component by creating a custom layout and plugging it into a stock container.

Layout References

Here’s a short list of useful Flex 4 layout references I was able to dig up. If you have anything to add, please leave a comment, and I’ll update this list.

My FlowLayout

I started with Evtim’s FlowLayout and made a few modifications of my own. I added a single gap parameter that controls both the horizontal and vertical separation of elements, and a border parameter that controls the padding around the outside of all the elements. The other major difference is how my version of the Flow layout handles the very first element.

I make sure the first element (when i = 0) is never shifted down, with a simple if (i > 0) check:

//does the element fit on this line, or should we move to the next line?
if (x + elementWidth > containerWidth) {
    //start from the left side
    x = _border;
 
    //move to the next line, and add the gap
    if (i > 0) { //never shift the first element down
        y += elementHeight + _gap;
    }
}

Here it is (view source enabled):

Flash is required. Get it here!
Files

NOTE: All code was built with Flash Builder 4 Beta 1.