001    package jcolibri.method.retrieve.NNretrieval.similarity.local;
002    
003    
004    
005    import jcolibri.method.retrieve.NNretrieval.similarity.LocalSimilarityFunction;
006    
007    
008    /**
009     * This function returns the similarity of two enum values as the their distance
010     * sim(x,y)=|ord(x) - ord(y)|
011     * 
012     * @author Juan A. Recio-García
013     */
014    public class EnumDistance implements LocalSimilarityFunction {
015    
016            /**
017             * Applies the similarity function.
018             * 
019             * @param o1
020             *            StringEnum or String
021             * @param o2
022             *            StringEnum or String
023             * @return the result of apply the similarity function.
024             */
025            public double compute(Object o1, Object o2) throws jcolibri.exception.NoApplicableSimilarityFunctionException{
026                    if ((o1 == null) || (o2 == null))
027                            return 0;
028                    if(!(o1 instanceof Enum))
029                            throw new jcolibri.exception.NoApplicableSimilarityFunctionException(this.getClass(), o1.getClass());
030                    if(!(o2 instanceof Enum))
031                            throw new jcolibri.exception.NoApplicableSimilarityFunctionException(this.getClass(), o2.getClass());
032                    
033                    Enum e1 = (Enum)o1;
034                    Enum e2 = (Enum)o2;
035                    
036                    double size = e1.getDeclaringClass().getEnumConstants().length;
037                    double diff = Math.abs(e1.ordinal() - e2.ordinal());
038                    
039                    return 1 - (diff / size);
040            }
041    
042            /** Applicable to Enum */
043            public boolean isApplicable(Object o1, Object o2)
044            {
045                    if((o1==null)&&(o2==null))
046                            return true;
047                    else if(o1==null)
048                            return o2 instanceof Enum;
049                    else if(o2==null)
050                            return o1 instanceof Enum;
051                    else
052                            return (o1 instanceof Enum)&&(o2 instanceof Enum);
053            }
054    
055    }