Sometimes, work drives you to do things that you would never think of otherwise… well, I hope that at least the end result can be of any help to someone else… :-)

If you have troubles installing Alfresco on Debian GNU/Linux 4.0, perhaps the following notes can help…

  • If you add “non-free” to your source.list, you will get nice packages for Sun JDK 1.5; I tried to use CGJ JDK 1.4 together with tomcat-compat, but could not get to starting up alfresco;
  • disable TOMCAT5_SECURITY setting its value to “no” in /etc/default/tomcat5.5; although setting this option to “no” should be required only for using the java-gcj-compat package, I could not have alfresco running with security enabled;
  • if you prefer manually installing MySQL and Tomcat, like I did, or you have them already installed on your system, then download just the alfresco.war package and copy it to /var/lib/tomcat5.5/webapps;
  • remember also to define the location for alfresco store, by defining the dir.root variable in /var/lib/tomcat5.5/webapps/alfresco/WEB-INF/ classes/alfresco/repository.properties.

Building universal binaries for MacOS is a snap if you use XCode. But things can get a bit trickier when you are compiling an open source project, specifically when it is not yours!

Actually, the process of building universal binaries from a configure based project is very simple, in principle. The only thing you need to do is configure the project so that it will be compiled for both platforms at once. This is thoroughly described in Apple Technical Note 2137, so I won’t go into detail about it.

The interesting point is that the approach described above is not universal at all and is prone to fail as soon as your project meets certain conditions. Apple’s Porting UNIX/Linux Applications to Mac OS X guide offers a fairly complete introduction to the wonders of Compiling for multiple architecture, so you can get an idea of the complexity of the task.

When all else fails, you are left with just one option: building your project once for each architecture you would like to support, then use lipo to create a universal binary. What follows describes in more detail that approach, along the lines of my experience trying to build a universal binary for the ACE framework.

Basically, one of the reason why ACE fails to build according to Apple’s guidelines, is the fact that it contains assembler code, and which assembler code to compile is determined at configure-time, so it is correctly configured either for one platform or for the other, but not for both.

First Step: building for your reference architecture

The first step, then is to compile for your actual platform, say i386. It will help if you create a build_i386 directory where to collect all intermediate files and final output, then configure and make like this:

mkdir $ACE_wrappers/build_i386 2>/dev/null
cd $ACE_wrappers/build_i386
../configure --prefix=$INSTALL_DIR --enable-static=yes --enable-shared=no --disable-debug ; make; make install

In this specific example, I am going to build a static library for ACE, no dynamic libraries, and install everything into $INSTALL_DIR (it can be what you like). $ACE_wrappers is the root of the ACE distribution or the place where you put your project files.

Second Step: building for your alternate architecture

The second step is building for the alternate architecture, in this case ppc. This is accomplished like this:

mkdir $ACE_wrappers/build_ppc 2>/dev/null
cd $ACE_wrappers/build_ppc
CC="gcc -arch ppc" CXX="g++ -arch ppc" ../configure --host=ppc-apple-darwin - --enable-static=yes --enable-shared=no --disable-debug; make

As you can see, there is more meat here. You’ll notice that, compared to Apple’s guidelines referenced above, here I am not simply overriding CFLAGS or CXXFLAGS and LDFLAGS. Strangely, doing that does not work for ACE, although I am pretty sure it will work in most cases. What works with ACE is overriding the definitions for you C and C++ compilers by setting CC and CXX when configuring your project. But that is not enough. One more thing that is necessary to do in the ACE case, and I guess in general, is specifying the host environment, although configure itself claims to be able to infer that information on its own when using a cross-compiler. Without that hint, however, configure will create a wrong libtool and your linking step will fail with an utterly misleading error message:

libtool: link: CURRENT '` is not a nonnegative integer not valid version information

If you are interested in the details, that failure lays with configure not being able to figure the correct value for libtool $version_type internal variable, which is then set to none instead of the more appropriate darwin. Using the -host option will get that under control.

One more thing to note is the fact that in the first step I configured my project so that it would be installed at a certain prefix, then compiled and installed it. In this way, we have a full reference installation, including documentation, header files, and binary files (for a single architecture), where we need it.

