org.squale.squaleweb.util.SqualeWebActionUtils.java Source code

Java tutorial

Introduction

Here is the source code for org.squale.squaleweb.util.SqualeWebActionUtils.java

Source

/**
 * Copyright (C) 2008-2010, Squale Project - http://www.squale.org
 *
 * This file is part of Squale.
 *
 * Squale 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 3 of the
 * License, or any later version.
 *
 * Squale 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 General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public License
 * along with Squale.  If not, see <http://www.gnu.org/licenses/>.
 */
package org.squale.squaleweb.util;

import java.lang.reflect.Method;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Collection;
import java.util.Date;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.squale.squalecommon.enterpriselayer.businessobject.component.AuditBO;
import org.squale.squalecommon.enterpriselayer.businessobject.result.ErrorBO;
import org.squale.squalecommon.enterpriselayer.businessobject.result.MarkBO;
import org.squale.squalecommon.util.ConstantRulesChecking;
import org.squale.squaleweb.resources.WebMessages;

/**
 * Fournit des fonctionnalits utiles  plusieurs actions.
 * 
 * @author M400842
 */
public class SqualeWebActionUtils {
    /**
     * Logger
     */
    private static Log log = LogFactory.getLog(SqualeWebActionUtils.class);

    /**
     * Images en fonction de la note 0..3
     */
    public static final String[] IMG = { "images/pictos/bad.png", "images/pictos/good.png",
            "images/pictos/best.png", "images/pictos/super.png", "images/pictos/na.gif" };

    /**
     * Constante "-" pour l'affichage
     */
    public static final String DASH = "-";

    /**
     * dfini une valeur de seuil significatif pour une variation de la tendance de constante  un peux mieux Tant que
     * la variation de la note est en dessous de ce seuil, on considre qu'il n'y a pas eu d'volution
     */
    private final static float BETTER = 0.05f;

    /**
     * dfini une valeur de seuil significatif pour une variation de la tendance de constante  beaucoup mieux
     */
    private final static float MUCH_BETTER = 0.3f;

    /**
     * @param currentMark la note courante
     * @param predecessorMark la note prcdente
     * @return l'image reprsentant l'volution entre currentMark et predecessorMark
     */
    public static String getImageForTrend(String currentMark, String predecessorMark) {
        String result = "images/pictos/na.gif";
        // Dans ce cas, c'est simple: il n'y a pas eu d'volution
        // la note prcdente peut etre null ou initialise  la chaine vide (pour le form)
        if (isValidMark(currentMark) && isValidMark(predecessorMark)) {
            float diff = Float.parseFloat(currentMark.replace(',', '.'))
                    - Float.parseFloat(predecessorMark.replace(',', '.'));
            if (Math.abs(diff) < BETTER) {
                // l'volution n'est pas significative, flche constante
                result = "images/pictos/ar_blueAF.gif";
            } else if (Math.abs(diff) < MUCH_BETTER) {
                // changement peu significatif
                if (diff < 0) { // lgre dgradation
                    result = "images/pictos/ar_blueAF_RD.gif";
                } else { // lgre amlioration
                    result = "images/pictos/ar_blueAF_RU.gif";
                }
            } else {
                if (diff < 0) { // dgradation significative
                    result = "images/pictos/ar_blueAF_D.gif";
                } else { // amlioration significative
                    result = "images/pictos/ar_blueAF_U.gif";
                }
            }
        }
        return result;
    }

    /**
     * Affiche l'image.
     * 
     * @param pNote la note.
     * @param pRequest la requte
     * @return le chemin de l'image
     */
    public static String generatePictoWithTooltip(String pNote, HttpServletRequest pRequest) {
        // On rcupre l'index en fonction de la note tronque.
        int imgIndex = generatePicto(pNote);
        String pictureHelp = WebMessages.getString(pRequest, "project.results.mark.status_" + imgIndex);
        if (imgIndex != IMG.length - 1) {
            int imgIndexRound = Integer.parseInt(formatFloat(pNote).substring(0, 1));
            if (imgIndexRound > imgIndex) {
                pictureHelp += " ("
                        + WebMessages.getString(pRequest, "project.results.mark.nearly.status_" + imgIndexRound)
                        + ")";
            }
        }
        // on remplace ' par \' pour le javascript
        return "<img src=\"" + IMG[imgIndex] + "\"title=\"" + pictureHelp.replaceAll("'", "\\\\'")
                + "\" border=\"0\" />";
    }

