Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
   /*
    * #%L
    * Wikitty :: api
    * %%
    * Copyright (C) 2009 - 2010 CodeLutin, Benjamin Poussin
    * %%
    * 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
   * <http://www.gnu.org/licenses/lgpl-3.0.html>.
   * #L%
   */
  
  package org.nuiton.wikitty;
  
  import java.io.File;
  import java.security.Key;
  import java.util.Arrays;
  import java.util.Date;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Locale;
  import java.util.Map;
  import java.util.Set;
  import java.util.UUID;
Util static method for wikitty.

Author(s):
poussin
Version:
$Revision$ki Last update: $Date$ by : $Author$
  
  public class WikittyUtil implements WikittyConstants {

    
Pattern que doivent respecter les noms des extensions
  
      public static final String extensionNamePattern = "\\w+";
    
Pattern que doivent respecter les noms des champs des extensions
  
     public static final String extensionFieldNamePattern = "\\w+";
 
     public static final String DEFAULT_MAJOR_VERSION = "0";
     public static final String DEFAULT_MINOR_VERSION = "0";
     public static final String DEFAULT_MAJOR_VERSION_PREFIX =  + ".";
 
     public static final String DATE_NOW = "NOW";
     public static final String DATE_TODAY = "TODAY";
 
     public static final String DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSSZ'Z'";
 
     // #1386 sletellier 20110309 : solr date is return like 2011-03-09T08:06:27.593Z
     public static final String SOLR_DATE_FORMAT = "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'";

    
to use log facility, just put in your code: log.info(\"...\");
 
     static private Log log = LogFactory.getLog(WikittyUtil.class);

    
used to format date for solr
 
     protected static final TimeZone CANONICAL_TZ = TimeZone.getTimeZone("UTC");
     protected static final Locale CANONICAL_LOCALE = .;
 
     // FastDateFormat is thread-safe
     static final protected FastDateFormat solrDateFormat = FastDateFormat.getInstance(
             );
 
     public static final String[] DATE_FORMAT_ALLOWED = {
         .getPattern(),
         ,
         ,
         new SimpleDateFormat().toPattern(),  // local dependent
         "dd/MM/yy",
         "dd/MM/yy hh:mm",
         "dd/MM/yyyy",
         "dd/MM/yyyy hh:mm",
         "dd-MM-yy",
         "dd-MM-yy hh:mm",
         "dd-MM-yyyy",
         "dd-MM-yyyy hh:mm",
         "yyyyMMdd",
         "yyyy-MM-dd",
         "yyyy-MM-dd hh:mm",
         "yyyy-MM-dd'T'hh:mm:ss'Z'",
         "yyMMdd",
     };

    
no break space, used to parse BigDecimal
 
     static final public String nbsp = new String(new int[]{160}, 0, 1);
     
 //    /** All date format parser used to convert string to date */
 //    static final protected DateFormat[] parserDateFormats = new DateFormat[] {
 //            solrDateFormat, DateFormat.getInstance(),
 //    // TODO poussin 20090813: add other date syntax
 //    };
 
     static public Date parseDate(String dateAsStringthrows ParseException {        
         return DateUtils.parseDate(dateAsString);
     }
 
     static public String formatDate(Date datethrows ParseException {
         if (date == null) {
             return null;
         }
         return .format(date);
     }
     
     // TODO poussin 20090902 use spring configuration to add mapping in this
     // variable
     
contains mapping between interface and concret class that must be used
 
     static public Map<Class<?>, Class<?>> interfaceToClass = new HashMap<Class<?>, Class<?>>();

    
Pattern for tag value: tag="value" or tag=value. value can contains '"'
 
     static protected String tagValuesPatternString = "(\\w*)=(\".*?(?<!\\\\)\"|[^(\\p{Space})]+)";
     static protected Pattern tagValuesPattern = Pattern.compile(
             .);
    
Field pattern parser
  • group 1: type (string)
  • group 2: name (string)
  • group 3: lower bound (number) can be null
  • group 4: upper bound (number) can be null, mutually exclusive with group 5
  • group 5: upper bound (n or *) can be null
  • group 6: unique can be null (legacy configuration, prefer use of unique="true"
  • group 7: not null can be null (legacy configuration, prefer use of notNull="true"
  • group 8: all tag/value (toto=titi tutu=tata;lala tata="truc bidulle")
  •  
         static protected Pattern fieldPattern = Pattern
                 .compile(
                         "\\s*(\\w+)\\s+(\\w+)(?:\\s*\\[(\\d+)-(?:(\\d+)|([\\*n]))\\])?(?:\\s+(unique))?(?:\\s+(not null))?((?:\\s+"
                                 +  + ")*)".);

        
    parse FieldType definition and return field name. All field information are stored in fieldType object passed in argument

    Parameters:
    def string field definition
    fieldType object used to put parsed information
    Returns:
    field name parsed in definition
     
         static public String parseField(String defFieldType fieldType) {
             Matcher match = .matcher(def);
             if (match.matches()) {
                 fieldType.setType(WikittyTypes.parse(match.group(1)));
                 String name = match.group(2);
                 String lower = match.group(3);
                 if (lower != null) {
                     fieldType.setLowerBound(Integer.parseInt(lower));
                 }
     
                 String upper = match.group(4);
                 if (upper != null) {
                     fieldType.setUpperBound(Integer.parseInt(upper));
                 }
     
                 String noupper = match.group(5);
                 if (noupper != null) {
                     fieldType.setUpperBound(.);
                 }
     
                 // parse group 8 before
                 String tagValues = match.group(8);
                 Map<StringStringtagValuesMap = tagValuesToMap(tagValues);
     
                 // legacy field definition : unique
                 String uniqueString = match.group(6);
                 if (uniqueString != null) {
                     tagValuesMap.put(."true");
                     if (.isWarnEnabled()) {
                         .warn("Old field constraints definition detected \"unique\" ; prefer use of \"unique=true\"");
                     }
                 }
     
                 // legacy field definition : not null
                 String notNullString = match.group(7);
                 if (notNullString != null) {
                     tagValuesMap.put(."true");
                     .warn("Old field constraints definition detected \"non null\" ; prefer use of \"notNull=true\"");
                 }
     
                 fieldType.setTagValues(tagValuesMap);
     
                 return name;
             } else {
                 throw new WikittyException(String.format(
                         "Bad FieldType definition '%s'"def));
             }
         }


        
    Serialize tagValues to string

    Parameters:
    tagValues tagValues as map
    Returns:
    string represent tagValues
     
         public static String tagValuesToString(Map<StringStringtagValues) {
             String result = WikittyTransformerUtil.tagValuesToString(tagValues);
             return result;
         }

        
    Deserialize tagValues to map

    Parameters:
    tagValues tagValues as string
    Returns:
    map represent tagValues
     
         public static Map<StringStringtagValuesToMap(String tagValues) {
             Map<StringStringresult = new HashMap<StringString>();
             if (tagValues != null) {
                 Matcher matchTagValues = .matcher(tagValues);
                 while (matchTagValues.find()) {
                     String tag = matchTagValues.group(1);
                     String value = matchTagValues.group(2);
                     if (value.startsWith("\"") && value.endsWith("\"")) {
                         // delete start and end "
                         value = value.substring(1, value.length() - 1);
                         // if value is between ", then inners " are quoted
                         value = StringEscapeUtils.unescapeJava(value);
                     }
                     result.put(tagvalue);
                 }
             }
             return result;
         }

        
    Create map from string representation. ex: "String name", "Wikitty attachment[0-*]"

    Parameters:
    definitions extension definition
    Returns:
    extensions map
     
                 String... definitions) {
             LinkedHashMap<StringFieldTyperesult = new LinkedHashMap<StringFieldType>();
             for (String def : definitions) {
                 FieldType fieldType = new FieldType();
                 String name = WikittyUtil.parseField(deffieldType);
                 if (.isDebugEnabled()) {
                     .debug("parse " + def + " => " + fieldType.toDefinition(name));
                 }
                 result.put(namefieldType);
             }
             return result;
         }

        
    if version if null return 0 else version If version is not in format <major>.<minor>, ".0" is added to the version

    Parameters:
    version version
    Returns:
    the normalized version
     
         public static String normalizeVersion(String version) {
             if (version == null || "".equals(version)) {
                 version = "0";
             }
             if (version.indexOf(".") == -1) {
                 version += ".0";
             }
             return version;
         }

        
    Return true if v1 and v2 are equals. 1.2.0 et 1.2 ne sont pas egaux

    Parameters:
    v1 version
    v2 version
    Returns:
    true if v1 == v2
     
         public static boolean versionEquals(String v1String v2) {
             if (v1 == null || v2 == null) {
                 return false;
             }
             return normalizeVersion(v1).equals(normalizeVersion(v2));
         }

        
    Return true if v1 greater than v2.

    Parameters:
    v1 version
    v2 version
    Returns:
    true if v1 > v2
     
         public static boolean versionGreaterThan(String v1String v2) {
             if (v1 != null && v2 == null) {
                 return true;
             }
             if (v1 == null) {
                 return false;
             }
             String[] v1s = normalizeVersion(v1).split("\\.");
             String[] v2s = normalizeVersion(v2).split("\\.");
             int minlen = Math.min(v1s.lengthv2s.length);
             for (int i = 0; i < minleni++) {
                 if (!v1s[i].equals(v2s[i])) {
                     return Integer.parseInt(v1s[i]) > Integer.parseInt(v2s[i]);
                 }
             }
             // si on est ici c que tout les nombres sont v1[i] = v2[i]
             return v1s.length > v2s.length;
         }

        
    Increment minor version.

    Parameters:
    v version as 3.1 where 1 is minor and 3 major
    Returns:
    incremented minor number (3.1 -> 3.2)
     
         static public String incrementMinorRevision(String v) {
             String result;
     
             if (v == null || "".equals(v)) {
                 result = "0.1";
             } else {
                 v = v.trim();
                 String[] mm = v.split("\\.");
                 if (mm.length == 1) {
                     result = v + ".1";
                 } else {
                     int i = Integer.parseInt(mm[1]) + 1;
                     result = mm[0] + "." + i;
                 }
             }
             return result;
         }

        
    increment major version.

    Parameters:
    v version as 3.2 where 2 is minor and 3 major
    Returns:
    incremented major number and reset minor number (3.2 -> 4.0)
     
         static public String incrementMajorRevision(String v) {
             String result;
     
             if (v == null || "".equals(v)) {
                 result = "1.0";
             } else {
                 v = v.trim();
                 String[] mm = v.split("\\.");
                 int i = Integer.parseInt(mm[0]) + 1;
                 result = i + ".0";
             }
             return result;
         }

        
    Pattern de recherche des field dans les chaines de formatage

    See also:
    Formatter
     
         static protected Pattern formatMatcher =
                 Pattern.compile("%([^0-9][^|$]*)(?:\\|(.*?))?(\\$(:?[-#+ 0,(\\<]*)?(:?\\d+)?(:?\\.\\d+)?[tT]?[a-zA-Z])");

        
    Format wikitty for string representation. exemple:
  • "%Person.lastName$s %Person.firstName$s: %Person.birthday$tm %Person.birthday$te,%Person.birthday$tY"
  • "Hello %Person.firstName|unknown$s" if firstName field doesn't exist, unknow is used
  • "My company %Employee.company,Company.name|unknown$s" if employee has company field and this company has name field

    Parameters:
    format format as http://download.oracle.com/javase/6/docs/api/java/util/Formatter.html.syntax except that position is replace with fq field name.
    w wikitty to format
    Returns:
    String that represent the wikitty
  •  
         static public String format(String formatWikittyWikitty w) {
             List<Pair<StringString>> fields = new ArrayList<Pair<StringString>>();
     
             StringBuffer formatBuffer = new StringBuffer();
             int i = 0;
             // on collect tous les champs demande et leur valeur par defaut
             // et en meme temps on cree la chaine formatBuffer qui substitue les
             // champs par des numeros
             Matcher matcher = .matcher(formatWikitty);
             while(matcher.find()) {
                 String fieldAsked = matcher.group(1);
                 String defaultValue = matcher.group(2);
                 fields.add(new ImmutablePair<StringString>(fieldAskeddefaultValue));
                 // i is incremented before replace, because String.format start at 1 not 0
                 matcher.appendReplacement(formatBuffer"%"+(++i)+"$3");
             }
             matcher.appendTail(formatBuffer);
             // la vrai chaine de formatage pour String.format
             String format = formatBuffer.toString();
     
             List<Objectvalues = new ArrayList<Object>(fields.size());
             // on recherche la valeur de chaque champs demande
             for (Pair<StringStringpair : fields) {
                 String fieldAsked = pair.getKey();
                 String defaultValue = pair.getValue();
     
                 Object value = getValue(wfieldAsked);
                 Object defaultValueObject = getValue(wdefaultValue);
                 
                 // on ajoute dans la liste la valeur du champs
                 values.add(ObjectUtils.defaultIfNull(valuedefaultValueObject));
             }
     
             if (.isDebugEnabled()) {
                 .debug(String.format("%s -> %s (with %s from %s)"formatWikittyformatvaluesfields));
             }
     
             // use standard String.format
             String result = String.format(formatvalues.toArray());
             return result;
         }

        
    Recupere la valeur du champs pointer par fieldAsked. Si fieldAsked contient des ',' alors on parcours les differents objets pour arrive a satisfaire la demande Si fieldAsked ne represente pas un champs alors on retourne fieldAsked

    Parameters:
    w
    fieldAsked
    Returns:
     
         static private Object getValue(Wikitty wString fieldAsked) {
             String initialFieldAsked = fieldAsked;
             Wikitty wtmp = w;
             // recherche de l'objet reel sur lequel prendre la valeur du champs
             if (StringUtils.contains(fieldAsked",")) {
                 String path = StringUtils.substringBeforeLast(fieldAsked",");
                 fieldAsked = StringUtils.substringAfterLast(fieldAsked",");
                 for (String field : StringUtils.split(path",")) {
                     if (wtmp.hasField(field)) {
                         String extName = WikittyExtension.extractExtensionName(field);
                         String fieldName = WikittyExtension.extractFieldName(field);
                         wtmp = wtmp.getFieldAsWikitty(extNamefieldNamefalse);
                     } else {
                         wtmp = null;
                     }
                     if (wtmp == null) {
                         break;
                     }
                 }
             }
     
             Object value = null;
             if(wtmp != null) {
                 // recuperation de la valeur du champs
                 if (wtmp.hasField(fieldAsked)) {
                     String extName = WikittyExtension.extractExtensionName(fieldAsked);
                     String fieldName = WikittyExtension.extractFieldName(fieldAsked);
                     // on essai toujours de recuperer l'objet plutot que l'id si
                     // possible en 1er
                     value = wtmp.getFieldAsWikitty(extNamefieldNamefalse);
                     if (value == null) {
                         // pas un wikitty ou pas pre-charge, on demande simplement le champs
                         value = wtmp.getFqField(fieldAsked);
                     }
                 } else {
                     // on a pas trouver le champs, on retourne la chaine car ce n'etait pas un champs
                     value = initialFieldAsked;
                 }
             }
             return value;
         }

        
    Get value as Binary.

    Parameters:
    value null and empty return empty byte[]
    Returns:
    value as byte[]
     
         static public byte[] toBinary(Object value) {
             byte[] result = null;
             if (value == null || "".equals(value)) {
                 result = new byte[0]; // default to 0
                 // poussin 20120305 non, il ne faut pas convertir automatiquement les
                 // chaine en base64. Si on le souhaite, il faut le faire explicitement
                 // par exemple pour l'export csv/xml
     //        } else if (value instanceof String) {
     //            try {
     //                result = Base64.decode((String) value);
     //            } catch (IOException eee) {
     //                throw new WikittyException("Bad Base64 format", eee);
     //            }
             } else if (value instanceof byte[]) {
                 result = (byte[]) value;
             } else if (value instanceof File) {
                 try {
                     result = FileUtils.readFileToByteArray((Filevalue);
                 } catch (IOException eee) {
                     throw new WikittyException("Unable to read the file " + valueeee);
                 }
             } else {
                 result = value.toString().getBytes();
             }
             return result;
         }

        
    Get value as BigDecimal. If value is String, mathematical evaluation is done. ex: 2+2*2 create BigDecimal(6) as result

    Parameters:
    value null and empty string are casted to '0' value.
    Returns:
    value as BigDecimal
    Throws:
    WikittyException on NumberFormatException or if value object can't be casted to number.
     
         static public BigDecimal toBigDecimal(Object value) {
             BigDecimal result = null;
             if (value == null || "".equals(value)) {
                 result = new BigDecimal(0); // default to 0
             } else if (value instanceof BigDecimal) {
                 result = (BigDecimalvalue;
             } else {
                 String all = value.toString();
                 try {
                 double d = new ExpressionBuilder(all).build().evaluate();
                 result = new BigDecimal(d);
                 } catch (Exception eee) {
                     String s = all;
                     // suppression de tous les blancs pour un parsing plus sur
                     s = StringUtils.deleteWhitespace(s);
                     s = StringUtils.remove(s);
                     try {
                         // on commence par essayer par la methode la plus simple
                         result = new BigDecimal(s);
                     } catch (NumberFormatException yyy) {
                         // on essaie avec un parse, en dernier ressort
                         // si jamais le nombre etait localise (ex: 99,987.76)
                         try {
                             DecimalFormat parser = new DecimalFormat();
                             // on veut des BigDecimal en resultat et pas un Double
                             parser.setParseBigDecimal(true);
     
                             Number n = parser.parse(s);
                             // meme si on demande au parser un BigDecimal, il retourne
                             // certaine fois un Double (NaN, Infinit, ...).
                             // mais dans ce cas la, ca revient a une erreur de parsing
                             // qui explosera avec le cast
                             result = (BigDecimal)n;
                         } catch (Exception zzz) {
                             // on fait suivre eee et non pas yyy ou zzz car l'erreur initial
                             // est bien eee, yyy et zzz sont juste le fallback, et certain fois
                             // on aurait un ClassCastException qui n'a rien a voir,
                             // mais on log tout de meme zzz
                             .debug(String.format(
                                     "Try one, can't convert value '%s(%s)' to numeric, this exception is not throw but just logged",
                                     valuegetClass(value)), yyy);
                             .debug(String.format(
                                     "Try two, can't convert value '%s(%s)' to numeric, this exception is not throw but just logged",
                                     valuegetClass(value)), zzz);
                             throw new WikittyException(
                                     String.format("Can't convert value '%s(%s)' to numeric",
                                             valuegetClass(value)), eee);
                         }
                     }
                 }
             }
             return result.stripTrailingZeros();
         }

        
    Convert object to boolean:
    • - null => false - 0 => false - numeric => true
    • - object.toString() == false => false - other => true

    Parameters:
    value value
    Returns:
    value as boolean
     
         static public boolean toBoolean(Object value) {
             boolean result = false;
             if (value != null) {
                 if (value instanceof Boolean) {
                     result = (Booleanvalue;
                 } else if (value instanceof Number) {
                     result = !((Numbervalue).equals(0);
                 } else {
                     // try to convert to Boolean
                     result = !"false".equalsIgnoreCase(value.toString());
                 }
             }
             return result;
         }

        
    Convert Object to String representation if value is not null Wikitty is converted to id, and Date to SolrDateFormat

    Parameters:
    value value to convert
    Returns:
    String representation or null
     
         static public String toString(Object value) {
             String result = null;
             if (value != null) {
                 if (value instanceof String) {
                     result = (Stringvalue;
                 } else if (value instanceof WikittyImpl) {
                     result = ((Wikittyvalue).getWikittyId();
                 } else if (value instanceof BusinessEntity) {
                     result = ((BusinessEntityvalue).getWikittyId();
                 } else if (value instanceof Date) {
                     result = .format((Datevalue);
                 } else if (value instanceof Calendar) {
                     result = .format((Calendar)value);
                 } else if (value instanceof BigDecimal) {
                     result = ((BigDecimal)value).stripTrailingZeros().toString();
                 } else if (value instanceof byte[]) {
                     // poussin 20120305 il faut etre coherent avec le toBinary qui fait un String.toByte
     //                result = Base64.encodeBytes((byte[]) value);
                     result = new String((byte[]) value);
                 } else {
                     // try to convert to String
                     result = value.toString();
                 }
             }
             return result;
         }

        
    Converti un objet en une date. Date et Calendar sont directement supporte, tous les autres types sont transformer en String et parser pour construire la Date.
  • Si la chaine est 'NOW', la date courante est utilisee avec l'heure courant
  • Si la chaine est 'TODAY', la date courante est utilisee avec l'heure a 0 L'implantation de cette methode n'est pas satisfaisante, il faudrait trouver un meilleur algo. Le but est de parser la date suivant different pattern, puis derrière cette date il peut y avoir des demandes de modification (math date) par exemple +3MONTHS. Pour qu'une date soit valide, il faut que le parsing de la date fonctionne et que le parsing de la partie math fonctionne. Mais le découpage des deux parties n'est pas simple a trouver vu que la date peut-etre dans de tres nombreux format et que la partie math peut-etre elle aussi complexe :(

    Parameters:
    value
    Returns:
  •  
         static public Date toDate(Object value) {
             Date result = null;
             // poussin 20140730 pour null ou chaine vide on laisse a null
             // c'est util pour les formulaires web qui sont soumis avec des champs sans valeurs
             if (value != null && !"".equals(value)) {
                 if (value instanceof Date) {
                     result = (Datevalue;
                 } else if (value instanceof Calendar) {
                     result = ((Calendar)value).getTime();
                 } else {
                     // try to convert to Date
                     String v = String.valueOf(value);
                     if (StringUtils.startsWithIgnoreCase(v)) {
                         try {
                             Date tryDate = new Date();
                             v = StringUtils.substringAfter(v);
                             result = dateModifier(tryDatev);
                         } catch (ParseException eee) {
                             if (.isDebugEnabled()) {
                                 .debug(String.format(
                                         "Can't convert value '%s' of type '%s' to Date because math date is wrong",
                                         valuegetClass(value)), eee);
                             }
                         }
                     } else if (StringUtils.startsWithIgnoreCase(v)) {
                         try {
                             Date tryDate = new Date();
                             tryDate = DateUtil.setMinTimeOfDay(tryDate);
                             v = StringUtils.substringAfter(v);
                             result = dateModifier(tryDatev);
                         } catch (ParseException eee) {
                             if (.isDebugEnabled()) {
                                 .debug(String.format(
                                         "Can't convert value '%s' of type '%s' to Date because math date is wrong",
                                         valuegetClass(value)), eee);
                             }
                         }
                     } else {
                         for (String pattern : ) {
                             // remove ' from pattern because 'T' is 3 char in patten and 1 in value
                             if (StringUtils.length(v) < StringUtils.length(StringUtils.remove(pattern"'"))) {
                                 // if pattern longer than v then parse is impossble
                                 continue;
                             }
                             String tmp = StringUtils.substring(v, 0, pattern.length());
                             try {
                                 Date tryDate = DateUtils.parseDate(tmppattern);
                                 // parse success
                                 String ajust = StringUtils.substring(vpattern.length());
     
                                 // try to interpret and of date (ex: +3Years)
                                 result = dateModifier(tryDateajust);
                                 break;
                             } catch (ParseException eee) {
                                 if (.isDebugEnabled()) {
                                     .debug(String.format(
                                             "Can't convert value '%s' of type '%s' to Date because math date is wrong",
                                             valuegetClass(value)), eee);
                                 }
                             } catch (Exception eee) {
                                 if (.isDebugEnabled()) {
                                     .debug(String.format("Can't parse date '%s'"tmp), eee);
                                 }
                             }
                         }
                     }
     
                     if (result == null) {
                         throw new WikittyException(String.format(
                                 "Can't convert value '%s' of type '%s' to Date",
                                 valuegetClass(value)));
                     }
                 }
             }
             return result;
         }
     
         static private Date dateModifier(Date dateString modifierthrows ParseException {
             Date result = date;
     
             // try to interpret and of date (ex: +3Years)
             if (StringUtils.length(modifier) > 0) {
                 DateMathParser parser = new DateMathParser(TimeZone.getDefault(), Locale.getDefault());
                 parser.setNow(result);
                 result = parser.parseMath(modifier);
             }
     
             return result;
         }

        
    Return wikitty id and not wikitty objet because this method can be call on server or client side and it's better to keep conversion between id and objet to the caller

    Parameters:
    value
    Returns:
    id of wikitty object or null
     
         static public String toWikitty(Object value) {
             String result = null;
             if (value != null) {
                 if (value instanceof String) {
                     result = (Stringvalue;
                 } else if (value instanceof Wikitty) {
                     result = ((Wikittyvalue).getWikittyId();
                 } else if (value instanceof BusinessEntity) {
                     result = ((BusinessEntityvalue).getWikittyId();
                 } else {
                     // try to convert to String
                     result = value.toString();
                 }
             }
     
             if (StringUtils.isBlank(result)) {
                 // id never can be empty or blank. If result is blank then result must be null
                 result = null;
             }
     
             return result;
         }

        
    Convert value to list.

    Parameters:
    <E> elements type
    value value to convert
    clazz element class
    Returns:
    unmodifiable list
     
         @SuppressWarnings({"unchecked"})
         static public <E> List<E> toList(Object valueClass<E> clazz) {
             try {
                 List<E> result = (List<E>) value;
                 if (result != null) {
                     result = Collections.unmodifiableList(result);
                 }
                 return result;
             } catch (Exception eee) {
                 throw new WikittyException(String.format(
                         "Can't convert value '%s' to list"getClass(value)), eee);
             }
         }

        
    Converti un BigDecimal en un nombre

    Parameters:
    target la class du nombre
    v
    Returns:
     
         static public Number toNumber(Class targetBigDecimal v) {
             Number result = v;
             if (BigDecimal.class.isAssignableFrom(target)) {
                 result = v;
             } else if (..isAssignableFrom(target) || Byte.class.isAssignableFrom(target)) {
                 result = v.byteValue();
             } else if (..isAssignableFrom(target) || Double.class.isAssignableFrom(target)) {
                 result = v.doubleValue();
             } else if (..isAssignableFrom(target) || Float.class.isAssignableFrom(target)) {
                 result = v.floatValue();
             } else if (..isAssignableFrom(target) || Integer.class.isAssignableFrom(target)) {
                 result = v.intValue();
             } else if (..isAssignableFrom(target) || Long.class.isAssignableFrom(target)) {
                 result = v.longValue();
             } else if (..isAssignableFrom(target) || Short.class.isAssignableFrom(target)) {
                 result = v.shortValue();
             } else if (BigInteger.class.isAssignableFrom(target)) {
                 result = v.toBigInteger();
             }
             return result;
         }

        
    Convert object o for export CSV/XML.

    Parameters:
    field field description
    o field value
    Returns:
    solr representation
     
         static public String toStringForExport(FieldType fieldObject o) {
             String result = null;
             if (o != null) {
                 if (o instanceof String) {
                     result = (Stringo;
                 } else {
                 switch (field.getType()) {
                         case :
                             result = Base64.encodeBytes((byte[]) o);
                             break;
                         case :
                             // Date date = (Date)o;
                             result = ..format((Dateo);
                             break;
                         default:
                             result = WikittyUtil.toString(o);
                             break;
                     }
                 }
             }
             return result;
         }

        
    Convert object o for export CSV/XML.

    Parameters:
    field field description
    o field value
    Returns:
    solr representation
     
         static public Object fromStringForExport(FieldType fieldString s) {
             Object result = null;
             switch (field.getType()) {
                 case :
                     try {
                         result = Base64.decode(s);
                     } catch (IOException eee) {
                         throw new WikittyException("Can't decode string"eee);
                     }
                     break;
                 default:
                     // pour les autres conversion, les conversions auto du wikitty
                     // suffise
                     result = s;
                     break;
             }
             return result;
         }

        
    Convert object o for indexation

    Parameters:
    field field description
    o field value
    Returns:
    solr representation
     
         static public String toStringForSearchEngine(FieldType fieldObject o) {
             String result = null;
             if (o != null) {
                 switch (field.getType()) {
                     case :
                         // don't index binary
                         result = "";
                         break;
                     case :
                         // Date date = (Date)o;
                         result = (o instanceof String) ? (Stringo
                                 : ..format((Dateo);
                         break;
                     default:
                         result = WikittyUtil.toString(o);
                         break;
                 }
             }
             return result;
         }
        
        
    Convert string field representation to correct value type.

    Parameters:
    field field description
    s string value
    Returns:
    object in type of field
     
         static public Object fromString(FieldType fieldString s) {
             Object result = null;
             switch (field.getType()) {
                 case :
                     result = WikittyUtil.toBinary(s);
                     break;
                 case :
                     result = WikittyUtil.toBoolean(s);
                     break;
                 case :
                     result = WikittyUtil.toDate(s);
                     break;
                 case :
                     result = WikittyUtil.toBigDecimal(s);
                     break;
                 default:
                     result = s;
                     break;
             }
             return result;
         }

        
    Return class of argument, if argument is null, return null.

    Parameters:
    value
    Returns:
    class of value or null
     
         static public Class<?> getClass(Object value) {
             Class<?> result = null;
             if (value != null) {
                 result = value.getClass();
             }
             return result;
         }

        
    Create new instance of WikittyDto without Wikitty object passed in argument. If arguement is Interface try to add 'Impl' to find instanciable class.

    clazz parameter must be child of WikittyDto or business interface

    Parameters:
    <E> element type
    clazz class of the new instance
    Returns:
    new instance of clazz
        static public <E extends BusinessEntity> E newInstance(Class<E> clazz) {
            try {
                Class<?> clazzInstanciable = clazz;
                if (clazzInstanciable.isInterface()) {
                    .debug(String.format("Argument '%s' is interface looking for implementation",
                                            clazzInstanciable.getName()));
                    // looking for implementation of this interface
                    if (.containsKey(clazz)) {
                        clazzInstanciable = .get(clazz);
                    } else {
                        // default use xxxImpl.class
                        clazzInstanciable = Class.forName(clazz.getName() + "Impl");
                    }
                }
                if (!BusinessEntityImpl.class
                        .isAssignableFrom(clazzInstanciable)) {
                    throw new WikittyException(String.format(
                            "Your class '%s' don't extends BusinessEntityImpl"clazz
                                    .getName()));
                }
                E result = (E)clazzInstanciable.newInstance();
                return result;
            } catch (Exception eee) {
                throw new WikittyException(String.format(
                        "Can't create new instance of %s"clazz), eee);
            }
        }

        
    Create new Business Entity with specified Wikitty

    Parameters:
    target Business Entity class
    w wikitty to used
    Returns:
    new instance of object wanted or null if w is null
        static public <E extends BusinessEntity> E newInstance(Class<E> targetWikitty w) {
            E result = null;
            if (w != null) {
                result = newInstance(target);
                BusinessEntityImpl bean = (BusinessEntityImplresult;
                bean.setWikitty(w);
            }
            return result;
        }

        
    Cast Business object to another Business Object If source don't have target extension, this extension is added

    Parameters:
    source business entity source
    target business entity class wanted
    Returns:
    new instance of object wanted or null if source is null
        public <E extends BusinessEntity> E newInstance(Class<E> targetBusinessEntityImpl source) {
            E result = null;
            if (source != null) {
                result = newInstance(targetsource.getWikitty());
            }
            return result;
        }


        
    Create new Business Entity List from wikitties

    Parameters:
    target Business Entity class
    wikitties list of wikitties
    Returns:
    new list of Business Entity or null if wikitties is null
        static public <E extends BusinessEntityList<E> newInstance(Class<E> targetList<Wikittywikitties) {
            List<E> result = null;
            if (wikitties != null) {
                result = new ArrayList<E>(wikitties.size());
                for (Wikitty w : wikitties) {
                    if (w == null) {
                        result.add(null);
                    } else {
                        result.add(newInstance(targetw));
                    }
                }
            }
            return result;
        }

        
    Create new Business Entity Set from wikitties

    Parameters:
    target Business Entity class
    wikitties set of wikitties
    Returns:
    new set of Business Entity or null if wikitties is null
        static public <E extends BusinessEntitySet<E> newInstance(Class<E> targetSet<Wikittywikitties) {
            Set<E> result = null;
            if (wikitties != null) {
                result = new LinkedHashSet<E>(wikitties.size());
                for (Wikitty w : wikitties) {
                    if (w == null) {
                        result.add(null);
                    } else {
                        result.add(newInstance(targetw));
                    }
                }
            }
            return result;
        }


        
    Create new instance of BusinessEntity from Wikitty object passed in argument. If argument is Interface try to add 'Impl' to find instanciable class.

    clazz parameter must be child of Business interface

    Deprecated:
    since 3.3 il n'est pas coherent d'acceder au serveur lorsqu'on instancie un objet. La verification de la securite de toute facon ne se fait qu'au moment de la sauvegarde.
    Parameters:
    <E> entity type
    wikittyService wikitty service
    clazz class of the new instance
    w wikitty object to use internaly for in new instance
    Returns:
    new instance
        static public <E extends BusinessEntity> E newInstance(String securityToken,
                WikittyService wikittyServiceClass<E> clazzWikitty w) {
            try {
                Class<?> clazzInstanciable = clazz;
                if (clazzInstanciable.isInterface()) {
                    .debug(String.format("Argument '%s' is interface looking for implementation",
                                            clazzInstanciable.getName()));
                    // looking for implementation of this interface
                    if (.containsKey(clazz)) {
                        clazzInstanciable = .get(clazz);
                    } else {
                        // default use xxxImpl.class
                        clazzInstanciable = Class.forName(clazz.getName() + "Impl");
                    }
                }
                if (!BusinessEntityImpl.class
                        .isAssignableFrom(clazzInstanciable)) {
                    throw new WikittyException(String.format(
                            "Your class '%s' don't extends BusinessEntityImpl"clazz
                                    .getName()));
                }
                E result = null;
                if (w != null) {
                    try {
                        // try to find constructor with wikitty argument
                        Constructor<?> cons = clazzInstanciable
                                .getConstructor(Wikitty.class);
                        Object[] parms = { null };
                        result = (E) cons.newInstance(parms);
                        BusinessEntityImpl bean = (BusinessEntityImplresult;
                        // FIXME poussin 20111229 on ne devrait pas avoir besoin
                        // d'acceder au serveur ici :(. Voir si le check est vraiment
                        // util
                        checkExtensionVersion(securityTokenwikittyServicewbean);
                        bean.setWikitty(w);
                    } catch (NoSuchMethodException noerror) {
                        if (.isErrorEnabled()) {
                            .error(String.format(
                                "Can't find constructor with wikitty arguement in '%s',"
                                        + "we try with setWikitty method",
                                clazzInstanciable.getName()), noerror);
                        }
                    }
                }
                return result;
            } catch (Exception eee) {
                throw new WikittyException(String.format(
                        "Can't create new instance of %s"clazz), eee);
            }
        }

        
    Check extension default, i.e. if bean contain a extension with a great version as in wikitty. In this case the extension is stored in last version and wikitty it is restored again. The upgrade data is during the restoration.

    Parameters:
    wikittyService
    wikitty
    entity
    Returns:
        static public Wikitty checkExtensionVersion(
                String securityTokenWikittyService wikittyService,
                Wikitty wikittyBusinessEntityImpl entity) {
            Wikitty result = wikitty;
            boolean upgradeData = false;
            Collection<WikittyExtensionextensions = entity.getStaticExtensions();
            for (WikittyExtension ext : extensions) {
                String extName = ext.getName();
                if (wikitty.hasExtension(extName)) {
                    WikittyExtension oldExt = wikitty.getExtension(extName);
                    String newVersion = ext.getVersion();
                    String oldVersion = oldExt.getVersion();
                    if (WikittyUtil.versionGreaterThan(newVersionoldVersion)) {
                        wikittyService.storeExtension(
                                securityToken, Arrays.asList(ext));
                        upgradeData = true;
                    }
                }
            }
            if (upgradeData) {
                String wikittyId = wikitty.getWikittyId();
                result = WikittyServiceEnhanced.restore(
                        wikittyServicesecurityTokenwikittyId);
            }
            return result;
        }

        
    Try to cast obj to class passed in argument.

    Parameters:
    <E> element type
    obj object to cast
    clazz new type of object
    Returns:
    the same object but casted to class wanted, except for primitive where is new object if obj BigDecimal
        public static <E> E cast(Object objClass<E> clazz) {
            E result = null;
            if (obj != null) {
                if (clazz.isAssignableFrom(obj.getClass())) {
                    result = clazz.cast(obj);
                } else if (obj instanceof BigDecimal) {
                    BigDecimal bd = (BigDecimalobj;
                    if (clazz == int.class || clazz == Integer.class) {
                        result = clazz.cast(bd.intValue());
                    } else if (clazz == float.class || clazz == Float.class) {
                        result = clazz.cast(bd.floatValue());
                    }
                }
                if (result == null) {
                    throw new WikittyException("Unable to cast from '"
                            + obj.getClass().getName() + "' to " + clazz.getName());
                }
            }
            return result;
        }

        
    Clone wikitty with new id if genId is true

    Parameters:
    wikittyToClone concerned
    genId true to generate new id
    Returns:
    cloned wikitty
    Throws:
    java.lang.CloneNotSupportedException if exception is thrown
        public static Wikitty clone(Wikitty wikittyToCloneboolean genIdthrows CloneNotSupportedException {
            if (genId) {
                Wikitty w = new WikittyImpl();
                w.replaceWith(wikittyToClonetrue);
                return w;
            }
            return wikittyToClone.clone();
        }

        
    SecurityToken is used like wikitty id and must begin with UUID_

    Returns:
    SecurityToken that can be used like wikitty id
        static public String genSecurityTokenId() {
            String result = "_" + Math.abs(Math.random());
            result = result.replace("."""); // on supprime le '.' dans le nombre aleatoire
            result = genUID() + result;
            return result;
        }
        // private static BASE64Encoder enc = new BASE64Encoder();
        public static String genUID() {
            return UUID.randomUUID().toString();
            /*
             * we can gain 10 chars per ID on applying a base64 on the UID. long
             * mostSignificant = uid.getMostSignificantBits(); long leastSignificant
             * = uid.getLeastSignificantBits(); long current = mostSignificant;
             * byte[] b = new byte[16]; for ( int i = 0; i < 16; i++ ) { b[i] =
             * (byte) (current & 0xff); current = current >> 8; if ( i == 7 )
             * current = leastSignificant; } return enc.encode(b);
             */
        }

        
    given a fully qualified field name, return the name of the extension TODO poussin 20101208 redondant code with org.nuiton.wikitty.entities.WikittyExtension.extractExtensionName(java.lang.String)
        public static String getExtensionNameFromFQFieldName(String fqFieldName) {
            String[] fqFieldElements = fqFieldName.split();
            return fqFieldElements[0];
        }

        
    given a fully qualified field name, return the name of the field TODO poussin 20101208 redondant code with org.nuiton.wikitty.entities.WikittyExtension.extractFieldName(java.lang.String)
        public static String getFieldNameFromFQFieldName(String fqFieldName) {
            try {
                String[] fqFieldElements = fqFieldName.split();
                return fqFieldElements[1];
            } catch(ArrayIndexOutOfBoundsException eee) {
                throw new WikittyException("Field is not fully qualified field:" + fqFieldNameeee);
            }
        }

        
    given names of extension and field, return a fully qualified field name
        public static String getFQFieldName(String extensionNameString fieldName) {
            String fqFieldName = extensionName +  + fieldName;
            return fqFieldName;
        }

        
    given a fully qualified meta-extension name, return the name of the meta-extension.

    Returns:
    null if fqFieldName doesn't contains a meta extension
        public static String getMetaExtensionNameFromFQMetaExtensionName(String fqFieldName) {
            String metaExtensionName = null;
            if (fqFieldName.indexOf() != -1) {
                String[] fqElements = fqFieldName.split(