001package com.hfg.image;
002
003import java.io.File;
004import java.io.StringReader;
005
006import org.xml.sax.Attributes;
007import org.xml.sax.InputSource;
008
009import com.hfg.util.Executor;
010import com.hfg.util.StringUtil;
011import com.hfg.xml.parser.AbstractContentHandler;
012import com.hfg.xml.parser.SaxyParser;
013
014//------------------------------------------------------------------------------
015/**
016 * Functions for interfacing with Apple's Aperture.
017 *
018 * @author J. Alex Taylor, hairyfatguy.com
019 */
020//------------------------------------------------------------------------------
021// com.hfg XML/HTML Coding Library
022//
023// This library is free software; you can redistribute it and/or
024// modify it under the terms of the GNU Lesser General Public
025// License as published by the Free Software Foundation; either
026// version 2.1 of the License, or (at your option) any later version.
027//
028// This library is distributed in the hope that it will be useful,
029// but WITHOUT ANY WARRANTY; without even the implied warranty of
030// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
031// Lesser General Public License for more details.
032//
033// You should have received a copy of the GNU Lesser General Public
034// License along with this library; if not, write to the Free Software
035// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
036//
037// J. Alex Taylor, President, Founder, CEO, COO, CFO, OOPS hairyfatguy.com
038// jataylor@hairyfatguy.com
039//------------------------------------------------------------------------------
040
041public class Aperture
042{
043   private static File mAperturePlistFile = new File(System.getProperties().getProperty("user.home")
044                                                     + "/Library/Preferences/com.apple.Aperture.plist");
045
046   //###########################################################################
047   // PUBLIC FUNCTIONS
048   //###########################################################################
049
050   //--------------------------------------------------------------------------
051   /**
052    This function retrieves the current default Aperture library path.
053    */
054   public static File getLibraryPath()
055         throws Exception
056   {
057      if (! mAperturePlistFile.exists())
058      {
059         throw new RuntimeException("It does not appear that Aperture is installed on this system.");
060      }
061
062      String cmd = "/usr/bin/plutil -convert xml1 -o - " + mAperturePlistFile.getPath();
063      Executor executor = new Executor(cmd);
064      int retVal = executor.exec();
065      if (retVal != 0)
066      {
067         throw new RuntimeException("Error executing " + StringUtil.singleQuote(cmd) + ": " + executor.getSTDERR());
068      }
069
070      /*
071      Looking for:
072              ...
073              <key>LibraryPath</key>
074              <string>/Photos/Aperture Library.aplibrary</string>
075              ...
076      */
077      PlistContentHandler handler = new Aperture().new PlistContentHandler("LibraryPath");
078      SaxyParser parser = new SaxyParser();
079      parser.setContentHandler(handler);
080      parser.parse(new InputSource(new StringReader(executor.getSTDOUT())));
081
082      return new File(handler.getTargetPropertyValue());
083   }
084
085   //###########################################################################
086   // INNER CLASS
087   //###########################################################################
088
089   private class PlistContentHandler extends AbstractContentHandler
090   {
091      private String mTargetPropertyKey;
092      private String mTargetPropertyValue;
093      private String mCurrentTagName;
094      private boolean mTargetPropertyFound = false;
095
096      //-----------------------------------------------------------------------
097      public PlistContentHandler(String inTargetPropertyKey)
098      {
099         mTargetPropertyKey = inTargetPropertyKey;
100      }
101
102      //-----------------------------------------------------------------------
103      public String getTargetPropertyValue()
104      {
105         return mTargetPropertyValue;
106      }
107
108      //-----------------------------------------------------------------------
109      public void startElement(String inURI, String inLocalName, String inName, Attributes inAttributes)
110      {
111         mCurrentTagName = inLocalName;
112      }
113
114      //-----------------------------------------------------------------------
115      public void characters(char[] inChars, int offset, int length)
116      {
117         if (mCurrentTagName.equals("key"))
118         {
119            String key = new String(inChars, offset, length);
120            if (key.equals(mTargetPropertyKey))
121            {
122               mTargetPropertyFound = true;
123            }
124         }
125         else if (mCurrentTagName.equals("string")
126                  && mTargetPropertyFound)
127         {
128            mTargetPropertyValue = new String(inChars, offset, length);
129            mTargetPropertyFound = false;
130         }
131      }
132   }
133
134}