All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.helger.masterdata.ean.AbstractUPCEAN Maven / Gradle / Ivy

/**
 * Copyright (C) 2014-2017 Philip Helger (www.helger.com)
 * philip[at]helger[dot]com
 *
 * Licensed 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.
 */
package com.helger.masterdata.ean;

import javax.annotation.Nonnegative;
import javax.annotation.Nonnull;

import com.helger.commons.ValueEnforcer;
import com.helger.commons.state.EValidity;

public abstract class AbstractUPCEAN
{
  protected static final EEANChecksumMode DEFAULT_CHECKSUM_MODE = EEANChecksumMode.AUTO;

  private final String m_sMsg;
  private final EEANChecksumMode m_eChecksumMode;

  /**
   * Main constructor
   *
   * @param sMsg
   *        The code string.
   * @param eMode
   *        the checksum mode
   */
  public AbstractUPCEAN (@Nonnull final String sMsg, @Nonnull final EEANChecksumMode eMode)
  {
    m_sMsg = ValueEnforcer.notNull (sMsg, "Msg");
    m_eChecksumMode = ValueEnforcer.notNull (eMode, "ChecksumMode");
  }

  @Nonnull
  public String getMessage ()
  {
    return m_sMsg;
  }

  /**
   * Returns the current checksum mode.
   *
   * @return the checksum mode
   */
  @Nonnull
  public EEANChecksumMode getChecksumMode ()
  {
    return m_eChecksumMode;
  }

  /**
   * Validate this code.
   *
   * @return {@link EValidity#VALID} if the msg is valid,
   *         {@link EValidity#INVALID} otherwise.
   */
  @Nonnull
  protected abstract EValidity validate ();

  /**
   * Validates a UPC/EAN message.
   *
   * @param sMsg
   *        the message to validate
   * @return {@link EValidity#VALID} if the msg is valid,
   *         {@link EValidity#INVALID} otherwise.
   */
  @Nonnull
  protected static EValidity validateMessage (@Nonnull final String sMsg)
  {
    ValueEnforcer.notNull (sMsg, "Msg");

    return validateMessage (sMsg.toCharArray ());
  }

  /**
   * Validates a UPC/EAN/GTIN/GLN message.
   *
   * @param aChars
   *        the chars to validate
   * @return {@link EValidity#VALID} if the msg is valid,
   *         {@link EValidity#INVALID} otherwise.
   */
  @Nonnull
  protected static EValidity validateMessage (@Nonnull final char [] aChars)
  {
    ValueEnforcer.notNull (aChars, "Chars");

    for (final char c : aChars)
      if (c < '0' || c > '9')
        return EValidity.INVALID;
    return EValidity.VALID;
  }

  static int asInt (final char c)
  {
    return Character.digit (c, 10);
  }

  static char asChar (final int i)
  {
    return Character.forDigit (i, 10);
  }

  protected static int calcChecksum (@Nonnull final char [] aChars, @Nonnegative final int nLen)
  {
    int nChecksumBase = 0;
    int nFactor = (nLen % 2) == 0 ? 1 : 3;
    for (int i = 0; i < nLen; ++i)
    {
      nChecksumBase += asInt (aChars[i]) * nFactor;
      nFactor = 4 - nFactor;
    }

    // 1000 is larger as "18*9*3" (18 == length of SSCC; 9 == largest possible
    // number; 3 == largest multiplication factor)
    return (1000 - nChecksumBase) % 10;
  }

  /**
   * Calculates the check character for a given message
   *
   * @param sMsg
   *        the message
   * @param nLength
   *        The number of characters to be checked. Must be ≥ 0 and <
   *        message.length
   * @return char the check character
   */
  protected static char calcChecksumChar (@Nonnull final String sMsg, @Nonnegative final int nLength)
  {
    ValueEnforcer.notNull (sMsg, "Msg");
    ValueEnforcer.isBetweenInclusive (nLength, "Length", 0, sMsg.length ());

    return asChar (calcChecksum (sMsg.toCharArray (), nLength));
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy