All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.nuiton.util.CardinalityHelper Maven / Gradle / Ivy

There is a newer version: 3.1
Show newest version
/*
 * #%L
 * Nuiton Utils
 * %%
 * Copyright (C) 2004 - 2010 CodeLutin
 * %%
 * This program 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 (at your option) any later version.
 * 
 * This program 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 Lesser Public License for more details.
 * 
 * You should have received a copy of the GNU General Lesser Public 
 * License along with this program.  If not, see
 * .
 * #L%
 */

package org.nuiton.util;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Une classe avec des méthodes utiles sur les cardinalités :
 *
 * parser une cardinalité {@link #parseCardinalite(String, boolean)}
 *
 * afficher une cardinité {@link #printCardinalite(StringBuilder, String, int, int, boolean, String, String, String, String)}
 *
 * et pour tester des cardinalités :
 *
 * {@link #isMandatory(int)}, savoir si une cardinalité est obligatoire à
 * partir de son min.
 *
 * {@link #isRepetable(int)}, savoir si une cardinalité est répétable à partir
 * de son max.
 *
 * {@link #isMaxBounded(int)}, savoir si une cardinalité est bornée sur son max
 * à partir de son max.
 *
 * {@link #isDefaultMandatory(int, int)}, savoir si la cardinalité est la
 * cardinalité obligatoire par défaut {1}.
 *
 * {@link #isDefaultOptional(int, int)}, savoir si la cardinalité est la
 * cardinalité optionel par défaut {0,1}.
 *
 * {@link #isAvailable(int, int)}, savoir si il reste encore des occurrences
 * disponibles sur une cardianlité à partir d'un nombre d'oocurrence et du max
 * de la cardinalité.
 *
 * @author Tony Chemit - [email protected]
 */
public class CardinalityHelper {

    static final Pattern PATTERN_OPTIONAL = Pattern.compile("\\[.*\\]");

    static final Pattern PATTERN_MANDATORY = Pattern.compile("\\<.*\\>");

    /** XXX + ou XXX * */
    public static final Pattern PATTERN_NO_MAX_BOUND = Pattern.compile("(.*)(\\+|\\*)");

    /** XXX {n} n est un entier */
    public static final Pattern PATTERN_EXTACLY = Pattern.compile("(.*)\\{([0-9]+)\\}");

    /** XXX {n,m} n est un entier, m est un entier ou * */
    public static final Pattern PATTERN_BOUNDED = Pattern.compile("(.*)\\{([0-9]+),([0-9]+|\\*)\\}");

    /**
     * Indique si une cardinalité est la cardinalité obligatoire par défaut {1}
     *
     * @param min le min de la cardinalité à tester
     * @param max le max de la cardinalité à tester
     * @return {@code true} si min==1 et max=1
     */
    public static boolean isDefaultMandatory(int min, int max) {
        return min == 1 && max == 1;
    }

    /**
     * Indique si une cardinalité est la cardinalité optionel par défaut {0,1}
     *
     * @param min le min de la cardinalité à tester
     * @param max le max de la cardinalité à tester
     * @return {@code true} si min==0 et max==1
     */
    public static boolean isDefaultOptional(int min, int max) {
        return min == 0 && max == 1;
    }

    /**
     * Indique si une cardinalité est obligatoire à partir de son min
     *
     * @param min le min de la cardinalité à tester
     * @return {@code true} si min>0
     */
    public static boolean isMandatory(int min) {
        return min > 0;
    }

    /**
     * Indique si une cardinalité est majorée à partir de son max
     *
     * @param max le max de la cardinalité à tester
     * @return {@code true} si max≠-1
     */
    public static boolean isMaxBounded(int max) {
        return max != -1;
    }

    /**
     * Indique si une cardinalité est répétable à partir de son max
     *
     * @param max le max de la cardinalité à tester
     * @return {@code true} si max>0 || max==-1
     */
    public static boolean isRepetable(int max) {
        return !isMaxBounded(max) || max > 1;
    }

    /**
     * Indique si on n'a pas encore  atteint la borne max d'une cardinalité à
     * partir de son max et d'un nombre d'occurrences déjà atteint.
     *
     * @param current le nombre d'occurence actuel
     * @param max     la borne max de la cardinalité
     * @return {@code true} si la cardinalité n'a pas atteint sa borne max
     */

    public static boolean isAvailable(int current, int max) {
        return !isMaxBounded(max) || current < max;
    }

    /**
     * Retourne le min par défault d'une cardinalité à partir du critère
     * obligatoire ou non.
     *
     * @param mandatory le critère à tester
     * @return {@code 1} si obligatoire, 0 sinon.
     */
    public static int getDefaultMin(boolean mandatory) {
        return mandatory ? 1 : 0;
    }

    /**
     * Parse la cardinalite à la fin d'un texte.
     *
     * @param txt       la valeur dont on cherche la cardinalité
     * @param mandatory si vrai, valeurs par default {1}, sinon {0,1}
     * @return un tableau contenant 3 object : le texte donné sans les
     *         informations de cardinalité, la répétitionMin, la répétitionMax.
     */
    public static Object[] parseCardinalite(String txt, boolean mandatory) {

        Object[] result = new Object[3];
        Matcher matcher;

        // always trim the text
        txt = txt.trim();
        if ((matcher = PATTERN_NO_MAX_BOUND.matcher(txt)).matches()) {
            // find a no max cardinalite *|+
            result[0] = matcher.group(1).trim();
            result[1] = getDefaultMin(matcher.group(2).equals("+"));
            result[2] = -1;
        } else if ((matcher = PATTERN_EXTACLY.matcher(txt)).matches()) {
            // found a exactly cardinalite {n}
            result[0] = matcher.group(1).trim();
            result[1] = Integer.valueOf(matcher.group(2));
            result[2] = result[1];
        } else if ((matcher = PATTERN_BOUNDED.matcher(txt)).matches()) {
            // found a bounded cardinalite {n,m}
            result[0] = matcher.group(1).trim();
            result[1] = Integer.valueOf(matcher.group(2));
            String max = matcher.group(3);
            result[2] = max.equals("*") ? -1 : Integer.valueOf(max);
        } else {
            // no cardinalite was found, use default values
            result[0] = txt.trim();
            result[1] = getDefaultMin(mandatory);
            result[2] = 1;
        }
        return result;
    }

    /**
     * Imprime dans le builder, le txt + une cardinalité.
     *
     * @param sb        le builder
     * @param txt       le txt à imprimer
     * @param min       la caridnalité min
     * @param max       la cardinalité max
     * @param mandatory pour indiquer dans quel cas on affiche la cardinalité :
     *                  si elle correspond aux valeurs par défaut
     *                  de mandatory {1} ou optionel {0,1}, pas d'impression.
     * @param mo        le caractère ouvrant pour un object obligatoire
     * @param mc        le caractère fermant pour un object obligatoire
     * @param oo        le caractère ouvrant pour un object optionel
     * @param oc        le caractère fermant pour un object optionel
     */
    public static void printCardinalite(StringBuilder sb, String txt, int min, int max, boolean mandatory, String mo, String mc, String oo, String oc) {
        // flag pour indiquer s'il faut ou non imprimer les bordures
        boolean print = false;

        boolean maxBounded = isMaxBounded(max);
        if (isMandatory(min)) {
            sb.append(mo).append(txt).append(mc);
            if (isDefaultMandatory(min, max)) {
                if (mandatory || mo.length() > 0) {
                    // rien a faire on a la valeur par defaut attendue, ou la
                    // bordure existe et remplace la valeur par defaut
                } else {
                    // pas de bordure, ou valeur optionel attendue, on doit imprimer la cardinalite
                    print = true;
                }
            } else {
                if (!maxBounded && min == 1) {
                    sb.append('+');
                } else {
                    print = true;
                }
            }
        } else {
            sb.append(oo).append(txt).append(oc);
            if (isDefaultOptional(min, max)) {
                if (!mandatory || oo.length() > 0) {
                    // rien a faire on a la valeur par defaut attendue, ou la
                    // bordure existe et remplace la valeur par defaut
                } else {
                    // pas de bordure, ou valeur optionel attendue, on doit imprimer la cardinalite
                    print = true;
                }
            } else {
                if (!maxBounded) {
                    sb.append('*');
                } else {
                    print = true;
                }
            }
        }
        if (print) {
            sb.append('{');
            sb.append(min);
            if (max != min) {
                sb.append(',');
                sb.append(maxBounded ? max : "*");
            }
            sb.append('}');
        }
    }

    protected CardinalityHelper() {
        // do not instanciate
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy