Friday, December 12, 2008

online money managers

This past month I started tracking all my expenses online, partly because we've hired a financial planner and she keeps asking how we spend our money. (Rude, I know.)

I started with Mint.com (because a vendor of my employer recommended them), and I'm very happy with their service. They:
  • They import from all my accounts (so far).
  • They categorize each expense automatically (and they're usually correct).
  • I can change the categorizations, and save the preference so that future expenses with the same description are categorized the same way.
  • I can split expenses and categorize parts separately.
I only have two complaints so far:
  • I cannot manage my cash.
  • While I can add my own categories, I cannot change or remove the predefined ones.
Coincidentally, today I found two other services that do much the same thing. I won't be switching yet, but I'll be watching for mothers:
  • Wesabe.com is very interesting because they want to make it a community that gives suggestions to one another; in addition, they have some APIs to help you work with your account data... they just want to make it really easy to analyze your finances and get help managing them. The current show-stoppers: they require a Mac or Windows install, so I cannot manage things from whatever computer I'm on; they currently only work with "USAA, Citibank, Chase, Wachovia, CapitalOne, and Bank of America"; and their APIs don't yet aggregate account data.
  • Egg.com seems to offer services similar to Mint, plus in-house financial services like loans, savings accounts, etc. The current show-stopper: it requires a Windows ActiveX install.

Thursday, December 11, 2008

Ancient teleconference demo... of mouse, screen-sharing, hypertext, and more!

Yesterday was the 40th anniversary of what The Register calls "The Mother of All Demos". They're not kidding. You can see it in a video that captured the presentation. Here are some highlights:
  • It starts out with 1 minute 30 seconds of text explaining how the whole production was set up, after which he jumps into his demonstration.
  • He starts showing the hyperlinking at 15:50.
  • He explains his mouse and his one-handed text entry device at 27-30 minutes in.
  • Someone else joins in to work on the same screen at 57 minutes in.
It's fascinating to watch, with all the glitches he hits and the things he has to explain along the way. Be sure to read the article and the explanatory text at the front of the video to get a full appreciation of this demo. It's history right before your eyes.

Tuesday, December 9, 2008

Jolly Old Mathematics

So I was reminiscing with Jen about Helaman Ferguson and creative math, so I had to google for fun with math for this Christmas season. I found a few lists (this is probably the best one), but here are the specific activities that looked like the most fun out of the dozens I perused:


Happy Holidays!

---

While I'm here, I've got to mention two cool fractal sites, even though they're not Christmas-oriented:

Tuesday, November 18, 2008

a few notes about the Java ClassLoader

I found a case today where the clazz.getResourceAsStream(String) retrieved a resource but the clazz.getClassLoader.getResourceAsStream(String) failed to find it. Weird.

I never figured it out, but I came up with the following as I tried:

  • There is no way to get all the entire path that is being searched. I always come to this point and try, but it's a hard fact of Java. I did find this blog entry that explained how you might patch the ClassLoader.toString() methods. But read on...
  • Even for URLClassLoader classes, it looks like it'll search through directories that are not found by the getURL() method (so that previous blog entry won't catch them all). I found this by running some unit tests in Maven with the method that follows, and it was retrieving things from the 'classes' and 'test-classes' directories that didn't show in the getURL() results.
  • If you try a call to getResource(""), it'll show some of the directory paths that are in the search path. I don't know for sure that this is true because I can't find it documented, but it seems to work. So the following method will show all the URL and path resources up the line from a given loader:

private static void showAllResourcePaths(ClassLoader loader) {
try {
String indent = "";
for (ClassLoader nextLoader = loader; nextLoader != null; nextLoader = nextLoader.getParent()) {
System.out.println(indent + " loader " + nextLoader);
for (Enumeration<URL> urls = nextLoader.getResources(""); urls.hasMoreElements(); ) {
URL url = urls.nextElement();
System.out.println(indent + " path: " + url);
}
if (nextLoader instanceof URLClassLoader) {
System.out.println(indent + " URLs: " + Arrays.asList(((URLClassLoader) nextLoader).getURLs()));
}
indent += "-";
}
} catch (Exception e) {
e.printStackTrace();
}
}

  • Using that method will show you most of what you want because, in my tests, all the class loaders in the ancestry turned out to be URLClassLoaders.

What is the difference between the clazz.getResource and clazz.getClassLoader().getResource methods?

Monday, November 17, 2008

online to-do lists

I've been keeping my to-do list in a text file on my phone, and that together with my phone's calendar and my email are the things that pretty much run my life. Someday I'm sure that there will be a way to have all of those things integrated the way I want, most likely through an online service. To do so, they'll have to:
  • make it easy to make notes wherever I am, ideally with Jott
  • allow me to attach a "context" (and a time estimate)
  • integrate with a calendar
  • allow for task dependencies
Today I figured it was time again to check around and see if today is that day. It looks like it's not. The dependency feature is the hardest to find, and I'm a bit surprised it's still not very widespread. Here's some of the info I've gleaned from about a dozen sites:

Remember The Milk is integrated with Jott for free, which makes it most attractive for a trial; I'd like to try Hivemind for their dependencies, and I will if I do a paid subscription to Jott (eg. pay-as-you-go, because Jott is critical but I use it rarely).

Thursday, October 30, 2008

integration tests with Wicket and Spring

I had a bear of a time getting my Wicket tests to work with services injected by Spring.

I started with the helpful Wicket-Spring unit-test instructions here; this got me through a basic test. Unfortunately, I must use Spring-managed services from my main AuthenticatedWebSession class since I'm using the standard Wicket "Auth-Roles" security (simply, without Acegi); Wicket has a helpful way to tie with Spring when it comes to the WebPage classes, but this doesn't work for the things I'm using in the main WebApplication or WebSession classes.

I found another project that uses Spring's test class AbstractTransactionalDataSourceSpringContextTests as it's parent class, and this proved to be my salvation. Basically, I extend that class and add the following 2 methods:

protected ConfigurableApplicationContext createApplicationContext(String[] locations) {
context.setServletContext(new org.springframework.mock.web.MockServletContext());
context.setConfigLocations(locations);
context.refresh();
return context;
}

protected String[] getConfigLocations() {
return new String[]{"context/backoffice-webapp.xml"};
}


Then I have to override the "onSetUpBeforeTransaction" method instead of the traditional JUnit "setUp" method:


@Override
protected void onSetUpBeforeTransaction() throws Exception {

super.onSetUpBeforeTransaction();

AuthenticatedWebApplication authenticatedWebApp = new WicketApplication() {
@Override
public void init() {
addComponentInstantiationListener(new SpringComponentInjector(this, TestHomePage.this.applicationContext));
initForAppAndTests(); // this is where I set up my global services, called by WicketApplication.init() as well
}
};
tester = new WicketTester(authenticatedWebApp);
}

That made it all work.

BTW, although I'm using Spring 2.5.5, the latest spring-mock library is only 2.0.8.

Tuesday, October 21, 2008

Google GData APIs

This is just so I can find the Java API for Google GData. (Go ahead: try googling "gdata api" and see if you can find it that way. I dare you.)

http://code.google.com/apis/gdata/javadoc/

Note that it's linked from the "Client Libraries" page.

Update: you can find it easily in a Google search on: "gdata javadoc"

Tuesday, October 7, 2008

Wicket i18n and l10n

I'm playing with text properties in Wicket, and I found this good article on it (up to and including v1.4) by Erik van Oosten. You can see more technical details in Wicket's basic references on i18n and l10n.

What I'd really like is the ability to refer to other properties within a text property, but it doesn't appear to have that. I even tried to put it in, but it assumes you have an object with that name laying around, or at least an accessor ("get...") method with that name (up to the first ".") somewhere in your component hierarchy, so I cannot figure out how to hack that in. Yet.

Wednesday, September 17, 2008

lessons from setting up Google Apps with Single-SignOn

Here are my lessons learned from setting up Google apps with Single-SignOn, where I can manage email and contact settings via an API.

Premier
search for "google apps"; be sure to "compare editions"
  • - provisioning via API
  • - email migration API
  • - contact/doc sharing

Purchase & Configure
  • - free for a month (temporarily?)
  • - they verify you own it (HTML file or CNAME change)
  • - for mail, you set them with the MX records
  • - asynchronous setup steps

Provision New Accounts
search for "google apps apis"; look around for "client libraries" and "sample code"
  • - we really only need the "samples" codebase to show how to use their libraries
  • - peruse the INSTALL and README files
  • - after editing some properties, you can create/delete users; here's a huge test:
  • ant -f appsforyourdomain.xml sample.appsforyourdomain.run
  • - I commented out the call to 'deleteUser' so I could see the effect in the UI

Enable SSO (Single-SignOn)
  • - look at how to enable it in the admin area
  • - read links to SSO docs as you do things; I had to read a ton of things in their proper contexts before it started making sense

SSO Attempts
  • - open source projects: http://code.google.com/apis/apps/open_source_projects.html#sso
  • - Shibboleth: error in IdP, but it worked after tweaking build.xml; unable to install SP, so I stopped http://code.google.com/apis/apps/articles/shibboleth2.0.html
  • - JOSSO: easy to get sample up and running; unclear how to wire to Google, so I stopped
  • - ESOE: didn't even try it
  • - Google has best basic example as Java JSP project in "client libraries" and "sample code": http://code.google.com/p/google-apps-sso-sample/downloads/list
  • - Google instructions, which are awesome (from README in download): http://code.google.com/apis/apps/sso/saml_reference_implementation_web.html

Lessons Learned during SSO Attempts
  • - use this reference for key generation: http://code.google.com/apis/apps/articles/sso-keygen.html
  • - many lessons about keys and certificates: private key vs. public key vs. certificate
  • - keytool stores things in home directory, protected by a password
  • - openssl generates artifacts via stdout or to files you specify
  • - Google tutorial doesn't explain how to change the SP URL (to your google apps domain). I've modified their v1.0.1 JSP code, so in my version you only need to change the domain name in the "saml_demo.jsp" file.
  • - Furthermore, I was able to create a one-step, single link that logs you in automatically. You'll have to contact me directly if you want this.

Thursday, July 3, 2008

executing a command from 'find' results in UNIX

This one greps through all the files from the 'find' for org/apache/regexp:


find . -exec grep "org/apache/regexp" '{}' \; -print

complicated rearrangements of text in UNIX

This shows how to take whitespace-delimited input and build something fancy from it:


