Wednesday, July 28, 2010

Cygwin: less reports WARNING: terminal is not fully functional

I have been using the "less" command Cygwin without problems for almost a year. For a new project I needed to have perl installed so I downloaed "Strawberry Perl" and installed it.

Afterwards, in cygwin everytime I tried to issue the "less" command it complained that the "terminal is not fully functional".

Turns out Strawberry perl was adding the environment variable TERM with a value of dumb.
Deleting the TERM fixed the issue.

Tuesday, July 27, 2010

inline elements and background-images

This dreaded issue has been looked at to death in so many forums, but in all my research I haven't found a working solution. In here, I wil describe a few solutions that worked for me but let's start with the basics first.

The issue that we're facing be described in detail here: http://www.maxdesign.com.au/articles/inline/

We are attaching a background-image to all elements that have the 'icon' attribute set. The advantage of doing this is that if we wanted to change a commonly used image, we'd only have to change it in one spot. Here's some of the code:


[icon] {
    padding-right: 20px;
    background: no-repeat center right;
}

[icon='required'] {
    background-image: url(../images/required.png);
}
[icon='toggle'] {
    background-image: url(../images/toggle.png);
}
[icon='addField'] {
    background-image: url(../images/add.png);
}
[icon='first'] {
    background-image: url(../images/btn_first.png);
}
[icon='last'] {
    background-image: url(../images/btn_last.png);
}
[icon='next'] {
    background-image: url(../images/btn_next.png);
}
[icon='prev'] {
    background-image: url(../images/btn_prev.png);
}

The image icon is visible in firefox, but not in IE 7. It's not at fault of IE (for once), because inline elements with padding on them has undefined behaviour and the CSS spec gives no details.


[icon] {
    padding-right: 20px;
    background: no-repeat center right;
}

We we're applying the icon attribute to Anchor elements as follows:

<a href="javascript:animatedcollapse.toggle('details')" icon="toggle" title="View Details"></a>


Solutions:

1) Adding a space

I stumbled upon this accidently while trying other possible solutions, and I haven't seen it documented anywhere else so it is worth mentioning. It's quite simple. If we add   inside the anchor element, then IE7 will display the icon correctly. The added side effect is that there will be a space. It works but then that means you have to add a silly   to all your elements.

2) Javascript/jQuery

The idea is to inspect all elements that have the icon attribute, and pull out the URL for the background-image and create a new element and assign the src attribute as follows:
<!--[if IE 7]>
    <script type="text/javascript">
    
        $(document).ready(function() 
        { 
        
            $("a[icon]").each(function() 
                    { 
                var iconUrl = $(this).css("background-image");
                iconUrl = iconUrl.replace(/"/g,"").replace(/url\(|\)$/ig, "");
                
                
                var imgEl = document.createElement('img');
                imgEl.src = iconUrl;
    
                $(this).css('icon','');
                this.removeAttribute("icon");
                
                $(this).append(imgEl);
                $(this).hover();
            }); 
        });
            
    </script>
<![endif]-->

It's not pretty, but if your project is already using jQuery and you have a template page, then you can add this to your template.

3)  Switching the CSS display property
 This is the best solution with the least amount code and less invasive. The idea is to trick IE 7 into using a display property of inline-block but then switching it back inline as follows:

[icon] {
    *display: inline-block;
}
[icon] {
    *display: inline;
    background: no-repeat right center;
    *position: absolute;
    padding-right: 20px;
}

The asteriks are IE 7 specific as mentioned here: http://css-tricks.com/how-to-create-an-ie-only-stylesheet/

maven eclipse:eclipse not adding aspectj jars to classpath

Normally when I want to add new JARs to my classpath in eclipse I execute the following maven command:

mvn eclipse:eclipse

However, when adding aspjectj libraries, the above command did not update my .classpath to inlucde aspectj.
I searched the web and found that I needed to add the following to my pom.xml file:


<!-- To allow aspectj jars be added to the classpath for eclipse-->    
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-eclipse-plugin</artifactId>
                <configuration>
                    <ajdtVersion>none</ajdtVersion>
                </configuration>
            </plugin>

Reference: http://maven.40175.n5.nabble.com/mvn-eclipse-eclipse-aspecjrt-not-added-to-classpath-td120235.html

Thursday, July 22, 2010

Hibernate count on superclass with discriminator

In Hibernate we can use discriminators to subclass from a common class. This is very helpful if we want to map common fields to different tables in the database.

For example, I have an abstract class called Gene. Now all organisms will have Genes, but if we want to differentiate the Gene based on the organism, we subclass Gene to make MouseGene and ZebrafishGene.