    /**
     * Rcupre le pictogramme associ  une note
     * 
     * @param pNote la note.
     * @return le chemin de l'image
     */
    public static int generatePicto(String pNote) {
        // initialisation  l'image Na par dfaut
        int i = IMG.length - 1;
        // Vrification simpliste de la note pour viter des exceptions
        // lors de sa conversion
        Float currentMark;
        if (isValidMark(pNote)) {
            i = Integer.parseInt(truncFloat(pNote).substring(0, 1));
            i = (i > IMG.length - 1 ? IMG.length - 1 : i);
        }
        return i;
    }

    /**
     * @param aFloat la note sous forme de String  tronquer
     * @return la note sous sa forme flottante en la tronquant  un chiffre aprs la virgule
     */
    private static String truncFloat(String aFloat) {
        final int toTrunc = 10;
        String result = DASH;
        float mark = stringToFloat(aFloat);
        if (mark != MarkBO.NOT_NOTED_VALUE) {
            // on tronque et garde que un chiffre aprs la virgule.
            mark = mark * toTrunc;
            mark = (int) mark;
            result = "" + mark / toTrunc;
        }
        return result;
    }

    /**
     * @param pNote La note de 0  3 ou non valide (i.e vide (?))
     * @return un boolean indiquant que la chaine est bien une note (non vide)
     */
    public static boolean isValidMark(String pNote) {
        return pNote != null && pNote.length() > 0 && Character.isDigit(pNote.charAt(0));
    }

    /**
     * @param aFloat le float  formatter
     * @return le float arrondi  un chiffre aprs la virgule ou "-" si la chaine ne peut pas etre correctement formate
     */
    public static String formatFloat(String aFloat) {
        String result = DASH;
        float mark = stringToFloat(aFloat);
        if (mark != MarkBO.NOT_NOTED_VALUE) {
            // on ne garde que un chiffre aprs la virgule.
            result = formatFloat(mark);
        }
        return result;
    }

    /**
     * @param aFloat la note sous forme de String
     * @return la note sous sa forme flottante en l'arrondissant  un chiffre aprs la virgule
     */
    private static float stringToFloat(String aFloat) {
        float result = MarkBO.NOT_NOTED_VALUE;
        if (isValidMark(aFloat)) {
            // Remplacement du "." par une ","
            result = Float.parseFloat(aFloat.replace(',', '.'));
        }
        return result;
    }

    /**
     * Factorisation de code, aucun test n'est fait
     * 
     * @param pFloat le float  formater
     * @return la chaine associe au float
     */
    private static String formatFloat(float pFloat) {
        NumberFormat nf = NumberFormat.getInstance();
        nf.setMaximumFractionDigits(1);
        nf.setMinimumFractionDigits(1);
        String result = nf.format(pFloat);
        return result;
    }

    /**
     * @param aFloat le nombre  formatter
     * @return le float formatt en String avec un chiffre aprs la virgule
     */
    public static String formatFloat(Float aFloat) {
        String result = DASH;
        if (aFloat != null && aFloat.floatValue() != MarkBO.NOT_NOTED_VALUE) {
            result = formatFloat(aFloat.floatValue());
        }
        return result;
    }

    /**
     * Donne une valeur  un attribut de l'objet.<br>
     * La classe de l'objet doit avoir le setter associ au nom de l'attribut : setMonAttribut et doit prendre une
     * String en paramtre.
     * 
     * @param pObject l'objet  remplir.
     * @param pSetterName le nom du setter de l'attribut.
     * @param pValue la nouvelle valeur de l'attribut.
     */
    public static void setValue(final Object pObject, final String pSetterName, final String pValue) {
        Class[] paramsType = { String.class };
        try {
            // Obtention de la mthode
            Method setter = pObject.getClass().getMethod(pSetterName, paramsType);
            Object[] params = { null };
            // Vrification du type de chane
            // TODO voir si le test sur un nombre est pertinent - redondance entre la regexp et le parseInt
            if (null != pValue && ((pValue.matches("-?[0-9]*") && Integer.parseInt(pValue) != -1)
                    || !pValue.matches("-?[0-9]*"))) {
                params[0] = pValue;
            }
            setter.invoke(pObject, params);
        } catch (Exception e) {
            log.error(e, e);
        }
    }

    /**
     * Remplit le bean pass en paramtre avec les valeurs donnes.
     * 
     * @param pBean le bean  remplir.
     * @param pAttributes la liste ordonne des attributs (String).
     * @param pValues la liste ordonne des valeurs (String).
     * @param pMessages prcise si les nom des attributs sont des cls  rsoudre, ils sont alors suffixs de
     *            ".attribute".
     */
    public static void fullFillBean(final Object pBean, final List pAttributes, final List pValues,
            final boolean pMessages) {
        String attributeName = null;
        String setterName = null;
        for (int i = 0; null != pBean && i < pAttributes.size(); i++) {
            if (pMessages) {
                attributeName = WebMessages.getString((String) pAttributes.get(i) + ".attribute");
            } else {
                attributeName = (String) pAttributes.get(i);
            }
            setterName = "set" + attributeName.substring(0, 1).toUpperCase() + attributeName.substring(1);
            setValue(pBean, setterName, (String) pValues.get(i));
        }
    }