In the second step, on the contrary, I skipped the install phase. Indeed, what is necessary at this point is simply “converting” the binaries that were installed in the first step and make them flat multi-platform binaries.

Third Step: the Magic of Fat-Files

The last step is accomplished by way of lipo, a graciuos and very useful tool from Apple. lipo allows (among other things) to create a fat-file by sort of mixing two slim-files. This is exactly what I have done in order to have a fat ACE library, thanks to the command:

lipo -create $ACE_wrappers/build_i386/ace/.libs/libACE.a $ACE_wrappers/build_ppc/ace/.libs/libACE.a -output $INSTALL_DIR/lib/libACE.a

In my case, this was an easy task, since the only binary I was interested in was the libACE.a file.

If you have multiple targets, you will need to identify all your binary files (which are usually installed in bin and lib directories) and lipo-ize them all. This could be made more an automated task if you install the alternate distribution in a temporary directory. Then it is simply a matter of finding all the files contained in the bin and lib directories and for each of them execute the lipo -create command. This is left as an exercise to the reader… :-)

The approach described here should also work for the TAO CORBA ORB, based on ACE and developed by the same group based at Washington University, and I guess in any case where the guidelines provided by Apple fall short for one reason or another.

Last week, I installed Debian etch on a HP x64 workstation based on an Intel Xeon processor. Debian offers an impressive support for a vast range of HW platforms, so I could readily install a 64 bit version of GNU/Linux using the netinst image.

Next, I tried to install VMWare Workstation, and everything seemed to go fine: kernel modules compiled (after installing the relevant kernel-headers package) and installed without problems. I could even successfully create a virtual machine, but when I tried to run it, it refused with a sad box message “Failed to connect to peer process”. VMWare error message.

With some investigation, I could identify the root cause of the issue. Indeed, the vmware executable was not able to find the following libraries: libX11.so.6, libXtst.so.6, libXext.so.6, libXrender.so.1, libXau.so.6, libXdcmp.so.6, as a quick check with ldd showed. Actually, I was forewarned of this problem when running the vmware-config.pl script, but I downplayed that message because I was sure that those libraries were installed on my system and actually accessible.

Well, the problem turned into why those libraries were not recognized and how to fix that. The reason was pretty clear: vmware is a 32 bit executable needing 32 bit libraries, and those 32 libraries were not installed on my 64 bit system. A quick check in Debian site allowed me to find a package containing a set of 32 bit system libraries, so I only had to execute the command
sudo aptitude install ia32-libs
and everything was fine again.

MacOS X offers a brilliant example of integration between a state-of-the-art windowing GUI and a traditional command line interface and you can choose the kind of interface that most suits your current needs or that makes easier the task you are at. One task that is very easily done via the Aqua user interface is printing a bunch of documents on a given printer. All that you need for that is a Desktop Printer that you can drag your documents to. (Desktop printers can be created via the Printers menu in the Printer Setup Utility).

This is perfectly fine, where it not for the fact that I don’t like icons I use sporadically cluttering my desktop. Furthermore, when I need to print a group of documents, I am usually working from the command line — e.g., I want to print all jpeg pictures in a folder or print some html files to PDF. So the way I usually do this is thru the magic of the open command. Indeed, when you execute:

open -a "Printer Setup Utility"

this will print all listed files on the default printer. Of course, if you want to print to a different printer from your default one, this will not do. Fortunately, you can also set your default printer via the command line, by using the command:

lpoptions -d .

All in all, say that you have a PDF printer driver (i.e., a program that acts like a printer driver but will “print” to a PDF file) installed with the name “PDF_Printer”. You can send documents to it to be printed by executing:


