Home
Tapina
Tech blog entries have now moved to the main Tapina Blog. This article on progressive enhancement with GWT can be found at http://www.tapina.com/blog/gwt-progressive-enhancement-existing-page.html.
 
 
Tapina
09 March 2009 @ 10:21 am
Tech blog entries have now moved to the main Tapina Blog. This article on progressive enhancement with GWT can be found at http://www.tapina.com/blog/substituting-variables-xml-templates.html.
 
 
Tapina
25 February 2009 @ 10:24 am
Tech blog entries have now moved to the main Tapina Blog. This article on progressive enhancement with GWT can be found at http://www.tapina.com/blog/integrating-gwt-with-spring.html.
 
 
Tapina

I had this old page linked (http://homepage.mac.com/rnc/EditMpegHeaderIFO.html) but it appears to have gone.

 

Reproduced below for my (and others’) information.

 

MPEG file

 

Locate the sequence header 00 00 01 b3 (usually hex address 000)

Make changes as need, then save.

 

Here is an example: 740x480, 16:9, 23.976 fps

 

0000000: 00 00 01 B3 2E 01 E0 31 00 00 00 00 00 00 00 00

 

Horizontal Size in Hex

16 0 = 352

1E 0 = 480

2D 0 = 720

2E 4 = 740

 

Vertical Size in Hex

0F 0 = 240

1E 0 = 480

 

Aspect Ratio

1 = 1:1

2 = 4:3

3 = 16:9

4 = 2.211 (not used in dvd)

 

Frame Rate

1 = 23.976

2 = 24

3 = 25

4 = 29.97

5 = 30

6 = 50

7 = 59.94

8 = 60

 

IFO file

 

Open your VTS_01_0.IFO in HexEditor,

Locate hex address 200

Make changes as need, then save.

 

Here is an example: 16:9, 740x480, AC3 audio

 

0000200: F9 00 00 01 00 01 00 00 00 00 00 00 00 00 00 00

 

Aspect Ratio

43 = 4:3

F9 = 16:9

 

Resolution NTSC (PAL)

00 = 720x480 (720x576)

1 = 704x480 (704x576)

0A = 352x480 (352x576)

0C = 352x240 (352x288)

 

Audio Coding

00 = AC3

02 = Mpeg-1

03 = Mpeg-2ext

04 = LPCM 

06 = DTS


 
 
Tapina
Tech blog entries have now moved to the main Tapina Blog. This article on progressive enhancement with GWT can be found at http://www.tapina.com/blog/thread-safe-replacement-gethostbyname.html.
 
 
Tapina
25 January 2008 @ 04:48 pm
I can’t believe I only just came across the Chicago Manual of Style! The actual manual seems to require subscription, but the Q&A is a great resource (and I do not mean “person”!) even without the manual.
 
 
Tapina
25 January 2008 @ 04:02 pm
When did company or project meetings start being called “town halls”?

Furthermore… why do people who work in offices feel bound to create euphemisms for perfectly workable phrases?
“opportunities”? “resources”? and “going forward”? Argh!
 
 
Tapina
18 January 2008 @ 11:48 am
Tech blog entries have now moved to the main Tapina Blog. This article on progressive enhancement with GWT can be found at http://www.tapina.com/blog/clipboard-file-transfer-protocol.html.
 
 
Tapina
18 December 2007 @ 10:32 am
Tech blog entries have now moved to the main Tapina Blog. This article on progressive enhancement with GWT can be found at http://www.tapina.com/blog/type-conversion-using-java-generics.html.
 
 
Tapina
31 October 2006 @ 02:06 pm
Yes, that subject is grammatically correct. I am referring the long file names in Windows, and whether they are visible or not. Mostly not, as I've found from recent experience with CVS and a Java project with a deep package structure. This leads to "No such file or directory" errors, an inability to manipulate the file with Explorer, and other goodies. Essentially, if you do a bit of Googling for 'windows MAX_PATH' then you'll find out that certain of Windows' file handling APIs are restricted to 255 character paths. This manifests itself in serious problems when trying to use CVSNT or similar utilities with long paths. Apparently, Windows' Unicode APIs don't have this restriction, but it seems that Windows Explorer doesn't even use them because the offending files cannot be manipulated from there - no Rename, no Delete, no nothing. If you try to delete the file in a command prompt window then you get a lovely error saying:
The filename or extension is too long.
As an example of the problem, I have a particular class file which is called:
uk\org\cough\develop\oranges\signed\fishandchipshops\modems\trackmylamps\
  widgetland\command\display\GetAppleAdjustmentPrimaryOrangeRefDataHandle.java
. Obviously I have changed the names to protect the guilty, but the length is right. The source is nicely modular so this sits inside a source folder which is components\actions\fishandchipshops_commandactions\src. This sits inside a folder called MyApp v1.20 which sits inside my Eclipse workspace, which is in C:\Documents and Settings\X123456\workspace. OK, so the total path is pretty huge, but none of these things are unreasonable (except possibly for the package depth, but that's not mine to alter). Trying to cvs update this folder even from lower down the tree gives errors like:
cvs: update (warning): uk\org\cough\develop\oranges\signed\fishandchipshops\
modems\trackmylamps\widgetland\command\display\
GetAppleAdjustmentPrimaryOrangeRefDataHandle.java is lost

cvs: update (warning): uk\org\cough\develop\oranges\signed\fishandchipshops\
modems\trackmylamps\widgetland\command\display\
GetAppleAdjustmentPrimaryOrangeRefDataHandle.java: No such file or directory
If I navigate with Windows Explorer to this file, I can't do anything with it except Open or Edit it. There are two workarounds:
  1. Use tools that use the Windows Unicode APIs exclusively. This is difficult, because the Windows GUI itself doesn't.
  2. Use SUBST. SUBST lets you map a drive letter to path. By cutting out the path to my workspace directory, I could save myself 40 characters and make this all work (until someone creates an even deeper, even longer-named source file):
    SUBST P: C:\Documents and Settings\X123456\workspace
    Once this is done, do your CVS commands from the P: drive instead of the C: drive and the path is short enough. Hoorah!
 
 
Tapina
05 June 2006 @ 07:15 pm
Did a presentation today on Selenium testing to the rest of the members of my team. I’ve invested a fair bit of time over the last few weeks in figuring out how to do some stuff with Selenium and have written a bunch of Selenium extensions. Must put some of that info up here for posterity.
 
 
Tapina
12 May 2006 @ 01:03 pm
Well, I gave up on NetBeans and went back to good old IntelliJ. So much better than the competition...

But right now, I'm on a machine which is struggling to run IntelliJ with a 110-module project (don't ask...) so I'm giving Eclipse a go since that's what everyone else uses (not that they actually structure their Eclipse project into modules and get the dependencies right).

But I hit a snag right away on this Windows box - Eclipse picked up an old Java version off the PATH (which I can't edit because I don't have Admin rights) and it took me a while to figure out how to change it. The answer was the edit the eclipse.ini file and add two lines at the top:
-vm
c:\Local\j2sdk1.4.1\bin\javaw
Obviously the second one reflects where my Java installation actually is. And don't ask why it's 1.4.1 - I feel like I've travelled back in time working on this project!
 
 
Tapina
06 April 2006 @ 06:21 am
I have been so spoilt using IntelliJ IDEA. I hadn't realised quite how bad all the free IDEs were in comparison.

Eclipse looks kinda powerful and has lots of plugins and industry support, but it's so fugly I can't bear to use it for more than a few minutes. I think Mac OS may crash just to get away from it. It probably feels dirty.

Netbeans looked very promising. I downloaded the 5.5 preview, which looks like an inferior, less-featured rip-off of IntelliJ. It worked nicely but I came across one really annoying problem - the build I had forced me to specify a classpath per Java source directory. This wasn't helpful, because my source and test source is split across multiple directories and I really didn't want to find all AppFuse's JAR files umpteen times and add them to the source for each one. The checkbox was there to disable this behaviour, but it was shaded. No idea why. So then I downloaded the 6.0 nightly build. Another 60MB later, it starts and then immediately quits. Maybe that's not ready for primetime yet. So now I'm on the current release, 5. We'll see how I get on with that.
 
 
Tapina
28 March 2006 @ 10:22 am

It takes talent to come up with a great idea for a reusable component, or a library, but it takes a particular creativity to design the API to make it usable. A good API is built around a metaphor, or set of metaphors which represent the universe in which your library operates. Good APIs:

  • Make code readable
  • Reduce bugs
  • Reduce testing time

The objects in the API are best represented as nouns and the methods as attributes of the metaphorical object (for properties) and verbs, verb phrases or verb–noun pairs (for actions) which an reasonably be applied to those nouns. For example, from the standard Java API:

List
add(Object)
clear()
contains(Object)
remove(Object)
LayoutManager
addLayoutComponent(String, Component)
removeLayoutComponent(Component)
preferredLayoutSize(Container)
layoutContainer(Container)

These are great examples of sensible metaphor and naming. Just from the name, you can tell that a List represents a list, and a LayoutManager is some kind of automated agent for managing the layout of something. You can also see that layout manager is able to add a named component to itself, and layout a given container. As an aside, note how LayoutManager’s methods are not abbreviated. How much more readable is:

addLayoutComponent

than

addCmp()

? Clue: the correct answer is “a lot”.

A colleague recently pointed me at the latest and greatest innovation in Java XML parsing, VTD-XML. On the face of it, it seems a great idea: don’t build a million objects to hold your XML structure in memory, just keep a flat list of offsets of tokens within the original document, with depths. And for good measure, don’t even create objects for your pointers—use a C-like bit field to keep it all as primitive types. Great! The trouble is that this kind of old-school pack’n’squish mentality which kept us 8-bit programmers semi-sane back in the 1980s has also been applied to the user’s API for the library.

Witness the example in the JavaWorld article (reproduced below):

VTDNav vn = vg.getNav();
            if (vn.matchElement("purchaseOrder")){
                System.out.println(" orderDate==>" 
                    + vn.toString(vn.getAttrVal("orderDate")));
                if (vn.toElement(VTDNav.FIRST_CHILD,"item")){
                    if (vn.toElement(VTDNav.FIRST_CHILD)){
                        do {
                            System.out.print( vn.toString(vn.getCurrentIndex()));
                                System.out.print("==>");

                            System.out.println( vn.toString(vn.getText()));
                        } while(vn.toElement(VTDNav.NEXT_SIBLING));
                    }
                }
            }

Look at the use of abbreviations: “VTDNav” and “getAttrVal”. Makes it less readable. Our (English-speaking) eyes are attuned to reading English, so let’s give them English. How about a “VTDNavigator” and “getAttributeValue”? Those precious few characters are not going to matter in Java bytecode. But the biggest crime here is toElement().

Any sane person would expect toElement(), as a method on an object, to take the object and turn it into an “Element”, whatever one of those is. But this VTDNav, which should be VTDNavigator, is a navigator—something to help you find your way. It doesn’t make sense to turn it into an Element, a component of an XML document. Here’s what the methods of VTDNav are really doing (paraphrasing the JavaDocs):

matchElement(String)
Test if the current element matches the name supplied. The navigator starts at the root of the document.
toElement(int, String)
Navigate through the document in the direction specified by the integer constant, provided the element reached matches the name supplied.
toElement(int)
Navigate through the document in the direction specified.

Take a look at the DOM version of the example in the JavaWorld article:

Element root = d.getDocumentElement();
            if (root.getNodeName().compareTo("purchaseOrder")==0){
                System.out.println(" orderDate==> "
                    + root.getAttribute("orderDate"));

                Node n = root.getFirstChild();
                if (n != null){
                    do {
                        if (n.getNodeType() == Node.ELEMENT_NODE
                            && n.getNodeName().compareTo("item")==0){
                            Node n2 = n.getFirstChild();
                            if (n2!=null){
                                do {
                                    if (n2.getNodeType()
                                        == Node.ELEMENT_NODE){    
                                        System.out.println( 
                                            n2.getNodeName() 
                                            + "==>" +
                                            n2.getFirstChild().getNodeValue()
                                        );
                                    }
                                }while((n2=n2.getNextSibling())!=null);
                            } 
                        }
                    }while ((n=n.getNextSibling()) != null ); 
                } 
            } 

It’s longer, sure, but any fool can see what it is doing (root.getNodeName().compareTo("purchaseOrder") versus vn.matchElement("purchaseOrder") and n.getNodeType() == Node.ELEMENT_NODE && n.getNodeName().compareTo("item")==0 versus vn.toElement(VTDNav.FIRST_CHILD,"item")). That compareTo() == 0 would be better as equals though!

Let’s try reworking the VTD API, without changing the semantics at all, to make more sense of the example:

VTDNavigator navigator = vg.getNavigator();
            if (navigator.currentElementMatches("purchaseOrder")){
                System.out.print(" orderDate==>");
                System.out.println(navigator.valueOf(navigator.getAttributeIndex("orderDate")));
                if (navigator.moveToFirstChild("item")){
                    if (navigator.moveToFirstChild()){
                        do {
                            System.out.print(navigator.valueOf(navigator.getCurrentElementIndex()));
                            System.out.print("==>");
                            System.out.println(navigator.valueOf(navigator.getTextIndex()));
                        } while(navigator.moveToNextSibling());
                    }
                }
            }

Better? I think so.

 
 
Tapina
27 March 2006 @ 10:09 am
I think everyone knows that unit testing is important, but sometimes it’s done in a pretty brain dead way. Someone on our application thought it was important to write a test for a couple of XSLT stylesheets, to make sure that they did the right thing. They used XMLUnit and everything.

But they copied the stylesheets from the main source folder into the test sources folder. Doh! That means the test is not testing the same stylesheet we use for the real system, which defeats the whole point of having automated unit tests to defeat regression. Always remember to actually test the system under test, not your test system!
 
 
Current Mood: irritated
 
 
Tapina
23 March 2006 @ 10:18 am
Just found an excellent article on using Mac OS X’s Spotlight file index from the command line. Basically, instead of the very slow:
find / -name '*Oracle*'

or the not-up-to-date:
locate Oracle

Both of these just work by name. If I don’t know for sure that there’s an Oracle in the name then I have to resort to:
grep -r Oracle /*

That sucks. But on Mac OS X you can just do:
mdfind Oracle

Now, I’ve done a lot of work with Oracle and therefore this still takes a while (5 seconds on a second run)—but the biggest problem is that it returns 942 records, including text files, Excel spreadsheets and e-mail messages. Now I could pipe the results through grep to narrow down the filename but if I know I’m looking for a spreadsheet I can get a lot cleverer (and here’s where find and locate just don’t cut it).

mdfind works with the whole file—not only its content but also metadata added specific to the file format. To that end, I can look for spreadsheets that I wrote. But how to find what the metadata fields are? Well, the best way is by example. So I take an existing Excel file that I know I wrote and run it through mdls:
kMDItemAttributeChangeDate     = 2006-03-21 17:56:41 +0000
kMDItemAuthors                 = ("Gareth Boden")
kMDItemContentCreationDate     = 2006-01-20 07:12:01 +0000
kMDItemContentModificationDate = 2006-03-21 17:56:40 +0000
kMDItemContentType             = "com.microsoft.excel.xls"
kMDItemContentTypeTree         = ("com.microsoft.excel.xls", "public.data", "public.item")
...

OK, so If I revise my Spotlight search to look for spreadsheets I created in my home directory which mention Oracle:
mdfind -onlyin /Users/gareth "kMDItemAuthors = 'Gareth Boden' && kMDItemContentType = 'com.microsoft.excel.xls' && kMDItemTextContent = 'Oracle'"

Bingo! Which reminds me of another neat feature in Mac OS X—content types.

Not content with MIME types and file extensions and creator and file types, Apple decided to invent yet another classification scheme. But this time, they did a good job. Rather like MIME, it’s hierarchical (but to more than two levels, which is better). Unlike MIME (and like other smart ideas like Java package names) it piggybacks onto DNS registration to avoid centralised registration. Apple manage the public namespace (and the com.apple one) but the rest is up for grabs. From my example before, you can see that an Excel spreadsheet is also a public.data and a public.item content type. My AAC grab of Gorillaz’ DARE is:
"public.mpeg-4-audio", 
    "public.audio", 
    "public.audiovisual-content", 
    "public.data", 
    "public.item", 
    "public.content"

And I can use those to search for all MPEG 4 audio, all audio files, etc etc. Very cool.

Is there anything like Spotlight for Linux? Is it part of Darwin’s open source stuff?
 
 
Tapina
22 March 2006 @ 02:04 pm
P3P  
I'm currently having annoyances embedding a third party app in a frame into our web application as a result of IE6's helpful cookie-blocking stuff.

The third party app doesn't have P3P compact policies (and judging by the quality of standard-conformance with regard to the rest of its output, isn't likely to soon). The only solution I've come up with so far is to proxy the requests to the other application and hope that it never refers to its own hostname in URLs or headers.

Not very satisfactory but I don't have any better ideas right now.
 
 
Tapina
19 March 2006 @ 04:59 pm
Had a drink with Paul Fray on Thursday night. He's currently attempting to get some clients for his startup business advisory service (currently promoting itself as a finance system consultancy), and working for Virtual Consulting Group.

He was also mulling over a few ideas:


  1. Spreadsheet with various statistical tests implemented in it in an easy-to-use way.

  2. Hosted ASP hotel booking service for guests and hotels to use in place of existing offline booking mechanisms.

  3. Decent Microsoft Word version control.. something better than track changes that actually does diffs ignoring stupid stuff, and that people understand how to use.



It was also prompting me to mull over writing a hosted, web-based basic small business finance system. It could use UNSPSC for product and service classification and a secondary tree-structure for your own account codes. Because of the use of UNSPSC you probably wouldn't need very many of your own account codes to still get good reporting out of it since mostly your account codes are for product type. It could have a basic standard set out of the box and the tree structure would avoid the nasty numeric groupings people normally come up with when left to their own devices.

I don't think it'd be too difficult to write.. probably use something like Ruby on Rails with an AJAX interface to make sure it's interactive enough to look good next to client-installed systems. I like the MoneyWorks system I use for Tapina, so I'd probably look to that for some inspiration on how to make tasks easy but with a better underlying structure.
 
 
Tapina
17 March 2006 @ 02:38 pm
We've been using the RNIB to test our application under their See It Right programme but this new scheme to do accessibility testing with real disabled people sounds like a cracking idea.

Usability Exchange is the company behind it. Can't quite figure out how much it costs though!
 
 
Tapina
17 March 2006 @ 07:06 am
Just found an excellent article (probably old news to many) on web typography called The Trouble With EM ’n EN (and Other Shady Characters).

It covers not only em and en dashes (which are almost never used correctly, on the web or in word processed stuff) but also different types of spaces, quotes and other typographical gubbins. Excellent stuff for pedants who enjoyed Eats, Shoots & Leaves.