Package jade.content.abs

Source Code of jade.content.abs.AbsObjectImpl

/**
* ***************************************************************
* JADE - Java Agent DEvelopment Framework is a framework to develop
* multi-agent systems in compliance with the FIPA specifications.
* Copyright (C) 2000 CSELT S.p.A.
*
* GNU Lesser General Public License
*
* This library 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,
* version 2.1 of the License.
*
* This library 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 library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA  02111-1307, USA.
* **************************************************************
*/
package jade.content.abs;

import jade.core.CaseInsensitiveString;
import jade.util.leap.ArrayList;
import jade.util.leap.HashMap;
import jade.util.leap.Iterator;

/**
* Base class for all non-primitive abstract descriptor classes.
* This class is not intended to be used by programmers.
* @author Federico Bergenti - Universita` di Parma
* @author Giovanni Caire - TILAB
*/
public class AbsObjectImpl implements AbsObject {
  private HashMap elements = new HashMap();
  /** This list keeps the keys in the same order as they were added **/
  private ArrayList orderedKeys = new ArrayList();
  private String    typeName = null;
  /** true if this object is changed and its hash must be recomputed **/
  private boolean changed = true;
  private int hashCode = 0;

  /**
   * Construct an Abstract descriptor to hold an object of
   * the proper type.
   * @param typeName The name of the type of the object held by this
   * abstract descriptor.
   */
  protected AbsObjectImpl(String typeName) {
    this.typeName = typeName;
  }

  /**
   * @return The name of the type of the object held by this
   * abstract descriptor.
   * @see AbsObject#getTypeName()
   */
  public String getTypeName() {
    return typeName;
  }

  void setTypeName(String typeName) {
    this.typeName = typeName;
  }
 
  /**
   * Sets an attribute of the object held by this
   * abstract descriptor.
   * @param name The name of the attribute to be set.
   * @param value The new value of the attribute. If <code>value</code>
   * is null the current mapping with <code>name</code> (if any) is
   * removed.
   */
  protected void set(String name, AbsObject value) {
    CaseInsensitiveString ciName = new CaseInsensitiveString(name);
    if (value == null) {
      orderedKeys.remove(name);
      elements.remove(ciName);
    }
    else {
      if (!orderedKeys.contains(name)) {
        orderedKeys.add(name);
      }
      elements.put(ciName, value);
    }
    changed = true;
  }

  /**
   * Gets the value of an attribute of the object held by this
   * abstract descriptor.
   * @param name The name of the attribute.
   * @return value The value of the attribute.
   * @see AbsObject#getAbsObject(String)
   */
  public AbsObject getAbsObject(String name) {
    return (AbsObject) elements.get(new CaseInsensitiveString(name));
  }

  /**
   * @return the name of all attributes.
   * @see AbsObject#getNames()
   */
  public String[] getNames() {
    String[] names = new String[orderedKeys.size()];
    int j=0;
    for (Iterator i=orderedKeys.iterator(); i.hasNext(); )
      names[j++] = (String)i.next();
    return names;
  }

  /**
   * Tests if the object is grounded, i.e., if no one of its attributes
   * is associated with a variable
   * @return <code>true</code> if the object is grounded.
   * @see AbsObject#isGrounded()
   */
  public boolean isGrounded() {
    for (Iterator i = elements.values().iterator(); i.hasNext(); ) {
      AbsObject abs = (AbsObject) i.next();
      if (!abs.isGrounded()) {
        return false;
      }
    }
    return true;
  }

  /**
   * Gets the number of attributes.
   * @return the number of attributes.
   * @see AbsObject#getCount()
   */
  public int getCount() {
    return elements.size();
  }

  /**
   * This method is here just for debugging. Notice that it is highly innefficient.
   * The method StringCodec.encode() should be used instead.
   * @see StringCodec.encode(AbsContentElement content)
   */
  public String toString() {
    StringBuffer sb = new StringBuffer("(");
    sb.append(getTypeName());

    String[] names = getNames();

    for (int i = 0; i < names.length; i++) {
      sb.append(" :");
      sb.append(names[i]);
      sb.append(" ");
      sb.append(getAbsObject(names[i]));
    }
    sb.append(")");

    return sb.toString();
  }

  //ADDED BY SANDER FAAS:
  /**
   * Returns true if the attribute is equal to
   * this abstract descriptor, based on the contents
   * of both descriptors.
   */
  public boolean equals(Object obj) {
    if (obj instanceof AbsObjectImpl) {
      AbsObjectImpl abs = (AbsObjectImpl) obj;
      if (abs.getClass().equals(getClass()) && abs.getTypeName().equals(typeName)) {
        return f(abs) == f(this);
      }
    }
    return false;
  }

  /**
   * Returns an integer hashcode calculated from the
   * contents of this abstract descriptor
   */
  public int hashCode() {
    // if this object is changed, then recompute its hash, otherwise use the previous value
    if (changed) {
      hashCode = f(this);
      changed = false;
    }
    return hashCode;
  }

  /**
   * Calculates the hashcode according to a formula based on the
   * slot names and values taken in an lexicographical order
   */
  private final int f(AbsObjectImpl o, int x) {
    String slotNames[] = o.getNames();
    sort(slotNames);
    int[] v = new int[2*slotNames.length + 1];
    int j=0;
    for(int i = 0; i < slotNames.length; i++)
    {
      v[j++] = slotNames[i].hashCode();
      v[j++] = o.getAbsObject(slotNames[i]).hashCode();
    }
    v[j++] = o.getTypeName().hashCode();

    int sum = 0;
    int counter = 0;
    for (int i=0; i<v.length; i++ ) {
      sum += v[i] * x^counter;
      counter++;
    }
    return sum;
  }

  private final int f(AbsObjectImpl o) {
    return f(o, 2);
  }

  private final void sort(String[] strs) {
    for (int i = 1; i < strs.length; ++i) {
      for (int j = i; j > 0 && (strs[j-1].compareTo(strs[j]) > 0); --j) {
        swap(strs, j, j-1);
      }
    }
  }

  private final void swap(String[] strs, int x, int y) {
    String t = strs[x];
    strs[x] = strs[y];
    strs[y] = t;
  }
 
    public int getAbsType() {
      return UNKNOWN;
    }
}

TOP

Related Classes of jade.content.abs.AbsObjectImpl

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.