package org.jdiameter.common.impl.validation;
import java.util.ArrayList;
import java.util.List;
/**
* Start time:10:50:39 2009-05-26<br>
* Project: diameter-parent<br>
* Represents command avp, it stores info about presence, multiplicity, avp
* code, vendor.
*
* @author <a href="mailto:baranowb@gmail.com"> Bartosz Baranowski </a>
* @author <a href="mailto:brainslog@gmail.com"> Alexandre Mendonca </a>
* @since 1.5.189
*/
public class VAvpRepresentation implements Cloneable {
/**
* <pre>
* 0 The AVP MUST NOT be present in the message.
* 0+ Zero or more instances of the AVP MAY be present in the
* message.
* 0-1 Zero or one instance of the AVP MAY be present in the
* message. It is considered an error if there are more than
* one instance of the AVP.
* 1 One instance of the AVP MUST be present in the message.
* 1+ At least one instance of the AVP MUST be present in the
* message.
* </pre>
*/
public final static String _MP_NOT_ALLOWED = "0";
public final static String _MP_ZERO_OR_MORE = "0+";
public final static String _MP_ZERO_OR_ONE = "0-1";
public final static String _MP_ONE = "1";
public final static String _MP_ONE_AND_MORE = "1+";
private final transient static int _FIX_POSITION_INDEX = -1;
public enum Rule {
must, may, mustnot, shouldnot
};
public enum Type {
OctetString, Integer32, Integer64, Unsigned32, Unsigned64, Float32, Float64, Grouped, Address, Time, UTF8String, DiameterIdentity, DiameterURI, Enumerated, IPFilterRule, QoSFilterRule
};
protected String description;
protected boolean mayEncrypt;
protected boolean _protected;
protected boolean _mandatory;
protected String ruleMandatory;
protected String ruleProtected;
protected String ruleVendorBit;
protected String type;
protected boolean constrained;
public final static String _DEFAULT_MANDATORY = "may";
public final static String _DEFAULT_PROTECTED = "may";
public final static String _DEFAULT_VENDOR = "mustnot";
// ususally this will be -1, as only SessionId has fixed position
private int positionIndex = _FIX_POSITION_INDEX;
protected int code = -1;
protected long vendor = 0;
protected boolean allowed = true;
protected String multiplicityIndicator = "0";
protected String name = "Some-AVP";
protected boolean grouped = false;
protected List<VAvpRepresentation> children = new ArrayList<VAvpRepresentation>();
protected boolean weak = false;
public VAvpRepresentation(VAvpRepresentation clone) {
this(-1, clone.code, clone.getVendorId(), clone.getMultiplicityIndicator(), clone.getName());
this.allowed = clone.allowed;
this.code = clone.code;
this.grouped = clone.grouped;
this.multiplicityIndicator = clone.multiplicityIndicator;
this.name = clone.name;
this.positionIndex = clone.positionIndex;
this.vendor = clone.vendor;
this.weak = clone.weak;
this._mandatory = clone._mandatory;
this._protected = clone._protected;
this.constrained = clone.constrained;
this.description = clone.description;
this.mayEncrypt = clone.mayEncrypt;
this.ruleMandatory = clone.ruleMandatory;
this.ruleProtected = clone.ruleProtected;
this.ruleVendorBit = clone.ruleVendorBit;
this.type = clone.type;
if (this.multiplicityIndicator.equals(_MP_NOT_ALLOWED))
this.allowed = false;
}
public VAvpRepresentation() {
super();
this.weak = true;
}
/**
* Constructor used to represent weak children. - weak means its only
* defined by name in some other avp. After configuration parse procedure is
* complete weak children are resolved. Weak children should not be stored
* in Set or any other has structure, its due to nature of hashing, which is
* done on vendor and code, which for weak children is always different than
* fully defined avp rep. <br>
* This constructor should be generaly used by extending classes, as well as
* no arg constructor.
*
* @param name
* @param vendor
*/
public VAvpRepresentation(String name, long vendor) {
super();
this.name = name;
this.vendor = vendor;
this.weak = true;
}
/**
* This constructor is used my validator to lookup correct representation.
* Its hash and equals methods will match to fully populated avp
* representation in any data structure
*
* @param code
* @param vendor
*/
public VAvpRepresentation(int code, long vendor) {
super();
this.code = code;
this.vendor = vendor;
if (this.multiplicityIndicator.equals(_MP_NOT_ALLOWED))
this.allowed = false;
}
public VAvpRepresentation(int positionIndex, int code, long vendor, String multiplicityIndicator, String name) {
super();
this.positionIndex = positionIndex;
this.code = code;
this.vendor = vendor;
this.multiplicityIndicator = multiplicityIndicator;
this.name = name;
if (this.multiplicityIndicator.equals(_MP_NOT_ALLOWED))
this.allowed = false;
}
public VAvpRepresentation(int code, long vendor, String name) {
super();
this.positionIndex = -1;
this.code = code;
this.vendor = vendor;
this.multiplicityIndicator = _MP_ZERO_OR_MORE;
this.name = name;
if (this.multiplicityIndicator.equals(_MP_NOT_ALLOWED))
this.allowed = false;
}
public VAvpRepresentation(String name, String description, int code, boolean mayEncrypt, String ruleMandatory, String ruleProtected, String ruleVendorBit, long vendorId, boolean constrained,
String type) {
// zero and more, since its definition.
this(-1, code, vendorId, _MP_ZERO_OR_MORE, name);
this.description = description;
this.mayEncrypt = mayEncrypt;
this.ruleMandatory = ruleMandatory;
this.ruleProtected = ruleProtected;
this.ruleVendorBit = ruleVendorBit;
if (this.ruleMandatory == null || this.ruleMandatory.equals(""))
this.ruleMandatory = _DEFAULT_MANDATORY;
if (this.ruleProtected == null || this.ruleProtected.equals(""))
this.ruleProtected = _DEFAULT_PROTECTED;
if (this.ruleVendorBit == null || this.ruleVendorBit.equals(""))
this.ruleVendorBit = _DEFAULT_VENDOR;
this.constrained = constrained;
this.type = type;
this._mandatory = this.ruleMandatory.equals("must");
this._protected = this.ruleProtected.equals("must");
if (type.equals(Type.Grouped.toString())) {
this.setGrouped(true);
}
if (this.multiplicityIndicator.equals(_MP_NOT_ALLOWED))
this.allowed = false;
}
public boolean isPositionFixed() {
return this.positionIndex == _FIX_POSITION_INDEX;
}
public void markFixPosition(int index) {
this.positionIndex = index;
}
public boolean isCountValidForMultiplicity(int avpCount) {
// This covver nto allowed
if (!allowed) {
if (avpCount == 0) {
return true;
}
} else {
if (this.multiplicityIndicator.equals(_MP_ZERO_OR_MORE)) {
if (avpCount >= 0)
return true;
} else if (this.multiplicityIndicator.equals(_MP_ZERO_OR_ONE)) {
if ((avpCount == 0) || (avpCount == 1))
return true;
} else if (this.multiplicityIndicator.equals(_MP_ONE)) {
if (avpCount == 1) {
return true;
}
} else if (this.multiplicityIndicator.equals(_MP_ONE_AND_MORE)) {
if (avpCount >= 1) {
return true;
}
}
}
// if we did not return, we are screwed.
return false;
}
public static int get_FIX_POSITION_INDEX() {
return _FIX_POSITION_INDEX;
}
public int getPositionIndex() {
return positionIndex;
}
public int getCode() {
return code;
}
public long getVendorId() {
return vendor;
}
public boolean isAllowed() {
return allowed;
}
public String getMultiplicityIndicator() {
return multiplicityIndicator;
}
public String getName() {
return name;
}
public boolean isGrouped() {
return grouped;
}
public void setGrouped(boolean grouped) {
this.grouped = grouped;
}
public List<VAvpRepresentation> getChildren() {
return children;
}
public void setChildren(List<VAvpRepresentation> children) {
this.children = children;
}
public void setCode(int code) {
this.code = code;
}
public void setVendorId(long vendor) {
this.vendor = vendor;
}
public void setMultiplicityIndicator(String multiplicityIndicator) {
this.multiplicityIndicator = multiplicityIndicator;
if (this.multiplicityIndicator.equals(_MP_NOT_ALLOWED))
this.allowed = false;
}
public void setName(String name) {
this.name = name;
}
public boolean isWeak() {
return weak;
}
public void markWeak(boolean isWeak) {
this.weak = isWeak;
}
public String getDescription() {
return description;
}
public boolean isMayEncrypt() {
return mayEncrypt;
}
public String getRuleMandatory() {
return ruleMandatory;
}
public int getRuleMandatoryAsInt() {
return Rule.valueOf(ruleMandatory).ordinal();
}
public String getRuleProtected() {
return ruleProtected;
}
public int getRuleProtectedAsInt() {
return Rule.valueOf(ruleProtected).ordinal();
}
public String getRuleVendorBit() {
return ruleVendorBit;
}
public int getRuleVendorBitAsInt() {
return Rule.valueOf(ruleVendorBit).ordinal();
}
public boolean isConstrained() {
return constrained;
}
public String getType() {
return type;
}
public boolean isProtected() {
return _protected;
}
public boolean isMandatory() {
return _mandatory;
}
// public String toString() {
// return this.getName() + "@" + hashCode() + " Name[" + getName() +
// "] Code[" + getCode() + "] Vendor[" + getVendorId() + "] MLP[" +
// getMultiplicityIndicator() + "] Allowed[" + isAllowed() + "] ";
// }
public String toString() {
StringBuffer sb = new StringBuffer();
sb.append("name: ").append(this.getName()).append(", code: ").append(this.getCode()).append(", vendor: ").append(this.getVendorId()).append(", weak: ").append(this.isWeak()).append(
", grouped: ").append(this.isGrouped()).append(", type: ").append(this.getType()).append(", multiplicity: ").append(this.getMultiplicityIndicator());
if (this.isGrouped()) {
for (VAvpRepresentation child : this.getChildren()) {
String childStr = child.toString().replace("\n", "\n---");
sb.append("\n---" + childStr);
}
}
return sb.toString();
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + code;
result = prime * result + (int) (vendor ^ (vendor >>> 32));
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
VAvpRepresentation other = (VAvpRepresentation) obj;
if (code != other.code)
return false;
if (vendor != other.vendor)
return false;
return true;
}
@Override
public Object clone() throws CloneNotSupportedException {
//VAvpRepresentation clone = (VAvpRepresentation) super.clone();
VAvpRepresentation clone = new VAvpRepresentation();
clone.allowed = this.allowed;
clone.code = this.code;
clone.grouped = this.grouped;
clone.multiplicityIndicator = this.multiplicityIndicator;
clone.name = this.name;
clone.positionIndex = this.positionIndex;
clone.vendor = this.vendor;
clone.weak = this.weak;
clone._mandatory = this._mandatory;
clone._protected = this._protected;
clone.constrained = this.constrained;
clone.description = this.description;
clone.mayEncrypt = this.mayEncrypt;
clone.ruleMandatory = this.ruleMandatory;
clone.ruleProtected = this.ruleProtected;
clone.ruleVendorBit = this.ruleVendorBit;
clone.type = this.type;
List<VAvpRepresentation> cloneChildren = new ArrayList<VAvpRepresentation>();
clone.children = cloneChildren;
for (VAvpRepresentation c : this.children) {
cloneChildren.add((VAvpRepresentation) c.clone());
}
return clone;
}
}