echo -e "123 abc\n987 zyx" | awk '{ print "<nodeXXX attr1=\"" $1 "\">\n\t" $2 "\n\t<nodeYYY attr2=" $1 "/>\n</nodeXXX>"}'

matching multiple lines in Unix

This will pull out the multiple lines from the log, where the first line has XXX and the last line has YYY:


perl -n -e "print if (/XXX/ ... /YYY/)" file


To substitute string "country_bumpkin" for "country" in a whole bunch of files:


perl -p -i -e "s/country/country_bumpkin/g" files

counting lines in Unix

Andrzej tracked down those open files with the following command. What's cool is that he counts how many instances a record occurs with 'uniq', and he uses 'sort -n':


lsof | grep -e '^java.* REG ' | grep ' dtstage ' | awk '{print $9}' | sort | uniq -d -c | sort -n


Here's a quick demo of 'sort -n'... see how the results are different if you remove the '-n':


echo " 1\n.5" | sort -n

Monday, June 30, 2008

multiple pictures in a post

I found that it's tricky to insert multiple pictures in a post and have it look decent, as in this post. I wanted to have the pictures near the text, so I had to do the following:

  • I alternate placement of pictures on the left and right sides. I tried placing some in the center but there isn't enough space and it can cause some of them to overlap.
  • I put plenty of new-lines between the sets of paragraphs and pictures so they generally stay together.
  • When a paragraph begins with a short word (like "so" or "we"), I follow it with an " " instead of a space. If I don't, that first word often shows up alone in the margin or between pictures, far away from the paragraph.

Thursday, June 19, 2008

ways to fix a Subversion comment

The first is if your log message is just one line, the second will open up your text
editor to edit the log entry directly, and the third is if your
log message is an a text file.

  • svn propset svn:log --revprop "My corrected log message" URL -r REVISION
  • svn propedit svn:log --revprop -r REVISION
  • svn propset svn:log --revprop -F FILE-WITH-CORRECTED-MESSAGE URL -r REVISION

Friday, June 13, 2008

using code examples in blogger.com

Including code snippets is always a mess in blogger; here's what I've found by trial and error:

  • Encode things with an HTML encoder such as this one. There's really no easy way to just paste what you want without this kind of preprocessing.


  • I prefer to use <pre> for formatting because it won't wrap:


like this example that preserves display but goes off the end of our narrow little page very quickly


  • Use <code> if you don't care that it wraps:


so here we have an example with the monospaced font, but it wraps to the next line as it gets to the end


  • The <blockquote> will give you indentation, but usually that pushes you off the screen, so I wouldn't use it:




like this example that quickly spirals out of control and out of the short bounds we have in this thing....



  • Don't even try to use <xmp> tags; they will get processed into mush when you jump back-and-forth from from 'Edit Html'.


such as this example using the &amp;amp;amp;amp;amp;amp;amp;amp;lt;xmp&amp;amp;amp;amp;amp;amp;amp;amp;gt; tag

export/import contents of a single table in FrontBase

Jon found this:

The WRITE TABLE statement is a way to dump just the content of a table into a flat-file.

Syntax:


WRITE TABLE <table name>
OUTPUT('<path of output file>' [, '<column sep>', '<row sep>']);


Example:


CREATE TABLE T0(C0 INT, C1 VARCHAR(1000000));
INSERT INTO T0 VALUES (1, 'Smith'), (2, 'Jones');
WRITE TABLE T0 OUTPUT('/tmp/T0.txt', '~', '~\n');


Resulting file (T0.txt):


<table Expr>
2
1 "C0","~"
2 "C1","~\n"
1~Smith~
2~Jones~


This file can then be imported into some other table by executing:


INSERT INTO <table name> FROM 'FrontBase' INPUT('/tmp/T0.txt');


Please note that if the column names of the table the data is to be imported into are different, you will have to edit T0.txt accordingly.

A while ago WRITE TABLE was actually enhanced to, in addition to a table name, accept a table expression, i.e. a way to dump out the result set of a SELECT.

Examples:


WRITE TABLE SELECT C1 FROM T0 WHERE C0 < 2 OUTPUT('/tmp/T0.txt', '~', '~\n');

WRITE TABLE VALUES('3⁄4?') OUTPUT('/tmp/T0.txt', '~', '~\n');


The latter example is a good way to see how FrontBase expects national characters to be represented:


<table Expr>
1
1 "_VALUES001","~\n"
\195\166\195\184\195\165\195\134\195\152\195\133~

Monday, May 12, 2008

creating a WebObjects application with Maven: WOProject, WOCreator, and WOLips


I'm starting a project working with WebObjects. I'm most familiar with
Tomcat, J2EE standards, and Ant/Maven, so let's see what it takes to get a working application.

WOCreator

A friend found posts referencing a different project WOCreator, and this one turned out to be very easy to install. Just follow the instructions on their main page. Here's what I ended up using (though I believe the 'repository' flag is wrong, but I suspect it's not being used in my case).


mvn com.bbc.newsi.mvn.plugins:maven-wocreator-plugin:create-project \
-DgroupId=com.icentris.webdynamics -DprojectName=sampleCreator \
-Drepository=file:///home/trent/.m2/repository -DwebObjectsVersion=5.4


