JSP Help Icon Tag

public class HelpIconTag extends TagSupport {
    
    private String key;
    public void setKey(String key) {
        this.key = key;
    }

    private String position = "";
    public void setPosition(String position) {
        this.position = position;
    }
    
    private int level = 1;
    public void setLevel(int level) {
        this.level = level;
    }
    
    @Override
    public int doStartTag() throws JspException {
        try {
            ServiceContainer services = (ServiceContainer) pageContext.getRequest().getAttribute(Key.SERVICES);
            TenantSettings settings = null;
            if(services.tenant != null ) {
                settings = services.tenant.getSettings();
            }
            if(settings == null || settings.getHelpId() == null || settings.getHelpId().intValue() <= level) {
                JspWriter out = pageContext.getOut();
                String helpString = services.cmsService.getHelp(key);
                if(helpString == null || helpString.isEmpty()) {
                    helpString = key + "Help";
                }
                out.print("");
            }
        } catch (Exception ioe) {
            ioe.printStackTrace();
        }
        return SKIP_BODY;
    }

    @Override
    public int doEndTag() throws JspException {
        return EVAL_PAGE;
    }
}
Advertisements

jQuery Dialog Utility

Ever have a web interface that requires a lot of dialog popup windows?  I came up with this JavaScript utility class to help me create, show, and delete dialog boxes.  I also added a confirmation dialog box method and a simple message method.

var Dialog = {
    dialogId: 'dialogBox',
    createDialog: function(id, width, height) {
        jQuery('body').append("");
        var buttons = {};
        jQuery('#' + id).dialog({
            width: width,
            height: height,
            position: ['center', 50],
            autoOpen: false,
            resizable: false,
            modal: true,
            close: function(event, ui) {
                Dialog.closeDialog(id);
            },
            buttons: buttons
        });
    },
    closeDialog: function(id) {
        jQuery('#' + id).dialog('destroy');
        jQuery('#' + id).remove();
    },
    showConfirm: function(message, width, callback, callbackArgs) {
        if(!width) {
            width = 200;
        }
        // Setup Dialog Box
        jQuery('body').append("");
        jQuery('#' + Dialog.dialogId).dialog({
            width: width + 'px',
            autoOpen: false,
            resizable: false,
            hide: "fade",
            modal: true,
            close: function(event, ui) {
                jQuery('#' + Dialog.dialogId).dialog('destroy');
                jQuery('#' + Dialog.dialogId).remove();
            },
            buttons: {
                Cancel: function() {
                    jQuery(this).dialog("close");
                },
                Yes: function() {
                    callback(callbackArgs);
                    jQuery(this).dialog("close");
                }
            }
        });
        jQuery('#' + Dialog.dialogId).dialog('open');
    },
    showMessage: function(message, width, closeTime) {
        if(!width) {
            width = 400;
        }
        // Setup Dialog Box
        jQuery('body').append("");
        jQuery('#' + Dialog.dialogId).dialog({
            width: width + 'px',
            autoOpen: false,
            resizable: false,
            position: ['center', 300],
            hide: "fade",
            modal: true,
            close: function(event, ui) {
                jQuery('#' + Dialog.dialogId).dialog('destroy');
                jQuery('#' + Dialog.dialogId).remove();
            },
            buttons: {
                Ok: function() {
                    jQuery(this).dialog("close");
                }
            }
        });
        jQuery('#' + Dialog.dialogId).dialog('open');
        if(closeTime) {
            setTimeout("jQuery('#" + Dialog.dialogId + "').dialog('close')", closeTime);
        }
    }
};

jQuery Calendar alternative to Google Calendar

Need a fancy calendar that has similar features to Google Calendar?  The FullCalendar jQuery plugin will give you a good start.  Within a fair amount of time I was able to make it do the following:

  • Ajax load calendar items when the calendar range changed
  • Load in public Google Calendar events
  • Show and hide holidays
  • Update items on drag, drop, and resize events on the calendar items

Here’s how it looks in ShelfReliancePro:

calendar

Geolocating and Mapping Points with Nominatim and Leaflet

I wanted to add a map feature to http://www.shelfreliancepro.com but had no budget to pay for map apis or libraries. The solution I found was http://nominatim.openstreetmap.org and http://leafletjs.com/.  Nominatim allows you to do all kind of geo-locating, address queries, and location queries.  Leaflet is a simple map interface for plotting points.  Leaflet works very well on mobile devices.

When users would update or add an address to the system, I would mark the address so I knew it needed to have it’s latitude and longitude updated via nominatim.  I run a scheduled task every 10 minutes to find addresses that need an update and update them.

Here’s how it turned out:

map

Magento – Resource is not set

After being stumped for a little while and not finding any solutions by googling, I write these blog posts to share my findings. In order for a Magento model to find it’s resource, the config.xml and constructors with the init method are both needed. The name of the magento module in the init methods needs to match for the model to find it’s resource.

class Company_Mymodule_Model_Mysql4_Myentity extends Mage_Core_Model_Mysql4_Abstract {
public function _construct() {
$this->_init(‘mymodule/myentity’, ‘entity_id’);
}
}

class Company_Mymodule_Model_MyEntity extends Mage_Core_Model_Abstract {
public function _construct() {
parent::_construct();
$this->_init(‘mymodule/myentity’);
}
}

config.xml

Company_Mymodule_Model
mymodule_mysql4

Company_Mymodule_Model_Mysql4

my_entity

Convert MySQL Tables and Columns to UTF-8

If you are like me and have never had experience with an internationalized website before, you probably setup your mysql database with the default latin character set and already have a ton of data in it. Luckily all the data in my app was latin and we had not ventured into Spanish or Japanese yet so my varchar and text fields were all in normal ascii latin characters that converted perfectly to UTF-8.

I found this bash script to work great:
mysql --database=dbname -B -N -e "SHOW TABLES" | awk '{print "ALTER TABLE", $1, "CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;"}' | mysql --database=dbname &

I did some research and found that utf8_general_ci is a legacy version that is slightly faster, but utf8_unicode_ci is the more robust collation.

Here’s the script’s source:
http://www.commandlinefu.com/commands/view/1575/convert-all-mysql-tables-and-fields-to-utf8

Not only did it convert the table default to UTF-8, but it also converted my varchar and text fields to that charset and collation as well.

I tried the following mysql conf settings with my Percona database:

[mysqld]
collation-server = utf8_unicode_ci
init-connect='SET NAMES utf8'
character-set-server = utf8
skip-character-set-client-handshake

Java OutOfMemoryError

On a machine with memory issues my Java app kept crashing due to an OutOfMemoryError:
Exception in thread “Thread-1” java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:657)

I started logging thread counts and memory usages and neither one was increasing/leaking. I tried to catch the ‘Exception’ as it was claiming but the app would still fail.

Finally I read the javadoc on the java.lang.OutOfMemoryError and discovered that the error inherits from Error and Throwable rather than Exception so I was not able to catch it. Catching the Throwable allowed me to keep my app going.

http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/OutOfMemoryError.html