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

org.jdiameter.common.impl.validation.MessageRepresentationImpl Maven / Gradle / Ivy

The newest version!
 /*
  * TeleStax, Open Source Cloud Communications
  * Copyright 2011-2016, TeleStax Inc. and individual contributors
  * by the @authors tag.
  *
  * This program is free software: you can redistribute it and/or modify
  * under the terms of the GNU Affero General Public License as
  * published by the Free Software Foundation; either version 3 of
  * the License, or (at your option) any later version.
  *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU Affero General Public License for more details.
  *
  * You should have received a copy of the GNU Affero General Public License
  * along with this program.  If not, see 
  *
  * This file incorporates work covered by the following copyright and
  * permission notice:
  *
  *   JBoss, Home of Professional Open Source
  *   Copyright 2007-2011, Red Hat, Inc. and individual contributors
  *   by the @authors tag. See the copyright.txt in the distribution for a
  *   full listing of individual contributors.
  *
  *   This is free software; you can redistribute it and/or modify it
  *   under the terms of the GNU Lesser General Public License as
  *   published by the Free Software Foundation; either version 2.1 of
  *   the License, or (at your option) any later version.
  *
  *   This software is distributed in the hope that it will be useful,
  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  *   Lesser General Public License for more details.
  *
  *   You should have received a copy of the GNU Lesser General Public
  *   License along with this software; if not, write to the Free
  *   Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  *   02110-1301 USA, or see the FSF site: http://www.fsf.org.
  */

package org.jdiameter.common.impl.validation;

import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;

import org.jdiameter.api.Avp;
import org.jdiameter.api.AvpSet;
import org.jdiameter.api.Message;
import org.jdiameter.api.validation.AvpNotAllowedException;
import org.jdiameter.api.validation.AvpRepresentation;
import org.jdiameter.api.validation.MessageRepresentation;
import org.jdiameter.api.validation.ValidatorLevel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
 * This class represents message/command in validation framework. It contains
 * basic info about command along with avp list - their multiplicity and
 * allowance.
 *
 * @author  Bartosz Baranowski 
 * @author  Alexandre Mendonca 
 * @since 1.5.4.0-build404
 *
 */
public class MessageRepresentationImpl implements MessageRepresentation {

  private static transient Logger logger = LoggerFactory.getLogger(MessageRepresentationImpl.class);

  private int commandCode = -1;
  private long applicationId = 0;

  private boolean isRequest = false;
  protected Map unmuttableMessageAvps = new HashMap();
  private String name = null;

  public MessageRepresentationImpl(int commandCode, long applicationId, boolean isRequest) {
    super();
    this.commandCode = commandCode;
    this.applicationId = applicationId;
    this.isRequest = isRequest;
  }

  public MessageRepresentationImpl(int commandCode, boolean isRequest) {
    this(commandCode, 0, isRequest);
  }

  public MessageRepresentationImpl(int commandCode, long applicationId, boolean isRequest, String name) {
    super();
    this.commandCode = commandCode;
    this.applicationId = applicationId;
    this.isRequest = isRequest;
    this.name = name;
  }

  public MessageRepresentationImpl(MessageRepresentationImpl clone) {
    super();
    this.applicationId = clone.applicationId;
    this.commandCode = clone.commandCode;
    this.isRequest = clone.isRequest;
    this.name = clone.name;
    // TODO: copy avps?
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = 1;
    result = prime * result + (int) (applicationId ^ (applicationId >>> 32));
    result = prime * result + commandCode;
    result = prime * result + (isRequest ? 1231 : 1237);
    return result;
  }

  @Override
  public boolean equals(Object obj) {
    if (this == obj) {
      return true;
    }
    if (obj == null) {
      return false;
    }
    if (getClass() != obj.getClass()) {
      return false;
    }

    MessageRepresentationImpl other = (MessageRepresentationImpl) obj;
    if (applicationId != other.applicationId) {
      return false;
    }
    if (commandCode != other.commandCode) {
      return false;
    }
    if (isRequest != other.isRequest) {
      return false;
    }
    return true;
  }

  @Override
  public Map getMessageAvps() {
    return unmuttableMessageAvps;
  }

  public void setMessageAvps(Map messageAvps) {
    //this.unmuttableMessageAvps = Collections.unmodifiableMap(messageAvps);
    this.unmuttableMessageAvps = messageAvps;
  }

  @Override
  public int getCommandCode() {
    return commandCode;
  }

  @Override
  public long getApplicationId() {
    return applicationId;
  }

  @Override
  public boolean isRequest() {
    return isRequest;
  }

  @Override
  public String getName() {
    return name;
  }

  @Override
  public AvpRepresentation getAvp(int code) {
    return getAvp(code, 0);
  }

  @Override
  public AvpRepresentation getAvp(int code, long vendorId) {
    AvpRepresentation avp = unmuttableMessageAvps.get(new AvpRepresentationImpl(code, vendorId));

    if (avp == null) {
      logger.warn("AVP with code " + code + " and Vendor-Id " + vendorId + " not present in Message Representation!");
    }

    return avp;
  }

  // Convenience methods ------------------------------------------------------

  @Override
  public boolean isAllowed(int code, long vendorId) {
    AvpRepresentation avpRep = new AvpRepresentationImpl(code, vendorId);
    avpRep = this.unmuttableMessageAvps.get(avpRep);
    if (avpRep == null) {
      return true;
    }
    return avpRep.isAllowed();
  }

  @Override
  public boolean isAllowed(int code) {
    return this.isAllowed(code, 0);
  }

  @Override
  public boolean isCountValidForMultiplicity(int code, int avpCount) {
    return this.isCountValidForMultiplicity(code, 0, avpCount);
  }