    /**
     * Retourne une liste htrogne sous la forme d'une liste de String.
     * 
     * @param pList la liste  transformer.
     * @return une liste de String.
     */
    public static List getAsStringsList(final List pList) {
        LinkedList result = null;
        if (null != pList) {
            result = new LinkedList();
            Iterator it = pList.iterator();
            Object value = null;
            // Parcours de la collection et conversion de chaque valeur
            while (it.hasNext()) {
                value = it.next();
                if (null != value) {
                    // Conversion spcifique pour un nombre flottant
                    if (value.getClass().equals(Float.class)) {
                        result.addLast(formatFloat((Float) value));
                    } else {
                        result.addLast(value.toString());
                    }
                } else {
                    // On conserve la valeur null initiale
                    result.addLast(null);
                }
            }
        }
        return result;
    }

    /**
     * Equivalent de la fonction sprintf du C.<br>
     * Ne fonctionne que pour les %s, puisque les paramtres sont des String.
     * 
     * @param pString la chaine  complter.
     * @param pValue la liste des valeurs  affecter.
     * @return la chane complte.
     */
    public static String sprintf(final String pString, final String[] pValue) {
        String result = pString;
        for (int i = 0; i < pValue.length; i++) {
            result.replaceFirst("%s", pValue[i]);
        }
        return result;
    }

    /**
     * Retourne une chaine formattant la date.
     * 
     * @param pDate la date  formatter.
     * @param lang langue d'affichage
     * @return une chaine reprsantant le date.
     */
    public static String getFormattedDate(Date pDate, Locale lang) {
        DateFormat df = DateFormat.getDateInstance(DateFormat.LONG, lang);
        return df.format(pDate);
    }

    /**
     * Retourne la date d'aujourd'hui selon le format dfini par la cl.
     * 
     * @param lang langue d'affichage
     * @param formatKey la cl du fichier de properties dfinissant le format de la date
     * @return une chaine reprsantant le date.
     */
    public static String getTodayDate(Locale lang, String formatKey) {
        Calendar today = Calendar.getInstance();
        return getFormattedDate(lang, today.getTime(), formatKey);
    }

    /**
     * Retourne la date formate selon le format dfini par la cl.
     * 
     * @param lang langue d'affichage
     * @param pDate la date  formater
     * @param formatKey la cl du fichier de properties dfinissant le format de la date
     * @return une chaine reprsantant le date.
     */
    public static String getFormattedDate(Locale lang, Date pDate, String formatKey) {
        SimpleDateFormat sdf = new SimpleDateFormat(WebMessages.getString(lang, formatKey), lang);
        return sdf.format(pDate);
    }

    /**
     * Suffixe toutes les valeurs du tableau.
     * 
     * @param pArray le tableau  transformer.
     * @param pSuffix la suffixe  ajouter.
     * @param pKey prcise si les valeurs suffixs sont des cls, auquel cas elles sont remplaces par les valeurs
     *            associes.
     * @return un tableau de la mme taille avec les valeurs suffixs.
     */
    public static String[] suffixString(final String[] pArray, final String pSuffix, boolean pKey) {
        String[] result = new String[pArray.length];
        for (int i = 0; i < pArray.length; i++) {
            if (pKey) {
                result[i] = WebMessages.getString(pArray[i] + pSuffix);
            } else {
                result[i] = pArray[i] + pSuffix;
            }
        }
        return result;
    }

    /**
     * Obtention de l'image associe  un niveau d'erreur
     * 
     * @param pErrorLevel le niveau d'erreur
     * @return image correspondante au niveau d'erreur
     */
    public static String getImageForErrorLevel(String pErrorLevel) {
        String result;
        if (pErrorLevel.equals(ErrorBO.CRITICITY_FATAL)) {
            result = "images/pictos/error.png";
        } else if (pErrorLevel.equals(ErrorBO.CRITICITY_WARNING)) {
            result = "images/pictos/warning.png";
        } else {
            result = "images/pictos/info.png";
        }
        return result;
    }

    /**
     * Obtention de l'image associe  la svrit de la rgle
     * 
     * @param pSeverity la svrit
     * @return image correspondante  la svrit
     */
    public static String getImageForRuleSeverity(String pSeverity) {
        String result;
        if (pSeverity.equals(ConstantRulesChecking.ERROR_LABEL)) {
            result = "images/pictos/error.png";
        } else if (pSeverity.equals(ConstantRulesChecking.WARNING_LABEL)) {
            result = "images/pictos/warning.png";
        } else {
            result = "images/pictos/info.png";
        }
        return result;
    }

