content: package com.onegravity.rteditor.utils.validator;
  
  /*
   * Licensed to the Apache Software Foundation (ASF) under one or more
   * contributor license agreements.  See the NOTICE file distributed with
   * this work for additional information regarding copyright ownership.
   * The ASF licenses this file to You under the Apache License, Version 2.0
   * (the "License"); you may not use this file except in compliance with
   * the License.  You may obtain a copy of the License at
   *
   *      http://www.apache.org/licenses/LICENSE-2.0
   *
   * Unless required by applicable law or agreed to in writing, software
   * distributed under the License is distributed on an "AS IS" BASIS,
   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
   * See the License for the specific language governing permissions and
   * limitations under the License.
   */
  
  import java.io.Serializable;
  import java.io.Serializable;
  import java.util.regex.Matcher;
  import java.util.regex.Pattern;
  
  /**
   * <p>Perform email validations.</p>
   * <p>
   * Based on a script by <a href="mailto:stamhankar@hotmail.com">Sandeep V. Tamhankar</a>
   * http://javascript.internet.com
   * </p>
   * <p>
   * This implementation is not guaranteed to catch all possible errors in an email address.
   * </p>.
   *
   * @version $Revision: 1649927 $
   * @since Validator 1.4
   */
  public class EmailValidator implements Serializable {
  
      private static final long serialVersionUID = 1705927040799295880L;
  
      private static final String SPECIAL_CHARS = "\\p{Cntrl}\\(\\)<>@,;:'\\\\\\\"\\.\\[\\]";
      private static final String VALID_CHARS = "[^\\s" + SPECIAL_CHARS + "]";
      private static final String QUOTED_USER = "(\"[^\"]*\")";
      private static final String WORD = "((" + VALID_CHARS + "|')+|" + QUOTED_USER + ")";
  
      private static final String EMAIL_REGEX = "^\\s*?(.+)@(.+?)\\s*$";
      private static final String IP_DOMAIN_REGEX = "^\\[(.*)\\]$";
      private static final String USER_REGEX = "^\\s*" + WORD + "(\\." + WORD + ")*$";
  
      private static final Pattern EMAIL_PATTERN = Pattern.compile(EMAIL_REGEX);
      private static final Pattern IP_DOMAIN_PATTERN = Pattern.compile(IP_DOMAIN_REGEX);
      private static final Pattern USER_PATTERN = Pattern.compile(USER_REGEX);
  
      private final boolean allowLocal;
  
      /**
       * Singleton instance of this class, which
       * doesn't consider local addresses as valid.
       */
      private static final EmailValidator EMAIL_VALIDATOR = new EmailValidator(false);
  
      /**
       * Singleton instance of this class, which does
       * consider local addresses valid.
       */
      private static final EmailValidator EMAIL_VALIDATOR_WITH_LOCAL = new EmailValidator(true);
  
      /**
       * Returns the Singleton instance of this validator.
       *
       * @return singleton instance of this validator.
       */
      public static EmailValidator getInstance() {
          return EMAIL_VALIDATOR;
      }
  
      /**
       * Returns the Singleton instance of this validator,
       * with local validation as required.
       *
       * @param allowLocal Should local addresses be considered valid?
       * @return singleton instance of this validator
       */
      public static EmailValidator getInstance(boolean allowLocal) {
          if (allowLocal) {
              return EMAIL_VALIDATOR_WITH_LOCAL;
          }
          return EMAIL_VALIDATOR;
      }
  
      /**
       * Protected constructor for subclasses to use.
       *
       * @param allowLocal Should local addresses be considered valid?
       */
      protected EmailValidator(boolean allowLocal) {
          super();
          this.allowLocal = allowLocal;
      }
  
      /**
       * <p>Checks if a field has a valid e-mail address.</p>
       *
       * @param email The value validation is being performed on.  A <code>null</code>
       *              value is considered invalid.
       * @return true if the email address is valid.
       */
      public boolean isValid(String email) {
          if (email == null) {
              return false;
          }
  
          if (email.endsWith(".")) { // check this first - it's cheap!
              return false;
          }
  
          // Check the whole email address structure
          Matcher emailMatcher = EMAIL_PATTERN.matcher(email);
          if (!emailMatcher.matches()) {
              return false;
          }
  
          if (!isValidUser(emailMatcher.group(1))) {
              return false;
          }
  
          if (!isValidDomain(emailMatcher.group(2))) {
              return false;
          }
  
          return true;
      }
  
      /**
       * Returns true if the domain component of an email address is valid.
       *
       * @param domain being validated, may be in IDN format
       * @return true if the email address's domain is valid.
       */
      protected boolean isValidDomain(String domain) {
          // see if domain is an IP address in brackets
          Matcher ipDomainMatcher = IP_DOMAIN_PATTERN.matcher(domain);
  
          if (ipDomainMatcher.matches()) {
              InetAddressValidator inetAddressValidator =
                      InetAddressValidator.getInstance();
              return inetAddressValidator.isValid(ipDomainMatcher.group(1));
          }
          // Domain is symbolic name
          DomainValidator domainValidator =
                  DomainValidator.getInstance(allowLocal);
          return domainValidator.isValid(domain) ||
                  domainValidator.isValidTld(domain);
      }
  
      /**
       * Returns true if the user component of an email address is valid.
       *
       * @param user being validated
       * @return true if the user name is valid.
       */
      protected boolean isValidUser(String user) {
          return USER_PATTERN.matcher(user).matches();
      }
  
  }
  