The one difficulty I had was with all the jars. First of all, you have to get the WebObjects jars into your repository; they provide a script that will install all the required jars into your local repository. This is incredibly helpful. Second, you have to manually install the following jars if you don't already have them; a quick web search will tell you where you can get them:
  • com.sun.jdmk jmxtools 1.2.1
  • com.sun.jmx jmxri 1.2.1
  • javax.jms jms 1.1
Quite frankly, after the struggles with WOProject, this is an awesome tool because it just works: you run the Maven tasks 'create-project', then 'package', then 'jetty:run-war'. The only thing that hung me up for a minute was the URL; Jetty started up and reported that I could go to the following URL:

http://trent-laptop/sampleCreator-application-1.0-SNAPSHOT/WebObjects/sampleCreator-application-1.0-SNAPSHOT.woa

However, this was wrong; I had to add the right port and change the context to the name I gave to 'create-project':

http://trent-laptop:8080/sampleCreator/WebObjects/sampleCreator-application-1.0-SNAPSHOT.woa

Wonderful! I have an application that I was able to tweak with 'webobject' tags and see something work. It only took about 24 hours because I started with WOProject first (see below). But start with WOCreator and you'll be working in no time.


WOProject bootstrap

It looks like the WOProject will install the jars and set up a sample app with Maven.

At first, I can't get the bootstrap to work:

[INFO] The plugin 'org.apache.maven.plugins:maven-wobootstrap-plugin' does not exist or no valid version could be found


I really struggled with this plugin stuff. The thing that finally seemed to get it to at least recognize the 'mdimension' repository was to create a dummy pom.xml and then add the plugin info to the 'reporting' section of a pom:


<plugins>
...
<plugin>
<groupid>org.objectstyle.woproject.maven2</groupid>
<artifactid>maven-wobootstrap-plugin</artifactid>
</plugin>
...
</plugins>


I then had to add the POM file directly to my local repo copy (to get around it's inability to find the org.apache.commons.lib.SystemUtil class):


http://webobjects.mdimension.com/maven2/releases/org/objectstyle/woproject/maven2/maven-wobootstrap-plugin/2.0.14/maven-wobootstrap-plugin-2.0.14.pom


... and I finally got something to work. Here's the final command:

mvn org.objectstyle.woproject.maven2:maven-wobootstrap-plugin:install \
-DwebObjectsLibFolder=/usr/local/apple/Library/WebObjects/lib -DwebObjectsVersion=5.4


That's frustrating, because I'm not quite sure what piece I added that made it all work. I spend about 6 hours fooling around with this stuff. Maybe I'll try and figure out this plugin craziness sometime.

Right now, I want to see if I can get the archetype setup to work.



WOProject archetype

I start with the following default from their example:

mvn archetype:generate -DarchetypeCatalog=local


It promps me to choose:

Choose archetype:
1: local -> woapplication-archetype (WebObjects Application Archetype)
Choose a number: (1):


... but the first time I got this error:

org.apache.maven.archetype.downloader.DownloadNotFoundException: Requested download does not exist.


Fine. So I try this, but it's totally wrong because it dies before I can even choose:

mvn org.objectstyle.woproject.maven2:archetype:generate \
-DarchetypeCatalog=local


And I graduate to a "FATAL ERROR" with this attempt:

mvn org.objectstyle.woproject.maven2:woapplication-archetype:generate \
-DarchetypeCatalog=local


At this point, I choose the first one again, and it seems to work because it prompts me for more and starts making the project. Argh! Is that good now that something's working, or bad because I have no idea what fixed it?

BTW, if you get the following error, make sure there's no pom.xml in the current directory:

[ERROR] org.apache.maven.archetype.exception.InvalidPackaging: Unable to add module to the current project as it is not of packaging type 'pom'


I learned I have to specify the "WebObjectsVersion" because it defaults to something else and doesn't ask you the first time around. (You could also answer "n" at the end of the other questions so that it prompts you for it, but then you have to answer all the questions again.) While I'm at it, I might as well specify it all.

So here's the final command:

mvn archetype:generate -DarchetypeCatalog=local -DWebObjectsVersion=5.4 \
-DgroupId=icentris-webdynamics -DartifactId=sample -Dversion=0.1 -Dpackage=app

Although this creates a basic app, the app doesn't build correctly with 'mvn package'. I tried a few things but it cannot find a properties file (that exists), and it says to run another buildfile (that doesn't exist):

org.objectstyle.woenvironment.env.WOBuildPropertiesNotFoundException: Could not find wobuild.properties. Run the buildfile: woproperties.xml first.

I've given up on this set of tools for now, mostly because I've found something else that works.


WOLips

I have to mention WOLips: it claims to be "the toolset that Apple itself uses internally"; it certainly has great documentation (which I used to help with WOCreator above), and a colleague has successfully started porting his Mac-based development environment to WOLips so that the rest of us can play with it. Unfortunately, I followed their instructions to install with Eclipse Update Manager and I ended up with a project that has a bunch of errors and a directory structure that doesn't match their screen shots (and their proposed fixes don't remedy the situation). Well, that was a dead-end, but at least it was a quick one!

Update: I've got WOLips working, and fairly easily. I don't know what I did, but I erased all my earlier stuff and started with a new WO Application and I got something without any errors, and something that ran great when I right-clicked on Application.java and choose "Run As" a "WOApplication. This generates some build files for an Ant build process as well. If you have to work with a WebObjects application, I've heard that the UI is essential so you really have to use WOLips.

Thursday, May 8, 2008

installing FrontBase on Ubuntu (and/or Debian)

I got a grundle of problems attempting to install FrontBase, but my flailing attempts finally worked, so here's what happened.

Start with the official guide at the FrontBase site.

On my first 'dpkg' attempt, I got the following errors:


$ sudo dpkg -i FrontBase-4.2.8.deb
(Reading database ... 122351 files and directories currently installed.)
Preparing to replace frontbase 4.2.8-1 (using FrontBase-4.2.8.deb) ...
Unpacking replacement frontbase ...
dpkg: dependency problems prevent configuration of frontbase:
frontbase depends on libncurses4 (>= 4.2-3.1); however:
Package libncurses4 is not installed.
frontbase depends on libreadline4 (>= 4.1); however:
Package libreadline4 is not installed.
dpkg: error processing frontbase (--install):
dependency problems - leaving unconfigured
Errors were encountered while processing:
frontbase



Then I tried 'apt-get' and still got errors:


$ sudo apt-get install -f
Reading package lists... Done
Building dependency tree
Reading state information... Done
Correcting dependencies... Done
The following extra packages will be installed:
libncurses4 libreadline4
The following NEW packages will be installed:
libncurses4 libreadline4
0 upgraded, 2 newly installed, 0 to remove and 18 not upgraded.
1 not fully installed or removed.
Need to get 298kB of archives.
After unpacking 709kB of additional disk space will be used.
Do you want to continue [Y/n]? y
Get:1 http://us.archive.ubuntu.com gutsy/universe libncurses4 4.2-10.1 [194kB]
Get:2 http://us.archive.ubuntu.com edgy/universe libreadline4 4.3-18 [104kB]
Fetched 298kB in 2s (131kB/s)
Selecting previously deselected package libncurses4.
(Reading database ... 122351 files and directories currently installed.)
Unpacking libncurses4 (from .../libncurses4_4.2-10.1_i386.deb) ...
Selecting previously deselected package libreadline4.
Unpacking libreadline4 (from .../libreadline4_4.3-18_i386.deb) ...
Setting up libncurses4 (4.2-10.1) ...

Setting up libreadline4 (4.3-18) ...

Setting up frontbase (4.2.8-1) ...
Starting FrontBase service

Processing triggers for libc6 ...
ldconfig deferred processing now taking place




Well, it looks like something happened, so I tried 'dpkg' again and got something a bit different:


$ sudo dpkg -i FrontBase-4.2.8.deb
(Reading database ... 122374 files and directories currently installed.)
Preparing to replace frontbase 4.2.8-1 (using FrontBase-4.2.8.deb) ...
Shutting down FrontBase service
/var/lib/dpkg/info/frontbase.prerm: 11: /etc/init.d/FBWeb: not found
dpkg: warning - old pre-removal script returned error exit status 127
dpkg - trying script from the new package instead ...
/var/lib/dpkg/tmp.ci/prerm: 11: /etc/init.d/FBWeb: not found
dpkg: error processing FrontBase-4.2.8.deb (--install):
subprocess new pre-removal script returned error exit status 127
Starting FrontBase service
Errors were encountered while processing:
FrontBase-4.2.8.deb



Even though it still complains of errors, I tried looking at my processes, and viola:


$ ps -edalf | grep FrontBase
0 S root 24174 1 0 75 0 - 1335 - 13:09 pts/4 00:00:00 /usr/lib/FrontBase/bin/FBExec -autostart




Then I ran through the example statements on the install page via sql92 and saw the first DB running:


$ ps -edalf | grep FrontBase
0 S root 24174 1 0 75 0 - 1335 - 13:09 pts/4 00:00:00 /usr/lib/FrontBase/bin/FBExec -autostart
0 S root 24248 1 0 75 0 - 4392 - 13:13 pts/4 00:00:00 /usr/lib/FrontBase/bin/FrontBase /usr/lib/FrontBase/Databases/firstdb.fb



Great! Now I can even connect with my Java SQL tool using the FrontBase driver with the following info:
  • URL: jdbc:FrontBase://localhost/firstdb
  • User: test
  • Pass:

Wednesday, April 23, 2008

is_ascii Oracle function


Here is an Oracle function that tells whether a column is all ASCII (from Mark Stafford):

create or replace function is_ascii (v varchar2) return varchar2 as
r boolean := false;
begin
r := length(v)
- length(
translate(v
, chr(1)
|| translate(v, chr(1) || ' !"#$%&''()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~', chr(1) )
, chr(1)
)
) = 0;
if v is null then r := true; end if;
if r = true then return 'y'; else return 'n'; end if;
exception
when others then
return null;
end;
/

Friday, April 4, 2008

working with FrontBase

I'm accustomed to working with Oracle, but I'm using FrontBase for a project. So here's some interesting info I've had to learn:

  • Here's a timestamp statement:
update client set enrollment_date = TIMESTAMP '2008-04-03 10:58:30' where client_id = 1000019

  • This sets it to the current time:
update client set enrollment_date = cast(CURRENT_TIMESTAMP as timestamp) where client_id = 1000019

  • Don't try to put numbers inside single-quotes. It will give error 217.

  • To drop a table, add CASCADE at the end:
drop table CLIENT_ADMIN_AUDIT cascade

  • Here are a bunch of error codes you can get back (found here and duplicated on many internet sites):

22 => DB_ERROR_SYNTAX,
85 => DB_ERROR_ALREADY_EXISTS,
108 => DB_ERROR_SYNTAX,
116 => DB_ERROR_NOSUCHTABLE,
124 => DB_ERROR_VALUE_COUNT_ON_ROW,
215 => DB_ERROR_NOSUCHFIELD,
217 => DB_ERROR_INVALID_NUMBER,
226 => DB_ERROR_NOSUCHFIELD,
231 => DB_ERROR_INVALID,
239 => DB_ERROR_TRUNCATED,
251 => DB_ERROR_SYNTAX,
266 => DB_ERROR_NOT_FOUND,
357 => DB_ERROR_CONSTRAINT_NOT_NULL,
358 => DB_ERROR_CONSTRAINT,
360 => DB_ERROR_CONSTRAINT,
361 = "Integrity constraint violation (FOREIGN_KEY...)" (from Java experiments)


  • I keep hitting problems trying to use any native sequence functionality with Hibernate. You get the next sequence number with "SELECT UNIQUE" on the table name, thus:

    select unique from admin_user


    This is automatically available for any table that you create.

    Now, the generic Hibernate JDBC dialect acts badly, so I changed things so that I have to retrieve this unique value every time I try to insert into the DB. Sometimes it was difficult to figure out that this was the problem; even P6Spy wasn't showing me why I was getting an error 116 "DB_ERROR_NOSUCHTABLE". I finally found this statement in the FrontBase logs:


    select next_hi from hibernate_unique_key;


Saturday, March 15, 2008

software to generate genealogy web pages

Our family organization is looking at ways to put our genealogy records and histories online for public view, so I'm looking at our options. Our genealogy records are stored in GEDCOM, so we need to be able to upload that; we want everyone to be able to browse the data without signing up or other complications; we have our own website, so we can generate the content from software and publish it ourselves if necessary; we don't mind spending some money if it'll give us good features for sharing.

Here are my comparisons. I looked at these main features; I'll only mention below if they do NOT have these features.

- access: Does it allow public access without signups or paying?
- reports: Does it have multiple kinds of output?
- map: Does it show a map? (This isn't critical, but it's an indicator of advanced reports.)
- search: Does it allow people to search online?
- history: Does it allow for publishing stories and pictures?


All of these import the Gedcom format, which is critical for us.

Desktop Software

There are many desktop applications that generate reports, so we could use them to take our info and output our web site. They do much the same thing, and they do well in all areas except: they don't have online maps (except GedHTree), and they don't set up great web searches, though they generate many links for things like surname searches to find the person you want.

Personal Ancestral File (look for download link) is the original program, it'll always be around (and free) and we currently use it to maintain our genealogy, but we're not impressed by the pages it generates.

These 3 seem to be at the top because they're comprehensive... so they do more than we need, but they'll import GedCom and generate what we want:

Here's a page that reviews these first three (and a few others).

Master Genealogist - $34-70
... and for the online work add Second Site - $30
I didn't find a comprehensive list of features, but supposedly this is the best; there are companion products offered for things like maps and mobile devices.

Roots Magic - $30
Feature list

Legacy - $35-60
Feature list, and their own comparison with other programs


These 3 were also recommended simply for generating web content:

GedHTree - $20
This one does do maps (and "map sequences" which look interesting). We downloaded and used this successfully; the pedigree charts are nice. It only handles up to about 30,000 names.

GedPage - $10
"Uses Family Group Sheet format." The pedigree chart is simplistic and text-based. You can try it for free (and it processed 120,000-person GEDCOM), but it doesn't generate the pedigree charts.

GED2WEB - $21
Has pedigree charts. Free download trial.


Ged-Gen - $15
Does not create pedigree (or map); reportedly doesn't include photos so those must be done separately. Allows lots of look and feel customization. Free download trial.

GED2HTML - Free
No pedigree charts.




Internet Services

Tribal pages - $0

This does well in all areas except: there are no histories; it seems to only do the relationships. For a good example of reports and maps, see this record: http://dee894500.tribalpages.com/tribe/browse?userid=dee894500&view=0&pid=1648&rand=626605690

Roots Web - $0
This does well except that there aren't many reports and it doesn't do the histories.


Ancestry.com - $13-30/month
This appears to do great in all areas except: it doesn't allow full access unless you sign up. It claims to allow access to existing information for free, so I even attempted to sign up to see someone's historical info, but the page just offered the paid memberships (with 14-day trial). I definitely don't want to use this to try and share with people!

As a side note: I've heard from sources in the LDS Church that their new version of familysearch.org will have more options for attaching notes to individuals, and it should be available worldwide by 2009 (maybe even sometime this year).

Friday, March 14, 2008

maven 2 deploy-file command

I can never remember the vagaries of the deployment URL, etc!

Here is an example for activation.jar in our "soa" repository. Make sure to have the username/password for "soa-repo" in settings.xml, and probably the distributionManagement.repository in the pom.xml.


mvn deploy:deploy-file -DgroupId=javax.activation -DartifactId=activation -Dversion=1.0.2 \
-Dpackaging=jar -Dfile=/home/trent/dl/jaf-1.0.2/activation.jar \
-DrepositoryId=soa-repo \
-Durl=scp://soa@soa.dev.hq.icentris/home/soa/tomcat/webapps/ROOT/repository2

Oracle and JDBC test from different timezones

I predicted that Java would send the right thing to Oracle and we'd see the same thing in the database. I was wrong and Vijay was right: Oracle ends up with a different value, even though we send the exact same java.util.Date value.

Following is our test where we point Java programs running in different timezones to the same Oracle database.

Here are our two runs of the program below, from UT and then LA timezones:



$ java -cp .:ojdbc-14_g.jar DateTest UT
UT Pi Time Los_Angeles: 1205533140000 = Fri Mar 14 16:19:00 MDT 2008
UT SQL Pi Time Los_Angeles: 1205533140000 = 2008-03-14 16:19:00.0

$ java -cp .:ojdbc-14_g.jar DateTest LA
LA Pi Time Los_Angeles: 1205533140000 = Fri Mar 14 15:19:00 PDT 2008
LA SQL Pi Time Los_Angeles: 1205533140000 = 2008-03-14 15:19:00.0



Here are the results we find in the database when the dust settles:

UT piTimeLos_Angeles 2008-03-14 16:19:00.0
LA piTimeLos_Angeles 2008-03-14 15:19:00.0


DateTest.java:




import java.util.*;
import java.sql.*;
import java.text.*;


/**

create table time_test (
name varchar2(100),
time date
)

*/
public class DateTest {
public static void main(String[] args) {
String outPrefix = "";
if (args.length > 0) {
outPrefix = args[0];
}

Connection conn = null;
PreparedStatement pstat = null;
try {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy/MM/dd HH:mm");
TimeZone timezone = TimeZone.getTimeZone("America/Los_Angeles");
formatter.setTimeZone(timezone);
java.util.Date piTimeLos_Angeles = formatter.parse("2008/03/14 15:19");
System.out.println(outPrefix + " Pi Time Los_Angeles: " + piTimeLos_Angeles.getTime() + " = " + piTimeLos_Angeles);

String DRIVER = "oracle.jdbc.driver.OracleDriver";
String URL = "...";
String USERNAME = "...";
String PASSWORD = "...";
Class.forName(DRIVER);

conn = DriverManager.getConnection(URL, USERNAME, PASSWORD);
pstat = conn.prepareStatement("insert into time_test (name, time) values (?, ?)");

//java.sql.Date piTimeLos_AngelesSql = new java.sql.Date(piTimeLos_Angeles.getTime());
java.sql.Timestamp piTimeLos_AngelesSql = new java.sql.Timestamp(piTimeLos_Angeles.getTime());
System.out.println(outPrefix + " SQL Pi Time Los_Angeles: " + piTimeLos_AngelesSql.getTime() + " = " + piTimeLos_AngelesSql);

pstat.setString(1, outPrefix + " piTimeLos_Angeles");
//pstat.setDate(2, piTimeLos_AngelesSql);
pstat.setTimestamp(2, piTimeLos_AngelesSql);
pstat.executeUpdate();

pstat.close();
conn.close();

} catch (Exception e) {
e.printStackTrace();
}
}
}



Tuesday, February 26, 2008

marking up the web

The article Five Ways to Mark Up the Web explains 5 services to mark up content on other web pages. A few look like they can be read without plugins or downloads (which is important for readers; I can do a plugin to create content, but I want everyone to read them):

- Diigo - searching my own bookmarks is great; search fails on group content...?

- Fleck - I cannot find any public search utility

- TrailFire - I couldn't download in my Linux FireFox ('cause tried to save the PHP files); plus it gave blank pages when I tried to look at some of the existing content

Tuesday, February 12, 2008

"cloning an iPod without software"


I got this from elsewhere.

_______________

I discovered by accident an easy and stupid way to not only clone an
entire iPod but also to recover the songs from it to your library in
case you HD goes missing in action or even if you get a new computer.

There are software out there costing $20 that do it for you, but I
discovered it is not needed if you do it like follows.

Here's the simple steps to it:

- Close iTunes
- And mount your iPod on Windows (works on Linux too) as if it was a
storage USB drive.
- Use windows Explorer and make sure you are displaying hidden files.
- Go to iPodControl directoy and copy the music folder to your HD. iPod
has a funky way to organize the songs into weird folder and weird names.
Don't worry we will fix it.
- Now go to you iTunes and set Automatically Organize songs on its
settings page.
- Click on Add/Import folder and point it to where you copied the songs
in your hard drive. This will copy the whole thing to your library
keeping the song titles, album information etc.

Ah, yes. In case you have 2 iPods with 2 different names, just create
another user account on your Windows machine so that you can have
different iTunes settings on the same computer.

There you go, all copied!!!

This is a nice way to backup your own music library to more than one
computer as well as copying to a second iPod in case you decide to get
one with bigger capacity.

If you happen to buy music online, it is a good way to back it up too in
case your iPod HD goes bad.

Also, if you want to update your iPod OS make sure you do this first
because you can risk loosing its content by updating its software.

Monday, February 4, 2008

automated emails for specific SVN commits

