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

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

There is a newer version: 2.0.5
Show 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
 */
@SuppressWarnings("all") //3rd party lib
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 - 2024 Weber Informatics LLC | Privacy Policy