edu.toronto.cs.phenotips.measurements.MeasurementsScriptService.java Source code

Java tutorial

Introduction

Here is the source code for edu.toronto.cs.phenotips.measurements.MeasurementsScriptService.java

Source

/*
 * See the NOTICE file distributed with this work for additional
 * information regarding copyright ownership.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */
package edu.toronto.cs.phenotips.measurements;

import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;

import javax.inject.Inject;
import javax.inject.Named;
import javax.inject.Provider;
import javax.inject.Singleton;

import org.apache.commons.lang3.ArrayUtils;
import org.slf4j.Logger;
import org.xwiki.component.annotation.Component;
import org.xwiki.component.manager.ComponentLookupException;
import org.xwiki.component.manager.ComponentManager;
import org.xwiki.script.service.ScriptService;

import edu.toronto.cs.phenotips.measurements.internal.AbstractMeasurementHandler;

/**
 * Bridge offering access to specific {@link MeasurementHandler measurement handlers} to scripts.
 * 
 * @version $Id: aa7bedfb7907f8b4bc7ad5472cdb677e7d8b7cef $
 * @since 1.0M3
 */
@Component
@Named("measurements")
@Singleton
public class MeasurementsScriptService implements ScriptService {
    /** Fuzzy value representing a measurement value considered extremely below normal. */
    private static final String VALUE_EXTREME_BELOW_NORMAL = "extreme-below-normal";

    /** Fuzzy value representing a measurement value considered below normal, but not extremely. */
    private static final String VALUE_BELOW_NORMAL = "below-normal";

    /** Fuzzy value representing a measurement value considered normal. */
    private static final String VALUE_NORMAL = "normal";

    /** Fuzzy value representing a measurement value considered above normal, but not extremely. */
    private static final String VALUE_ABOVE_NORMAL = "above-normal";

    /** Fuzzy value representing a measurement value considered extremely above normal. */
    private static final String VALUE_EXTREME_ABOVE_NORMAL = "extreme-above-normal";

    /** Logging helper object. */
    @Inject
    private Logger logger;

    /** Provides access to the different measurement handlers by name at runtime. */
    @Inject
    @Named("context")
    private Provider<ComponentManager> componentManager;

    /**
     * Get the handler for a specific kind of measurements.
     * 
     * @param measurementType the type of measurement to return
     * @return the requested handler, {@code null} if not found
     */
    public MeasurementHandler get(String measurementType) {
        try {
            return this.componentManager.get().getInstance(MeasurementHandler.class, measurementType);
        } catch (ComponentLookupException ex) {
            this.logger.warn("Requested unknown measurement type [{}]", measurementType);
            return null;
        }
    }

    /**
     * Get all the measurements handlers.
     * 
     * @return a list of all the measurement handlers, or an empty list if there was a problem retrieving the actual
     *         list
     */
    public List<MeasurementHandler> getAvailableMeasurementHandlers() {
        try {
            List<MeasurementHandler> result = this.componentManager.get().getInstanceList(MeasurementHandler.class);
            if (result == null) {
                result = Collections.emptyList();
            }
            Collections.sort(result, MeasurementSorter.instance);
            return result;
        } catch (ComponentLookupException ex) {
            this.logger.warn("Failed to list available measurements", ex);
            return Collections.emptyList();
        }
    }

    /**
     * Get the names of all the measurements handlers.
     * 
     * @return a set with the names of all the measurement handlers, or an empty set if there was a problem retrieving
     *         the actual values
     */
    public Set<String> getAvailableMeasurementNames() {
        try {
            Map<String, MeasurementHandler> handlers = this.componentManager.get()
                    .getInstanceMap(MeasurementHandler.class);
            if (handlers != null) {
                Set<String> result = new TreeSet<String>(MeasurementNameSorter.instance);
                result.addAll(handlers.keySet());
                return result;
            }
        } catch (ComponentLookupException ex) {
            this.logger.warn("Failed to list available measurement types", ex);
        }
        return Collections.emptySet();
    }

    /**
     * Convert a percentile number into a string grossly describing the value.
     * 
     * @param percentile a number between 0 and 100
     * @return the percentile description
     */
    public String getFuzzyValue(int percentile) {
        String returnValue = VALUE_NORMAL;
        if (percentile <= 1) {
            returnValue = VALUE_EXTREME_BELOW_NORMAL;
        } else if (percentile <= 3) {
            returnValue = VALUE_BELOW_NORMAL;
        } else if (percentile >= 99) {
            returnValue = VALUE_EXTREME_ABOVE_NORMAL;
        } else if (percentile >= 97) {
            returnValue = VALUE_ABOVE_NORMAL;
        }
        return returnValue;
    }

    /**
     * Convert a standard deviation number into a string grossly describing the value.
     * 
     * @param deviation standard deviation value
     * @return the deviation description
     */
    public String getFuzzyValue(double deviation) {
        String returnValue = VALUE_NORMAL;
        if (deviation <= -3.0) {
            returnValue = VALUE_EXTREME_BELOW_NORMAL;
        } else if (deviation <= -2.0) {
            returnValue = VALUE_BELOW_NORMAL;
        } else if (deviation >= 3.0) {
            returnValue = VALUE_EXTREME_ABOVE_NORMAL;
        } else if (deviation >= 2.0) {
            returnValue = VALUE_ABOVE_NORMAL;
        }
        return returnValue;
    }

    /**
     * Temporary mechanism for sorting measurements, uses a hardcoded list of measurements in the desired order.
     *
     * @version $Id: aa7bedfb7907f8b4bc7ad5472cdb677e7d8b7cef $
     */
    private static final class MeasurementSorter implements Comparator<MeasurementHandler> {
        /** Hardcoded list of measurements and their order. */
        private static final String[] TARGET_ORDER = new String[] { "weight", "height", "bmi", "armspan", "sitting",
                "hc", "philtrum", "ear", "ocd", "icd", "pfl", "ipd", "hand", "palm", "foot" };

        /** Singleton instance. */
        private static MeasurementSorter instance = new MeasurementSorter();

        @Override
        public int compare(MeasurementHandler o1, MeasurementHandler o2) {
            String n1 = ((AbstractMeasurementHandler) o1).getName();
            String n2 = ((AbstractMeasurementHandler) o2).getName();
            int p1 = ArrayUtils.indexOf(TARGET_ORDER, n1);
            int p2 = ArrayUtils.indexOf(TARGET_ORDER, n2);
            if (p1 == -1 && p2 == -1) {
                return n1.compareTo(n2);
            } else if (p1 == -1) {
                return 1;
            } else if (p2 == -1) {
                return -1;
            }
            return p1 - p2;
        }
    }

    /**
     * Temporary mechanism for sorting measurements, uses a hardcoded list of measurements in the desired order.
     *
     * @version $Id: aa7bedfb7907f8b4bc7ad5472cdb677e7d8b7cef $
     */
    private static final class MeasurementNameSorter implements Comparator<String> {
        /** Singleton instance. */
        private static MeasurementNameSorter instance = new MeasurementNameSorter();

        @Override
        public int compare(String n1, String n2) {
            int p1 = ArrayUtils.indexOf(MeasurementSorter.TARGET_ORDER, n1);
            int p2 = ArrayUtils.indexOf(MeasurementSorter.TARGET_ORDER, n2);
            if (p1 == -1 && p2 == -1) {
                return n1.compareTo(n2);
            } else if (p1 == -1) {
                return 1;
            } else if (p2 == -1) {
                return -1;
            }
            return p1 - p2;
        }
    }
}