$ lpoptions -d PDF_Printer
$ open -a "Printer Setup Utility" */*.jpg
$ lpoptions -d Color_Printer

If you have several printers and you don’t know which one was your default printer before switching to PDF_Printer, you can execute:

lpoptions -d

to read the current default printer before switching it. With all this bits, creating a shell script automating your specific workflow is a matter of minutes.

Since I have been recently doing a lot of work with RubyCocoa, I have created a new blog where I will collect all my experiences and learnings with it. You can find it at this link. I will continue posting to this blog more general stuff.

Sixteen years after Richard Stallman released GPLv2, we now have GPLv3. I am not much of an expert in copyright or patent issues, so I have to believe what I read in authorative sources about its provisions to prevent any entity taking advantage of GPL in order to modify or extend a GPLv3 licensed software program from sueing developers or users of that software program on patent infringement.

It is definitely good news that we have now an up-to-date GPL that tries to tackle the strongest threat to the free software community. Let’s hope it is effective. :-)

This post is a follow-up to another post I wrote on the very same subject. I am showing here the full implementation of a NSPersistentDocument based class that allows to use package documents embedding a Core Data store.

I short, what this post adds to the previous one is:

  • improved encapsulation;
  • NSDocumentController subclass to correctly handle the Recent Document menus;
  • fixed a problem with NSError handling, though still not doing any proper error management.

Those improvements originated from a discussion with Tim Perrett in the cocoa-dev mailing list and from a comment by Laurent Sansonetti to my original post. Thanks to both.

PersistentPackageDocument Class

The PersistentPackageDocument class can be used as a base class for your document classes whenever you want them use a document package embedding the actual Core Data data store. PersistentPackageDocument derives from NSPersistentDocument and overrides four methods: initWithContentsOfURL_ofType_error, writeToURL_ofType_forSaveOperation_originalContentsURL_error, readFromURL_ofType_error, displayname. Here’s the code:


class PersistentPackageDocument < OSX::NSPersistentDocument

   #-- returns the document name to display in the window title
   def displayName
     if (fileURL)
       documentNameFromDataStoreURL(fileURL)
     else
       'Untitled'
     end
   end

   #-- returns the package document path by stripping the dataStoreName component
   #-- from the data store URL; used in displayName
   def documentNameFromDataStoreURL(url)
     /([^\/]+)\/?$/ =~ url.relativePath.gsub(/#{dataStoreName}$/, '')
     $1 + " - View"
   end

   def dataStoreURLFromPackageURL(url)
     dataStorePath = url.relativePath.stringByAppendingPathComponent(dataStoreName)
     OSX::NSURL.fileURLWithPath(dataStorePath)
   end

   def readFromURL_ofType_error(url, type, errorPtr)
     path=url.relativePath
     if (!OSX::NSFileManager.defaultManager.fileExistsAtPath_isDirectory(path, nil))
#-- YOUR ERROR MANAGEMENT HERE
     end
     result = super_readFromURL_ofType_error(url, type, nil)
     if (!result)
#-- SET ERROR INFORMATION TO BE RETURNED VIA errorPtr.assign(nserror_object)
     end
     result
   end

   def writeToURL_ofType_forSaveOperation_originalContentsURL_error(url, type, op, content, errorPtr)

#-- if content is not nil, then we are saving a newly created document
#-- in this case, initWithURL is not called, so we had no chance to fix the url,
#-- let's do it here.
     if (content == nil)
       path = url.relativePath
       url = dataStoreURLFromPackageURL(url)
       isDirectory = false
       if (!OSX::NSFileManager.defaultManager.createDirectoryAtPath_attributes(path, nil))
#-- YOUR ERROR MANAGEMENT HERE, set errorPtr
         return false
       end
     end

     ok = super_writeToURL_ofType_forSaveOperation_originalContentsURL_error(url, type, op, content, nil)

     if (!ok)
#-- SET ERROR INFORMATION TO BE RETURNED VIA errorPtr.assign(nserror_object)
     end
     ok
   end

   def initWithContentsOfURL_ofType_error(url, type, errPtr)
     url = dataStoreURLFromPackageURL(url)
     ok, err = super_initWithContentsOfURL_ofType_error(url, type, nil)
     if (!ok)
#-- SET ERROR INFORMATION TO BE RETURNED VIA errorPtr.assign(nserror_object)
     end
     ok
   end

end

For a more detailed discussion of the rationale behind this implementation, see my previous post.

You should then change your MyDocument class (the one produced by XCode templates) so that it derives from PersistentPackageDocument instead of NSPersistentDocument and it adds a dataStoreName method that returns the data store file name for that specific document. Here an example:


class MyDocument < PersistentPackageDocument

  def dataStoreName
    'data.xml'
  end

#-- default RubyCocoa implementation: managedObjectModel, setManagedObjectContext, windowNibName, etc.

end

Supporting Recent Documents

The PersistentPackageDocumentClass as given above is fully capable of dealing with package documents embedding a Core Data data store. Unfortunately, it alone cannot ensure that the Recent Documents menu is correctly handled in your application. To that aim, you need to override your NSDocumentController noteNewRecentDocumentURL method so that it does some juggling with the path that is stored with the recent document menus.

If your package document is enough rich, chances are that you are already subclassing NSDocumentController, so overriding noteNewRecentDocumentURL is a snap. Otherwise, here is a sample subclass:


class PersistentPackageDocumentController < OSX::NSDocumentController

  def init
    super_init
  end

  def packageURLFromDataStoreURL(url)
    dataStoreName = currentDocument.dataStoreName
    OSX::NSURL.fileURLWithPath(url.relativePath.gsub(/#{dataStoreName}$/, ''))
  end

  def noteNewRecentDocumentURL(url)
    if (currentDocument)
     super_noteNewRecentDocumentURL(packageURLFromDataStoreURL(url))
    end
  end

end

As already mentioned, the key point is the method noteNewRecentDocumentURL, while packageURLFromDataStoreURL is just responsible for string manipulation. Note also that packageURLFromDataStoreURL accesses the current document to retrieve its dataStoreName and this forces to guard against the case when there is no current document. There are many alternative implementation of this behaviour, in particular you could define the method dataStoreName in the document controller class and let PersistentPackageDocument access it there. This approach has the adavantage that a “current” document controller is always there, but for presentation reasons it is not taken here.

Sublassing NSDocumentController has its own particularities. The easiest way to do it is in Interface Builder MainMenu.nib file. Just subclass and instantiate it in the nib and the above code will be used for your document shared controller. Read this FAQ for more information.

Summing up

The two classes defined above will allow you to easily integrate package documents in your Core Data application.

One final note: make sure you define your document classes as packages in your target properties.

I find myself quite often needing executing a shell command when I am working in the Finder, say, for example, to “touch” a file in a certain folder on screen. What one needs to do in such cases is opening a Terminal window, drag and drop the folder icon on to it, preprend a “cd” to the folder path, and finally type the desired command.

All of this is readily accomplished in a very elegant way by means of the simple Automator workflow that’s described by the following snapshot (click to see it larger).

If you create the Automator workflow depicted above, and save it as a Finder workflow (see picture below),

you will be then able to right-click on any folder, or on the Desktop, and then choose ExecuteShellCommand from the Automator menu that will be displayed.

Thereafter, you will be asked for the command to execute. If you ran the workflow on a folder, then the command will be executes inside that folder. If you ran it on a file, then the command you specified will be passed the file as the last argument.

As said, this is useful when you want to carry out a one-shot operation, like touching a file (if it does not exist, you will need to run the workflow on the folder that’s going to contain it and specify the file name; if the file exists, you only need to run the workflow on that file and specify “touch” as a command to execute), opening a file with a given application (“open -a “), and so on…

If anyone finds interesting uses for this workflow, please let me know. Also welcome, since I am not really good at Automator :-) , are any suggestions as to better ways to implement it.

You all know how easy it is to create a Core Data application by using XCode and Interface Builder. Things get trickier, though, if you want to create a document-based application that uses package documents. This post will guide you through the process.

A bit of context

Bundles are a great way to package files in a directory structure. I won’t go into detail here about all the advantages that bundles offer and what important role they play in MacOS X. So, I will assume that the reader knows what a bundle is and simply tell my story.

One of the feature I wanted to implement in a simple Core Data document-based application I am developing was the possibility of using package documents to store together all the files related to some specific sort of document.

After the miserable failure of my first, naive attempt at subclassing NSPersistentDocument, I resorted to the web for insights. My feeling that the task at hand was going to be hard, was immediately confirmed by this CocoaBuilder thread. Indeed, a possible implementation was proposed, based on overriding a few NSPersistentDocument methods, but it did not really work, since it crashed at the second attempt at saving a document. So I kept on googling around and found about a completely different approach to the problem, namely subclassing NSDocument (instead of NSPersistenDocument). That amounted to sort of reimplementing from scratch NSPersistentDocument, but did not work for me either. So I realized I had to go deeper down into NSPersistentDocument design, if I wanted to come up with anything useful, be it simply an understanding of the reason why mixing NSPersistentDocument and packages was possibly beyond reach.

Design of a (Core Data) persistent package document

If you look at Apple documents about NSPersistentDocument, you’ll find a very streamlined document class, with three methods that literally scream for you to override them. They are:

– readFromURL:ofType:error:
– revertToContentsOfURL:ofType:error:
– writeToURL:ofType:forSaveOperation:originalContentsURL:error:

A fourth method documented in NSPersistentDocument, that is relevant to our present discussion, is:

- configurePersistentStoreCoordinatorForURL:ofType:error:

Briefly, each of the methods in the upper block is called on response to an action on the user’s part (creating a new document, saving or reverting the current document), while the fourth is called once for each document, usually when it’s first written to or read from disk.

In Apple document, you can further read:

“You can customize the architecture of the persistence stack by overriding the methods managedObjectModel and configurePersistentStoreCoordinator:forURL:ofType:error:. You might wish to do this, for example, to specify a particular managed object model, or to distribute storage of different entities among different file stores within a file wrapper.”

Actually, mixing file wrappers and configurePersistentStoreCoordinator:forURL:ofType:error: does not seem to work, as you can read here. So I did not even bother to try it. If you don’t use file wrappers, you will quickly hit a wall, because NSPersistentDocument swaps documents around, and if you don’t use file wrapper it will do that with the Core Data data file instead of with the whole package.

An approach that leads nowhere

An approach I tried out is the following. Apparently, it should be straightforward to override the above mentioned methods, so that you can:

  • “intercept” a call to them before the url (you see, each of the methods accepts an NSURL as its first argument) is actually accessed by NSPersistentDocument;
  • change the url on-the-fly to make it point to the actual Core Data store inside of the package document, and possibly create the directory underlying the latter;
  • call the base class implementation with the new url and return its output;

and get, hopefully, the kind of behaviour desired.

That was, by the way, the approach followed in the CocoaBuilder link I mentioned above, but in reality, apart from a few shortcomings of that implementation, the complex interplay going on among these methods makes things a little trickier.

In fact, all three methods of the above code block, apart from being called directly from NSApplicationMain, also call one another (revertToContentsFromURL: calls readFromURL:; both readFromURL: and writeToURL: call configurePersistentStoreCoordinator:) and you must pay attention to not “fix” your URL twice. So, either you implement different behaviours to take into account the fact that, when called from another NSPersistentDocument method, the url will already be pointing to the right place, or you define an idempotent method that returns the path to the inner data file.

If you take this approach, another point you need to consider is that writeToURL: has an originalContentsURL: argument that is not null on all calls except the first one (of course, when you firstly save a document, there is no “original content” yet). You’ll also have to deal with this url and “fix” it the same way as done with the other one.

Finally, you have the option of using the fileURL:/setFileURL: methods. Setting fileURL will make your NSPersistentDocument remember the actual location of the data file. So, if you call setFileURL in your override of readFromURL: (i.e., when opening a document), then successive calls to writeToURL: will have the url parameter already set up to point to the Core Data data file. This appears to be really handy, although it does not apply to the originalContentsURL: parameter. Anyhow, be consequent…

With all this in mind, I have tried hard to devise an implementation of a NSPersistentDocument subclass. However, in the end, no matter what I tried, I could not succeed in getting a reliable behaviour by following this approach. There was something that was wrong somewhere, possibly you cannot play around with the url your NSPersistentDocument subclass is managing from within that same class, or at least, I have not found the correct way to do it.

A working solution

The solution was, anyway, closer than I thought. It seemed clear to me that the right way had to do with changing how NSPersistentDocument was initialized. So, I overrode the initWithContentsOfURL:ofType:error method like this (it’s ruby, but porting back to ObjC is straightforward):


  def initWithContentsOfURL_ofType_error(url, type, err)
    url = dataFilePath(url)
    ok, err = super_initWithContentsOfURL_ofType_error(url, type, nil)
    if (!ok)
# YOUR ERROR MANAGEMENT HERE
    end
    ok
  end

This method is executed each time you open a document, and it makes all of the other methods of the class receive and NSURL pointing at the right place.

I had still to deal with a few issues. First of all, I had to create somewhere the directory corresponding to the bundle. The right place to do this was the writeToURL: method.

Secondly, I had to consider the case of a newly created document, which calls the init method into action. Unfortunately, in this case the approach taken in initWithContentsOfURL:ofType:error would not do, since no url is specified when creating a new document. Again, the right place to tackle this was writeToURL:, where I needed a way to tell whether the method was called for the first time. This was ready accomplished by looking at the fact that, as mentioned above, the originalDocumentsURL: argument to writeToURL: is set to null on the very first call. This gave me the following code for writeToURL:


def writeToURL_ofType_forSaveOperation_originalContentsURL_error(url, type, op, content, error)

  if (content == nil)
    path = url.relativePath
    url = dataStorePathFromPackageURL(url)
    if (!OSX::NSFileManager.defaultManager.createDirectoryAtPath_attributes(path, nil))
      return false
    end
  end

  ok, error = super_writeToURL_ofType_forSaveOperation_originalContentsURL_error(url, type, op, content, nil)
  if (!ok)
# YOUR ERROR MANAGEMENT HERE
  end
  ok
end

A few more bits to check that the package directory exists in readFromURL:, and it was done. There is no need to override revertToContentsOfURL:, but you can if you would like to do anything special when reverting a document.

The code


class MyDocument < OSX::NSPersistentDocument

  def initWithContentsOfURL_ofType_error(url, type, err)
    url = dataFilePath(url)
    ok, err = super_initWithContentsOfURL_ofType_error(url, type, nil)
    if (!ok)
# YOUR ERROR MANAGEMENT HERE
    end
    ok
  end

def writeToURL_ofType_forSaveOperation_originalContentsURL_error(url, type, op, content, error)

  if (content == nil)
    path = url.relativePath
    url = dataStorePathFromPackageURL(url)
    if (!OSX::NSFileManager.defaultManager.createDirectoryAtPath_attributes(path, nil))
      return false
    end
  end

  ok, error = super_writeToURL_ofType_forSaveOperation_originalContentsURL_error(url, type, op, content, nil)
  if (!ok)
# YOUR ERROR MANAGEMENT HERE
  end
  ok
end

def readFromURL_ofType_error(url, type, error)
  path= packagePathFromDataStoreURL(url)
  if (!OSX::NSFileManager.defaultManager.fileExistsAtPath_isDirectory(path, nil))
  result, err = super_readFromURL_ofType_error(url, type, nil)
  if (!result)
# YOUR ERROR MANAGEMENT HERE
  end
  result
  end

# here go the rubycocoa template generated methods
# (managedObjectModel, setManagedObjectContext, windowControllerDidLoadNib)

end

As usual, in the code above, error management is poor to not existing. In particular, you should take care to never return false from NSPersistentDocument methods that returns an NSError without correctly ensuring that one is returned.

If you have got a Mac and love working at night, then read on, your eyes will be grateful (and less abused!)… :-)

You have probably experienced that strange feeling of being almost blinded by the light coming out from you monitor when you are working at night. I don’t know if this happens only when you, like I usually do, prefer a dark to soft-lighted room to stay up that late, with just a light bubble encircling you, or if it is simply a sort of automatic reflex, like the one that makes you soften down your music at night — unless you are on some disco-drug, I mean…

Well, in that case, you know that just dimming your monitor lightness usually does not help that much, and, above all, you know well that the high contrast between your monitor and the dark background of your room does not really do a favour to your eyes… to make things worse, there is no simple way to position some light source behind your monitor so that it creates a homogeneous lighting without the light source to actually be in your eyesight (which is really nasty)…

So try this: press command-option-control-8 on your keyboard and enjoy a nightly style for your Mac… not as gorgeous as the themes you get with ShapeShifter, but still just a keystroke away… :-)