Potential Uses for JoSQLPotential Uses for JoSQL
It's become pretty apparent (to me at least ;) that one of the main areas of confusion for developers is: What would I use JoSQL to do? Whilst I can't answer that question for everyone, here are potential examples of where you might use JoSQL.

Note: the code/queries below have NOT been tested or compiled, it is there for illustration purposes only, please don't complain at me if it doesn't compile (or even work, I'm not here to do your work for you)!
Finding Files
A pretty simple example would be if you wanted to find some files in a directory(ies) that have a specific file extension or have been updated since a certain date, or are between certain size criteria, or just a mix of them all.

Example query, return all .html files that have been updated since 01/Jan/2006, are readable, are between 10K and 20K in size. Order the results by the last modified date (more recently modified first) and then by size (greatest first).
SELECT *
FROM   java.io.File
WHERE  lower (name) LIKE '%.html'
AND    length BETWEEN (10 * 1024) + (20 * 1024)
ORDER BY  lastModified DESC, length DESC
Example Java code to make this work:
File d = new File (dirName);

Query q = new Query ();
q.parse (queryText);

QueryResults qr = q.execute (new ArrayList (d.listFiles ()));
Augmenting Google API Search Results
Let's try something a little more interesting ;) Now, Google has made their Web Search API available, so that you can perform Google searches from your Java code. Now whilst Google is very powerful, it does have some limitations. For example, let's say you want to find out want to find out all the pages that mention JoSQL on the SourceForge and freshmeat sites. Easy enough to do, just perform this query. So far so good, but we've got about 440 results that are ordered by Google's relevance criteria, pretty useless if you want to get details about each site!

So the following query will tell you some aggregate information about the query AND will group the results for you by site making life much easier ;)
SELECT * result
FROM   GoogleSearchResultWrapper
GROUP BY  urlObj.host
GROUP BY ORDER :_allobjs.size DESC
EXECUTE ON GROUP_BY_RESULTS avg (cachedSizeAsInt) cachedAvgSize
Example Java code to make this work (note we assume here that the GoogleSearchResultWrapper class will take the com.google.soap.search.GoogleSearchResultElement class and create a java.net.URL object for the URL returned by the getURL call and return an int via the getCachedSizeAsInt class:
GoogleSearch search = new GoogleSearch();

// Set mandatory attributes.
search.setKey("000000000000000000000000");

// Set the query string.
search.setQueryString("josql+site%3Asourceforge.net+OR+site%3Afreshmeat.net");

// Invoke the actual search
GoogleSearchResult result = search.doSearch();    

// Get the result.
GoogleSearchResultElement[] els = result.getResultElements ();

List l = new ArrayList ();

// Convert to our wrapper object and prepare for JoSQL call.
for (int i = 0; i < els.length i++)
{

    l.add (new GoogleSearchResultWrapper (els[i]));

}

Query q = new Query ();
q.parse (queryText);

QueryResults qr = q.execute (l);

// Now iterate over the results.
List josqlRes = qr.getResults ();

// Note: here we are iterating over the group by results, so each list
// here will contain a single column that is the "host".
for (int i = 0; i < josqlRes.size (); i++)
{

    List h = josqlRes.get (i);

    String host = h.get (0);

    // Get the results associated with this host.
    List hostResults = (Map) qr.getGroupByResults ().get (h);

    // Get the save values associated with this host.
    Map saveValues = qr.getGroupBySaveValues (h);

    // Get the average cache size.
    double avgCacheSize = ((Number) saveValues.get ("avgCacheSize")).doubleValue ();

    // Now do something with the results!

}
This is just one potential use, another is to return a unique list of the sites that mention a term, for example to get list of sites that mention JoSQL. The JoSQL query would look something like:
SELECT DISTINCT urlObj.host
FROM   GoogleSearchResultWrapper
Trimming Exception traces to items you are interested in
If you've ever used a framework or plugin manager then you'll have sometimes have got a scary looking exception trace when something goes wrong. Often times the stack trace generated contains about 20-30 elements that you aren't really interested in because they relate to the internals of the framework/plugin manager, sometimes the elements you are interested in are the top 2-3. Wouldn't it be nice to be able to remove all that fluff?

Note: you don't actually have to implement this yourself, see org.josql.filters.StackTraceElementFilter for details of a filter that will handle the nasty bits for you!

Example query, return limit the elements to those within the org.josql package.
SELECT * 
FROM   java.lang.StackTraceElement
WHERE  className LIKE 'org.josql.%'
Example Java code to see this in action.
public static Exception filterAndRethrow (Exception e)
{

   // Assume that the query has been parsed already when the class was inited.
   try
   {

       QueryResult qr = stackTraceFilterQuery.execute (Arrays.asList (e.getStackTrace ()));

       // Note: this line probably won't work, for some reason I haven't been
       // able to cast to a "StackTracElement[]", if anyone can explain 
       // why please let me know!
       e.setStackTrace ((StackTraceElement[]) qr.getResults ().toArray ());

   } catch (Exception ex) {

       // Just throw the exception we have been unable to filter and
       // we are already (probably) in an error chain so it's not wise to
       // "lose" this exception by throwing a JoSQL problem which should
       // be handled by another mechanism.

   }

   throw e;

}
It is also potentially possible to limit who can call a method using this technique, although according to the JavaDocs it may not be 100% reliable due to optimizations provided by the JVM that may cause stack frames to not be available.
A Rule-based Event dispatcher
The Java standard event listener event architecture is fine and dandy but it generally provides a very broad mechanism of "tell me about all events". This is ok, but it is then down to the listener to determine whether it's interested in the event after all. It would be useful to put this logic into the event dispatcher. Well using a JoSQL WHERE clause this is possible (note: for convenience here we use a org.josql.filters.DefaultObjectFilter instance to do the heavy lifting for us). For example:
/**
 * Note: we assume here that the listener interface is called: ObjectListener
 * and events of type: ObjectEvent will be dispatched to the listener via a:
 * handleEvent method.
 *
 * The mechanism would be the same for ANY type of object used to capture
 * details about an "event".  
 *
 * It is also possible (of course) to create a configurable dispatcher that allows
 * configuration of the specific event method to be fired, but that is beyond the
 * scope of this discussion!
 */
public class RuleEventDispatcher 
{

   private Map listeners = new LinkedHashMap ();

   /**
    * The method needs to be synchronized because JoSQL query objects are
    * NOT thread-safe.
    *
    * @param o The event object.
    * @throws JoSQLExecutionException If the where clause cannot be evaluated against
    *                                 the event object.
    */
   public synchronized void fireEvent (ObjectEvent o)
                                       throws      JoSQLExecutionException
   {

       Iterator iter = this.listeners.keySet ().iterator ();

       while (iter.hasNext ())
       {

           ObjectListener ol = (ObjectListener) iter.next ();

           DefaultObjectFilter dof = (DefaultObjectFilter) this.listeners.get (ol);

           // See if the listener is interested in this event.
           if (dof.accept (o))
           {

               // Yes they are, send them the event.
               ol.handleEvent (o);

           } else {

               // See if an exception has occurred.
               if (dof.getException () != null)
               {

                  // Wrap the exception to provide more details.
                  JoSQLExecutionException ee = 
                     new JoSQLExecutionException ("Unable to execute WHERE clause for listener: " +
                                                  ol.getClass ().getName () + 
                                                  " against event: " +
                                                  o.getClass ().getName () + 
                                                  " using statement: " +
                                                  dof.getQuery (),
                                                  dof.getException ());

                  // Reset the exception.
                  dof.clearException ();

                  throw ee;

               }

           }

       }

   }

   public synchronized void addListener (ObjectListener o,
                                         String         whereClause)
                                         throws         JoSQLParseException
   {

      DefaultObjectFilter f = new DefaultObjectFilter (whereClause,
                                                       ObjectEvent.class);

      this.listeners.put (o,
                          f);
           
   }

   public synchronized void removeListener (ObjectListener o)
   {

       this.listeners.remove (o);

   }

}
If you wanted to get more flexible then you could always use java.util.EventObject instead and have an extra parm on the addListener method which specifies the specific sub-class of EventObject that will be used, or even just leave it at EventObject if that would be enough!