views:

36

answers:

1

For a page that displays product information, we have to select the best product image from a set of images that show the same content, but have different formats (gif, png, jpg, etc.), different quality (jpeg comrpession), different sizes (thumbnails, small, medium, big) etc.

The choice depends on the user's browser, current size of page, purpose of the image, etc.

Our current solution is to build an sql query according to the current requirements that might look like this:

SELECT img.id 
FROM img 
WHERE img.format IN ('GIF','JPG') 
AND img.width <= 1000
ORDER BY img.quality DESC

This is a simplyfied example, the original is much more complex. The java code that creates this statement uses a lot of ifs and cases and is starting to grow very ugly.

What is the best way to implement such a heuristic in Java? Is there any library that could help? Maybe along the lines of defining rule objects:

Engine engine = new Engine();
engine.addRule(new IncludeRule("format", {"GIF", "JPG"}));//only gif and jpg
engine.addRule(new MaxRule("width", 1000));//max width
engine.addRule(new WeightedRule("quality", DESC));//go for high quality
Image result = engine.getResult();

I searched for Rule Engine, and there even is a JSR and some open source rule engines, but they seem to be all dealing with Buissness rules.

I have the strong feeling that we are reinventing the wheel, and that we simply can't find any solution because we don't know the right name for this stuff ;-)

Any help would be greatly appreciated!

A: 

If you're just building a SQL query you could probably build the engine yourself:

public interface Rule{
    String getSQLWhereClause();
    String getSQLOrderClause();
}

public class Engine
{
    String buildSQLFromRules(Collection<Rule> rules) {
        String s = "SELECT IMG.ID FROM IMG";
        String w = "";
        String o = "";

        for(Rule r : rules)
        {
             if (r.getSQLWhereClause() != null) {
                 if (!w.isEmpty()) { w = w + " AND " }

                  w += r.getSQLWhereClause()
             }
             ... same for order
         }

         return s + (w.isEmpty()? "" : " WHERE " + w) + (o.isEmpty()?"": " ORDER BY " + o);
      }
 }

Then you can just define the interfaces as:

 public class MaxRule implements Rule
 {
       String fld;
       String max;

       public MaxRule() { ... }

       String getSQLWhereClause() { return "img." + fld + " <= " + max; }
       String getSQLOrderClause() { return null; }
 }
AdamH