  @Override
  public boolean isCountValidForMultiplicity(int code, long vendorId, int avpCount) {
    AvpRepresentation avpRep = getAvp(code, vendorId);
    if (avpRep == null) {
      return true;
    }
    return avpRep.isCountValidForMultiplicity(avpCount);
  }

  @Override
  public boolean isCountValidForMultiplicity(AvpSet destination, int code, long vendorId) {
    return this.isCountValidForMultiplicity(destination, code, vendorId, 0);
  }

  @Override
  public boolean isCountValidForMultiplicity(AvpSet destination, int code) {
    return this.isCountValidForMultiplicity(destination, code, 0L);
  }

  @Override
  public boolean isCountValidForMultiplicity(AvpSet destination, int code, long vendorId, int numberToAdd) {
    AvpRepresentation avpRep = getAvp(code, vendorId);
    if (avpRep == null) {
      return true;
    }

    return avpRep.isCountValidForMultiplicity(destination, numberToAdd);
  }

  @Override
  public boolean isCountValidForMultiplicity(AvpSet destination, int code, int numberToAdd) {
    return this.isCountValidForMultiplicity(destination, code, 0, numberToAdd);
  }

  /*
   * (non-Javadoc)
   *
   * @see java.lang.Comparable#compareTo(java.lang.Object)
   */
  public int compareTo(MessageRepresentation o) {
    if (o == this) {
      return 0;
    }
    if (o == null) {
      return 1;
    }
    return this.hashCode() - o.hashCode();
  }

  @Override
  public Object clone() throws CloneNotSupportedException {
    MessageRepresentationImpl clone = (MessageRepresentationImpl) super.clone();
    clone.applicationId = this.applicationId;
    clone.commandCode = this.commandCode;
    clone.isRequest = this.isRequest;
    clone.name = this.name;
    // clone.messageAvps = new HashMap();
    Map map = new HashMap();
    for (Entry entry : this.unmuttableMessageAvps.entrySet()) {
      map.put((AvpRepresentation) entry.getKey().clone(), (AvpRepresentation) entry.getValue().clone());
    }
    clone.setMessageAvps(map);
    return clone;
  }

  @Override
  public String toString() {
    StringBuffer sb = new StringBuffer();
    sb.append(isRequest ? "Request" : "Answer").append(" code: ").append(this.commandCode).append(" applicationId: ").append(this.applicationId)
    .append(" name: ").append(this.name);
    for (AvpRepresentation childAvp : this.getMessageAvps().values()) {
      sb.append("\n").append(childAvp.toString());
    }

    return sb.toString();
  }

  // Validation part ----------------------------------------------------------

  @Override
  public void validate(Message msg, ValidatorLevel validatorLevel) throws AvpNotAllowedException {
    if (validatorLevel == ValidatorLevel.OFF) {
      return;
    }

    // if its !OFF, we will go down, at least to this section
    for (AvpRepresentation ap : this.unmuttableMessageAvps.values()) {
      AvpSet innerSet = msg.getAvps().getAvps(ap.getCode(), ap.getVendorId());

      int count = 0;
      if (innerSet != null) {
        count = innerSet.size();
      }

      if (!ap.isCountValidForMultiplicity(count)) {
        throw new AvpNotAllowedException("AVP: \n" + ap + "\n, has wrong count in message - " + (count), ap.getCode(), ap.getVendorId());
      }
      // if its ALL, we need to go down deeper in AVPs
      if (validatorLevel != ValidatorLevel.ALL) {
        continue;
      }
      if (count != 0 && ap.isGrouped()) {
        // we are grouped
        validateGrouped(ap, innerSet);
      }
    }
  }

  /**
   * @param ap
   * @param innerSet
   */
  private void validateGrouped(AvpRepresentation ap, AvpSet innerSet) {
    // we have set of grouped avps, and ap is grouped, lets validate
    // NOTE this methods can be called multiple time, until we dont have

    for (int index = 0; index < innerSet.size(); index++) {

      Avp presumablyGrouped = innerSet.getAvpByIndex(index);
      ap.validate(presumablyGrouped);
      // AvpSet groupedPart = null;
      // try {
      //   groupedPart = presumablyGrouped.getGrouped();
      // }
      // catch (AvpDataException e) {
      //   logger.debug("Failed to get grouped AVP.", e);
      // }
      //
      // if (groupedPart == null) {
      //   logger.error("Avp should be grouped, but its not: " + ap);
      //
      //   continue;
      // }
      // else {
      //   validateGroupedChildren(ap, groupedPart);
      // }
    }
  }

  //  /**
  //   * @param ap
  //   * @param presumablyGrouped
  //   */
  //  private void validateGroupedChildren(AvpRepresentation ap, AvpSet groupedAvp) {
  //    // we have grouped avp, and its representation, we should validate
  //    // children.
  //    for (AvpRepresentation childrenVAvp : ap.getChildren()) {
  //      AvpSet childSset = groupedAvp.getAvps(childrenVAvp.getCode(), childrenVAvp.getVendorId());
  //      int count = childSset.size();
  //
  //      if (!childrenVAvp.isCountValidForMultiplicity(count)) {
  //        throw new AvpNotAllowedException("AVP: " + childrenVAvp + " has wrong count, in grouped parent avp - " + (count) + ", allowed: "
  //            + childrenVAvp.getMultiplicityIndicator(), ap.getCode(), ap.getVendorId());
  //      }
  //      if (childrenVAvp.isGrouped()) {
  //
  //        validateGrouped(childrenVAvp, childSset);
  //      }
  //      // else we are good ?
  //    }
  //
  //  }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy