TariffHeading.java
package com.tradecloud.domain.duties;
import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang3.StringUtils;
import javax.persistence.Column;
import javax.persistence.Embeddable;
import java.io.Serializable;
/**
* The tariff heading describes what product it applies to.
* It was decided that the tariff heading warranted its own object instead of a
* simple String as there are validation rules around this heading which
* requires examining the internal parts.
* See https://connect.devstream.net/display/Dev/Tariffing for further
* information.
*/
@Embeddable
public class TariffHeading implements Serializable, Cloneable {
private static final long serialVersionUID = 1L;
@Column(length = 4)
private String part1;
@Column(length = 2)
private String part2;
@Column(length = 2)
private String part3;
@Column(length = 2)
private String part4;
@Column(length = 2)
private String part5;
public static final int PART2_MAX_LENGTH = 2;
public static final int PART3_MAX_LENGTH = 2;
public static final int PARTS_MAX_LENGTH = 3;
private transient boolean failOnInValidaTariff = true;
private transient boolean validFormat = true;
public TariffHeading() {
}
/**
* Sets each part of the tariff heading by delegating to
* {@link #setPart1(String)}, {@link #setPart2(String)}, and
* {@link #setPart3(String)}.
*
* @param part1 the first part of the tariff heading
* @param part2 the second part of the tariff heading
* @param part3 the third part of the tariff heading
*/
public TariffHeading(String part1, String part2, String part3) {
setPart1(StringUtils.trim(part1));
setPart2(StringUtils.trim(part2));
setPart3(StringUtils.trim(part3));
}
public TariffHeading(String part1, String part2, String part3, String part4) {
setPart1(StringUtils.trim(part1));
setPart2(StringUtils.trim(part2));
setPart3(StringUtils.trim(part3));
setPart4(StringUtils.trim(part4));
}
public TariffHeading(TariffHeading tariffHeading) {
setPart1(StringUtils.trim(tariffHeading.part1));
setPart2(StringUtils.trim(tariffHeading.part2));
setPart3(StringUtils.trim(tariffHeading.part3));
setPart4(StringUtils.trim(tariffHeading.part4));
setPart5(StringUtils.trim(tariffHeading.part5));
}
/**
* Retrieves a string in the format of {@link #part1}.{@link #part2}.
* {@link #part3}.
* Examples: If part1 is null then this method will return "null.12.23". If
* part2 is null then this method will return "1234.null.23". If part3 is
* null then this method will return "1234.12.null".
*
* @return a string made up of each part of the tariff heading.
*/
public String getTariffHeading() {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(getPartValue(part1).trim()).append(".").append(getPartValue(part2).trim()).append(".").
append(getPartValue(part3).trim());
if (part4 != null) {
stringBuilder.append("/").append(getPartValue(part4).trim());
}
return stringBuilder.toString();
}
public String getPart1() {
return part1;
}
/**
* Sets part1 if it is less than or equal to {@link #PART1_MAX_LENGTH}.
*
* @param part1 the first part of the tariff heading
* @throws IllegalArgumentException if part1 is longer than {@link #PART1_MAX_LENGTH}
*/
public void setPart1(String part1) {
this.part1 = part1;
}
public String getPart2() {
return part2;
}
/**
* Sets part2 if it is less than or equal to {@link #PART2_MAX_LENGTH}.
*
* @param part2 the second part of the tariff heading
* @throws IllegalArgumentException if part2 is longer than {@link #PART2_MAX_LENGTH}
*/
public void setPart2(String part2) {
validatePartLength(part2, "part2", PART2_MAX_LENGTH);
this.part2 = part2;
}
public String getPart3() {
return part3;
}
/**
* Sets part3 if it is less than or equal to {@link #PART3_MAX_LENGTH}.
*
* @param part3 the third part of the tariff heading
* @throws IllegalArgumentException if part3 is longer than {@link #PART3_MAX_LENGTH}
*/
public void setPart3(String part3) {
validatePartLength(part3, "part3", PART3_MAX_LENGTH);
this.part3 = part3;
}
public String getPart4() {
return part4;
}
public void setPart4(String part4) {
this.part4 = part4;
}
public String getPart5() {
return part5;
}
public void setPart5(String part5) {
this.part5 = part5;
}
public String getParts() {
return part1 == null ? null : getTariffHeading();
}
public final void setParts(String tariffCode) {
if (tariffCode != null) {
setPart1(getSchedulePart(tariffCode.trim(), 1));
setPart2(getSchedulePart(tariffCode.trim(), 2));
setPart3(getSchedulePart(tariffCode.trim(), 3));
setPart4(getSchedulePart(tariffCode.trim(), 4));
setPart5(getSchedulePart(tariffCode.trim(), 5));
} else {
part1 = null;
part2 = null;
part3 = null;
part4 = null;
part5 = null;
}
}
@Override
public TariffHeading clone() {
try {
TariffHeading clone = (TariffHeading) super.clone();
clone.setPart1(part1 != null ? part1.trim() : null);
clone.setPart2(part2 != null ? part2.trim() : null);
clone.setPart3(part3 != null ? part3.trim() : null);
clone.setPart4(part4 != null ? part4.trim() : null);
clone.setPart5(part5 != null ? part5.trim() : null);
return clone;
} catch (CloneNotSupportedException ex) {
return null;
}
}
/**
* Validates that the part field named partName is less than or equal to the
* supplied maxLength.
*
* @param part the part field to validate, this will be {@link #part1},
* {@link #part2}, or {@link #part3}
* @param partName the name of the part being validated e.g. "part1"
* @param maxLength the max length the supplied part field is allowed
* @throws IllegalArgumentException if the part is greater than maxLength
* @see #PART2_MAX_LENGTH
* @see #PART3_MAX_LENGTH
*/
public void validatePartLength(String part, String partName, int maxLength) {
if (part != null && part.trim().length() > maxLength) {
if (failOnInValidaTariff) {
throw new IllegalArgumentException("The maximum length of Tariff Heading " + partName + " is " + maxLength);
} else {
validFormat = false;
}
}
}
public String getTariff() {
if (part1 != null) {
StringBuilder stringBuilder = new StringBuilder();
appendPart(part1, stringBuilder, true, ".");
appendPart(part2, stringBuilder, false, ".");
appendPart(part3, stringBuilder, false, ".");
if (part5 == null) {
appendPart(part4, stringBuilder, false, "/");
} else {
appendPart(part4, stringBuilder, false, ".");
}
appendPart(part5, stringBuilder, false, "/");
return stringBuilder.toString();
}
return null;
}
public String getPart3Tariff() {
if (part1 != null) {
StringBuilder stringBuilder = new StringBuilder();
appendPart(part1.trim(), stringBuilder, true, ".");
appendPart(part2.trim(), stringBuilder, false, ".");
appendPart(part3.trim(), stringBuilder, false, ".");
return stringBuilder.toString();
}
return null;
}
private void appendPart(String part, StringBuilder stringBuilder, boolean isFirst, String seperator) {
if (getPartValue(part) != null && !getPartValue(part).equals("")) {
if (!isFirst) {
stringBuilder.append(seperator);
}
stringBuilder.append(getPartValue(part));
}
}
public void setTariff(String tariff, boolean failOnInValidaTariff) {
this.failOnInValidaTariff = failOnInValidaTariff;
tariff = StringUtils.trim(tariff);
setPart1(getSchedulePart(tariff, 1));
setPart2(getSchedulePart(tariff, 2));
setPart3(getSchedulePart(tariff, 3));
setPart4(getSchedulePart(tariff, 4));
setPart5(getSchedulePart(tariff, 5));
if (!failOnInValidaTariff && !validFormat) {
clearInvalidTariff();
failOnInValidaTariff = true;
validFormat = true;
}
}
public void setTariff(String tariff) {
this.failOnInValidaTariff = false;
String tariffHeading = StringUtils.trim(tariff);
setPart1(getSchedulePart(tariffHeading, 1));
setPart2(getSchedulePart(tariffHeading, 2));
setPart3(getSchedulePart(tariffHeading, 3));
setPart4(getSchedulePart(tariffHeading, 4));
setPart5(getSchedulePart(tariffHeading, 5));
if (!failOnInValidaTariff && !validFormat) {
clearInvalidTariff();
failOnInValidaTariff = true;
validFormat = true;
}
}
private void clearInvalidTariff() {
setPart1(null);
setPart2(null);
setPart3(null);
setPart4(null);
setPart5(null);
}
/**
* @param tariffHeading Gets the third part of the tariffHeading
* Example, "1234.12.34" returns 34
* "1234.12." returns null
*/
private String getScheduleThirdPart(String tariffHeading) {
if (tariffHeading != null && tariffHeading.contains(".")) {
String[] parts = tariffHeading.split("\\.");
if (parts.length == PARTS_MAX_LENGTH) {
String part3 = parts[2];
if (part3.contains("_")) {
part3 = part3.replaceAll("_", " ");
}
return part3;
}
}
return null;
}
private String getSchedulePart(String tariffHeading, int part) {
String schedulePart = null;
String part3 = null;
if (tariffHeading != null && part == 3 && tariffHeading.contains("/")) {
tariffHeading = tariffHeading.substring(0, tariffHeading.indexOf("/"));
}
if (tariffHeading != null && part == 4 && tariffHeading.contains("/")) {
tariffHeading = tariffHeading.endsWith("/") ? tariffHeading.substring(0, tariffHeading.length() - 1) : tariffHeading;
String[] parts = tariffHeading.split("/");
schedulePart = parts[1];
}
if (tariffHeading != null && tariffHeading.contains(".") && !tariffHeading.contains("..")) {
String[] parts = tariffHeading.split("\\.");
switch (part) {
case 1:
schedulePart = parts[0].trim();
break;
case 2:
schedulePart = parts[1].trim();
break;
case 3:
if (parts.length > 2) {
schedulePart = parts[2].trim();
}
break;
case 4:
if (parts.length > 3 && !parts[3].contains("/")) {
schedulePart = parts[3].trim();
}
if (parts.length > 3 && parts[3].contains("/")) {
schedulePart = parts[3].split("/")[0];
}
break;
case 5:
if (parts.length > 3 && !parts[3].contains("/")) {
schedulePart = parts[3].trim();
}
if (parts.length > 3 && parts[3].contains("/")) {
schedulePart = parts[3].split("/")[1];
}
break;
}
if (schedulePart != null) {
if (schedulePart.contains("_")) {
schedulePart = schedulePart.replaceAll("_", " ");
}
}
}
return schedulePart;
}
private String getPartValue(String part) {
return part == null ? "" : part;
}
@Override
public boolean equals(Object obj) {
if (this == obj) {
return true;
}
if (!(obj instanceof TariffHeading)) {
return false;
}
TariffHeading other = (TariffHeading) obj;
return new EqualsBuilder().
append(StringUtils.trim(part1), StringUtils.trim(other.part1)).
append(StringUtils.trim(part2), StringUtils.trim(other.part2)).
append(StringUtils.trim(part3), StringUtils.trim(other.part3)).
append(StringUtils.trim(part4), StringUtils.trim(other.part4)).
append(StringUtils.trim(part5), StringUtils.trim(other.part5)).
isEquals();
}
}