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.entities;
  
  
  import java.util.Arrays;
  import java.util.Date;
  import java.util.HashMap;
  import java.util.HashSet;
  import java.util.List;
  import java.util.Map;
  import java.util.Set;

Wikitty implementation. getDirty() contains 2 types of info :
  • the name of a modified field (extension.field)
  • an extension added or deleted (extension)
  • Author(s):
    poussin
    Version:
    $Revision$ Last update: $Date$ by : $Author$
      
      public class WikittyImpl implements Wikitty {

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

        
    serialVersionUID.
      
          private static final long serialVersionUID = 4910886672760691052L;

        
    Technical id for this wikitty object. id must be never null.
      
          protected String id;

        
    Current version of this wikitty object.
      
          protected String version = .;

        
    If not null, date of deletion, if date this object is marked as deleted.
      
          protected Date deleteDate = null;

        
    Used to add property change support to wikitty object. Warning, this field can be null after deserialization.
      
          private transient PropertyChangeSupport propertyChange;

        
    key: field name prefixed by extension name (dot separator) value: value of field
      
          protected HashMap<StringObjectfieldValue = new HashMap<StringObject>();

        
    all field name currently modified (field name = extension . fieldname)
      
          protected Set<StringfieldDirty = new HashSet<String>();

        
    Map is LinkedHashMap to maintains order like user want key: extension name value: extension definition
     
         protected Map<StringWikittyExtensionextensions =
                 new LinkedHashMap<StringWikittyExtension>();
        
        
    Pattern de prechargement demande par l'utilisateur lors de la restauration du wikitty. Peut-etre null si aucun prechargement n'est demande.
     
         protected String preloadPattern;

        
    Ensemble des liens vers des Wikitty precharge. Cette map peut-etre null si aucun prechargement n'existe.
  • key: wikitty id
  • value: wikitty
  •  
         // poussin 20120305 peut-etre mettre transient le champs ? a voir a l'usage
         protected Map<StringWikittypreloaded;
     
         public WikittyImpl() {
             this(null);
         }
     
         public WikittyImpl(String id) {
             if (id == null) {
                 this. = WikittyUtil.genUID();
             } else {
                 this. = id;
             }
         }
     
         @Override
         public String getPreloadPattern() {
             return ;
         }
     
         @Override
         public void setPreloadPattern(String preloadPattern) {
             this. = preloadPattern;
         }
     
         @Override
         public Set<StringgetAllPreloadPattern() {
             Set<Stringresult = new HashSet<String>();
             String[] preloadPatterns = StringUtils.split(getPreloadPattern(), ";");
             if (preloadPatterns != null) {
                 result.addAll(Arrays.asList(preloadPatterns));
             }
     
             for (WikittyExtension ext : getExtensions()) {
                 preloadPatterns = StringUtils.split(
                         ext.getTagValue(.), ";");
                 if (preloadPatterns != null) {
                     result.addAll(Arrays.asList(preloadPatterns));
                 }
             }
             result.remove(null);
             return result;
         }
     
         @Override
         public Map<StringWikittygetPreloaded() {
             if ( == null) {
                  = new HashMap<StringWikitty>();
             }
             return Collections.unmodifiableMap();
         }
     
         @Override
         public void setPreloaded(Map<StringWikittypreloaded) {
             // on fait une copie et on la rend non modifiable.
             Map<StringWikittymap = new HashMap<StringWikitty>();
             if (preloaded != null) {
                 map.putAll(preloaded);
             }
             this. = map;
         }
     
         @Override
         public void addPreloaded(Wikitty w) {
             if (w != null) {
                 if ( == null) {
                      = new HashMap<StringWikitty>();
                 }
                 this..put(w.getWikittyId(), w);
             }
         }

        
    Replace all field of current wikitty with field found in w. This two wikitty must have same id. This method is used to clone Wikitty too

    Parameters:
    w wikitty where we take information
     
         @Override
         public void replaceWith(Wikitty w) {
             replaceWith(wfalse);
         }

        
    Replace all field of current wikitty with field found in w. This two wikitty must have same id if force is false. This method is used to clone Wikitty too

    Parameters:
    w wikitty where we take information
     
         @Override
         public void replaceWith(Wikitty wboolean force) {
             // il faut que ce soit le meme objet mais pas la meme instance
             // car ca ne sert a rien de copier un objet sur lui meme
             if (this == w) {
                 return;
             }
             // all time search for WikittyImpl to do copy (prevent error)
             if (w instanceof WikittyCopyOnWrite) {
                 replaceWith(((WikittyCopyOnWrite)w).getTarget(), force);
             } else if (force || this.getWikittyId().equals(w.getWikittyId())) {
                 // poussin 20120305 quid des listeners ? ne faudrait-il pas les copier aussi ?
                 // mais si on les copie, comment l'utilisateur sera-t-il qu'il faut les supprimer
                 // ne risque t-il pas d'y avoir des listeners recevant trop de notification.
                 // le plus simple est donc pour l'instant de ne pas copier les listeners, a la
                 // charge du developpeur d'appli, lorsqu'il fait un clone de remettre les listeners
                 // qu'il souhaite
     
                 // copy preload (not in deep copy mode)
                 this.setPreloaded(w.getPreloaded());
                 this.setPreloadPattern(w.getPreloadPattern());
     
                 this..clear();
                 this..clear();
                 for (WikittyExtension ext : w.getExtensions()) {
                     String extName = ext.getName();
                     this..put(extNameext);
                     for(String fieldName : ext.getFieldNames()) {
                         Object value = w.getFieldAsObject(extNamefieldName);
                         if (value != null) {
                             // seul les collections sont a cloner, sinon ce ne sont
                             // que des types primitifs immutable
                             if (value instanceof Collection && value instanceof Cloneable) {
                                 try {
                                     value = ObjectUtil.clone((Cloneablevalue);
                                 } catch (CloneNotSupportedException eee) {
                                     throw new WikittyException(String.format(
                                             "Can't copy field %s.%s",
                                             extNamefieldName), eee);
                                 }
                             }
                             this.setField(extNamefieldNamevalue);
                         }
                     }
                 }
     
                 // Dont keep version if force
                 if (!force) {
                     // we must change version after field value copy, because
                     // copy increment version because it use setField method
                     this. = w.getWikittyVersion();
                     this. = w.getDeleteDate();
                 }
     
                 clearDirty();
             } else {
                 throw new IllegalArgumentException("Wikitty in argument don't have same id");
             }
         }

        
    Always call this method because field is transient.

    Returns:
     
             if ( == null) {
                  = new PropertyChangeSupport(this);
             }
             return ;
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#addPropertyChangeListener(java.beans.PropertyChangeListener)
          */
         @Override
         public synchronized void addPropertyChangeListener(
                 PropertyChangeListener listener) {
         }
     
     
         /*
          * @see org.nuiton.wikitty.Wikitty#removePropertyChangeListener(java.beans.PropertyChangeListener)
          */
         @Override
         public synchronized void removePropertyChangeListener(
                 PropertyChangeListener listener) {
         }
     
     
         /*
          * @see org.nuiton.wikitty.Wikitty#addPropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
          */
         @Override
         public synchronized void addPropertyChangeListener(String propertyName,
                 PropertyChangeListener listener) {
             getPropertyChangeSupport().addPropertyChangeListener(propertyNamelistener);
         }
     
     
         /*
          * @see org.nuiton.wikitty.Wikitty#removePropertyChangeListener(java.lang.String, java.beans.PropertyChangeListener)
          */
         @Override
         public synchronized void removePropertyChangeListener(String propertyName,
                 PropertyChangeListener listener) {
             getPropertyChangeSupport().removePropertyChangeListener(propertyNamelistener);
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#getWikittyId()
          */
         @Override
         public String getId() {
             return ;
         }
     
         @Override
         public String getWikittyId() {
             return ;
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#isDeleted()
          */
         @Override
         public boolean isDeleted() {
             boolean result =  != null;
             return result;
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#getDeleteDate()
          */
         @Override
         public Date getDeleteDate() {
             return ;
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#setDeleteDate(java.util.Date)
          */
         @Override
         public void setDeleteDate(Date delete) {
             this. = delete;
         }

        
    Mark field as dirty.

    Parameters:
    ext
    fieldName
     
         protected void setFieldDirty(String extString fieldName,
                 Object oldValueObject newValue) {
             String key = WikittyUtil.getFQFieldName(extfieldName);
             incrementVersion(key);
             getPropertyChangeSupport().firePropertyChange(keyoldValuenewValue);
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#addExtension(org.nuiton.wikitty.WikittyExtension)
          */
         @Override
         public void addExtension(WikittyExtension ext) {
             // on check qu'on avait pas deja cette extension dans une version plus
             // recente, dans ce cas, on leve une exception en disant qu'il faut
             // se mettre a jour
             WikittyExtension currentExt = .get(ext.getName());
             if (currentExt != null &&
                     VersionUtil.greaterThan(currentExt.getVersion(), ext.getVersion())) {
                 throw new WikittyException(String.format(
                         "In wikitty '%s' You try to put extension '%s' in older version (%s) than"
                         + " current version (%s). You must update your software.",
                         getWikittyId(), ext.getName(), ext.getVersion(), currentExt.getVersion()));
             }
     
             // on check les dependances
             List required = ext.getRequires();
             if (required != null && !required.isEmpty() &&
                     !.keySet().containsAll(required)) {
                 throw new WikittyException(String.format(
                         "You try to add extension '%s' that" +
                         " required not available extension '%s' in this wikitty",
                         ext.getName(), required));
             }
     
             .put(ext.nameext);
             incrementVersion(ext.name);
     
             // mise en place des valeurs par defaut des champs de l'extension
             for (String fieldName : ext.getFieldNames()) {
                 FieldType type = ext.getFieldType(fieldName);
                 if (type.hasDefault()) {
                     setField(ext.namefieldNametype.getDefault());
                 }
             }
         }
     
         @Override
         public void removeExtension(String ext) {
             Collection<WikittyExtensionexts = getExtensionDependencies(exttrue);
             exts.add(.get(ext));
             for (WikittyExtension e : exts) {
                 String extName = e.getName();
                 .remove(extName);
                 for (String field : e.getFieldNames()) {
                     .remove(WikittyUtil.getFQFieldName(extNamefield));
                 }
             }
         }
     
         @Override
         public void removeExtensions(Collection<Stringexts) {
             for (String e : exts) {
                 removeExtension(e);
             }
         }

        
     
         @Override
         public boolean hasMetaExtension(String metaExtensionName,
                                         String extensionName) {
             String metaExtensionFQName = WikittyUtil.getFQMetaExtensionName(
                                                             metaExtensionName,
                                                             extensionName);
             boolean hasMetaExtension = .containsKey(metaExtensionFQName);
             return hasMetaExtension;
         }
        
        
     
         @Override
         public void addMetaExtension(WikittyExtension metaExtension,
                                      WikittyExtension extension) {
             addMetaExtension(metaExtensionextension.getName());
         }

        
     
         @Override
         public void addMetaExtension(WikittyExtension metaExtension,
                                      String extensionName) {
             if (hasExtension(extensionName)) {
                 String metaExtensionFQName = WikittyUtil.getFQMetaExtensionName(
                                                             metaExtension.getName(),
                                                             extensionName);
                 .put(metaExtensionFQNamemetaExtension);
                 incrementVersion(metaExtensionFQName);
             } else {
                 throw new IllegalArgumentException("this wikitty doesn't have an extension named " + extensionName);
             }
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#addExtension(java.util.Collection)
          */
         @Override
         public void addExtension(Collection<WikittyExtensionexts) {
             for (WikittyExtension ext : exts) {
                 addExtension(ext);
             }
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#hasExtension(java.lang.String)
          */
         @Override
         public boolean hasExtension(String extName) {
             return .containsKey(extName);
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#hasField(java.lang.String, java.lang.String)
          */
         @Override
         public boolean hasField(String extNameString fieldName) {
             boolean result = false;
             WikittyExtension ext = .get(extName);
             if (ext != null) {
                 result = ext.getFieldType(fieldName) != null;
             }
             return result;
         }
     
         @Override
         public boolean hasField(String fqfieldName) {
             boolean result = false;
             try {
                 String extName = WikittyExtension.extractExtensionName(fqfieldName);
                 String fieldName = WikittyExtension.extractFieldName(fqfieldName);
             
                 result = hasField(extNamefieldName);
             } catch (Exception eee) {
                 .trace("Invalide field name is never field"eee);
             }
             return result;
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#getExtension(java.lang.String)
          */
         @Override
         public WikittyExtension getExtension(String ext) {
             WikittyExtension result = .get(ext);
             return result;
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#getExtensionNames()
          */
         @Override
         public Collection<StringgetExtensionNames() {
             Collection<Stringresult = .keySet();
             return result;
         }
     
         @Override
         public Collection<StringgetExtensionFields(String ext) {
             Collection<Stringresult = getExtension(ext).getFieldNames();
             return result;
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#getExtensions()
          */
         @Override
             Collection<WikittyExtensionresult = .values();
             return result;
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#getExtensionDependencies(java.lang.String, boolean)
          */
         @Override
         public Collection<WikittyExtensiongetExtensionDependencies(String extboolean recursively) {
             Collection<WikittyExtensionresult = new HashSet<WikittyExtension>();
             Collection<WikittyExtensionall = .values();
             for (WikittyExtension dependency : all) {
                 List<Stringrequires = dependency.getRequires();
                 if(requires != null && !requires.isEmpty() && requires.contains(ext)) {
                     result.add(dependency);
                     if(recursively) {
                         String dependencyName = dependency.getName();
                         Collection<WikittyExtensiondependencies =
                                 getExtensionDependencies(dependencyNamerecursively);
                         result.addAll(dependencies);
                     }
                 }
             }
             return result;
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#getFieldType(java.lang.String)
          */
         @Override
         public FieldType getFieldType(String fqfieldName) {
             String extName = WikittyExtension.extractExtensionName(fqfieldName);
             String fieldName = WikittyExtension.extractFieldName(fqfieldName);
             FieldType result = getFieldType(extNamefieldName);
             return result;
         }
     
         @Override
         public FieldType getFieldType(String extNameString fieldName) {
             WikittyExtension ext = getExtension(extName);
             if (ext == null) {
                 throw new WikittyException(String.format(
                         "Extension '%s' doesn't exists on wikitty '%s'"extName));
             } else {
                 int crochet = fieldName.indexOf("[");
                 if (crochet != -1) {
                     fieldName = fieldName.substring(0, crochet);
                 }
                 FieldType result = ext.getFieldType(fieldName);
                 if (result == null) {
                     throw new WikittyException(String.format(
                             "field '%s' doesn't exists on extension '%s'"fieldNameextName));
     
                 }
                 return result;
             }
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#setField(java.lang.String, java.lang.String, java.lang.Object)
          */
         @Override
         public void setField(String extString fieldNameObject value) {
             if (! hasField(extfieldName)) {
                 String def = "";
                 for ( WikittyExtension extension : .values() ) {
                     def += extension.toDefinition() + "\n";
                 }
                 throw new WikittyException(String.format(
                         "field '%s' is not valid, extensions definition : %s",
                         WikittyUtil.getFQFieldName(extfieldName), def));
             }
             String key = WikittyUtil.getFQFieldName(extfieldName);
     
             // take old value if needed
             Object oldValue = null;
             if (getPropertyChangeSupport().hasListeners(key)) {
                 oldValue = .get(key);
             }
     
             // put new value
             FieldType fieldType = getExtension(ext).getFieldType(fieldName);
             Object validValue = fieldType.getValidValue(value);
             .put(keyvalidValue);
     
             // if user pass in argument object that permit to take wikitty,
             // we put it, in preload map
             if (value != null && fieldType.getType() == .) {
                 if (fieldType.isCollection()) {
                     if (value instanceof Collection) {
                         for ( Object o : (Collection<?>) value ) {
                             Wikitty w = WikittyUtil.getWikitty(o);
                             addPreloaded(w);
                         }
                     } else {
                         // Array
                         for ( Object o : (Object[]) value ) {
                             Wikitty w = WikittyUtil.getWikitty(o);
                             addPreloaded(w);
                         }
                     }
                 } else {
                     Wikitty w = WikittyUtil.getWikitty(value);
                     addPreloaded(w);
                 }
             }
     
             // mark field dirty and call listener
             setFieldDirty(extfieldNameoldValuevalidValue);
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#getFieldAsObject(java.lang.String, java.lang.String)
          */
         @Override
         public Object getFieldAsObject(String extString fieldName) {
             if (!hasField(extfieldName)) {
                 WikittyExtension extension = .get(ext);
                 String type;
                 Collection list;
                 if (extension == null) {
                     type = "extension";
                     list = getExtensionNames();
                 } else {
                     type = "fieldname";
                     list = extension.getFieldNames();
                 }
                 throw new WikittyException(String.format(
                         "field '%s' is not a valid field. acceptable %s are: %s",
                         WikittyUtil.getFQFieldName(extfieldName), typelist));
             }
             String key = WikittyUtil.getFQFieldName(extfieldName);
             Object result = .get(key);
             return result;
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#getFieldAsString(java.lang.String, java.lang.String)
          */
         @Override
         public byte[] getFieldAsBytes(String extString fieldName) {
             Object value = getFieldAsObject(extfieldName);
             try {
                 byte[] result = WikittyUtil.toBinary(value);
                 return result;
             } catch (WikittyException eee) {
                 throw new WikittyException(String.format(
                         "field '%s' is not a valid byte[]",
                         WikittyUtil.getFQFieldName(extfieldName)), eee);
             }
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#getFieldAsBoolean(java.lang.String, java.lang.String)
          */
         @Override
         public boolean getFieldAsBoolean(String extString fieldName) {
             Object value = getFieldAsObject(extfieldName);
             try {
                 boolean result = WikittyUtil.toBoolean(value);
                 return result;
             } catch (WikittyException eee) {
                 throw new WikittyException(String.format(
                         "field '%s' is not a valid boolean",
                         WikittyUtil.getFQFieldName(extfieldName)), eee);
             }
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#getFieldAsBigDecimal(java.lang.String, java.lang.String)
          */
         @Override
         public BigDecimal getFieldAsBigDecimal(String extString fieldName) {
             Object value = getFieldAsObject(extfieldName);
             try {
                 BigDecimal result = WikittyUtil.toBigDecimal(value);
                 return result;
             } catch (WikittyException eee) {
                 throw new WikittyException(String.format(
                         "field '%s' is not a valid numeric",
                         WikittyUtil.getFQFieldName(extfieldName)), eee);
             }
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#getFieldAsInt(java.lang.String, java.lang.String)
          */
         @Override
         public int getFieldAsInt(String extString fieldName) {
             try {
                 BigDecimal value = getFieldAsBigDecimal(extfieldName);
                 int result = value.intValue();
                 return result;
             } catch (WikittyException eee) {
                 throw new WikittyException(String.format(
                         "field '%s' is not a valid int",
                         WikittyUtil.getFQFieldName(extfieldName)), eee);
             }
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#getFieldAsLong(java.lang.String, java.lang.String)
          */
         @Override
         public long getFieldAsLong(String extString fieldName) {
             try {
                 BigDecimal value = getFieldAsBigDecimal(extfieldName);
                 long result = value.longValue();
                 return result;
             } catch (WikittyException eee) {
                 throw new WikittyException(String.format(
                         "field '%s' is not a valid int",
                         WikittyUtil.getFQFieldName(extfieldName)), eee);
             }
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#getFieldAsFloat(java.lang.String, java.lang.String)
          */
         @Override
         public float getFieldAsFloat(String extString fieldName) {
             try {
                 BigDecimal value = getFieldAsBigDecimal(extfieldName);
                 float result = value.floatValue();
                 return result;
             } catch (WikittyException eee) {
                 throw new WikittyException(String.format(
                         "field '%s' is not a valid float",
                         WikittyUtil.getFQFieldName(extfieldName)), eee);
             }
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#getFieldAsDouble(java.lang.String, java.lang.String)
          */
         @Override
         public double getFieldAsDouble(String extString fieldName) {
             try {
                 BigDecimal value = getFieldAsBigDecimal(extfieldName);
                 double result = value.doubleValue();
                 return result;
             } catch (WikittyException eee) {
                 throw new WikittyException(String.format(
                         "field '%s' is not a valid float",
                         WikittyUtil.getFQFieldName(extfieldName)), eee);
             }
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#getFieldAsString(java.lang.String, java.lang.String)
          */
         @Override
         public String getFieldAsString(String extString fieldName) {
             Object value = getFieldAsObject(extfieldName);
             try {
                 String result = WikittyUtil.toString(value);
                 return result;
             } catch (WikittyException eee) {
                 throw new WikittyException(String.format(
                         "field '%s' is not a valid String",
                         WikittyUtil.getFQFieldName(extfieldName)), eee);
             }
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#getFieldAsDate(java.lang.String, java.lang.String)
          */
         @Override
         public Date getFieldAsDate(String extString fieldName) {
             Object value = getFieldAsObject(extfieldName);
             try {
                 Date result = WikittyUtil.toDate(value);
                 return result;
             } catch (WikittyException eee) {
                 throw new WikittyException(String.format(
                         "field '%s' is not a valid Date",
                         WikittyUtil.getFQFieldName(extfieldName)), eee);
             }
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#getFieldAsWikitty(java.lang.String, java.lang.String)
          */
         @Override
         public String getFieldAsWikitty(String extString fieldName) {
             Object value = getFieldAsObject(extfieldName);
             String result = WikittyUtil.toWikitty(value);
             return result;
         }
     
         @Override
         public Wikitty getFieldAsWikitty(String extNameString fieldNameboolean exceptionIfNotLoaded) {
             String id = getFieldAsWikitty(extNamefieldName);
             Wikitty result = null;
             if (id != null) {
                 result = getPreloaded().get(id);
                 if (exceptionIfNotLoaded && result == null) {
                     throw new WikittyException(String.format(
                             "field %s.%s is not preloaded"extNamefieldName));
                 }
             }
             return result;
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#getFieldAsList(java.lang.String, java.lang.String, java.lang.Class)
          */
         @Override
         public <E> List<E> getFieldAsList(String extString fieldNameClass<E> clazz) {
             try {
                 Collection<E> collection = (Collection<E>) getFieldAsObject(extfieldName);
                 if (collection != null) {
                     // return unmodiable collection that check type of element
                     return new UnModifiableCopyList<E>(clazzcollection);
                 }
                 return null;
             } catch (Exception eee) {
                 throw new WikittyException(String.format(
                         "Can't get value to field '%s'",
                         WikittyUtil.getFQFieldName(extfieldName)), eee);
             }
         }
     
         @Override
                 String extString fieldNameboolean exceptionIfNotLoaded) {
     
             List<Wikittyresult = null;
     
             Collection<Stringcollection = getFieldAsList(extfieldNameString.class);
             if (collection != null) {
                 result = new ArrayList<Wikitty>(collection.size());
                 for (String s : collection) {
                     Wikitty w = getPreloaded().get(s);
                     if (exceptionIfNotLoaded && w == null) {
                         throw new WikittyException(
                                 String.format("Wikitty for field %s.%s is not preloaded (%s)",
                                 extfieldNames));
                     }
                     result.add(w);
                 }
     
                 // return unmodiable collection
                 result = Collections.unmodifiableList(result);
             }
             return result;
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#getFieldAsSet(java.lang.String, java.lang.String, java.lang.Class)
          */
         @Override
         public <E> Set<E> getFieldAsSet(String extString fieldNameClass<E> clazz) {
             try {
                 Collection<E> collection = (Collection<E>) getFieldAsObject(extfieldName);
                 if (collection != null) {
                     // return unmodifable Set
                     return new UnModifiableCopySet<E>(clazzcollection);
                 }
                 return null;
             } catch (Exception eee) {
                 throw new WikittyException(String.format(
                         "Can't get value to field '%s'",
                         WikittyUtil.getFQFieldName(extfieldName)), eee);
             }
         }
     
         @Override
         public Set<WikittygetFieldAsWikittySet(
                 String extString fieldNameboolean exceptionIfNotLoaded) {
     
             Set<Wikittyresult = null;
     
             Collection<Stringcollection = getFieldAsSet(extfieldNameString.class);
             if (collection != null) {
                 result = new LinkedHashSet<Wikitty>();
                 for (String s : collection) {
                     Wikitty w = getPreloaded().get(s);
                     if (exceptionIfNotLoaded && w == null) {
                         throw new WikittyException(
                                 String.format("Wikitty for field %s.%s is not preloaded (%s)",
                                 extfieldNames));
                     }
                     result.add(w);
                 }
     
                 // return unmodiable collection
                 result = Collections.unmodifiableSet(result);
             }
             return result;
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#addToField(java.lang.String, java.lang.String, java.lang.Object)
          */
         @Override
         public void addToField(String extString fieldNameObject value) {
             try {
                 FieldType fieldType = getExtension(ext).getFieldType(fieldName);
                 Collection col = (CollectiongetFieldAsObject(extfieldName);
                 if (col == null) {
                     if (fieldType.isUnique()) {
                         // LinkedHashSet to try to maintains order
                         col = new LinkedHashSet();
                     } else {
                         col = new ArrayList();
                     }
                     col.add(value);
                     setField(extfieldNamecol);
                     // no call dirty, because already done in setField
                 } else {
                     // check upper bound only if col exists,
                     // because ask upper bound == 0 is ridiculous
     
                     Object validValue = fieldType.getContainedValidObject(value);
                     if (fieldType.isUnique() && col.contains(validValue)) {
                         // do nothing, only add if not already in unique collection
                     } else {
                         if (col.size() + 1 > fieldType.getUpperBound()) {
                             // if upper bound reached, throw an exception
                             throw new WikittyException(String.format(
                                     "Can't add value for field '%s', upper bound is reached",
                                     WikittyUtil.getFQFieldName(extfieldName)));
                         }
                         col.add(validValue);
                         // if user pass in argument object that permit to take wikitty,
                         // we put it, in preload map
                         if (fieldType.getType() == .) {
                             Wikitty w = WikittyUtil.getWikitty(value);
                             addPreloaded(w);
                         }
                         setFieldDirty(extfieldNamenullcol);
                     }
                 }
             } catch (Exception eee) {
                 throw new WikittyException(String.format(
                         "Can't add value to field '%s'",
                         WikittyUtil.getFQFieldName(extfieldName)), eee);
             }
         }
     
         /*
          * @see org.nuiton.wikitty.Wikitty#removeFromField(java.lang.String, java.lang.String, java.lang.Object)
          */
         @Override
         public void removeFromField(String extString fieldNameObject value) {
             try {
                 Collection col = (CollectiongetFieldAsObject(extfieldName);
                 if (col != null) {
                     FieldType type = getExtension(ext).getFieldType(fieldName);
                     Object validValue = type.getContainedValidObject(value);
                     if (col.contains(validValue)) {
                        if (col.size() - 1 < type.getLowerBound()) {
                            throw new WikittyException(String.format(
                                    "Can't remove value for field '%s', lower bound is reached",
                                    WikittyUtil.getFQFieldName(extfieldName)));
                        } else {
                            if (col.remove(validValue)) {
                                // field is dirty only if remove is done
                                setFieldDirty(extfieldNamenullcol);
                            }
                        }
                    }
                }
            } catch (Exception eee) {
                throw new WikittyException(String.format(
                        "Can't remove value for field '%s'",
                        WikittyUtil.getFQFieldName(extfieldName)), eee);
            }
        }
        /*
         * @see org.nuiton.wikitty.Wikitty#clearField(java.lang.String, java.lang.String)
         */
        @Override
        public void clearField(String extString fieldName) {
            FieldType type = getExtension(ext).getFieldType(fieldName);
            if (type.getLowerBound() > 0) {
                throw new WikittyException(String.format(
                        "Can't clear values for field '%s', lower bound is > 0",
                        WikittyUtil.getFQFieldName(extfieldName)));
            }
            try {
                Collection col = (CollectiongetFieldAsObject(extfieldName);
                if (col != null) {
                    col.clear();
                    setFieldDirty(extfieldNamenullcol);
                }
            } catch (Exception eee) {
                throw new WikittyException(String.format(
                        "Can't clear value for field '%s'",
                        WikittyUtil.getFQFieldName(extfieldName)), eee);
            }
        }
        
        
        @Override
        public void addToField(String fqFieldNameObject value) {
            String[] extAndField = fqFieldName.split("\\.");
            addToField(extAndField[0], extAndField[1], value);
        }

        
        @Override
        public void removeFromField(String fqFieldNameObject value) {
            String[] extAndField = fqFieldName.split("\\.");
            removeFromField(extAndField[0], extAndField[1], value);
        }

        
        @Override
        public void clearField(String fqFieldName) {
            String[] extAndField = fqFieldName.split("\\.");
            clearField(extAndField[0], extAndField[1]);
        }
        @Override
        public boolean equals(Object obj) {
            boolean result = false;
            if (obj instanceof Wikitty) {
                Wikitty other = (Wikittyobj;
                result = .equals(other.getWikittyId());
            }
            return result;
        }
        @Override
        public int hashCode() {
            if ( == null) {
                return super.hashCode();
            } else {
                return .hashCode();
            }
        }
        /*
         * @see org.nuiton.wikitty.Wikitty#fieldNames()
         */
        @Override
        public Set<StringfieldNames() {
            return .keySet();
        }
        @Override
        public Map<StringObjectgetFieldValue() {
            return Collections.unmodifiableMap();
        }
        @Override
        public Set<StringgetAllFieldNames() {
            Set<Stringresult = new HashSet<String>();
            for (WikittyExtension ext : getExtensions()) {
                String extName = ext.getName() + .;
                for (String f : ext.getFieldNames()) {
                    result.add(extName + f);
                }
            }
            return result;
        }
        /*
         * @see org.nuiton.wikitty.Wikitty#getFqField(java.lang.String)
         */
        @Override
        public Object