    /**
     * Retourne le contenu de pValues sans les valeurs vides.
     * 
     * @param pValues la tableau des valeurs  nettoyer
     * @return un tableau de String propre
     */
    public static String[] cleanValues(final String[] pValues) {
        String[] result = null;
        // Nettoyage des noms
        ArrayList temp = new ArrayList();
        for (int i = 0; i < pValues.length; i++) {
            if (pValues[i].trim().length() > 0) {
                temp.add(pValues[i]);
            }
        }
        String[] type = new String[0];
        result = (String[]) temp.toArray(type);
        return result;
    }

    /**
     * @param pRequest la requete http
     * @return le formatter de nombre correspondant  la locale
     */
    public static NumberFormat getNumberFormat(HttpServletRequest pRequest) {
        NumberFormat formatter = null;
        try {
            // En anglais par dfaut
            formatter = (DecimalFormat) DecimalFormat.getInstance();
            // Si c'est en francais , on n'affiche pas les "," pour sparer les chiffres
            if (pRequest.getLocale().getLanguage().equals(Locale.FRENCH.toString())) {
                ((DecimalFormat) formatter).setGroupingUsed(false);
            }
        } catch (NumberFormatException nfe) {
            // en cas de problme rencontr, on renvoie le formatter par dfaut
            formatter = NumberFormat.getInstance();
        }
        return formatter;
    }

    /**
     * @param pStrings la liste de String
     * @param pSeparator le sparateur
     * @return la string reprsentant le tableau dont les lement sont spars pas <code>separator</code>
     */
    public static String formatArray(Collection pStrings, String pSeparator) {
        String result = "";
        for (Iterator it = pStrings.iterator(); it.hasNext();) {
            result += (String) it.next();
            if (it.hasNext()) {
                result += pSeparator;
            }
        }
        return result;
    }

    /**
     * Permet d'aller  la ligne dans un menu pour pouvoir afficher le nom en entier au lieu qu'il soit tronqu car la
     * charte graphique impose une taille fixe
     * 
     * @param pItem l'item a couper
     * @return l'item avec des '\n' tous les n caractres
     */
    public static String formatStringForMenuItem(String pItem) {
        final int MAX_CHAR = 26; // Nombre de caractres qu'on suppose affichable
        StringBuffer result = new StringBuffer(pItem);
        int nbInsertion = result.length() / MAX_CHAR;
        for (int i = 1; i <= nbInsertion; i++) {
            result.insert(i * MAX_CHAR, "... "); // On dcale de 3 caractres
        }
        return result.toString();
    }

    /**
     * Rcupre la cl de configuration reprsentant le nombre minimum d'applications que doit avoir le menu pour tre
     * group
     * 
     * @param request la requte
     * @return le nombre minimum d'applications que doit avoir le menu pour tre group (10 par dfaut)
     */
    public static int getApplicationMenuKey(HttpServletRequest request) {
        // On groupe les applications si on en a plus de 10 dans le menu
        final int MIN_APPLIS = 10;
        // On rcupre le nombre minimum d'applications que doit avoir le menu pour tre group
        String minApplisForGrouping = WebMessages.getString(request, "nbApplisForGrouping");
        int minApplis;
        try {
            minApplis = Integer.parseInt(minApplisForGrouping);
        } catch (NumberFormatException nfe) {
            // Si erreur de cl, on met le nombre par dfaut
            minApplis = MIN_APPLIS;
        }
        return minApplis;
    }

    /**
     * @param pRequest la requte
     * @param pTres la liste des tres
     * @return la lgende prcisant la signification des tres
     */
    public static String getLegendForTres(HttpServletRequest pRequest, List pTres) {
        String legend = "<ul>";
        for (int i = 0; i < pTres.size(); i++) {
            String tre = (String) pTres.get(i);
            String acronyme = tre;
            int lastDot = tre.lastIndexOf(".");
            if (lastDot > 0) {
                acronyme = tre.substring(lastDot + 1);
            }
            legend += "<li>" + acronyme + " = " + WebMessages.getString(pRequest, tre) + "</li>";
        }
        return legend + "</ul>";
    }

    /**
     * @param pStatus le statut de l'audit
     * @return le type servant  la cl reprsentant le statut de l'audit.
     */
    public static String getAuditKind(int pStatus) {
        // TODO : Il faudrait exploiter le statut de l'audit
        // --> faire une passe sur la cl "kind" pour la remplacer par
        // un int et rcuprer la string par les fichiers de properties
        String result = "terminated";
        if (pStatus == AuditBO.FAILED) {
            result = "failed";
        } else if (pStatus == AuditBO.PARTIAL) {
            result = "partial";
        }
        return result;
    }
}