/hudson-core/src/main/java/hudson/tasks/MailAddressResolver.java

http://github.com/hudson/hudson · Java · 163 lines · 52 code · 15 blank · 96 comment · 9 complexity · 4585cb6b2ba452ac8de93cacfa536ad5 MD5 · raw file

  1. /*
  2. * The MIT License
  3. *
  4. * Copyright (c) 2004-2009, Sun Microsystems, Inc., Kohsuke Kawaguchi, Luca Domenico Milanesio
  5. *
  6. * Permission is hereby granted, free of charge, to any person obtaining a copy
  7. * of this software and associated documentation files (the "Software"), to deal
  8. * in the Software without restriction, including without limitation the rights
  9. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. * copies of the Software, and to permit persons to whom the Software is
  11. * furnished to do so, subject to the following conditions:
  12. *
  13. * The above copyright notice and this permission notice shall be included in
  14. * all copies or substantial portions of the Software.
  15. *
  16. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. * THE SOFTWARE.
  23. */
  24. package hudson.tasks;
  25. import hudson.Extension;
  26. import hudson.ExtensionList;
  27. import hudson.ExtensionListView;
  28. import hudson.ExtensionPoint;
  29. import hudson.model.Hudson;
  30. import hudson.model.User;
  31. import hudson.model.UserProperty;
  32. import hudson.scm.SCM;
  33. import java.util.List;
  34. import java.util.logging.Logger;
  35. import java.util.regex.Matcher;
  36. import java.util.regex.Pattern;
  37. /**
  38. * Infers e-mail addresses for the user when none is specified.
  39. *
  40. * <p>
  41. * This is an extension point of Hudson. Plugins tha contribute new implementation
  42. * of this class should put {@link Extension} on your implementation class, like this:
  43. *
  44. * <pre>
  45. * &#64;Extension
  46. * class MyMailAddressResolver extends {@link MailAddressResolver} {
  47. * ...
  48. * }
  49. * </pre>
  50. *
  51. * <h2>Techniques</h2>
  52. * <p>
  53. * User identity in Hudson is global, and not specific to a particular job. As a result, mail address resolution
  54. * only receives {@link User}, which by itself doesn't really have that much information in it.
  55. *
  56. * <p>
  57. * So the common technique for a mail address resolution is to define your own {@link UserProperty} types and
  58. * add it to {@link User} objects where more context is available. For example, an {@link SCM} implementation
  59. * can have a lot more information about a particular user during a check out, so that would be a good place
  60. * to capture information as {@link UserProperty}, which then later used by a {@link MailAddressResolver}.
  61. *
  62. * @author Kohsuke Kawaguchi
  63. * @since 1.192
  64. */
  65. public abstract class MailAddressResolver implements ExtensionPoint {
  66. /**
  67. * Infers e-mail address of the given user.
  68. *
  69. * <p>
  70. * This method is called when a {@link User} without explicitly configured e-mail
  71. * address is used, as an attempt to infer e-mail address.
  72. *
  73. * <p>
  74. * The normal strategy is to look at {@link User#getProjects() the projects that the user
  75. * is participating}, then use the repository information to infer the e-mail address.
  76. *
  77. * <p>
  78. * When multiple resolvers are installed, they are consulted in order and
  79. * the search will be over when an address is inferred by someone.
  80. *
  81. * <p>
  82. * Since {@link MailAddressResolver} is singleton, this method can be invoked concurrently
  83. * from multiple threads.
  84. *
  85. * @return
  86. * null if the inference failed.
  87. */
  88. public abstract String findMailAddressFor(User u);
  89. public static String resolve(User u) {
  90. LOGGER.fine("Resolving e-mail address for \""+u+"\" ID="+u.getId());
  91. for (MailAddressResolver r : all()) {
  92. String email = r.findMailAddressFor(u);
  93. if(email!=null) {
  94. LOGGER.fine(r+" resolved "+u.getId()+" to "+email);
  95. return email;
  96. }
  97. }
  98. // fall back logic
  99. String extractedAddress = extractAddressFromId(u.getFullName());
  100. if (extractedAddress != null)
  101. return extractedAddress;
  102. if(u.getFullName().contains("@"))
  103. // this already looks like an e-mail ID
  104. return u.getFullName();
  105. String ds = Mailer.descriptor().getDefaultSuffix();
  106. if(ds!=null) {
  107. // another common pattern is "DOMAIN\person" in Windows. Only
  108. // do this when this full name is not manually set. see HUDSON-5164
  109. Matcher m = WINDOWS_DOMAIN_REGEXP.matcher(u.getFullName());
  110. if (m.matches() && u.getFullName().replace('\\','_').equals(u.getId()))
  111. return m.group(1)+ds; // user+defaultSuffix
  112. return u.getId()+ds;
  113. } else
  114. return null;
  115. }
  116. /**
  117. * Tries to extract an email address from the user id, or returns null
  118. */
  119. private static String extractAddressFromId(String id) {
  120. Matcher m = EMAIL_ADDRESS_REGEXP.matcher(id);
  121. if(m.matches())
  122. return m.group(1);
  123. return null;
  124. }
  125. /**
  126. * Matches strings like "Kohsuke Kawaguchi &lt;kohsuke.kawaguchi@sun.com>"
  127. * @see #extractAddressFromId(String)
  128. */
  129. private static final Pattern EMAIL_ADDRESS_REGEXP = Pattern.compile("^.*<([^>]+)>.*$");
  130. /**
  131. * Matches something like "DOMAIN\person"
  132. */
  133. private static final Pattern WINDOWS_DOMAIN_REGEXP = Pattern.compile("[^\\\\ ]+\\\\([^\\\\ ]+)");
  134. /**
  135. * All registered {@link MailAddressResolver} implementations.
  136. *
  137. * @deprecated as of 1.286
  138. * Use {@link #all()} for read access and {@link Extension} for registration.
  139. */
  140. public static final List<MailAddressResolver> LIST = ExtensionListView.createList(MailAddressResolver.class);
  141. /**
  142. * Returns all the registered {@link MailAddressResolver} descriptors.
  143. */
  144. public static ExtensionList<MailAddressResolver> all() {
  145. return Hudson.getInstance().getExtensionList(MailAddressResolver.class);
  146. }
  147. private static final Logger LOGGER = Logger.getLogger(MailAddressResolver.class.getName());
  148. }