Commits

Sebastian Sdorra committed c654976

prepare for version 1.17

Comments (0)

Files changed (6)

   <parent>
     <artifactId>scm-plugins</artifactId>
     <groupId>sonia.scm.plugins</groupId>
-    <version>1.8</version>
+    <version>1.17-SNAPSHOT</version>
   </parent>
 
   <groupId>sonia.scm.plugins</groupId>
     <developerConnection>scm:hg:https://bitbucket.org/sdorra/scm-authormapping-plugin</developerConnection>
     <url>https://bitbucket.org/sdorra/scm-authormapping-plugin</url>
   </scm>
-  
-  <build>
-    <plugins>
-      
-      <plugin>
-        <groupId>sonia.scm.maven</groupId>
-        <artifactId>scm-maven-plugin</artifactId>
-        <version>1.10</version>
-        <executions>
-          <execution>
-            <phase>process-resources</phase>
-            <goals>
-              <goal>fix-descriptor</goal>
-            </goals>
-          </execution>
-        </executions>
-      </plugin>
-    
-    </plugins>
-  </build>
 
   <dependencies>
 

src/main/java/sonia/scm/authormapping/AbstractMappingPreProcessorFactory.java

+/**
+ * Copyright (c) 2010, Sebastian Sdorra All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer. 2. Redistributions in
+ * binary form must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution. 3. Neither the name of SCM-Manager;
+ * nor the names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://bitbucket.org/sdorra/scm-manager
+ *
+ */
+
+
+
+package sonia.scm.authormapping;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import sonia.scm.cache.Cache;
+import sonia.scm.cache.CacheManager;
+import sonia.scm.repository.Person;
+import sonia.scm.repository.Repository;
+import sonia.scm.user.UserManager;
+import sonia.scm.util.AssertUtil;
+import sonia.scm.web.security.AdministrationContext;
+
+/**
+ *
+ * @author Sebastian Sdorra
+ */
+public class AbstractMappingPreProcessorFactory
+{
+
+  /** Field description */
+  public static final String CACHE_NAME = "sonia.cache.authormapping";
+
+  /**
+   * the logger for MappingChangesetPreProcessorFactory
+   */
+  private static final Logger logger =
+    LoggerFactory.getLogger(AbstractMappingPreProcessorFactory.class);
+
+  //~--- constructors ---------------------------------------------------------
+
+  /**
+   * Constructs ...
+   *
+   *
+   * @param adminContext
+   * @param userManager
+   * @param cacheManager
+   */
+  protected AbstractMappingPreProcessorFactory(
+          AdministrationContext adminContext, UserManager userManager,
+          CacheManager cacheManager)
+  {
+    this.adminContext = adminContext;
+    this.userManager = userManager;
+    this.cache = cacheManager.getCache(String.class, Person.class, CACHE_NAME);
+    this.userManager.addListener(new MappingCacheListener(cache));
+  }
+
+  //~--- methods --------------------------------------------------------------
+
+  /**
+   * Method description
+   *
+   *
+   * @param repository
+   *
+   * @return
+   */
+  public MappingPreProcessor createMappingPreProcessor(
+          Repository repository)
+  {
+    AssertUtil.assertIsNotNull(repository);
+
+    if (logger.isTraceEnabled())
+    {
+      logger.trace("create MappingPreProcessor for repository {}",
+                   repository.getName());
+    }
+
+    MappingResolver resolver = new MappingResolver(adminContext, userManager,
+                                 cache, new MappingConfiguration(repository));
+
+    return new MappingPreProcessor(resolver);
+  }
+
+  //~--- fields ---------------------------------------------------------------
+
+  /** Field description */
+  private AdministrationContext adminContext;
+
+  /** Field description */
+  private Cache<String, Person> cache;
+
+  /** Field description */
+  private UserManager userManager;
+}

src/main/java/sonia/scm/authormapping/MappingBlameLinePreProcessorFactory.java

+/**
+ * Copyright (c) 2010, Sebastian Sdorra All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * this list of conditions and the following disclaimer. 2. Redistributions in
+ * binary form must reproduce the above copyright notice, this list of
+ * conditions and the following disclaimer in the documentation and/or other
+ * materials provided with the distribution. 3. Neither the name of SCM-Manager;
+ * nor the names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR
+ * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://bitbucket.org/sdorra/scm-manager
+ *
+ */
+
+
+
+package sonia.scm.authormapping;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import com.google.inject.Inject;
+import com.google.inject.Singleton;
+
+import sonia.scm.cache.CacheManager;
+import sonia.scm.plugin.ext.Extension;
+import sonia.scm.repository.BlameLinePreProcessorFactory;
+import sonia.scm.repository.Repository;
+import sonia.scm.user.UserManager;
+import sonia.scm.web.security.AdministrationContext;
+
+/**
+ *
+ * @author Sebastian Sdorra
+ */
+@Singleton
+@Extension
+public class MappingBlameLinePreProcessorFactory
+        extends AbstractMappingPreProcessorFactory
+        implements BlameLinePreProcessorFactory
+{
+
+  /**
+   * Constructs ...
+   *
+   *
+   * @param adminContext
+   * @param userManager
+   * @param cacheManager
+   */
+  @Inject
+  public MappingBlameLinePreProcessorFactory(
+          AdministrationContext adminContext, UserManager userManager,
+          CacheManager cacheManager)
+  {
+    super(adminContext, userManager, cacheManager);
+  }
+
+  //~--- methods --------------------------------------------------------------
+
+  /**
+   * Method description
+   *
+   *
+   * @param repository
+   *
+   * @return
+   */
+  @Override
+  public MappingPreProcessor createPreProcessor(Repository repository)
+  {
+    return createMappingPreProcessor(repository);
+  }
+}

src/main/java/sonia/scm/authormapping/MappingChangesetPreProcessor.java

-/**
- * Copyright (c) 2010, Sebastian Sdorra
- * All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *
- * 1. Redistributions of source code must retain the above copyright notice,
- *    this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright notice,
- *    this list of conditions and the following disclaimer in the documentation
- *    and/or other materials provided with the distribution.
- * 3. Neither the name of SCM-Manager; nor the names of its
- *    contributors may be used to endorse or promote products derived from this
- *    software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
- * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
- * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
- * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * http://bitbucket.org/sdorra/scm-manager
- *
- */
-
-
-
-package sonia.scm.authormapping;
-
-//~--- non-JDK imports --------------------------------------------------------
-
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import sonia.scm.repository.Changeset;
-import sonia.scm.repository.ChangesetPreProcessor;
-import sonia.scm.repository.Person;
-import sonia.scm.util.AssertUtil;
-import sonia.scm.util.Util;
-
-//~--- JDK imports ------------------------------------------------------------
-
-import java.io.UnsupportedEncodingException;
-
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-
-/**
- *
- * @author Sebastian Sdorra
- */
-public class MappingChangesetPreProcessor implements ChangesetPreProcessor
-{
-
-  /** Field description */
-  public static final String DIGEST_ENCODING = "CP1252";
-
-  /** Field description */
-  public static final String DIGEST_TYPE = "MD5";
-
-  /** Field description */
-  public static final String PROPERTY_GRAVATAR = "gravatar-hash";
-
-  /** the logger for MappingChangesetPreProcessor */
-  private static final Logger logger =
-    LoggerFactory.getLogger(MappingChangesetPreProcessor.class);
-
-  //~--- constructors ---------------------------------------------------------
-
-  /**
-   * Constructs ...
-   *
-   *
-   *
-   * @param resolver
-   */
-  public MappingChangesetPreProcessor(MappingResolver resolver)
-  {
-    this.resolver = resolver;
-  }
-
-  //~--- methods --------------------------------------------------------------
-
-  /**
-   * Method description
-   *
-   *
-   * @param changeset
-   */
-  @Override
-  public void process(Changeset changeset)
-  {
-    AssertUtil.assertIsNotNull(changeset);
-
-    Person person = changeset.getAuthor();
-
-    if (person == null)
-    {
-      person = new Person();
-    }
-
-    String name = person.getName();
-
-    if (Util.isNotEmpty(name))
-    {
-      person = resolver.resolve(name, person.getMail());
-      changeset.setAuthor(person);
-
-      // append gravatar hash to fix plugin order
-      appendGravatarProperty(changeset, person);
-    }
-    else if (logger.isWarnEnabled())
-    {
-      logger.warn("person object of changeset {} has no name",
-                  changeset.getId());
-    }
-  }
-
-  /**
-   * Method description
-   *
-   *
-   * @param changeset
-   * @param author
-   */
-  private void appendGravatarProperty(Changeset changeset, Person author)
-  {
-    String gravatarHash = changeset.getProperty(PROPERTY_GRAVATAR);
-
-    if (Util.isNotEmpty(gravatarHash))
-    {
-      setGravatarHash(changeset, author);
-    }
-  }
-
-  /**
-   * Method description
-   *
-   *
-   * @param array
-   *
-   * @return
-   */
-  private String hex(byte[] array)
-  {
-    StringBuilder sb = new StringBuilder();
-
-    for (int i = 0; i < array.length; ++i)
-    {
-      sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1, 3));
-    }
-
-    return sb.toString();
-  }
-
-  /**
-   * Method description
-   *
-   *
-   * @param message
-   *
-   * @return
-   */
-  private String md5Hex(String message)
-  {
-    String out = null;
-
-    if (Util.isNotEmpty(message))
-    {
-      message = message.toLowerCase().trim();
-
-      try
-      {
-        MessageDigest md = MessageDigest.getInstance(DIGEST_TYPE);
-
-        out = hex(md.digest(message.getBytes(DIGEST_ENCODING)));
-      }
-      catch (NoSuchAlgorithmException ex)
-      {
-        logger.error(ex.getMessage(), ex);
-      }
-      catch (UnsupportedEncodingException ex)
-      {
-        logger.error(ex.getMessage(), ex);
-      }
-    }
-
-    return out;
-  }
-
-  //~--- set methods ----------------------------------------------------------
-
-  /**
-   * Method description
-   *
-   *
-   * @param changeset
-   * @param person
-   */
-  private void setGravatarHash(Changeset changeset, Person person)
-  {
-    String value = person.getMail();
-
-    if (Util.isEmpty(value))
-    {
-      value = person.getName();
-    }
-
-    if (Util.isNotEmpty(value))
-    {
-      value = md5Hex(value);
-      changeset.setProperty(PROPERTY_GRAVATAR, value);
-    }
-  }
-
-  //~--- fields ---------------------------------------------------------------
-
-  /** Field description */
-  private MappingResolver resolver;
-}

src/main/java/sonia/scm/authormapping/MappingChangesetPreProcessorFactory.java

 import com.google.inject.Inject;
 import com.google.inject.Singleton;
 
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
-
-import sonia.scm.cache.Cache;
 import sonia.scm.cache.CacheManager;
 import sonia.scm.plugin.ext.Extension;
 import sonia.scm.repository.ChangesetPreProcessor;
 import sonia.scm.repository.ChangesetPreProcessorFactory;
-import sonia.scm.repository.Person;
 import sonia.scm.repository.Repository;
 import sonia.scm.user.UserManager;
-import sonia.scm.util.AssertUtil;
 import sonia.scm.web.security.AdministrationContext;
 
 /**
 @Singleton
 @Extension
 public class MappingChangesetPreProcessorFactory
+        extends AbstractMappingPreProcessorFactory
         implements ChangesetPreProcessorFactory
 {
 
-  /** Field description */
-  public static final String CACHE_NAME = "sonia.cache.authormapping";
-
-  /**
-   * the logger for MappingChangesetPreProcessorFactory
-   */
-  private static final Logger logger =
-    LoggerFactory.getLogger(MappingChangesetPreProcessorFactory.class);
-
-  //~--- constructors ---------------------------------------------------------
-
   /**
    * Constructs ...
    *
           AdministrationContext adminContext, UserManager userManager,
           CacheManager cacheManager)
   {
-    this.adminContext = adminContext;
-    this.userManager = userManager;
-    this.cache = cacheManager.getCache(String.class, Person.class, CACHE_NAME);
-    this.userManager.addListener(new MappingCacheListener(cache));
+    super(adminContext, userManager, cacheManager);
   }
 
   //~--- methods --------------------------------------------------------------
   @Override
   public ChangesetPreProcessor createPreProcessor(Repository repository)
   {
-    AssertUtil.assertIsNotNull(repository);
-
-    if (logger.isTraceEnabled())
-    {
-      logger.trace("create MappingChangesetPreProcessor for repository {}",
-                   repository.getName());
-    }
-
-    MappingResolver resolver = new MappingResolver(adminContext, userManager,
-                                 cache, new MappingConfiguration(repository));
-
-    return new MappingChangesetPreProcessor(resolver);
+    return createMappingPreProcessor(repository);
   }
-
-  //~--- fields ---------------------------------------------------------------
-
-  /** Field description */
-  private AdministrationContext adminContext;
-
-  /** Field description */
-  private Cache<String, Person> cache;
-
-  /** Field description */
-  private UserManager userManager;
 }

src/main/java/sonia/scm/authormapping/MappingPreProcessor.java

+/**
+ * Copyright (c) 2010, Sebastian Sdorra
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ * 3. Neither the name of SCM-Manager; nor the names of its
+ *    contributors may be used to endorse or promote products derived from this
+ *    software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
+ * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * http://bitbucket.org/sdorra/scm-manager
+ *
+ */
+
+
+
+package sonia.scm.authormapping;
+
+//~--- non-JDK imports --------------------------------------------------------
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import sonia.scm.repository.BlameLine;
+import sonia.scm.repository.BlameLinePreProcessor;
+import sonia.scm.repository.Changeset;
+import sonia.scm.repository.ChangesetPreProcessor;
+import sonia.scm.repository.Person;
+import sonia.scm.util.AssertUtil;
+import sonia.scm.util.Util;
+
+//~--- JDK imports ------------------------------------------------------------
+
+import java.io.UnsupportedEncodingException;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+/**
+ *
+ * @author Sebastian Sdorra
+ */
+public class MappingPreProcessor
+        implements ChangesetPreProcessor, BlameLinePreProcessor
+{
+
+  /** Field description */
+  public static final String DIGEST_ENCODING = "CP1252";
+
+  /** Field description */
+  public static final String DIGEST_TYPE = "MD5";
+
+  /** Field description */
+  public static final String PROPERTY_GRAVATAR = "gravatar-hash";
+
+  /** the logger for MappingPreProcessor */
+  private static final Logger logger =
+    LoggerFactory.getLogger(MappingPreProcessor.class);
+
+  //~--- constructors ---------------------------------------------------------
+
+  /**
+   * Constructs ...
+   *
+   *
+   *
+   * @param resolver
+   */
+  public MappingPreProcessor(MappingResolver resolver)
+  {
+    this.resolver = resolver;
+  }
+
+  //~--- methods --------------------------------------------------------------
+
+  /**
+   * Method description
+   *
+   *
+   * @param changeset
+   */
+  @Override
+  public void process(Changeset changeset)
+  {
+    AssertUtil.assertIsNotNull(changeset);
+
+    Person person = changeset.getAuthor();
+
+    person = resolve(person);
+    changeset.setAuthor(person);
+
+    // append gravatar hash to fix plugin order
+    appendGravatarProperty(changeset, person);
+  }
+
+  /**
+   * Method description
+   *
+   *
+   * @param blameLine
+   */
+  @Override
+  public void process(BlameLine blameLine)
+  {
+    AssertUtil.assertIsNotNull(blameLine);
+
+    Person person = blameLine.getAuthor();
+
+    person = resolve(person);
+    blameLine.setAuthor(person);
+  }
+
+  /**
+   * Method description
+   *
+   *
+   * @param changeset
+   * @param author
+   */
+  private void appendGravatarProperty(Changeset changeset, Person author)
+  {
+    String gravatarHash = changeset.getProperty(PROPERTY_GRAVATAR);
+
+    if (Util.isNotEmpty(gravatarHash))
+    {
+      setGravatarHash(changeset, author);
+    }
+  }
+
+  /**
+   * Method description
+   *
+   *
+   * @param array
+   *
+   * @return
+   */
+  private String hex(byte[] array)
+  {
+    StringBuilder sb = new StringBuilder();
+
+    for (int i = 0; i < array.length; ++i)
+    {
+      sb.append(Integer.toHexString((array[i] & 0xFF) | 0x100).substring(1, 3));
+    }
+
+    return sb.toString();
+  }
+
+  /**
+   * Method description
+   *
+   *
+   * @param message
+   *
+   * @return
+   */
+  private String md5Hex(String message)
+  {
+    String out = null;
+
+    if (Util.isNotEmpty(message))
+    {
+      message = message.toLowerCase().trim();
+
+      try
+      {
+        MessageDigest md = MessageDigest.getInstance(DIGEST_TYPE);
+
+        out = hex(md.digest(message.getBytes(DIGEST_ENCODING)));
+      }
+      catch (NoSuchAlgorithmException ex)
+      {
+        logger.error(ex.getMessage(), ex);
+      }
+      catch (UnsupportedEncodingException ex)
+      {
+        logger.error(ex.getMessage(), ex);
+      }
+    }
+
+    return out;
+  }
+
+  /**
+   * Method description
+   *
+   *
+   * @param person
+   *
+   * @return
+   */
+  private Person resolve(Person person)
+  {
+    if (person == null)
+    {
+      person = new Person();
+    }
+
+    String name = person.getName();
+
+    if (Util.isNotEmpty(name))
+    {
+      person = resolver.resolve(name, person.getMail());
+    }
+    else if (logger.isWarnEnabled())
+    {
+      logger.warn("person object has no name");
+    }
+
+    return person;
+  }
+
+  //~--- set methods ----------------------------------------------------------
+
+  /**
+   * Method description
+   *
+   *
+   * @param changeset
+   * @param person
+   */
+  private void setGravatarHash(Changeset changeset, Person person)
+  {
+    String value = person.getMail();
+
+    if (Util.isEmpty(value))
+    {
+      value = person.getName();
+    }
+
+    if (Util.isNotEmpty(value))
+    {
+      value = md5Hex(value);
+      changeset.setProperty(PROPERTY_GRAVATAR, value);
+    }
+  }
+
+  //~--- fields ---------------------------------------------------------------
+
+  /** Field description */
+  private MappingResolver resolver;
+}