<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:georss='http://www.georss.org/georss' xmlns:gd='http://schemas.google.com/g/2005' xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-24995747</id><updated>2011-11-15T14:43:49.864Z</updated><category term='apache'/><category term='gnuplot'/><category term='troubleshooting'/><category term='xml'/><category term='proxy'/><category term='installation'/><category term='sparql'/><category term='login'/><category term='shell'/><category term='puelia'/><category term='header'/><category term='linked data'/><category term='macosx'/><category term='content negotiation'/><category term='debian'/><category term='drupal'/><category term='graphics'/><category term='command line'/><category term='http'/><category term='wordpress'/><category term='json'/><category term='subversion'/><title type='text'>Confused Development</title><subtitle type='html'>I develop software and I often get confused in the process. I usually find the answers after a while, but a month later I can't remember them. So from now on, I will write them down here.</subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default?max-results=100'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>36</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>100</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-24995747.post-2606219641695249104</id><published>2011-10-27T11:35:00.003+01:00</published><updated>2011-10-27T11:42:55.481+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='content negotiation'/><category scheme='http://www.blogger.com/atom/ns#' term='linked data'/><category scheme='http://www.blogger.com/atom/ns#' term='puelia'/><title type='text'>HTML Output in Puelia/Linked Data API</title><content type='html'>&lt;p&gt;&lt;a href="http://code.google.com/p/puelia-php/" title="Puelia"&gt;Puelia&lt;/a&gt; is a PHP implementation of the &lt;a href="http://code.google.com/p/linked-data-api/wiki/Specification" title="Linked Data API Specification"&gt;Linked Data API&lt;/a&gt; to facilitate publishing of Linked Data from a SPARQL endpoint in the form of a RESTful API. Puelia can give back data representations in various different formats, such as JSON, XML, Turtle or HTML. This is done by implementing so-called "formatter" modules, which are responsible for creating the actual representation. However, while there are a built-in formatters available for a range of formats, there is none available for HTML.&lt;/p&gt;
&lt;p&gt;So, how do we get an HTML representation? There are some hints in the Linked Data API spec, but not a complete howto. The answer is, we need to create an instance of the built-in XSLT formatter, tell it to respond to the relevant mimetypes to enable content negotiation (&lt;code&gt;text/html&lt;/code&gt; and &lt;code&gt;application/xhtml+xml&lt;/code&gt;) and point it to an appropriate XSLT stylesheet (there are a handful available out of the box in Puelia, but we might want to modify them for our needs). We do this in the Puelia configuration file (which uses &lt;a href="http://www.w3.org/TeamSubmission/turtle/" title="Turtle Specification"&gt;Turtle&lt;/a&gt; syntax) as follows:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;#HTMLFormatter&amp;gt; a api:XsltFormatter ;
  api:name "html" ;
  api:mimeType "text/html" , "application/xhtml+xml" ;
  api:stylesheet "views/xslt-styles/sample.xsl" ;
.
&lt;/pre&gt;
&lt;p&gt;If you're wondering what XML the stylesheet will operate on: it's the XML generated by the built-in XML formatter (&lt;code&gt;api:xmlFormatter&lt;/code&gt;). One other thing we have to do is to register our new HTML formatter in a relevant location in the config file. This could either be the API object, or an endpoint object. Below is an example for the API itself, for which we register the built-in JSON formatter and our new HTML formatter:&lt;/p&gt;
&lt;pre&gt;
&amp;lt;#FooAPI&amp;gt; a api:API ;
  rdfs:label "A RESTful API for the Foo Dataset"@en ;
  # ...
  api:formatter api:JsonFormatter, &amp;lt;#HTMLFormatter&amp;gt; ;
  # ...
.
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-2606219641695249104?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/2606219641695249104/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=2606219641695249104' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/2606219641695249104'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/2606219641695249104'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2011/10/html-output-in-puelialinked-data-api.html' title='HTML Output in Puelia/Linked Data API'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-1099375087145829825</id><published>2011-02-11T17:21:00.001Z</published><updated>2011-02-11T17:21:42.071Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='subversion'/><title type='text'>Using the svn:keywords property (Keyword Substitution)</title><content type='html'>&lt;p&gt;I always forget this, so here it goes:&lt;/p&gt;
&lt;pre&gt;
svn propset svn:keywords "Id" filename.txt
&lt;/pre&gt;
&lt;p&gt;Other keywords are: &lt;code&gt;Date&lt;/code&gt;, &lt;code&gt;Revision&lt;/code&gt;, &lt;code&gt;Author&lt;/code&gt;, &lt;code&gt;HeadURL&lt;/code&gt;. You can set several keywords at once like this:&lt;/p&gt;
&lt;pre&gt;
svn propset svn:keywords "Date Author" filename.txt
&lt;/pre&gt;
&lt;p&gt;The original documentation is in the &lt;a href="http://svnbook.red-bean.com/en/1.5/svn.advanced.props.special.keywords.html" title="Keyword Substitution in the SVN book"&gt;SVN book&lt;/a&gt;.&lt;/p&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-1099375087145829825?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/1099375087145829825/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=1099375087145829825' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/1099375087145829825'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/1099375087145829825'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2011/02/using-svnkeywords-property-keyword.html' title='Using the svn:keywords property (Keyword Substitution)'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-4526520296440938692</id><published>2010-10-29T16:51:00.004+01:00</published><updated>2010-11-08T17:15:47.885Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='http'/><category scheme='http://www.blogger.com/atom/ns#' term='sparql'/><category scheme='http://www.blogger.com/atom/ns#' term='command line'/><category scheme='http://www.blogger.com/atom/ns#' term='xml'/><category scheme='http://www.blogger.com/atom/ns#' term='json'/><category scheme='http://www.blogger.com/atom/ns#' term='header'/><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Using CURL to access a SPARQL endpoint</title><content type='html'>&lt;p&gt;You can use the command line tool &lt;code&gt;curl&lt;/code&gt; to access a SPARQL endpoint, e.g. from Sesame 2. Just do like this:&lt;/p&gt;
&lt;pre&gt;
curl -H "Accept: application/sparql-results+xml" "http://REPOSITORY_URI?query=ESCAPED_QUERY"
&lt;/pre&gt;
&lt;p&gt;The interesting bit is the &lt;code&gt;-H&lt;/code&gt; parameter, where you specify header information. What you do here is to tell the endpoint what kind of result format you accept. I always forget how to do that...&lt;/p&gt;

&lt;h2&gt;Edit:&lt;/h2&gt;
&lt;p&gt;To get JSON back, the mimetype has to be &lt;code&gt;application/sparql-results+json&lt;/code&gt;, at least on SESAME 2. This mimetype was defined in &lt;a href="http://www.w3.org/TR/rdf-sparql-json-res/" title="Serializing SPARQL Query Results in JSON"&gt;this W3C note&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-4526520296440938692?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/4526520296440938692/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=4526520296440938692' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/4526520296440938692'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/4526520296440938692'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2010/10/using-curl-to-access-sparql-endpoint.html' title='Using CURL to access a SPARQL endpoint'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-3385863390817525781</id><published>2009-10-13T19:00:00.002+01:00</published><updated>2010-02-19T14:29:37.065Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='debian'/><category scheme='http://www.blogger.com/atom/ns#' term='command line'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><category scheme='http://www.blogger.com/atom/ns#' term='proxy'/><title type='text'>Reverse Proxy to Make SPARQL Endpoint Available on Nice URI</title><content type='html'>&lt;p&gt;When you set up an RDF repository such as Sesame2, you are likely to get a SPARQL endpoint at a URI such as &lt;code&gt;http://my.server.org:8080/openrdf-sesame/repositories/repname&lt;/code&gt;. That's ok, but it doesn't look very nice. In order to serve the same endpoint at a nicer URI, say &lt;code&gt;http://my.server.org/sparql&lt;/code&gt;, you can set up something called a &lt;em&gt;reverse proxy&lt;/em&gt; on your Apache server. Here is how to do it on Debian:&lt;/p&gt;
&lt;h3&gt;Add the Reverse Proxy Rule&lt;/h3&gt;
&lt;p&gt;In &lt;code&gt;/etc/apache2/conf.d&lt;/code&gt;, add a new configuration file &lt;code&gt;sparql.conf&lt;/code&gt;. Make it look like this:&lt;/p&gt;
&lt;pre&gt;
# Make the SPARQL endpoint of the Sesame server running on port 8080
# available as http://my.server.org/sparql.
#
# Configuration is done as per the Basic Example for Reverse Proxies
# in http://httpd.apache.org/docs/2.2/mod/mod_proxy.html .

&amp;lt;Proxy *&gt;
 Order deny,allow
 Allow from all
&amp;lt;/Proxy&gt;
ProxyPass /sparql http://my.server.org:8080/openrdf-sesame/repositories/repname
ProxyPassReverse /sparql http://my.server.org:8080/openrdf-sesame/repositories/repname
&lt;/pre&gt;
&lt;h3&gt;Enable the Proxy Modules&lt;/h3&gt;
&lt;p&gt;In order for this to work, Apache has to load a number of modules having to do with proxies. The easiest and safest way to load them is by using the &lt;code&gt;a2enmod&lt;/code&gt; command and select all proxy-related modules:&lt;/p&gt;
&lt;pre&gt;
knumoe@exp3:/etc/apache2/conf.d$ sudo a2enmod
Your choices are: actions alias asis auth_basic auth_digest authn_alias authn_anon authn_dbd authn_dbm authn_default authn_file authnz_ldap authz_dbm authz_default authz_groupfile authz_host authz_owner authz_user autoindex cache cern_meta cgi cgid charset_lite dav dav_fs dav_lock dbd deflate dir disk_cache dump_io env expires ext_filter file_cache filter headers ident imagemap include info ldap log_forensic mem_cache mime mime_magic negotiation php5 proxy proxy_ajp proxy_balancer proxy_connect proxy_ftp proxy_http rewrite setenvif speling ssl status substitute suexec unique_id userdir usertrack version vhost_alias
Which module(s) do you want to enable (wildcards ok)?
proxy*
&lt;/pre&gt;
&lt;h3&gt;Restart Apache&lt;/h3&gt;
&lt;pre&gt;sudo /etc/init.d/apache2 restart&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-3385863390817525781?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/3385863390817525781/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=3385863390817525781' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/3385863390817525781'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/3385863390817525781'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2009/10/reverse-proxy-to-make-sparql-endpoint.html' title='Reverse Proxy to Make SPARQL Endpoint Available on Nice URI'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-3637232932965360349</id><published>2009-10-08T16:27:00.001+01:00</published><updated>2009-10-08T16:27:27.441+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='troubleshooting'/><category scheme='http://www.blogger.com/atom/ns#' term='command line'/><category scheme='http://www.blogger.com/atom/ns#' term='shell'/><title type='text'>Linux/Unix: Redirecting Output Using "&gt;" with sudo</title><content type='html'>&lt;p&gt;Problem: In Linux/Unix, you want to redirect output of something to a file with &lt;code&gt;&amp;gt;&lt;/code&gt; you don't have write permissions for:&lt;/p&gt;
&lt;pre&gt;
local$ ls -la &amp;gt; test.txt
-bash: test.txt: Permission denied
&lt;/pre&gt;
&lt;p&gt;You think "I can solve this by using sudo"! But, alas:&lt;/p&gt;
&lt;pre&gt;
local$ sudo ls -la &amp;gt; test.txt
-bash: test.txt: Permission denied
&lt;/pre&gt;
&lt;p&gt;The shell won't even ask for your password. This indicates to me that somehow &lt;code&gt;sudo&lt;/code&gt; only applies to the &lt;code&gt;ls&lt;/code&gt; command here. What seems to happen is that &lt;strong&gt;first&lt;/strong&gt;, the shell tries to open the file and only &lt;strong&gt;then&lt;/strong&gt; runs the &lt;code&gt;ls&lt;/code&gt; command to feed it with input. But since you don't have write permissions for this file, the execution of the whole expression is stopped. The way to solve this, as I found out &lt;a href="http://notfaq.wordpress.com/2007/09/26/unixlinux-redirect-output-as-sudo/"&gt;in this blog post&lt;/a&gt;, is to run bash (or any other shell) as sudo and then give it the entire expression as a parameter:&lt;/p&gt;
&lt;pre&gt;
local$ sudo bash -c "ls -la &amp;gt; test.txt"
Password:
local$ more test.txt
total 16
drwxr-xr-x  18 root  wheel   612 Oct  8 16:23 .
drwxr-xr-x@ 13 root  wheel   442 Dec  6  2007 ..
drwxr-xr-x@ 13 knud  staff   442 Sep  8 11:45 arc
drwxr-xr-x  61 root  wheel  2074 Apr 17 12:30 bin
drwxr-xr-x  14 root  wheel   476 Dec  4  2007 gwTeX
drwxr-xr-x  33 root  wheel  1122 Feb 17  2009 include
drwxr-xr-x  56 root  wheel  1904 Feb 17  2009 lib
-rw-r--r--   1 root  wheel     0 Oct  8 16:23 test.txt
&lt;/pre&gt;
&lt;p&gt;Note that &lt;code&gt;test.txt&lt;/code&gt; is already in the this list, proving that the file was created &lt;strong&gt;before&lt;/strong&gt; the &lt;code&gt;ls&lt;/code&gt; command was run!&lt;/p&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-3637232932965360349?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/3637232932965360349/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=3637232932965360349' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/3637232932965360349'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/3637232932965360349'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2009/10/linuxunix-redirecting-output-using-with.html' title='Linux/Unix: Redirecting Output Using &amp;quot;&amp;gt;&amp;quot; with sudo'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-6738403932125256331</id><published>2009-06-15T15:09:00.000+01:00</published><updated>2009-06-15T15:10:12.009+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='wordpress'/><category scheme='http://www.blogger.com/atom/ns#' term='troubleshooting'/><category scheme='http://www.blogger.com/atom/ns#' term='subversion'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><title type='text'>WordPress Blank Screen of Death</title><content type='html'>&lt;p&gt;I'm using subversion to keep my WordPress installation updated. This always worked perfectly fine, but recently I did an update and wasn't able to access any php driven part of the blog anymore (so, basically everything). All I would get is the dreaded WordPress Blank Screen of Death.&lt;/p&gt;
&lt;p&gt;I looked in the error logs (WP had a special error log in the Apache log folder) and saw that there was a &lt;code&gt;Parse Error: parse error, unexpected T_SL&lt;/code&gt; reported for one of the php files. After some googling, &lt;a href="http://www.faqts.com/knowledge_base/view.phtml/aid/18379/fid/51"&gt;this post&lt;/a&gt; here made me realise that the problem could be related to a subversion conflict, which will lead to &lt;code&gt;&amp;lt;&lt;/code&gt; signs showing up in the source files, rendering them invalid. I checked the offending files and really, it turned out that my last svn update had introduced a conflict. To resolve it, I simply deleted the offending files, executed &lt;code&gt;svn update&lt;/code&gt; again, and all my troubles were gone!&lt;/p&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-6738403932125256331?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/6738403932125256331/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=6738403932125256331' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/6738403932125256331'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/6738403932125256331'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2009/06/wordpress-blank-screen-of-death.html' title='WordPress Blank Screen of Death'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-7605992688965091512</id><published>2009-01-23T17:20:00.001Z</published><updated>2009-01-26T15:54:23.071Z</updated><category scheme='http://www.blogger.com/atom/ns#' term='gnuplot'/><category scheme='http://www.blogger.com/atom/ns#' term='graphics'/><category scheme='http://www.blogger.com/atom/ns#' term='macosx'/><title type='text'>Creating Bar Charts with Gnuplot</title><content type='html'>&lt;p&gt;As part of the work on my thesis, I'm currently analysing lots of log files that show the access patterns to the &lt;a href="http://data.semanticweb.org"&gt;Semantic Web Dogfood&lt;/a&gt; linked data server. At the end, I want to auto-generate nice-looking bar charts from them which show usage over time. Having generate lots of csv files (using a combination of &lt;a href="http://www.webalizer.org/"&gt;Webalizer&lt;/a&gt;, standard Unix commands like sed and grep, and finally some Ruby scripting), my first idea was to do this with Excel. However, while it is certainly possible and easy enough to generate one chart with Excel, I couldn't see an easy way to do it in batches (maybe with AppleScript?). So I decided to use &lt;a href="http://www.gnuplot.info/"&gt;gnuplot&lt;/a&gt;, which, while it has a higher learning curve, is so much easier to configure and automate.&lt;/p&gt;
&lt;p&gt;Installation was easy enough on Mac OS 10.5. I tried a MacPorts port first, but unfortunately that just generate lots of errors during the installation process. As a last resort, I tried installing gnuplot from source (I'm always a little scared of doing that...) - and it worked like a breeze! I had expected it to be the other way around…&lt;/p&gt;
&lt;p&gt;Anyway, after going through some short tutorials and the gnuplot documentation, I finally came up with this plot to generate the bar charts, which reads its data from a &lt;code&gt;'numbers.dat'&lt;/code&gt; file:&lt;/p&gt;
&lt;pre&gt;
#our dat file looks like this:
##   date    hits   files   pages  visits   sites  kbytes
#20081126    1854    1080    1811     246     136   18060

# we want the x-axis to be a time line
set xdata time

# by default, the x-axis is defined by the first column in the 
# .dat file.  the format of our dates is like "20081230", we 
# need to tell gnuplot about that:
set timefmt "%Y%m%d"

# rotate the labels on the x-axis by 90°
set xtics rotate

# set the 
set term postscript eps color blacktext

# we want to output the plot to a file:
set output "hits.eps"

# we want to generate solid looking bars for our bar charts, so 
# we tell gnuplots to use a solid fill style
set style fill solid 0.5

# now plot the second (hits) and third (files) column from our 
# data file, using boxes instead of the default crosses
plot "numbers.dat" using 1:2 title 'hits' with boxes,\
     "numbers.dat" using 1:3 title 'files' with boxes
&lt;/pre&gt;
&lt;p&gt;And the output is:&lt;/p&gt;
&lt;a href="http://www.flickr.com/photos/dunken69/3219912841/" title="Log File Visualisation with Gnuplot by Dunkoman, on Flickr"&gt;&lt;img src="http://farm4.static.flickr.com/3422/3219912841_09ac0a8dc6.jpg" width="500" height="350" alt="Log File Visualisation with Gnuplot" /&gt;&lt;/a&gt;
&lt;p&gt;P.S.: Very handy for editing the plot file is the &lt;a href="http://github.com/mattfoster/gnuplot-tmbundle"&gt;gnuplot bundle for TextMate&lt;/a&gt;.&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-7605992688965091512?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/7605992688965091512/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=7605992688965091512' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/7605992688965091512'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/7605992688965091512'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2009/01/creating-bar-charts-with-gnuplot.html' title='Creating Bar Charts with Gnuplot'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://farm4.static.flickr.com/3422/3219912841_09ac0a8dc6_t.jpg' height='72' width='72'/><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-7077403062995892298</id><published>2008-09-17T16:33:00.001+01:00</published><updated>2008-09-17T16:33:12.016+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='troubleshooting'/><category scheme='http://www.blogger.com/atom/ns#' term='login'/><category scheme='http://www.blogger.com/atom/ns#' term='macosx'/><title type='text'>Login Problems on Mac OS X</title><content type='html'>&lt;p&gt;After upgrading to OS X 10.5.5, I could no longer log in to my main account. No PRAM zapping or safe booting, as suggested in many places, helped. Luckily I had another account with admin rights set up and found out that the source of the problem could lie the user's directory service entry. It needs to be deleted and rebuilt like so:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Delete the corrupted entry: &lt;code&gt;sudo rm /var/db/dslocal/nodes/Default/users/short-user-name.plist&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;The user has now dissapeared from the user list in the system preferences, but its home folder (i.e. all the data) is still there.&lt;/li&gt;
&lt;li&gt;To rebuild the ds entry, create a new user with the same short user name as the old.&lt;/li&gt;
&lt;li&gt;You'll be asked if you want to use the existing home folder for the new user. Agree to that.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Of course I didn't find out about all that myself. It was all nicely described somewhere down in &lt;a href="http://discussions.apple.com/message.jspa?messageID=8004767#8004767" title="Help! Can't switch to my user account!"&gt;this post&lt;/a&gt; on Apple's discussion boards.&lt;/p&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-7077403062995892298?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/7077403062995892298/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=7077403062995892298' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/7077403062995892298'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/7077403062995892298'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2008/09/login-problems-on-mac-os-x.html' title='Login Problems on Mac OS X'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-8894514377563438465</id><published>2008-08-26T17:36:00.002+01:00</published><updated>2008-08-26T17:40:02.136+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='drupal'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><title type='text'>Let Regular Web Sites Coexist with a CMS like Drupal</title><content type='html'>&lt;p&gt;I have a server setup where I want Drupal (could be any other &lt;span class="caps"&gt;CMS,&lt;/span&gt; though) to be served from the document root. I.e., I don't want a &lt;span class="caps"&gt;URL&lt;/span&gt; like &lt;code&gt;http://my.server/drupal/interesting-page&lt;/code&gt;, but instead I want &lt;code&gt;http://my.server/interesting-page&lt;/code&gt;. This is easy to achieve in Apache2: I simply have to set the document root to the Drupal folder. Here is an example from an Apache2 configuration file:&lt;/p&gt;
&lt;pre&gt;
  &amp;lt;VirtualHost *&amp;gt;
  ...
  DocumentRoot /var/www/drupal
  &amp;lt;Directory /&amp;gt;
    Options FollowSymLinks
    AllowOverride None
  &amp;lt;/Directory&amp;gt;
  &amp;lt;Directory /var/www/drupal&amp;gt;
    Options Indexes FollowSymLinks MultiViews
    AllowOverride all
    Order allow,deny
    allow from all
  &amp;lt;/Directory&amp;gt;
  ...
  &amp;lt;/VirtualHost&amp;gt;
&lt;/pre&gt;
&lt;p&gt;Another requirement I have is that certain folders should be served alongside Drupal. E.g., let's assume I have a folder called &lt;code&gt;dumps&lt;/code&gt;, which I want to serve at &lt;code&gt;http://my.server/dumps&lt;/code&gt;. Now, I could of course just put it into the drupal folder at &lt;code&gt;/var/www/drupal/dumps&lt;/code&gt;. However, I would like the drupal folder to only contain drupal stuff. Otherwise things might get messy when I do updates, etc. This is where the &lt;code&gt;Alias&lt;/code&gt; directive in Apache's mod_alias module comes in handy. I can put &lt;code&gt;dumps&lt;/code&gt; at &lt;code&gt;/var/www/dumps&lt;/code&gt; and then map requests to &lt;code&gt;http://my.server/dumps&lt;/code&gt; to that folder. Here is what that looks like in my Virtual Host definition (including some settings for how to handle that folder):&lt;/p&gt;
&lt;pre&gt;
Alias /dumps "/var/www/dumps"
&amp;lt;Directory "/var/www/dumps"&amp;gt;
  Options Indexes MultiViews
  AllowOverride None
  Order deny,allow
  Allow from all
&amp;lt;/Directory&amp;gt;
&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-8894514377563438465?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/8894514377563438465/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=8894514377563438465' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/8894514377563438465'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/8894514377563438465'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2008/08/let-regular-web-sites-coexist-with-cms.html' title='Let Regular Web Sites Coexist with a CMS like Drupal'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-4238205569195232329</id><published>2008-08-20T19:21:00.000+01:00</published><updated>2008-08-20T19:22:03.297+01:00</updated><category scheme='http://www.blogger.com/atom/ns#' term='debian'/><category scheme='http://www.blogger.com/atom/ns#' term='installation'/><category scheme='http://www.blogger.com/atom/ns#' term='drupal'/><category scheme='http://www.blogger.com/atom/ns#' term='apache'/><title type='text'>Installing Drupal6.4 on Debian4 + Apache2</title><content type='html'>&lt;p&gt;I had to install Drupal today on one of our servers. I ran into a few minor problems:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;There were some problems with file permissions in the &lt;code&gt;&lt;strong&gt;drupal/sites&lt;/strong&gt;&lt;/code&gt; folder, so I changed owner and group of some files and folders to &lt;code&gt;&lt;strong&gt;www-data&lt;/strong&gt;&lt;/code&gt;.&lt;/li&gt;

  &lt;li&gt;Drupal complained that the PHP GD library is not installed: just run &lt;code&gt;&lt;strong&gt;apt-get install php5-gd&lt;/strong&gt;&lt;/code&gt; and restart Apache.&lt;/li&gt;

  &lt;li&gt;Drupal couldn't send mails, so I installed postfix (&lt;code&gt;&lt;strong&gt;sudo apt-get install postfix&lt;/strong&gt;&lt;/code&gt;), set the server for outgoing mail (here called the "smart server") to our institute's smtp server, and used mailx to test it.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-4238205569195232329?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/4238205569195232329/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=4238205569195232329' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/4238205569195232329'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/4238205569195232329'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2008/08/installing-drupal64-on-debian4-apache2.html' title='Installing Drupal6.4 on Debian4 + Apache2'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-5542861606125047145</id><published>2008-05-12T10:05:00.002+01:00</published><updated>2008-07-21T16:25:55.995+01:00</updated><title type='text'>Adding a User, adding to sudoers, enabling ssh access</title><content type='html'>&lt;p&gt;I don't do this very often and always forget something. So:&lt;/p&gt;
&lt;h2&gt;(on Fedora Core 3)&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;add user:&lt;/b&gt; &lt;code&gt;/usr/sbin/useradd&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;set password:&lt;/b&gt; &lt;code&gt;passwd&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;add to sudoers:&lt;/b&gt; &lt;code&gt;/usr/sbin/visudo&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;enable ssh access:&lt;/b&gt; modify &lt;code&gt;AllowUsers&lt;/code&gt; in &lt;code&gt;/etc/ssh/sshd_config&lt;/code&gt; (or disable it)&lt;/li&gt;
&lt;li&gt;&lt;b&gt;restart ssh:&lt;/b&gt; &lt;code&gt;sudo /etc/init.d/sshd restart&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;On Debian&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;add user, password, etc:&lt;/b&gt; &lt;code&gt;/usr/sbin/adduser&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;b&gt;add new user to admin group:&lt;/b&gt; &lt;code&gt;usermod -a -G admin tony&lt;/code&gt; ... if the sudoers file allows sudo for the admin group ...&lt;/li&gt;
&lt;li&gt;&lt;b&gt;enable ssh access:&lt;/b&gt; seems to be enabled already on the box I was working&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-5542861606125047145?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/5542861606125047145/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=5542861606125047145' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/5542861606125047145'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/5542861606125047145'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2008/05/adding-user-adding-to-sudoers-enabling.html' title='Adding a User, adding to sudoers, enabling ssh access'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-314097070594074527</id><published>2008-03-09T01:23:00.000Z</published><updated>2008-03-09T01:24:06.676Z</updated><title type='text'>Problems with Conflicting Ruby Versions</title><content type='html'>&lt;p&gt;I havn't posted much lately, but of course I'm still very confused. Just now, I was pulling my hair out when I tried to follow the simple &lt;a href="http://developer.apple.com/tools/developonrailsleopard.html" title="Apple Rails Tutorial for Leopard"&gt;rails tutorial on the Apple developer site&lt;/a&gt;. I got to the point where I was supposed to build the scaffolding for the data model like so:&lt;/p&gt;
&lt;pre&gt;
$ script/generate scaffold event name:string budget:decimal
&lt;/pre&gt;
&lt;p&gt;Unfortunately, this is when I got a nasty complaint:&lt;/p&gt;
&lt;pre&gt;
Rails requires RubyGems &amp;gt;= 0.9.4. Please install RubyGems and try again: http://rubygems.rubyforge.org
&lt;/pre&gt;
&lt;p&gt;This seemed very weird, especially because I had just installed gems 1.0.1 - I could even prove it:&lt;/p&gt;
&lt;pre&gt;
$ gem -v
1.0.1
&lt;/pre&gt;
&lt;p&gt;Things like that frustrate me, especially when it's late at night. Luckily, after some digging, I found out that the problem was that I had installed Ruby in various different places, which seemed to upset things. In had used &lt;a href="http://www.macports.org/" title="MacPorts homepage"&gt;MacPorts&lt;/a&gt; to install it in &lt;code&gt;/opt/local/bin&lt;/code&gt;, but another ruby lived in &lt;code&gt;/usr/bin&lt;/code&gt;, which is where Apple installs it by default (both version 1.8.6). Deinstalling the MacPorts version solved the problem then:&lt;/p&gt;
&lt;pre&gt;
$ which ruby
/opt/local/bin/ruby
$ sudo port uninstall ruby
Password:
---&amp;gt;  Deactivating ruby 1.8.6-p110_0+darwin_9+thread_hooks
---&amp;gt;  Uninstalling ruby 1.8.6-p110_0+darwin_9+thread_hooks
$ which ruby
/usr/bin/ruby
&lt;/pre&gt;
&lt;p&gt;Now I'm less confused.&lt;/p&gt;

&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-314097070594074527?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/314097070594074527/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=314097070594074527' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/314097070594074527'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/314097070594074527'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2008/03/problems-with-conflicting-ruby-versions.html' title='Problems with Conflicting Ruby Versions'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-4823678996540454931</id><published>2007-10-15T09:54:00.001+01:00</published><updated>2007-10-15T09:59:32.332+01:00</updated><title type='text'>Realm-based authentification for Tomcat Web Apps</title><content type='html'>I needed to find out how to secure a Tomcat Web App with a password, and found the answer &lt;a href="http://www.cafesoft.com/products/cams/tomcat-security.html"&gt;here&lt;/a&gt;. Basically, you need to edit the Web app's &lt;code&gt;web.xml&lt;/code&gt; and add this little piece of xml to it:
&lt;pre&gt;
&amp;lt;!-- Define a security constraint on this application --&gt;
&amp;lt;security-constraint&gt;
  &amp;lt;web-resource-collection&gt;
    &amp;lt;web-resource-name&gt;Entire Application&amp;lt;/web-resource-name&gt;
    &amp;lt;url-pattern&gt;/*&amp;lt;/url-pattern&gt;
  &amp;lt;/web-resource-collection&gt;
  &amp;lt;auth-constraint&gt;
    &amp;lt;!-- This role is not in the default user directory --&gt;
    &amp;lt;role-name&gt;manager&amp;lt;/role-name&gt;
  &amp;lt;/auth-constraint&gt;
&amp;lt;/security-constraint&gt; 			
&amp;lt;!-- Define the login configuration for this application --&gt;
&amp;lt;login-config&gt;
  &amp;lt;auth-method&gt;BASIC&amp;lt;/auth-method&gt;
  &amp;lt;realm-name&gt;Tomcat Manager Application&amp;lt;/realm-name&gt;
&amp;lt;/login-config&gt;
&lt;/pre&gt;
This is enough if you want to protect the Web app with the same password as the manager application (changing the realm name would probably make sense). If you want to define a new role for this Web app, you can do it as follows (again taking the example from the manager, so change the description and role name): 
&lt;pre&gt;
&amp;lt;!-- Security roles referenced by this web application --&gt;
&amp;lt;security-role&gt;
  &amp;lt;description&gt;
    The role that is required to log in to the Manager Application
  &amp;lt;/description&gt;
  &amp;lt;role-name&gt;manager&amp;lt;/role-name&gt;
&amp;lt;/security-role&gt;
&lt;/pre&gt;
All that needs to be done now is to reload your Web app.
&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-4823678996540454931?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/4823678996540454931/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=4823678996540454931' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/4823678996540454931'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/4823678996540454931'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2007/10/realm-based-authentification-for-tomcat.html' title='Realm-based authentification for Tomcat Web Apps'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-4816109687295239174</id><published>2007-10-11T23:08:00.001+01:00</published><updated>2007-10-12T16:24:06.474+01:00</updated><title type='text'>The Sesame 2 console: Creating Repositories, Loading Data with
Context,SPARQL-Querying with Context</title><content type='html'>I have started using the &lt;a href="http://www.openrdf.org"&gt;Sesame 2&lt;/a&gt; (beta 5) RDF store for hosting the conference metadata for &lt;a href="http://iswc2007.semanticweb.org"&gt;ISWC+ASWC2007&lt;/a&gt; at &lt;a href="http://data.semanticweb.org"&gt;http://data.semanticweb.org&lt;/a&gt;. The software is still beta and a lot of the interface funtionality is missing, but when you figure out how everything works (which I did, with a lot of help from &lt;a href="http://www.openrdf.org/forum/mvnforum/"&gt;Aduna's OpenRDF forum&lt;/a&gt;), it seems to do the job. Even though the Web Interface is lacking a lot at the moment, Aduna supplies a console that can do most of what I need. Here is what I did:
&lt;h2&gt;Creating Repositories&lt;/h2&gt;
After having installed Sesame as a Web application in Tomcat (5.5 works for me), I installed the console in a different location. I start it like this:
&lt;pre&gt;
$ bin/start-console.sh 
OpenRDF Sesame console 2.0-beta5
Using data dir: /home/knumoe/.aduna/openrdf-sesame-console

The following repositories are available:
+----------
|SYSTEM ("System configuration repository")
+----------

Commands end with '.' at the end of a line
Type 'help.' for help
&gt;
&lt;/pre&gt;
At the beginning, the console (which has its own data and doesn't know yet about the Sesame Web app), only knows one repository: its own &lt;code&gt;SYSTEM&lt;/code&gt; repository. To get started, we have to let the console know about the Web apps &lt;code&gt;SYSTEM&lt;/code&gt; repository. This is done by using the &lt;code&gt;create&lt;/code&gt; command:
&lt;pre&gt;
&gt; create remote.
Please specify values for the following variables:
Sesame server location [http://localhost:8080/openrdf-sesame]: http://localhost:8080/openrdf-http-server-2.0-beta5 
Remote repository ID [SYSTEM]:
Local repository ID [SYSTEM@localhost]: 
Repository title [SYSTEM repository @localhost]: 
Repository created
&gt;
&lt;/pre&gt;
Here is the first pitfall: the default server location is &lt;code&gt;http://localhost:8080/openrdf-sesame&lt;/code&gt;, whereas, at least in this release of Sesame, the server location is actually &lt;code&gt;http://localhost:8080/openrdf-http-server-2.0-beta5&lt;/code&gt;, so you need to change the default here (and if we don't, the console won't even complain). The rest of the default values are just fine, so we leave them as they are. The console now knows two repositories:
&lt;pre&gt;
&gt; show r.
+----------
|SYSTEM ("System configuration repository")
|SYSTEM@localhost ("SYSTEM repository @localhost")
+----------
&gt;
&lt;/pre&gt;
Note that we havn't actually created a new repository on the server, we have just made sure the console knows about it. Every repository that the console knows can be opened and manipulated. We open &lt;code&gt;SYSTEM@localhost&lt;/code&gt;: 
&lt;pre&gt;
&gt; open SYSTEM@localhost.
Opened repository 'SYSTEM@localhost'
SYSTEM@localhost&gt; 
&lt;/pre&gt;
The &lt;code&gt;SYSTEM@localhost&lt;/code&gt; repository is for internal housekeeping, so we don't want to add any actual data to it. Instead we now create a new repository, which I will call &lt;code&gt;test&lt;/code&gt;. Because we have previously opened the server's &lt;code&gt;SYSTEM&lt;/code&gt;, the new repository will be created on the server. We can either create a native, a memory, or a memory-rdfs store. I choose native:
&lt;pre&gt;
SYSTEM@localhost&gt; create native.
WARNING: You are about to add a repository configuration to repository SYSTEM@localhost
Proceed? (yes|no) [yes]:    
Please specify values for the following variables:
Repository ID [native]: test
Repository title [Native store]: Test store
Triple indexes [spoc,posc]: 
Repository created
SYSTEM@localhost&gt;
&lt;/pre&gt;
Now, even though we have just created a new repository on the server, the console doesn't know about it (strange, yes):
&lt;pre&gt;
SYSTEM@localhost&gt; show r.
+----------
|SYSTEM ("System configuration repository")
|SYSTEM@localhost ("SYSTEM repository @localhost")
+----------
SYSTEM@localhost&gt;
&lt;/pre&gt;
To let the console know about it, we need to close &lt;code&gt;SYSTEM@localhost&lt;/code&gt; and create another remote repository as a placeholder for the console:
&lt;pre&gt;
SYSTEM@localhost&gt; close.
Closed repository 'SYSTEM@localhost'
&gt; create remote.
Please specify values for the following variables:
Sesame server location [http://localhost:8080/openrdf-sesame]: http://localhost:8080/openrdf-http-server-2.0-beta5
Remote repository ID [SYSTEM]: test
Local repository ID [SYSTEM@localhost]: test@localhost
Repository title [SYSTEM repository @localhost]: Test Repository
Repository created
&gt; show r.
+----------
|SYSTEM ("System configuration repository")
|SYSTEM@localhost ("SYSTEM repository @localhost")
|test@localhost ("Test Repository")
+----------
&gt; 
&lt;/pre&gt;
Now we are finally done with this bit: we have created a placeholder for the server's &lt;code&gt;SYSTEM&lt;/code&gt; repository, created a repository for our data on the server, and created another placeholder for this new data repository.
&lt;h2&gt;Loading Data with Context&lt;/h2&gt;
Loading data from the Web Interface in Tomcat is easy. However, it has one drawback - you cannot specify contexts (or named graphs, if you like). So, if you need named graphs, you need to resort to the console again. It's not hard though.
The first thing we do is open our newly created remote repository placeholder:
&lt;pre&gt;
&gt; open test@localhost.
Opened repository 'test@localhost'
test@localhost&gt; 
&lt;/pre&gt;
Now we can load data from a URL using the &lt;code&gt;load&lt;/code&gt; command. If we just use the command like that, it will load the data into the repository without any specific context. To add a context for the new data, you can use the &lt;code&gt;-c&lt;/code&gt; option. I want to load Eyal's foaf file. For the context, I just make up a URI (not good practice, I know):
&lt;pre&gt;
test@localhost&gt; load -c http://context.next/eyalsfoaf http://eyaloren.org/foaf.rdf.
Loading data...
Data has been added to the repository (12736 ms)
test@localhost&gt; 
&lt;/pre&gt;
So now, all the triples from &lt;code&gt;http://eyaloren.org/foaf.rdf&lt;/code&gt; have been added to the &lt;code&gt;test&lt;/code&gt; repository on the server, using &lt;code&gt;http://context.next/eyalsfoaf&lt;/code&gt; as a name for the context (the "next" was a spelling error which I didn't bother to correct). Note that with the current version of Sesame (2b5), if you explore your repository with the Web interface, the contexts don't show up. Don't worry though, they're there. You can see the contexts in the console (in the meantime, I have added another foaf file with another context):
&lt;pre&gt;
test@localhost&gt; show c.
+----------
|http://context.net/knudsfoaf
|http://context.next/eyalsfoaf
+----------
test@localhost&gt;
&lt;/pre&gt;
&lt;h2&gt;Querying with Context&lt;/h2&gt;
Now that we have data in two different named graphs (Sesame has the concept of &lt;em&gt;contexts&lt;/em&gt; internally, but they are the same as named graphs for my purposes), we can also make use of this with &lt;a href="http://www.w3.org/TR/rdf-sparql-query/"&gt;SPARQL&lt;/a&gt; queries. To do this, we can use SPARQL's &lt;code&gt;GRAPH&lt;/code&gt; construct. E.g., if I simply want to find all instances of &lt;code&gt;foaf:Person&lt;/code&gt; in the repository, I can use this query, which is just your basic SPARQL, that every self-respecting SW nerd knows:
&lt;pre&gt;
PREFIX foaf: &lt; http://xmlns.com/foaf/0.1/&gt;
SELECT $person
WHERE {
   $person a foaf:Person
}
&lt;/pre&gt;
This will give me six different instances, ignoring context (I did the queries in the Web interface - you can also do them in the console, but that is kind of unwieldy).&lt;br/&gt;&lt;br/&gt;
&lt;a href="http://1.bp.blogspot.com/_1bR_xwKupqE/Rw6f5AZANOI/AAAAAAAAABE/0zXefJLTZJ0/s1600-h/sparqlSimpleQuery.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand; border-width:1px; border-style:solid;" src="http://1.bp.blogspot.com/_1bR_xwKupqE/Rw6f5AZANOI/AAAAAAAAABE/0zXefJLTZJ0/s320/sparqlSimpleQuery.png"  alt="Simple SPARQL query result in Sesame2 Web interface" id="BLOGGER_PHOTO_ID_5120205628073063650" /&gt;&lt;/a&gt;
The following query, which uses the GRAPH construct, also tells us from which named graph/context each instance stems from:
&lt;pre&gt;
PREFIX foaf: &lt; http://xmlns.com/foaf/0.1/&gt;
SELECT $person $g
WHERE {
   GRAPH $g {
      $person a foaf:Person
   }
}
&lt;/pre&gt;
The result of this query also shows us that one instance comes from the named graph &lt;code&gt;http://context.net/knudsfoaf&lt;/code&gt; and five from &lt;code&gt;http://context.next/eyalsfoaf&lt;/code&gt;.&lt;br/&gt;&lt;br/&gt;
&lt;a href="http://1.bp.blogspot.com/_1bR_xwKupqE/Rw6f5AZANPI/AAAAAAAAABM/dvyIYREksHg/s1600-h/sparqlGraphResult.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;border-width:1px; border-style:solid;" src="http://1.bp.blogspot.com/_1bR_xwKupqE/Rw6f5AZANPI/AAAAAAAAABM/dvyIYREksHg/s320/sparqlGraphResult.png" alt="SPARQL query result with named graphs in Sesame2 Web interface" id="BLOGGER_PHOTO_ID_5120205628073063666" /&gt;&lt;/a&gt;
Finally, we can rewrite the query such that we will only get those instances that come from a particular graph:
&lt;pre&gt;
PREFIX foaf: &lt; http://xmlns.com/foaf/0.1/&gt;
SELECT $person
WHERE {
   GRAPH &lt; http://context.next/eyalsfoaf&gt; {
      $person a foaf:Person
   }
}
&lt;/pre&gt;
The result set of this query now contains those five instances that are in the &lt;code&gt;http://context.next/eyalsfoaf&lt;/code&gt; named graph. Hooray!&lt;br/&gt;&lt;br/&gt;
&lt;a href="http://4.bp.blogspot.com/_1bR_xwKupqE/Rw6f5wZANQI/AAAAAAAAABU/m1T4EVkHe3Y/s1600-h/sparqlEyalGraph.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand; border-width:1px; border-style:solid;" src="http://4.bp.blogspot.com/_1bR_xwKupqE/Rw6f5wZANQI/AAAAAAAAABU/m1T4EVkHe3Y/s320/sparqlEyalGraph.png" alt="SPARQL query result with from a particular named graph in Sesame2 Web interface" id="BLOGGER_PHOTO_ID_5120205640957965570" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-4816109687295239174?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/4816109687295239174/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=4816109687295239174' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/4816109687295239174'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/4816109687295239174'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2007/10/sesame-2-console-creating-repositories.html' title='The Sesame 2 console: Creating Repositories, Loading Data with&#xA;Context,SPARQL-Querying with Context'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://1.bp.blogspot.com/_1bR_xwKupqE/Rw6f5AZANOI/AAAAAAAAABE/0zXefJLTZJ0/s72-c/sparqlSimpleQuery.png' height='72' width='72'/><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-7547844506889322788</id><published>2007-10-08T16:57:00.001+01:00</published><updated>2007-10-08T16:57:27.057+01:00</updated><title type='text'>WordPress install.php not showing</title><content type='html'>Although, judging by the time that has passed since my last post, it may appear I'm no longer confused, this is not true. I'm constantly confused, about everything.

In fact, just today I tried to install WordPress 2.3 on a virtual server here at &lt;a href="http://www.deri.ie"&gt;DERI&lt;/a&gt;, and was very confused when the setup php script didn't run (&lt;code&gt;.../blog/wp-admin/install.php&lt;/code&gt;). The browser didn't show any error message, but instead just a blank page. After a while of scratching my head I decided to look at the httpd error logs (always a good idea in such situations, I guess), and found this:

&lt;pre&gt;
$ sudo tail /etc/httpd/logs/error_log
...
[client 10.2.18.50] PHP Fatal error:  Allowed memory size of 8388608 bytes exhausted (tried to allocate 233472 bytes) in /var/www/html/blog/wp-admin/includes/schema.php on line 107
Allowed memory size of 8388608 bytes exhausted (tried to allocate 0 bytes)
&lt;/pre&gt;

Aha! Some memory problem. So, googling for "PHP Fatal error:  Allowed memory size of" quickly brought me to &lt;a href="http://www.tech-recipes.com/php_programming_tips777.html"&gt;this page&lt;/a&gt;, which had the solution: just increase the allowed memory size for PHP scripts from the default 8MB to something higher (e.g. 12MB). This can either be done at the top of the culprit script itself (didn't work for me):

&lt;pre&gt;
ini_set("memory_limit","12M");
&lt;/pre&gt;

or in &lt;code&gt;/etc/php.ini&lt;/code&gt; (or wherever your &lt;code&gt;php.ini&lt;/code&gt; is):

&lt;pre&gt;
memory_limit = 12M
&lt;/pre&gt;

Perfect. After fixing this, the installation ran smoothly.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-7547844506889322788?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/7547844506889322788/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=7547844506889322788' title='7 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/7547844506889322788'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/7547844506889322788'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2007/10/wordpress-installphp-not-showing.html' title='WordPress install.php not showing'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>7</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-6036236175359914409</id><published>2007-05-07T21:02:00.001+01:00</published><updated>2007-05-07T21:12:51.141+01:00</updated><title type='text'>Let's see if RDFa is possible in Blogger</title><content type='html'>This is just a test post to find out if I can use RDFa in Blogger. I will add some RDFa about &lt;span about='[_:615027C3-462D-459F-B28F-87E5E0FE2F77:ABPerson]' xmlns:foaf='http://xmlns.com/foaf/0.1/' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'&gt;
&lt;span rel='rdf:type' href='foaf:Person'/&gt;
&lt;span property='foaf:name'&gt;Tom Heath&lt;/span&gt;
&lt;span property='foaf:firstName' content='Tom'/&gt;
&lt;span property='foaf:surname' content='Heath'/&gt;
&lt;span property='foaf:mbox_sha1sum' content='25840e40f0a481f0e113028c977d5acfa0af7b3d'/&gt;
&lt;/span&gt; and about &lt;span about='[_:FCB1AB0D-B2DD-475E-BF09-48EFF6642FB8:ABPerson]' xmlns:foaf='http://xmlns.com/foaf/0.1/' xmlns:rdf='http://www.w3.org/1999/02/22-rdf-syntax-ns#'&gt;
&lt;span rel='rdf:type' href='foaf:Person'/&gt;
&lt;span property='foaf:name'&gt;Gerald Reif&lt;/span&gt;
&lt;span property='foaf:firstName' content='Gerald'/&gt;
&lt;span property='foaf:surname' content='Reif'/&gt;
&lt;span property='foaf:mbox_sha1sum' content='3168a28c43d9c8fe4b2c6252b81bac8473dfefba'/&gt;
&lt;/span&gt;. It seems to work - the RDFa made it into the final HTML page. Unfortunately though, the page's HTML is not well-formed, and RDFa parsers die when reading it... :-(&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-6036236175359914409?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/6036236175359914409/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=6036236175359914409' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/6036236175359914409'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/6036236175359914409'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2007/05/let-see-if-rdfa-is-possible-in-blogger.html' title='Let&amp;#39;s see if RDFa is possible in Blogger'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-8780812126683167568</id><published>2007-02-20T01:15:00.000Z</published><updated>2007-02-20T01:31:03.092Z</updated><title type='text'>Overriding isEqual:</title><content type='html'>&lt;p&gt;Ideally, I would always read all available documentation before I start programming something... However, I don't. That's why it took me a while to figure out that it is not enough to implement &lt;a href="http://developer.apple.com/documentation/Cocoa/Reference/Foundation/Protocols/NSObject_Protocol/Reference/NSObject.html#//apple_ref/occ/intfm/NSObject/isEqual:"&gt;&lt;code&gt;isEqual:&lt;/code&gt;&lt;/a&gt; in a new class I was working on to ensure that equality for that class is handled correctly (in Objective-C).&lt;/p&gt;
&lt;p&gt;This is only enough when you do comparisons between objects manually by calling &lt;code&gt;isEqual:&lt;/code&gt;. On other occasions (e.g. when you call &lt;code&gt;addObject:&lt;/code&gt; on an &lt;code&gt;NSMutableSet&lt;/code&gt;), equality is computed by some magic combination of &lt;code&gt;isEqual&lt;/code&gt; and the object's hash value, returned by &lt;code&gt;hash&lt;/code&gt;. If you want to make sure two objects really are considered the same, make sure that &lt;i&gt;both&lt;/i&gt; &lt;code&gt;isEqual:&lt;/code&gt; and &lt;code&gt;hash&lt;/code&gt; return the same value! When equality is supposed to be based on the value of some NSString member of your class (as it was the case for me), this is very easy to achieve - just let &lt;code&gt;hash&lt;/code&gt; return the hash of that string. E.g., in my case equality depends on the value of the &lt;code&gt;url&lt;/code&gt; member, which is a string. The code then looks like this:&lt;/p&gt;
&lt;pre&gt;
- (unsigned)hash
{
   return [url hash];
}
&lt;/pre&gt;
&lt;p&gt;I got the solution off &lt;a href="http://www.cocoabuilder.com/archive/message/cocoa/2003/12/18/563"&gt;this thread&lt;/a&gt; on &lt;a href="http://www.cocoabuilder.com/"&gt;Cocoabuilder&lt;/a&gt;.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-8780812126683167568?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/8780812126683167568/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=8780812126683167568' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/8780812126683167568'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/8780812126683167568'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2007/02/overriding-isequal.html' title='Overriding isEqual:'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-2251849219756486483</id><published>2007-01-29T15:23:00.000Z</published><updated>2007-02-20T01:32:12.764Z</updated><title type='text'>Deleting posts in WordPress via XMLRPC</title><content type='html'>&lt;p&gt;Somehow I find it impossible to find a definite list of the methods that &lt;a href="http://wordpress.org"&gt;WordPress&lt;/a&gt; supports via &lt;a href="http://www.xmlrpc.com"&gt;xmlrpc&lt;/a&gt;. This whole blogging API thing seems quite messy. Anyway, I wanted to find out if there is a method to delete posts. Neither the outdated &lt;a href="http://www.blogger.com/developers/api/1_docs/"&gt;Blogger API&lt;/a&gt; nor the &lt;a href="http://www.xmlrpc.com/metaWeblogApi"&gt;MetaWeblog API&lt;/a&gt; mention one (or maybe I'm blind). Googling around (almost) randomly however, I found several places that talk about a method &lt;code&gt;blogger.deletePost&lt;/code&gt;. The nice guys from &lt;a href="http://www.sixapart.com/"&gt;SixApart&lt;/a&gt; even have a nice &lt;a href="http://www.sixapart.com/developers/xmlrpc/blogger_api/bloggerdeletepost.html"&gt;documentation for deletePost&lt;/a&gt;. So, here is the method signature in short:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.sixapart.com/developers/xmlrpc/blogger_api/bloggerdeletepost.html"&gt;blogger.deletePost (appKey, postID, username, password, publish)&lt;/a&gt;&lt;br/&gt;
returns boolean&lt;br/&gt;
If appKey is irrelevant (as it would be with a a WordPress installation), leave it at 0.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Exactly what I need, thanks!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-2251849219756486483?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/2251849219756486483/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=2251849219756486483' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/2251849219756486483'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/2251849219756486483'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2007/01/deleting-posts-in-wordpress-via-xmlrpc.html' title='Deleting posts in WordPress via XMLRPC'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-7723792208124240814</id><published>2007-01-24T18:08:00.000Z</published><updated>2007-01-25T14:38:08.488Z</updated><title type='text'>Shipping libical in a Mac Application Bundle</title><content type='html'>&lt;p&gt;I have been working with the &lt;a href="http://sourceforge.net/projects/freeassociation/"&gt;libical&lt;/a&gt; library for parsing and manipulating &lt;a href="http://www.ietf.org/rfc/rfc2445.txt"&gt;iCal&lt;/a&gt; data for a while now, and it works fine (even though we probably don't need it anymore, once Leopard is out). Now that I have finally put my code for &lt;a href="http://semiblog.semanticweb.org"&gt;semiBlog&lt;/a&gt; online, a number of new problems arose. So here is a little summary of what those problems were and how I solved them:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Making sure the library is a universal binary:&lt;/strong&gt; Generating universal binaries in Xcode is very simple. However, when you want to turn  a configure/make based project (like libical) into a universal binary, things get a little more complicated. Luckily, &lt;a href="http://developer.apple.com/technotes/tn2005/tn2137.html"&gt;this document&lt;/a&gt; on Apple's developer pages explains it all.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bundling a &lt;i&gt;.a&lt;/i&gt;-type library with an application bundle:&lt;/strong&gt; This is actually very easy. You need to do three things. &lt;ol&gt;
&lt;li&gt;Drag and drop the library files (in the case of libical those are &lt;i&gt;libical.a&lt;/i&gt;, &lt;i&gt;libicalss.a&lt;/i&gt; and &lt;i&gt;libicalva.a&lt;/i&gt;) into the "Linked Frameworks" group of your project in Xcode (a little trick if you don't know how to get a finder window for hidden folders like &lt;code&gt;/usr/local&lt;/code&gt;: move into the folder in the terminal window and then open a finder window for it by typing &lt;code&gt;open .&lt;/code&gt;).&lt;a href="http://2.bp.blogspot.com/_1bR_xwKupqE/Rbi_6dSSU3I/AAAAAAAAAAM/LbaTyTGRLy4/s1600-h/libical.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://2.bp.blogspot.com/_1bR_xwKupqE/Rbi_6dSSU3I/AAAAAAAAAAM/LbaTyTGRLy4/s320/libical.png" border="0" alt="including libical in Xcode project" id="BLOGGER_PHOTO_ID_5023976395346432882" /&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Set the header search paths correctly: make sure you point the "User Header Search Paths" of your target to the right location (e.g. &lt;code&gt;/usr/local/include&lt;/code&gt;).&lt;/li&gt;
&lt;li&gt;Set the library search paths correctly: make sure you point the "Library Search Paths" of your target to the right location (e.g. &lt;code&gt;/usr/local/lib&lt;/code&gt;).&lt;/li&gt;
&lt;/ol&gt;
&lt;a href="http://3.bp.blogspot.com/_1bR_xwKupqE/Rbi_6tSSU4I/AAAAAAAAAAU/nzob80yZiqY/s1600-h/settings.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://3.bp.blogspot.com/_1bR_xwKupqE/Rbi_6tSSU4I/AAAAAAAAAAU/nzob80yZiqY/s320/settings.png" border="0" alt="Setting header and library search paths in Xcode" id="BLOGGER_PHOTO_ID_5023976399641400194" /&gt;&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Make sure libical finds those time zone info files:&lt;/strong&gt; libical needs to have access to a bunch of time zone definition files. They are located in in a &lt;code&gt;share&lt;/code&gt; sub-directory of the libical install directory. (&lt;code&gt;.../share/libical/zoneinfo&lt;/code&gt;). By default, libical will look for that folder in the location it was first installed, which is fine in many cases. However, when you distribute your project's code or the application bundle, things can get messed up. If libical doesn't find the time zone information, you get errors like those:
&lt;pre&gt;
icalerror.c:99: FILE: An operation on a file failed. Check errno for more detail.
icalerror.c:100: failed assertion `0'
&lt;/pre&gt;
That's why you need to call &lt;code&gt;set_zone_directory()&lt;/code&gt; at runtime, and pass it the right path. I copy the zoneinfo folder into the application bundle (using a bunch of &lt;i&gt;Copy Files&lt;/i&gt; build phases), and then ask &lt;code&gt;NSBundle&lt;/code&gt; for the right path, like so:&lt;/li&gt;
&lt;/ul&gt;
&lt;pre&gt;
NSBundle *pluginBundle = [NSBundle bundleForClass: [SBICalInterface class]];
NSString *zoneinfoPath = [NSString stringWithFormat: @"%@/zoneinfo", [pluginBundle resourcePath]];
set_zone_directory([zoneinfoPath cString]);
&lt;/pre&gt;
(note that I use &lt;code&gt;bundleForClass:&lt;/code&gt; because the zoneinfo folder is actually inside a plugin bundle within the real application bundle. If it was in the application bundle directly, I could just call &lt;code&gt;mainBundle&lt;/code&gt;)&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-7723792208124240814?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/7723792208124240814/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=7723792208124240814' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/7723792208124240814'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/7723792208124240814'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2007/01/shipping-libical-in-mac-application.html' title='Shipping libical in a Mac Application Bundle'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><media:thumbnail xmlns:media='http://search.yahoo.com/mrss/' url='http://2.bp.blogspot.com/_1bR_xwKupqE/Rbi_6dSSU3I/AAAAAAAAAAM/LbaTyTGRLy4/s72-c/libical.png' height='72' width='72'/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-116642885231352707</id><published>2006-12-18T07:53:00.000Z</published><updated>2006-12-18T08:00:52.326Z</updated><title type='text'>RDF visualization on the Mac</title><content type='html'>Over in Todd Ditchendorf's Blog I just read &lt;a href="http://www.ditchnet.org/wp/2006/12/17/visualizing-rdf-with-xsltsvg-is-hard-shopping-is-fun/"&gt;a post about his approach to visualizing RDF&lt;/a&gt; on a Mac (actually, the approach will work anywhere). He discovered the problem that has troubled many a Semantic Web person, namely that processing rdf/xml with XSLT is not per se possibly. The RDF graph has to be expressed in a canonical form, first. Todd uses &lt;a href="http://librdf.org/"&gt;Redland&lt;/a&gt; to do that, then applies his xslt to produce SVG and finally uses the latest &lt;a href="http://webkit.org/"&gt;nightly build of WebKit&lt;/a&gt; to render it (cool - Safari will include native SVG support). Nice!&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-116642885231352707?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/116642885231352707/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=116642885231352707' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/116642885231352707'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/116642885231352707'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2006/12/rdf-visualization-on-mac.html' title='RDF visualization on the Mac'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-116499030002265273</id><published>2006-12-01T16:03:00.000Z</published><updated>2006-12-01T16:30:24.280Z</updated><title type='text'>Including an .a library in an XCode project</title><content type='html'>&lt;p&gt;Compiler and linker settings scare me. I recently tried to include the &lt;a href="http://sourceforge.net/projects/freeassociation/"&gt;libical&lt;/a&gt; library into a project in XCode. I had already done it before in &lt;a href="http://semiblog.semanticweb.org"&gt;semiBlog&lt;/a&gt;, and it worked just fine. All I had to do was to drag the library into XCode.&lt;/p&gt;
&lt;p&gt;However, this time it just didn't work. Trying to import libical's header file (&lt;code&gt;#import "ical.h"&lt;/code&gt;) just gave me a "file not found" error. After some looking around and help from the &lt;a href="irc://irc.freenode.net#macdev"&gt;macdev irc channel&lt;/a&gt;, I figured out that I had to add &lt;code&gt;/usr/local/include&lt;/code&gt; to the header search path, since this is where &lt;code&gt;ical.h&lt;/code&gt; lives. Very obvious, in hindsight. The only thing I don't really understand is: why did this work without specifying the path before, but not now? Apparently, the default settings for project templates have changed in XCode 2.4 (or before). Strange.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-116499030002265273?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/116499030002265273/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=116499030002265273' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/116499030002265273'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/116499030002265273'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2006/12/including-a-library-in-xcode-project.html' title='Including an .a library in an XCode project'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-116320357377944638</id><published>2006-11-10T23:54:00.000Z</published><updated>2006-11-20T18:53:29.770Z</updated><title type='text'>RDFa</title><content type='html'>&lt;p&gt;As reported over on &lt;a href="http://semiblog.semanticweb.org/?p=85"&gt;semiBlog&lt;/a&gt;, I spent this week at ISWC2006 in Athens, GA and presented my blogging tool there during the poster session. I got to present it to a lot of people, among them Dean Allemang of &lt;a href="http://www.topquadrant.com/"&gt;TopQuadrant&lt;/a&gt;. He seemed to like it, but immediately gave me a lecture on how I should link the blog posts to the RDF metadata - &lt;strong&gt;use RDFa, use RDFa, use RDFa&lt;/strong&gt;! In fact, he insisted that my life would turn into paradise straight away if I would start using &lt;a href="http://www.w3.org/2001/sw/BestPractices/HTML/2005-rdfa-syntax"&gt;RDFa&lt;/a&gt; in semiBlog, and that I would go to hell otherwise. That convinced me! :-)&lt;/p&gt;
&lt;p&gt;Anyway, having the metadata embedded in the actual HTML code instead of linking to some file (as I do at the moment) would relieve me of some annoying problems I have with uploading rdf/xml file.&lt;/p&gt;
&lt;p&gt;So, here are a few quick notes on how RDFa works. Generally speaking, RDFa encodes RDF triples as attributes to arbitrary XML elements (and is thus strictly speaking a method of embedding RDF in XHTML, not just any HTML).&lt;/p&gt;
&lt;strong&gt;Encoding Triples with Literal Objects:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;SUBJECT&lt;/strong&gt; is referenced either by the &lt;code&gt;id&lt;/code&gt; or the &lt;code&gt;about&lt;/code&gt; attribute of an XML element. &lt;code&gt;xml:base&lt;/code&gt; is respected.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;PREDICATE&lt;/strong&gt; is referenced using the &lt;code&gt;property&lt;/code&gt; attribute of an XML element.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;OBJECT&lt;/strong&gt; is referenced using either the &lt;code&gt;content&lt;/code&gt; attribute or the actual content. The &lt;code&gt;content&lt;/code&gt; attribute takes precedence.&lt;/li&gt;
&lt;li&gt;Objects can be typed as a specific datataype using the &lt;code&gt;type&lt;/code&gt; attribute.&lt;/li&gt;
&lt;/ul&gt;
&lt;strong&gt;Example:&lt;/strong&gt;
&lt;pre&gt;
&amp;#60;span about="http://semiblog.semanticweb.org/rdfaexamples/posterSession"
   role="cal:Vevent"
   xmlns:cal="http://www.w3.org/2002/12/cal/ical#"&gt;
   &amp;#60;span property="cal:summary"&gt;Posters Reception&amp;#60;/span&gt;
   &amp;#60;span property="cal:dtstart" content="2006-11-08T00:00:00+0000" type="xsd:date"/&gt;
   &amp;#60;span property="cal:dtend" content="2006-11-08T02:00:00+0000" type="xsd:date"/&gt;
&amp;#60;/span&gt;
&lt;/pre&gt;
&lt;strong&gt;Encoding Triples with Resource Objects:&lt;/strong&gt;
&lt;ul&gt;
&lt;li&gt;The &lt;strong&gt;SUBJECT&lt;/strong&gt; is referenced either by the &lt;code&gt;id&lt;/code&gt; or the &lt;code&gt;about&lt;/code&gt; attribute of an XML element. &lt;code&gt;xml:base&lt;/code&gt; is respected.&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;PREDICATE&lt;/strong&gt; is referenced using the &lt;code&gt;rel&lt;/code&gt; attribute of an XML element. Using &lt;code&gt;rev&lt;/code&gt; instead of &lt;code&gt;rel&lt;/code&gt; inverts the relationship, and turns the subject into the object and vice versa (think of passivization in natural language).&lt;/li&gt;
&lt;li&gt;The &lt;strong&gt;OBJECT&lt;/strong&gt; is referenced using either the &lt;code&gt;href&lt;/code&gt; attribute.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;All this is explained in much more detail in the&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.w3.org/2001/sw/BestPractices/HTML/2005-rdfa-syntax"&gt;RDFa Syntax Specification&lt;/a&gt;, and the&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.w3.org/TR/xhtml-rdfa-primer/"&gt;RDFa Primer&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;i&gt;(A sidenote: One aspect that I don't like about the RDFa solution in comparison to linking from the HTML to a SPARQL query is this: when I embed the RDF, it remains static. When I link to a query, I always get the latest, most up-to-date result. However, that's not really an issue at the moment, since I don't actually link to a SPARQL endpoint!)&lt;/i&gt;&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-116320357377944638?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/116320357377944638/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=116320357377944638' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/116320357377944638'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/116320357377944638'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2006/11/rdfa.html' title='RDFa'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-116291918762607260</id><published>2006-11-07T17:03:00.000Z</published><updated>2006-11-07T17:08:56.400Z</updated><title type='text'>Enabling RDF Upload on WordPress 2.0</title><content type='html'>&lt;p&gt;Just as a reminder to self: to enable the old &lt;i&gt;Uploads Options&lt;/i&gt; panel in WordPress2.0+, I need to install the &lt;a href="http://www.ilfilosofo.com/blog/old-style-upload/"&gt;Filosofo Old-Style Upload&lt;/a&gt; plugin. I need this to allow &lt;a href="http://semiblog.semanticweb.org"&gt;semiBlog&lt;/a&gt; to upload RDF annotations to the blogging server.&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-116291918762607260?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/116291918762607260/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=116291918762607260' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/116291918762607260'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/116291918762607260'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2006/11/enabling-rdf-upload-on-wordpress-20.html' title='Enabling RDF Upload on WordPress 2.0'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-116129764481248391</id><published>2006-10-19T23:31:00.000+01:00</published><updated>2006-10-20T00:21:41.540+01:00</updated><title type='text'>More Fun with Autocomplete</title><content type='html'>&lt;p&gt;Today I did some more stuff with autocomplete in &lt;code&gt;NSTextView&lt;/code&gt;. What I wanted to achieve is have a list of suggestions for the autocomplete, but have the text that will actually be inserted in the view differ from the suggestions. Have a look at the picture below to see what I mean. You can see that each entry in the suggestions list starts out with &lt;i&gt;"iCal Event: ..."&lt;/i&gt;. The one selected at the moment is &lt;i&gt;"iCal Event: Meeting with Rory O'Connor"&lt;/i&gt; - however, the text that gets inserted in the view is just &lt;i&gt;"Meeting with Rory O'Connor"&lt;/i&gt;.&lt;/p&gt;

&lt;img style="display:block; margin:0px auto 10px; text-align:center;" src="http://photos1.blogger.com/blogger/2022/2092/1600/autocomplete.2.png" border="0" alt="advanced autocomplete in NSTextView" /&gt;

&lt;p&gt;Now, why is that exciting? Because the way autocomplete works is that &lt;code&gt;NSTextView&lt;/code&gt;'s &lt;code&gt;completionsForPartialWordRange:indexOfSelectedItem:&lt;/code&gt; (or the corresponding delegate method) just returns an array of strings, and those strings will both be shown in the suggestion dropdown box and be string that will actually inserted. So, the first task is to have the insertion be different from the suggestion. This can be achieved by overriding &lt;code&gt;NSTextView&lt;/code&gt;'s &lt;code&gt;insertCompletion:forPartialWordRange:movement:isFinal:&lt;/code&gt;, which is responsible for the actual insertion. You could do something like this:&lt;/p&gt;

&lt;pre&gt;
- (void)insertCompletion: (NSString *)word 
     forPartialWordRange: (NSRange)charRange 
                movement: (int)movement 
                 isFinal: (BOOL)flag
{
    [super insertCompletion: @"not the same"
        forPartialWordRange: charRange 
                   movement: movement 
                    isFinal: flag];
}
&lt;/pre&gt;

&lt;p&gt;This would always insert &lt;i&gt;"not the same"&lt;/i&gt;, regardless of what the user had chosen from the list. Amazing, but not very useful yet. To make it a little more useful, I guess there are a number of options. One could have a lookup function (e.g. via an &lt;code&gt;NSDictionary&lt;/code&gt;) to get from &lt;code&gt;word&lt;/code&gt; to whatever we want. Or a simple transformation, to get rid of the leading &lt;i&gt;"iCal Event: "&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt; However, I chose to go a different route - extending &lt;code&gt;NSString&lt;/code&gt; so that I could ask &lt;code&gt;word&lt;/code&gt; for the string that should be inserted, along the lines of &lt;code&gt;[word completionString]&lt;/code&gt;. Categories will not do that for me, because they don't allow me to define additional instance variables (i.e. the completionString), so I had to subclass &lt;code&gt;NSString&lt;/code&gt;. There is a little complication here, because &lt;code&gt;NSString&lt;/code&gt; is the abstract superclass of a class cluster, so subclassing isn't as straight-forward as in other cases. I need to override the primitive methods &lt;code&gt;length&lt;/code&gt; and &lt;code&gt;characterAtIndex:&lt;/code&gt;, and I need to store the actual string. The interface for my &lt;code&gt;NSString&lt;/code&gt; subclass looks like this:

&lt;pre&gt;
@interface MultiString : NSString {
 NSString *completionString;
 NSString *string;
}

- (id)initWithString: (NSString*)string1
 andCompletionString: (NSString*)string2;

- (NSString *)string;
- (NSString *)completionString;

// primitive methods I need to implement:
- (unsigned int)length;
- (unichar)characterAtIndex: (unsigned)index;

@end
&lt;/pre&gt;

&lt;p&gt;The implementation looks like this:&lt;/p&gt;

&lt;pre&gt;
@implementation MultiString

- (id)initWithString: (NSString*)string1
 andCompletionString: (NSString*)string2
{
 self = [super init];
 if (self) {
  string = string1;
  completionString = string2;
 } 
 return self;
}

- (NSString *)string
{
 return string;
}

- (NSString *)completionString
{
 return completionString;
}

- (unsigned int)length
{
 return [string length];
}

- (unichar)characterAtIndex: (unsigned)index
{
 return [string characterAtIndex: index];
}

@end
&lt;/pre&gt;

&lt;p&gt;Having this, I can use &lt;code&gt;MultiString&lt;/code&gt; to generate strings with two representations, add them to the autocompletion array, and let &lt;code&gt;insertCompletion:forPartialWordRange:movement:isFinal:&lt;/code&gt; return the &lt;code&gt;completionString&lt;/code&gt; instead of the "normal" string. This is what it looks like:&lt;/p&gt;

&lt;pre&gt;
- (void)insertCompletion: (NSString *)word 
  forPartialWordRange: (NSRange)charRange 
    movement: (int)movement 
     isFinal: (BOOL)flag
{
 if ([word isKindOfClass: [MultiString class]]) {
  [super insertCompletion: [word completionString]
   forPartialWordRange: charRange 
        movement: movement 
      isFinal: flag];
 } else {
  [super insertCompletion: word
   forPartialWordRange: charRange 
        movement: movement 
      isFinal: flag];
 }
}
&lt;/pre&gt;

&lt;p&gt;You might wonder why I test for the class of &lt;code&gt;word&lt;/code&gt;. The reason is that, if the user aborts the autocomplete process (by hitting escape again), none of the elements of the completion arrays will be inserted, but instead the original word from the text view. Now, this word is not of class &lt;code&gt;MultiString&lt;/code&gt;, so calling &lt;code&gt;completionString&lt;/code&gt; on it would result in an error, and &lt;code&gt;insertCompletion:forPartialWordRange:movement:isFinal:&lt;/code&gt; would not successfully return anything.&lt;/p&gt;
&lt;p&gt;That's all!&lt;/code&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-116129764481248391?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/116129764481248391/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=116129764481248391' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/116129764481248391'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/116129764481248391'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2006/10/more-fun-with-autocomplete.html' title='More Fun with Autocomplete'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-116121813141922574</id><published>2006-10-19T01:23:00.000+01:00</published><updated>2006-10-20T00:28:26.960+01:00</updated><title type='text'>Waiting for a Spotlight Query to Finish (Spotlight and autocomplete)</title><content type='html'>&lt;p&gt;After a long time of doing other things, I finally got around to working on &lt;a href="http://semiblog.semanticweb.org"&gt;semiBlog&lt;/a&gt; again. In that context, I was playing with integrating Spotlight (through &lt;code&gt;NSMetadataQuery&lt;/code&gt;). Now, &lt;code&gt;NSMetadataQueries&lt;/code&gt; are asynchronous, i.e. you create your query, you register a call-back method for when then query gives some results, and then you run the query. In other words, after the query starts running, the code doesn't halt and wait for the query to finish - instead, it just continues. Then, whenever the query returns some results, the call-back method is called. Looks like this:&lt;/p&gt;

&lt;pre&gt;
- (void)someMethod
{
    NSMetadataQuery *query = [[NSMetadataQuery alloc] init];
    NSPredicate *pred = [NSPredicate predicateWithFormat: queryString]; 
    [query setPredicate: pred];
    
    [[NSNotificationCenter defaultCenter]
             addObserver: self
                selector: @selector(queryHandler:)
                    name: NSMetadataQueryDidFinishGatheringNotification
                  object: query];
    
    [query startQuery];

    // whatever comes now happens immediately:
    NSLog(@"something happens");
}

- (void)queryHandler: (NSNotification *) inNotification
{
     NSLog(@"The query is finished, do something.");
     // blabla...
}
&lt;/pre&gt;

&lt;p&gt;So far, so good. Now, what I want to do in semiBlog is integrate such a Spotlight query in the autocomplete of an &lt;code&gt;NSTextView&lt;/code&gt;. I can manipulate the autocomplete suggestions of &lt;code&gt;NSTextView&lt;/code&gt; by overriding &lt;code&gt;completionsForPartialWordRange:indexOfSelectedItem:&lt;/code&gt; (or by calling &lt;code&gt;textView:completions:forPartialWordRange:indexOfSelectedItem:&lt;/code&gt; in the delegate). Whenever autocomplete is initiated, these methods are called. The &lt;code&gt;NSArray&lt;/code&gt; they return determines what will show up in the list of completion suggestions. Looks like this:&lt;/p&gt;

&lt;pre&gt;
- (NSArray *)completionsForPartialWordRange: (NSRange)charRange 
indexOfSelectedItem: (int *)index
{
   return [NSArray arrayWithObjects: @"eins", @"zwei", @"drei", nil];
}
&lt;/pre&gt;

&lt;img style="display:block; margin:0px auto 10px; text-align:center;" src="http://semiblog.semanticweb.org/wp-content/autocomplete.png" border="0" alt="Basic autocomplete" /&gt;

Of course, when I want to use Spotlight here (e.g. I type "Knud", initiate autocomplete, Spotlight finds all contacts and events that somehow match the string "Knud", I use the result set for the completion suggestions), I run into problems. I can initiate the query in this method, but I will not get the result here, so that I can construct the return array from it. Instead, the result is handled in the asynchronous call-back. So, what to do? After a bit of searching, I found that run loops are what is needed here (see the documentation for &lt;code&gt;CFRunLoops&lt;/code&gt; &lt;a href="http://developer.apple.com/documentation/CoreFoundation/Reference/CFRunLoopRef/Reference/reference.html"&gt;here&lt;/a&gt;). In short, from a current run loop I have to start a new run loop right after I initiate the query (calling &lt;code&gt;CFRunLoopRun()&lt;/code&gt;). The current will then wait until the new loop finishes (calling &lt;code&gt;CFRunLoopStop(CFRunLoopGetCurrent ())&lt;/code&gt;), which I will let it do at the end of the call-back, after the query results have been processed. So, now the code looks a little like this:&lt;/p&gt;

&lt;pre&gt;
- (NSArray *)completionsForPartialWordRange: (NSRange)charRange 
indexOfSelectedItem: (int *)index
{
 // get the current word. That will be the keyword in our query
 NSString *word = [[self string] substringWithRange: charRange];
 
 // construct the query string from this word:
 NSString *queryString = @"someQueryString";
 
 // construct the objects needed to perform the query
 NSMetadataQuery *query = [[NSMetadataQuery alloc] init];
 NSPredicate *pred = [NSPredicate predicateWithFormat: queryString];
 [query setPredicate: pred];
 
        // register the call-back
 [[NSNotificationCenter defaultCenter]
             addObserver: self
    selector: @selector(queryHandler:)
     name: NSMetadataQueryDidFinishGatheringNotification
      object: query];
 
 [query startQuery];
 
        //start a new run loop
 CFRunLoopRun();
 
        // after the new loop is finished, continue by returning the new suggestions:
 return [self suggestions];
}

- (void)queryHandler: (NSNotification *) inNotification
{
 NSMetadataQuery *query = [inNotification object];

 NSArray *suggestions = // create the suggestions array from the query result
 
 [self setSuggestions: suggestions];
 
        // stop the new run loop
 CFRunLoopStop(CFRunLoopGetCurrent ());
}
&lt;/pre&gt;

&lt;img style="display:block; margin:0px auto 10px; text-align:center;" src="http://photos1.blogger.com/blogger/2022/2092/1600/autocomplete2.png" border="0" alt="Autocomplete based on a Spotlight query" /&gt;

&lt;p&gt;Now, I'm not sure I have grasped this run loop business completely - maybe there are some pitfalls here - , but the code seems to work! :-)&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-116121813141922574?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/116121813141922574/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=116121813141922574' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/116121813141922574'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/116121813141922574'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2006/10/waiting-for-spotlight-query-to-finish.html' title='Waiting for a Spotlight Query to Finish (Spotlight and autocomplete)'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-116118542995862156</id><published>2006-10-18T15:56:00.000+01:00</published><updated>2006-10-18T16:41:11.236+01:00</updated><title type='text'>Page Source for AJAX Web Pages</title><content type='html'>&lt;p&gt;Most web browsers have a &lt;i&gt;view page source&lt;/i&gt; function that is very handy for debugging web sites or learning from existing ones. However, when using AJAXy stuff, I found out that elements of a web page changed via &lt;i&gt;replace_html&lt;/i&gt; (or maybe some other function) actually do not appear in the source. I don't really know why that is the case, but here is a way to get around it:&lt;/p&gt;
&lt;ul&gt;
  &lt;li&gt;Open the page in Firefox.&lt;/li&gt;
  &lt;li&gt;Firefox has a function called &lt;i&gt;view DOM&lt;/i&gt; (or something like that, I'm using the German localization).&lt;/li&gt;
  &lt;li&gt;This will show you the DOM of the page in a nice expandable tree view, including the recently ajaxed nodes.&lt;/li&gt;
  &lt;li&gt;You can select the node you are interested in and choose &lt;i&gt;copy XML&lt;/i&gt;.&lt;/li&gt;
  &lt;li&gt;Et voila! There you have the code of the selected node!&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-116118542995862156?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/116118542995862156/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=116118542995862156' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/116118542995862156'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/116118542995862156'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2006/10/page-source-for-ajax-web-pages.html' title='Page Source for AJAX Web Pages'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-116066884076356756</id><published>2006-10-12T16:53:00.000+01:00</published><updated>2006-12-02T07:30:58.363Z</updated><title type='text'>Problems with Spotlight</title><content type='html'>&lt;p&gt;I finally got around to playing with Apple's Spotlight, which I want to use in &lt;a href="http://semiblog.semanticweb.org"&gt;semiBlog&lt;/a&gt;. Somehow, I find Apple's documentation on the topic a bit lacking. Sure there are lots of documents, and they help, but they also confuse.&lt;/p&gt;
&lt;p&gt;E.g. the &lt;a href="http://developer.apple.com/documentation/Carbon/Conceptual/SpotlightQuery/Concepts/QueryFormat.html"&gt;Query Expression Syntax document&lt;/a&gt; tells you that you can write the following query:&lt;/p&gt;
&lt;pre&gt;kMDItemAuthors == "Steve"wc &amp;&amp; kMDItemContentType == "audio"wc&lt;/pre&gt;
&lt;p&gt;Now, when you try to create an &lt;b&gt;NSPredicate&lt;/b&gt; to run in an &lt;b&gt;NSMetadataQuery&lt;/b&gt; object with that expression, you will get an error. Why? Because, as I later found out, if you want to do Spotlight queries the ObjC way (using the classes I just mentioned), you have to use a &lt;i&gt;similar, but slightly different&lt;/i&gt; query syntax. :-( How stupid is that? I'm sure there are reasons for that (&lt;a href="http://developer.apple.com/documentation/Cocoa/Conceptual/Predicates/Articles/pSpotlightComparison.html"&gt;This document explains&lt;/a&gt; it all...), but it was a somewhat frustrating process to find out. The same query in an &lt;b&gt;NSPredicate&lt;/b&gt; has to look like this:&lt;/p&gt;
&lt;pre&gt;(kMDItemAuthors LIKE[wc] 'Steve') &amp;&amp; (kMDItemContentType LIKE[wc] 'audio')&lt;/pre&gt;
&lt;p&gt;Another problem I had is that I found it hard to figure out what the &lt;b&gt;kMDItemContentType&lt;/b&gt; of various kinds of data like AddressBook entries or iCal events are (I want to ask things like &lt;i&gt;"give me all contacts"&lt;/i&gt; or &lt;i&gt;"give me all events"&lt;/i&gt;. The &lt;a href="http://developer.apple.com/documentation/Carbon/Conceptual/understanding_utis/utilist/chapter_4_section_1.html#//apple_ref/doc/uid/TP40001319-CH205-CHDIJFGJ"&gt;System-Declared Uniform Type Identifiers&lt;/a&gt; document lists a vast number of those types. But - I had two problems here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;b&gt;Contacts:&lt;/b&gt; A type &lt;b&gt;public.contact&lt;/b&gt; is mentioned as the &lt;i&gt;"Base type for all contacts"&lt;/i&gt;. That is true, but if you query for &lt;i&gt;kMDItemContentType == 'public.contact'&lt;/i&gt; you will probably get nothing. This is because AB contacts actually have the type &lt;b&gt;com.apple.addressbook.person&lt;/b&gt; (not mentioned in the document...), which is a more specific type (a little like a subclass). And, asking for the type will only give you the most specific one - it doesn't give you the super-types by inference. Instead, you have to query for the &lt;i&gt;kMDItemContentType&lt;b&gt;Tree&lt;/b&gt;&lt;/i&gt; - this attribute contains a collection of all types, from the most specific to the most general. So, either &lt;i&gt;kMDItemContentTypeTree == 'public.contact'&lt;/i&gt; or &lt;i&gt;kMDItemContentType == 'com.apple.addressbook.person'&lt;/i&gt; will get you what you want (if you want all contacts).&lt;/li&gt;
&lt;li&gt;&lt;b&gt;Events:&lt;/b&gt; The document also mentiones a type &lt;b&gt;public.calendar-event&lt;/b&gt; as the &lt;i&gt;"Base functional type for all scheduled events"&lt;/i&gt;. Annoyingly, this type doesn't seem to be used at all, not even as a super type for &lt;b&gt;com.apple.ical.bookmark&lt;/b&gt; (again not mentioned in the document). So, if you are looking for all events, query for &lt;i&gt;kMDItemContentType == 'com.apple.ical.bookmark'&lt;/i&gt;.&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-116066884076356756?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/116066884076356756/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=116066884076356756' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/116066884076356756'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/116066884076356756'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2006/10/problems-with-spotlight.html' title='Problems with Spotlight'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-115500076384625823</id><published>2006-08-08T02:27:00.000+01:00</published><updated>2006-08-08T02:35:01.803+01:00</updated><title type='text'>WWDC2006</title><content type='html'>&lt;a href="http://www.flickr.com/photos/dunken69/209385472/" title="Photo Sharing"&gt;&lt;img src="http://static.flickr.com/63/209385472_d09258d71d.jpg" width="85%" alt="WWDC2006 Keynote" /&gt;&lt;/a&gt;
&lt;p&gt;Yaih, I'm at &lt;a href="http://developer.apple.com/wwdc2006"&gt;WWDC2006&lt;/a&gt;, and it's cool. Attending Steve Job's keynote this morning was like going to a rock concert (well, a little like that). Bizarre. I'm sure this is all covered in detail in a thousand other places, but:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;There will be Objective-C 2.0, and it will have &lt;a href="http://rss.slashdot.org/~r/Slashdot/slashdotApple/~3/9811137/article.pl"&gt;garbage collection&lt;/a&gt;!&lt;/li&gt;
&lt;li&gt;XCode 3.0 will have a lot of new nifty features. E.g. refactoring features like you would expect them from a good IDE. Only, they look cooler than in Eclipse. ;-)&lt;/li&gt;
&lt;li&gt;and, and, and, ... read it everywhere else!&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-115500076384625823?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/115500076384625823/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=115500076384625823' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/115500076384625823'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/115500076384625823'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2006/08/wwdc2006.html' title='WWDC2006'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-115395841813459131</id><published>2006-07-27T00:50:00.000+01:00</published><updated>2006-07-27T01:14:11.280+01:00</updated><title type='text'>Cocoa XML-RPC Client</title><content type='html'>&lt;p&gt;A nice way to test all the various blogging API methods listed in &lt;a href="http://confuseddevelopment.blogspot.com/2006/07/blogging-apis-get-me-those-posts.html"&gt;the previous post&lt;/a&gt; is Todd Ditchendorf's &lt;a href="http://www.ditchnet.org/wp/2005/12/14/cocoa-release-xml-rpc-client-15/"&gt;Cocoa XML-RPC client&lt;/a&gt;. E.g., to test the metaweblog.getRecentPosts, you can just type the following into this nice little app, hit execute and get a response! Not earth-shaking, but useful.&lt;/p&gt;
&lt;a href="http://photos1.blogger.com/blogger/2022/2092/1600/xmlrpcClient.0.png"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/2022/2092/320/xmlrpcClient.0.png" border="0" alt="Cocoa XML-RPC Client" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-115395841813459131?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/115395841813459131/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=115395841813459131' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/115395841813459131'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/115395841813459131'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2006/07/cocoa-xml-rpc-client.html' title='Cocoa XML-RPC Client'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-115395344887573083</id><published>2006-07-26T23:32:00.000+01:00</published><updated>2006-07-27T01:51:48.273+01:00</updated><title type='text'>Blogging APIs ("get me those posts!")</title><content type='html'>&lt;p&gt;I know less about all these blogging APIs than I thought I did, and than I should: today I just set out to begin work on an import function for &lt;a href="http://semiblog.semanticweb.org"&gt;semiBlog&lt;/a&gt;, allowing it to import a complete blog from e.g. WordPress. The idea is that you could say &lt;i&gt;"Here is the URL of my blog, now go and get all the posts, so that I can work on them in semiBlog."&lt;/i&gt; Without thinking, I assumed that any self-respecting blogging API would allow one to say something like &lt;i&gt;"Give me all posts"&lt;/i&gt; or at least &lt;i&gt;"Give me the postIDs of all posts"&lt;/i&gt;. However, after looking around for a while, it seems that this functionality does not exist. So maybe I should take a step back and have a closer look at all the various APIs. I'll collect all the relevant information here in this post.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Blogger API&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;I started my quest for knowledge with the &lt;a href="http://www.blogger.com/developers/api/1_docs/"&gt;Blogger API&lt;/a&gt; (which is actually deprecated by &lt;a href="http://www.blogger.com"&gt;Blogger&lt;/a&gt; itself, in favour of the Atom API). The spec lists the following API calls:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.blogger.com/developers/api/1_docs/xmlrpc_newPost.html"&gt;blogger.newPost&lt;/a&gt;&lt;br/&gt;
Makes a new post to a designated blog. Optionally, will publish the blog after making the post.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.blogger.com/developers/api/1_docs/xmlrpc_editPost.html"&gt;blogger.editPost&lt;/a&gt;&lt;br/&gt;
Edits a given post. Optionally, will publish the blog after making the edit.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.blogger.com/developers/api/1_docs/xmlrpc_getUsersBlogs.html"&gt;blogger.getUsersBlogs&lt;/a&gt;&lt;br/&gt;
Returns information on all the blogs a given user is a member of.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.blogger.com/developers/api/1_docs/xmlrpc_getUserInfo.html"&gt;blogger.getUserInfo&lt;/a&gt;&lt;br/&gt;
Authenticates a user and returns basic user info (name, email, userid, etc).&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.blogger.com/developers/api/1_docs/xmlrpc_getTemplate.html"&gt;blogger.getTemplate&lt;/a&gt;&lt;br/&gt;
Returns the main or archive index template of a given blog.&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.blogger.com/developers/api/1_docs/xmlrpc_setTemplate.html"&gt;blogger.setTemplate&lt;/a&gt;&lt;br/&gt;
Edits the main or archive index template of a given blog.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;None of these strike me as particularly helpful in my task of getting all posts for a given blog.&lt;/p&gt;
&lt;p&gt;&lt;b&gt;MetaWeblogAPI&lt;/b&gt;&lt;/p&gt;
&lt;p&gt;The MetaWeblogAPI is &lt;i&gt;"designed to enhance the Blogger API"&lt;/i&gt;, as its &lt;a href="http://www.xmlrpc.com/metaWeblogApi"&gt;specification&lt;/a&gt; states. That document lists the following API calls:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="http://www.xmlrpc.com/metaWeblogApi#basicEntrypoints"&gt;metaWeblog.newPost (blogid, username, password, struct, publish)&lt;/a&gt;&lt;br/&gt;
returns string&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.xmlrpc.com/metaWeblogApi#basicEntrypoints"&gt;metaWeblog.editPost (postid, username, password, struct, publish)&lt;/a&gt;&lt;br/&gt;
returns true&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.xmlrpc.com/metaWeblogApi#basicEntrypoints"&gt;metaWeblog.getPost (postid, username, password)&lt;/a&gt;&lt;br/&gt;
returns struct&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.xmlrpc.com/metaWeblogApi#metaweblognewmediaobject"&gt;metaWeblog.newMediaObject (blogid, username, password, struct)&lt;/a&gt;&lt;br/&gt;
returns struct&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.xmlrpc.com/metaWeblogApi#metawebloggetcategories"&gt;metaWeblog.getCategories (blogid, username, password)&lt;/a&gt;&lt;br/&gt;
returns struct&lt;/li&gt;
&lt;li&gt;&lt;a href="http://www.xmlrpc.com/metaWeblogApi#metawebloggetrecentposts"&gt;metaWeblog.getRecentPosts (blogid, username, password, numberOfPosts)&lt;/a&gt;&lt;br/&gt;
returns array of structs&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ah, I seem to be getting closer: &lt;i&gt;getPost&lt;/i&gt; and &lt;i&gt;getRecentPosts&lt;/i&gt; seem to help somewhat. &lt;i&gt;getPost&lt;/i&gt; will of course only give me one post, specified by its postID. The documentation for &lt;i&gt;getRecentPost&lt;/i&gt; says: &lt;i&gt;If numberOfPosts is 1, you get the most recent post. If it's 2 you also get the second most recent post, as the second array element. If numberOfPosts is greater than the number of posts in the weblog you get all the posts in the weblog.&lt;/i&gt; That last bit is interesting - however, I still have to know how many post there are. Alternatively, I could just pass a ridiculously high number, and hope that it will be higher than the total number of posts. Hm...&lt;/p&gt;
&lt;p&gt;Out of curiosity I tried passing &lt;i&gt;0&lt;/i&gt; as the &lt;i&gt;numberOfPosts&lt;/i&gt; parameter. This is not documented in the spec, but with my WordPress 2.0.2 test blog it consistently gives me all posts back - just what I wanted! :-) After stumbling upon this, I tried to figure out if this was documented anywhere. All I found was the statement &lt;i&gt;"using blogger.getRecentPosts with the number 'zero' returns all posts in the blog"&lt;/i&gt;. Apart from the fact that it seems slightly wrong (it should read &lt;i&gt;metaWeblog.getRecentPosts&lt;/i&gt;), I couldn't find its original source. The statement appears in various places on the web, which all apparently copy from each other (and now it also appears here). Also, I'm afraid I can't expect this to work with all systems supporting MetaWeblog API - or can I?&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-115395344887573083?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/115395344887573083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=115395344887573083' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/115395344887573083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/115395344887573083'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2006/07/blogging-apis-get-me-those-posts.html' title='Blogging APIs (&quot;get me those posts!&quot;)'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-115377902135165300</id><published>2006-07-24T23:01:00.000+01:00</published><updated>2006-12-02T07:38:49.916Z</updated><title type='text'>Cocoa Bindings to "virtual" data</title><content type='html'>&lt;p&gt;Uh, this took me a while to figure out, even though it's fairly obvious now. I have the following situation:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;I have an application which loads a bunch of plugins.&lt;/li&gt;
&lt;li&gt;Each plugin has a UI, defined as a NIB file I created in Interface Builder.&lt;/li&gt;
&lt;li&gt;The UI elements are bound to what I think could be called "virtual" attributes of an object (an instance of the plugin class). What do I mean by virtual attributes? The object doesn't actually have these attributes (e.g. "blogURL", "userName", ...) as data. Instead, it has one big data object ("publisherDetails"), and when it receives a message such as &lt;i&gt;valueForKey: @"blogURL"&lt;/i&gt;, the return value gets computed from the &lt;i&gt;publisherDetails&lt;/i&gt; object.&lt;/li&gt;
&lt;li&gt;Now, in IB I have e.g. bound an &lt;i&gt;NSTextField&lt;/i&gt; to &lt;i&gt;someObject.blogURL&lt;/i&gt;.&lt;/li&gt;
&lt;li&gt;However, the &lt;i&gt;publisherDetails&lt;/i&gt; only get set _after_ these bindings where established. As a result, the TextField shows a NULL value. No &lt;a href="https://developer.apple.com/documentation/Cocoa/Conceptual/KeyValueCoding/index.html#//apple_ref/doc/uid/10000107i"&gt;KVC (Key-Value Coding)&lt;/a&gt; method like &lt;i&gt;setBlogURL:&lt;/i&gt; or &lt;i&gt;setValue: bla forKey: @"blogURL"&lt;/i&gt; ever gets called.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Sort of complicated, but I don't have the patience to explain it any better now. Anyway, what has to happen is that the UI elements have to be notified that the virtual data they are bound to has changed. That data changes every time the big &lt;i&gt;publisherDetails&lt;/i&gt; object is changed, so that's where we have to add some code. What we have to do is call the &lt;a href="https://developer.apple.com/documentation/Cocoa/Reference/Foundation/Protocols/NSKeyValueObserving_Protocol/Reference/Reference.html#//apple_ref/occ/cat/NSKeyValueObserving"&gt;KVO (Key-Value Observing)&lt;/a&gt; methods &lt;i&gt;willChangeValueForKey:&lt;/i&gt; and &lt;i&gt;didChangeValueForKey:&lt;/i&gt; for each of the virtual attributes. Here is what my &lt;i&gt;setPublisherDetails:&lt;/i&gt; method looks like:&lt;/p&gt;
&lt;pre&gt;
- (void)setPublisherDetails: (NSManagedObject *)object
{
  [object retain];
  [publisherDetails release];
  publisherDetails = object;
  
  // when the publisher details are changed, I want observers watching
  // the individual detail settings to be informed that these
  // details changed as well.
  // detailKeys is an array with the names of all the "virtual" attributes
  NSEnumerator *detailKeyEnum = [[self detailKeys] objectEnumerator];
  NSString *key;
  while (key = [detailKeyEnum nextObject]) {
    [self willChangeValueForKey: key];
    [self didChangeValueForKey: key];
  }
}
&lt;/pre&gt;
&lt;p&gt;Now each time the big &lt;i&gt;publisherDetails&lt;/i&gt; data gets set, the UI elements get notified that the "virtual" attributes which they are bound to also changed. Thus they will update themselves neatly!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-115377902135165300?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/115377902135165300/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=115377902135165300' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/115377902135165300'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/115377902135165300'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2006/07/cocoa-bindings-to-virtual-data.html' title='Cocoa Bindings to &quot;virtual&quot; data'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>2</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-115334598731828279</id><published>2006-07-19T22:46:00.000+01:00</published><updated>2006-07-19T22:53:07.336+01:00</updated><title type='text'>WordPress locally on MacOS X</title><content type='html'>&lt;p&gt;Uuuuhhh, i'm a lazy blogger. The last post is over a months old.&lt;/p&gt;
&lt;p&gt;Anyhow, I had trouble installing a local WordPress on my Mac. It should be very easy, but there were always some annoying problems arising from PhP not being able to talk to MySQL. Once I figured out how to do it, and then the next time I had forgotten how. However, there is a &lt;i&gt;really&lt;/i&gt; easy way to do it, using the brilliant &lt;a href="http://www.living-e.com/en/produkte/The-MAMP/index.php"&gt;MAMP&lt;/a&gt; installation ("Macintosh, Apache, MySQL and PHP"). &lt;a href="http://michaeldoig.net/4/installing-mamp-and-wordpress.htm"&gt;This post&lt;/a&gt; from Michael Doig's blog explains exactly how to do it. Hooray!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-115334598731828279?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/115334598731828279/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=115334598731828279' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/115334598731828279'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/115334598731828279'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2006/07/wordpress-locally-on-macos-x.html' title='WordPress locally on MacOS X'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-115001686948954115</id><published>2006-06-11T10:05:00.000+01:00</published><updated>2006-06-11T10:47:15.243+01:00</updated><title type='text'>Using configure / installing libical on Mac OS X</title><content type='html'>&lt;p&gt;I recently tried to build &lt;a href="http://sourceforge.net/projects/freeassociation/"&gt;libical&lt;/a&gt; (make sure you get the current version from there, and not the obsolete one from &lt;a href="http://www.softwarestudio.org/libical/"&gt;here&lt;/a&gt;), which I need to develop an iCal plugin for &lt;a href="http://semiblog.semanticweb.org"&gt;semiBlog&lt;/a&gt;. Running configure, I always ran into this error:&lt;/p&gt;

&lt;pre&gt;
[knud@Dunkers-Hole]# ./configure
creating cache ./config.cache
checking for a BSD compatible install... /usr/bin/install -c

[...]

checking whether ln -s works... yes
checking for a BSD compatible install... /usr/bin/install -c
checking host system type... configure: error: can not guess host type; you must specify one
&lt;/pre&gt;

Ok, so I need to specify a host type. After some searching, it turned out that the correct host to specify for me was &lt;i&gt;powerpc-apple-darwin8.6.0&lt;/i&gt; (I still don't have an Intel-Mac...). And - hooray -, by running

&lt;pre&gt;
./configure powerpc-apple-darwin8.6.0
&lt;/pre&gt;

the configure script runs perfectly,&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-115001686948954115?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/115001686948954115/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=115001686948954115' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/115001686948954115'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/115001686948954115'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2006/06/using-configure-installing-libical-on.html' title='Using configure / installing libical on Mac OS X'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-114475436133984052</id><published>2006-04-11T12:16:00.000+01:00</published><updated>2006-12-12T22:56:43.530Z</updated><title type='text'>Changing Data Cells in NSTableView</title><content type='html'>&lt;p&gt;I guess I shouldn't be afraid of posting even the stupidest things here (or &lt;i&gt;most stupid&lt;/i&gt;, check &lt;a href="http://www.eternal-lands.com/forum/index.php?showtopic=3452"&gt;this poll&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;I recently tried to change the data cell type in an NSTableView (in the column, to be more precise) from the default text field to a check-box, so that I could bind it to a BOOL variable. I didn't see straight away how to do this in &lt;a href="http://developer.apple.com/tools/interfacebuilder.html"&gt;Interface Builder&lt;/a&gt;, and so started to try doing it programmatically. All kinds of funky problems ensued (read about it &lt;a href="http://lists.apple.com/archives/cocoa-dev/2006/Apr/msg00754.html"&gt;here&lt;/a&gt;), but the short version is: I couldn't get it to work.&lt;/p&gt;
&lt;p&gt;Only when I was informed that you indeed &lt;i&gt;can&lt;/i&gt; change the data cell in IB, I figured out how to do it - and guess what, it's amazingly simple, and it works straight away. Just drag any desired cell type (e.g. a check-box) from the "Cocoa Data" palette onto the table column. It's that easy. :-P&lt;/p&gt;
&lt;a href="http://photos1.blogger.com/blogger/2022/2092/1600/assignDataCellInIB.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/2022/2092/320/assignDataCellInIB.jpg" border="0" alt="" /&gt;&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-114475436133984052?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/114475436133984052/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=114475436133984052' title='4 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/114475436133984052'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/114475436133984052'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2006/04/changing-data-cells-in-nstableview.html' title='Changing Data Cells in NSTableView'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>4</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-114426394383960662</id><published>2006-04-05T19:59:00.000+01:00</published><updated>2006-12-02T07:46:30.590Z</updated><title type='text'>Dynamically creating a va_list in C ...</title><content type='html'>&lt;p&gt;... seems to be impossible, from what I can find out on the web.&lt;/p&gt;
&lt;p&gt;A &lt;i&gt;va_list&lt;/i&gt; is a variable argument list which you can define as an argument to a function (or a method in &lt;a href="http://www.objc.info/"&gt;Objective-C&lt;/a&gt;). A prominent example of this is &lt;i&gt;vprintf&lt;/i&gt; (see &lt;a href="http://en.wikipedia.org/wiki/Printf"&gt;printf&lt;/a&gt; and &lt;a href="http://en.wikipedia.org/wiki/Variadic_function"&gt;variadic functions&lt;/a&gt; on Wikipedia). In &lt;a href="http://developer.apple.com/cocoa/"&gt;Apple's Cocoa library&lt;/a&gt;, one example is NSString's &lt;i&gt;initWithFormat:arguments:&lt;/i&gt;.&lt;/p&gt;
&lt;p&gt;My problem was this: I want to call this method, but I don't know at compile-time which arguments I want to pass. Instead, I create an array with arguments. Now, I &lt;i&gt;thought&lt;/i&gt; I would be able to create a va_list from this array and pass it to &lt;i&gt;initWithFormat:arguments:&lt;/i&gt;, but, as noted above, this is apparently not possible. So, to make a long story short, I had to conjure up my own mock-up of such a format function. I only need to deal with strings, so basically I scan for occurrences of "%@" (indicates an object in Objective-C) and replace them with the elements from the array. Not very elegant, but it works.&lt;/p&gt;
&lt;pre&gt;
- (NSString *)evaluatePseudoFormat: (NSString *)format
                     withArguments: (NSArray *)array
{
  NSMutableString *evaluatedString = 
    [NSMutableString stringWithString: format];
  NSRange varRange, scanRange;
  int length = [format length];
  scanRange = NSMakeRange(0, length);
  int index = [array count];
  NSString *replacement;
  while ((varRange = [format rangeOfString: @"%@"
      options: NSBackwardsSearch
        range: scanRange]).length &gt; 0 &amp;&amp; index &gt;= 0) {
    replacement = [array objectAtIndex: --index];
    [evaluatedString replaceCharactersInRange: varRange 
                                   withString: replacement];
    length = varRange.location;
    scanRange = NSMakeRange(0, length);
  }
  return evaluatedString;
}
&lt;/pre&gt;
&lt;p&gt;Don't ask me why I search backwards. I had some complicated reason for that. After changing some things, the reason became obsolete. However, since the code works, I don't see why I should change it now. ;-) &lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-114426394383960662?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/114426394383960662/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=114426394383960662' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/114426394383960662'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/114426394383960662'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2006/04/dynamically-creating-valist-in-c.html' title='Dynamically creating a va_list in C ...'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-24995747.post-114365392827430323</id><published>2006-03-29T18:34:00.000+01:00</published><updated>2006-12-02T07:49:13.590Z</updated><title type='text'>Embeddable Frameworks in Cocoa</title><content type='html'>&lt;p&gt;In &lt;a href="http://developer.apple.com/cocoa/"&gt;Cocoa&lt;/a&gt;, class libraries are called Frameworks (actually, Frameworks can be a bit more than just compiled code). Frameworks can be configured such that you can embed them into an application, relieving your users from having to install the framework. However, for this to work, one has to make sure to adjust the relevant build settings correctly. Otherwise you will get the horrible "dyld: Library not loaded:" error. I have done this several times already in the past, but every time the problem pops up, I have forgotten how to do it again.&lt;/p&gt;

&lt;p&gt;Jonathan Rentzsch apparently had the same problem and has therefore &lt;a href="http://rentzsch.com/cocoa/embeddedFrameworks"&gt;recorded a little movie&lt;/a&gt; on how to do it. How great is that! The movie explains in detail the how to adjust the build settings in XCode. There is just one little thing I would like to add, as a note to self: in XCode (im currently using 2.2.1) you can access the build settings of the target build and of the project itself. I have no clue what the latter are for, but setting them won't help you. At least they didn't for me. Instead, &lt;i&gt;make sure you adjust the settings for the target&lt;/i&gt;.&lt;/p&gt;

&lt;a href="http://photos1.blogger.com/blogger/2022/2092/1600/buildSettings.0.jpg"&gt;&lt;img style="display:block; margin:0px auto 10px; text-align:center;cursor:pointer; cursor:hand;" src="http://photos1.blogger.com/blogger/2022/2092/320/buildSettings.0.jpg" border="0" alt="The right build settings in XCode 2.2.1" /&gt;&lt;/a&gt;

&lt;p&gt;One other thing I found (in the &lt;a href="http://www.cocoadev.com/index.pl?MoreOnEmbeddingFrameworks"&gt;cocoadev wiki&lt;/a&gt;) is a nice way of checking if you actually succeeded. Once you have built your embeddable framework and the application that embeds it, you can use the otool command line tool to find out where your application will actually look for the libraries it needs.&lt;/p&gt;

&lt;pre&gt;
otool -L semiBlog.app/Contents/MacOS/semiBlog
semiBlog.app/Contents/MacOS/semiBlog:
        @executable_path/../Frameworks/XMLRPC.framework/Versions/A/XMLRPC
        /System/Library/Frameworks/WebKit.framework/Versions/A/WebKit
&lt;/pre&gt;

&lt;p&gt;Embedded frameworks will have a relative path starting with "@executable_path" (the applications path), others will have an absolut path.&lt;/p&gt;

&lt;p&gt;And just to give credit: the &lt;a href="http://sourceforge.net/projects/xml-rpc/"&gt;XMLRPC framework&lt;/a&gt; that is mentioned in the examples is &lt;a href="http://www.divisiblebyzero.com/"&gt;Eric Czarny&lt;/a&gt;'s work. I just made it embeddable!&lt;/p&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/24995747-114365392827430323?l=confuseddevelopment.blogspot.com' alt='' /&gt;&lt;/div&gt;</content><link rel='replies' type='application/atom+xml' href='http://confuseddevelopment.blogspot.com/feeds/114365392827430323/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://www.blogger.com/comment.g?blogID=24995747&amp;postID=114365392827430323' title='2 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/114365392827430323'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/24995747/posts/default/114365392827430323'/><link rel='alternate' type='text/html' href='http://confuseddevelopment.blogspot.com/2006/03/embeddable-frameworks-in-cocoa.html' title='Embeddable Frameworks in Cocoa'/><author><name>Knud Möller</name><uri>http://www.blogger.com/profile/17308912211776698525</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='27' height='32' src='http://4.bp.blogspot.com/-nsKiv3bG_CQ/Tqk0pmb2zdI/AAAAAAAAAEc/1wpFAbCVPrw/s220/knud-200x240.jpg'/></author><thr:total>2</thr:total></entry></feed>