In the hibernate O/R mapping file we can have the following:



  <class name="au.edu.apf.phenomebank.strain.Gene" abstract="true" table="genes">
      
          <id name="id" type="java.lang.Long">
            <generator class="increment"/>
        </id>
      
        <!-- DISCRIMINATOR MUST COME IMMEDIATELY AFTER ID ELEMENT. AND SUBCLASS ELEMENTS MUST BE AT THE END !!! -->
        <discriminator column="gene_class" type="string" />      
      
          <property name="geneName" column="affected_gene_name" type="text" />
        <property name="symbol" column="affected_gene_symbol" type="text" />
        <property name="synonyms" type="text" />
        <property name="alleleName" column="allele_name" type="text" />
        <property name="alleleSymbol" column="allele_symbol" type="text" />
        <property name="alleleSynonyms" column="allele_synonyms" type="text" />
        
        <property name="proteinExpression" column="protein_expression" type="au.edu.apf.phenomebank.db.ProteinExpressionUserType" />
        <property name="microsatelliteMarkers" column="microsatellite_markers" type="text" />
        <property name="ensembl" column="ensembl" type="text" />
        <many-to-one name="mutationSequence" column="mutation_sequence_id" cascade="save-update" />
        <property name="geneticAlteration" column="genetic_alteration" type="text" />
        
        <property name="chromosomeLocation" column="chromosome_location" type="text"  />
        <property  name="locationOnChr" column="location_on_chr" type="text" />
        
        <!-- ALL SUBCLASS ELEMENTS MUST BE AFTER PROPERTY ELEMENTS. ORDERING IS VERY IMPORTANT !!! --> 
        <subclass name="au.edu.apf.phenomebank.db.mouse.MouseGene" discriminator-value="mouse">
            <property name="mgiGeneAccessionId" column="MGI_gene_accession_id" type="text" />
            <property name="mgiGeneAccessionIdUrl" column="MGI_gene_accession_id_url" type="text" />
            <property name="mgiAlleleAccessionId" column="MGI_allele_accession_id" type="text" />
            <property name="mgiAlleleAccessionIdUrl" column="MGI_allele_accession_id_url" type="text" />    
        </subclass>         
        
  </class>


  <class name="au.edu.apf.phenomebank.strain.ZebrafishGene" table="zebrafish_genes">
      
          <id name="id" type="java.lang.Long">
            <generator class="increment"/>
        </id>
      
        <!-- DISCRIMINATOR MUST COME IMMEDIATELY AFTER ID ELEMENT. AND SUBCLASS ELEMENTS MUST BE AT THE END !!! -->
        <discriminator column="gene_class" type="string" />      
      
          <property name="geneName" column="affected_gene_name" type="text" />
        <property name="symbol" column="affected_gene_symbol" type="text" />
        <property name="synonyms" type="text" />
        <property name="alleleName" column="allele_name" type="text" />
        <property name="alleleSymbol" column="allele_symbol" type="text" />
        <property name="alleleSynonyms" column="allele_synonyms" type="text" />
        
        <property name="proteinExpression" column="protein_expression" type="au.edu.apf.phenomebank.db.ProteinExpressionUserType" />
        <property name="microsatelliteMarkers" column="microsatellite_markers" type="text" />
        <property name="ensembl" column="ensembl" type="text" />
        <many-to-one name="mutationSequence" column="mutation_sequence_id" cascade="save-update" />
        <property name="geneticAlteration" column="genetic_alteration" type="text" />
        
        <property name="chromosomeLocation" column="chromosome_location" type="text"  />
        <property  name="locationOnChr" column="location_on_chr" type="text" />
        
        <!-- ALL SUBCLASS ELEMENTS MUST BE AFTER PROPERTY ELEMENTS. ORDERING IS VERY IMPORTANT !!! --> 
        <subclass name="au.edu.apf.phenomebank.db.zebrafish.ZebrafishGene" discriminator-value="zebrafish">
            <property name="zebrafishProperty" column="MGI_gene_accession_id" type="text" />
        </subclass>         
        
  </class>    




Now in Hibernate, if you performed a count using the following HQL call:
String sql = "SELECT COUNT(DISTINCT g.geneName) FROM "+Gene.class.getSimpleName()+ " g"; 
List list = getHibernateTemplate().find(sql); 

This will actually return a count of all the distinct gene names from both MouseGene table and Zebrafish Gene table where each column of the returned result represents a count from each table. This is because we are searching based on the abstract class Gene, and Hibernate is smart enough to search all subclasses.

Now if you want to only search on the one table then you have to specify the subclass as follows:


String sql = "SELECT COUNT(DISTINCT g.geneName) FROM "+MouseGene.class.getSimpleName()+ " g";