I have two scripts that I plug in to SVN to notify me when changes are made to certain files. The first script should be referenced in the SVN repository's "hooks/post-commit" file, and it will call the second.

svn-diff-hist1.sh and svn-diff-hist2.sh

Usage:
svn-log-diff1.sh {REPO} {REV} {FILE_SUBSTR_REGEXP} {EMAIL}

For example:
svn-log-diff1.sh $1 $2 "trunk.*greenzone" trent.larson@icentris.com
... will email me whenever any file is checked in that has "trunk" followed by "greenzone" in it's path.

svn-diff-hist.sh: searching back through SVN changes

This script walks backward through the SVN commits and shows the changes that happened for each revision. The output comes in 3 sections (separated by a line of '#' symbols):
- all the logged comments
- each change diff
- the entire file when it was first committed

Usage:
svn-diff-hist.sh {FILE} [{EARLIEST-REVISION}]


By default, it walks all the way back to the first version where it was checked in.

Friday, January 18, 2008

Fabled $250 Neimann-Marcus Chocolate-Chip Cookies

That really is the title of this recipe in our cookbook. See the history here.

Anyway, this is my favorite cookie recipe, and I love cookies.

Note that this version is a double recipe: 200 cookies

2 cups butter
2 cups sugar
2 cups brown sugar
4 eggs
2 teaspoons vanilla
4 cups flour
3 cups oatmeal (2 1/4 c. blended)
1 teaspoon salt
2 teaspoons baking powder
2 teaspoons baking soda
1 24-ounce package chocolate chips
1 8-ounce Hershey's bar, grated
3 cups nuts, chopped

Cream butter with sugars. Add eggs and vanilla. Add flour, oatmeal, salt, baking powder and baking soda to creamed mixture. Add chocolate chips, candy and nuts. Form dough into balls and place 2 inches apart on cookie sheet. Bake at 375 degrees for 6 minutes. Yields 200 cookies.

Monday, January 14, 2008

convert an Oracle CLOB to a string

I had to use the UTL_RAW package so I could do string (aka VARCHAR2) operations:

utl_raw.cast_to_varchar2(utl_raw.cast_to_raw(...))

Note that you can do operations like 'substr' and 'instr', and the result is still a CLOB and not a varchar! Ug.

Friday, January 11, 2008

basic Japanese phrases

First, for good pronunciation, there are 5 vowel sounds and they're always the same:

a - like "aaah", eg. father
i - like "ee", eg. eat
u - like "oooo", eg. food
e - is "eh", eg. end
o - is "oh", eg. Ohio

Practice saying that over and over "aaah, eeee, oooo, eh, oh", so you'll get in the habit of saying only those 5 sounds.

I'll spell these phrases the regular (romanized) way, then as they might sound in English:

phrase == romanized spelling == phonetic spelling
----------------------------------------------------------------------------------------------------
Hello (Good day) == kon-ni-chi wa == cone-nee-chee-wah
Good Morning == o-ha-yo == oh-hi-yo
... and if you want that to be very polite, say: o-ha-yo go-za-i-mas == oh-hi-yo go-zah-ee-mah-s
Good Afternoon == same as "Hello" above
Good Evening == kon-ban-wa == cone-bahn-wah
Good Night == same as "Good Night", unless you're saying good-bye, and then it would be: o-ya-su-mi-na-sa-i == oh-yah-sue-me-nah-sa-ee
Excuse Me == su-mi-ma-sen == sue-me-mah-sen
Thank You == a-ri-ga-to == ah-ree-gah-toe
Thank You Very Much == a-ri-ga-to go-za-i-mas == ah-ree-gah-toe go-za-i-mah-s

One that will probably impress them is something to say when you're leaving someone; you say "I'm being rude":
I'm being rude == shi-tsu-re-i-shi-mas == she-tsoo-ray-she-mah-s

Thursday, January 10, 2008

setup Apache and Tomcat (with mod_jk in Ubuntu), plus load-balancing (or simple clustering)

These directions were kindly shared with me by Matt Dame.

If you're load-balancing between Tomcats, do the following:

  • In the Tomcat 'conf/server.xml' file(s), add the following to the "Engine" element:
    jvmRoute="jvm1"
  • Change the "8009" port on each of the other Tomcats, and change jk.conf accordingly (below).


Start your Tomcat(s). (I've heard of problems if you don't have Tomcat started before starting Apache.)


Run as root:
  • apt-get install apache2 ssl-cert libapache2-mod-jk
  • make-ssl-cert generate-default-snakeoil
  • cd /etc/apache2
  • ln -s /etc/ssl/certs/ssl-cert-snakeoil.pem ssl.crt
  • ln -s /etc/ssl/private/ssl-cert-snakeoil.key ssl.key
  • Place 'http' and 'https' in the 'sites-available' directory. (Note that these are just slightly modified versions of 'default' in that directory).
  • Place 'jk.conf' in the 'mods-available' directory.
  • a2dissite default
  • a2ensite http
  • a2ensite https
  • a2dismod jk
  • a2enmod jk
  • /etc/init.d/apache2 force-reload
---

Andre recommended the following readings about connectors:

generic_howto/loadbalancers.html


reference/workers.html


ajp/ajpv13a.html


reference/apache.html


webserver_howto/apache.html