Package org.snmp4j.agent.agentx.master.index

Source Code of org.snmp4j.agent.agentx.master.index.AgentXIndexRegistry

/*_############################################################################
  _##
  _##  SNMP4J-AgentX - AgentXIndexRegistry.java 
  _##
  _##  Copyright (C) 2005-2009  Frank Fock (SNMP4J.org)
  _## 
  _##  This program is free software; you can redistribute it and/or modify
  _##  it under the terms of the GNU General Public License version 2 as
  _##  published by the Free Software Foundation.
  _##
  _##  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 General Public License for more details.
  _##
  _##  You should have received a copy of the GNU General Public License
  _##  along with this program; if not, write to the Free Software
  _##  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
  _##  MA  02110-1301  USA
  _## 
  _##########################################################################*/

package org.snmp4j.agent.agentx.master.index;

import java.util.*;

import org.snmp4j.agent.agentx.AgentXProtocol;
import org.snmp4j.smi.*;
import org.snmp4j.agent.agentx.master.index.AgentXIndexRegistry.IndexEntry;
import org.snmp4j.agent.agentx.master.index.AgentXIndexRegistry.IndexRegistryEntry;
import org.snmp4j.log.LogAdapter;
import org.snmp4j.log.LogFactory;


public class AgentXIndexRegistry {

  private static final LogAdapter LOGGER =
      LogFactory.getLogger(AgentXIndexRegistry.class);

  private Map indexes = Collections.synchronizedMap(new HashMap());

  public AgentXIndexRegistry() {
  }

  public int allocate(int sessionID,
                      OctetString context, VariableBinding vb,
                      boolean testOnly) {
    try {
      vb.getVariable().toSubIndex(true);
    }
    catch (UnsupportedOperationException ex) {
      return AgentXProtocol.AGENTX_INDEX_WRONG_TYPE;
    }
    IndexRegistryEntry newEntry = new IndexRegistryEntry(context, vb);
    IndexRegistryEntry oldEntry = (IndexRegistryEntry) indexes.get(newEntry);
    if (oldEntry == null) {
      if (!testOnly) {
        int status = newEntry.allocate(sessionID, vb.getVariable(), testOnly);
        if (status == AgentXProtocol.AGENTX_SUCCESS) {
          indexes.put(newEntry, newEntry);
        }
        return status;
      }
      return AgentXProtocol.AGENTX_SUCCESS;
    }
    else {
      return oldEntry.allocate(sessionID, vb.getVariable(), testOnly);
    }
  }

  public int release(int sessionID,
                     OctetString context, VariableBinding vb,
                     boolean testOnly) {
    IndexRegistryEntry newEntry = new IndexRegistryEntry(context, vb);
    IndexRegistryEntry entry = (IndexRegistryEntry) indexes.get(newEntry);
    if (entry == null) {
      return AgentXProtocol.AGENTX_INDEX_NOT_ALLOCATED;
    }
    else {
      if (entry.getIndexType().getSyntax() != vb.getSyntax()) {
        return AgentXProtocol.AGENTX_INDEX_NOT_ALLOCATED;
      }
      return entry.release(sessionID, vb.getVariable(), testOnly);
    }
  }

  public void release(int sessionID) {
    synchronized (indexes) {
      for (Iterator it = indexes.values().iterator(); it.hasNext(); ) {
        IndexRegistryEntry entry = (IndexRegistryEntry) it.next();
        entry.release(sessionID);
      }
    }
  }

  public int newIndex(int sessionID,
                      OctetString context, VariableBinding vb,
                      boolean testOnly) {
    IndexRegistryEntry newEntry = new IndexRegistryEntry(context, vb);
    IndexRegistryEntry entry = (IndexRegistryEntry) indexes.get(newEntry);
    if (entry == null) {
      entry = new IndexRegistryEntry(context, vb);
    }
    Variable v = entry.newIndex(sessionID, testOnly);
    if (v == null) {
      return AgentXProtocol.AGENTX_INDEX_NONE_AVAILABLE;
    }
    else if (!testOnly) {
      vb.setVariable(v);
    }
    return AgentXProtocol.AGENTX_SUCCESS;
  }

  public int anyIndex(int sessionID,
                      OctetString context, VariableBinding vb,
                      boolean testOnly) {
    IndexRegistryEntry newEntry = new IndexRegistryEntry(context, vb);
    IndexRegistryEntry entry = (IndexRegistryEntry) indexes.get(newEntry);
    boolean newEntryCreated = false;
    if (entry == null) {
      entry = new IndexRegistryEntry(context, vb);
      newEntryCreated = true;
    }
    Variable v = entry.anyIndex(sessionID, testOnly);
    if (v == null) {
      return AgentXProtocol.AGENTX_INDEX_NONE_AVAILABLE;
    }
    else if (!testOnly) {
      vb.setVariable(v);
      if (newEntryCreated) {
        indexes.put(entry, entry);
      }
    }
    return AgentXProtocol.AGENTX_SUCCESS;
  }

  class IndexEntry implements Comparable {
    private int sessionID;
    private Variable indexValue;

    public IndexEntry(int sessionID, Variable indexValue) {
      this.sessionID = sessionID;
      this.indexValue = indexValue;
    }

    public int getSessionID() {
      return sessionID;
    }

    public Variable getIndexValue() {
      return indexValue;
    }

    public int hashCode() {
      return indexValue.hashCode();
    }

    public boolean equals(Object o) {
      if (o instanceof IndexEntry) {
        return ((indexValue.equals(((IndexEntry)o).indexValue)) &&
                (sessionID == ((IndexEntry)o).sessionID));
      }
      else if (o instanceof Variable) {
        return indexValue.equals(o);
      }
      return false;
    }

    public int compareTo(Object o) {
      OID indexOID = indexValue.toSubIndex(true);
      if (o instanceof IndexEntry) {
        return indexOID.compareTo(((IndexEntry)o).indexValue.toSubIndex(true));
      }
      else if (o instanceof Variable) {
        return indexOID.compareTo(((Variable)o).toSubIndex(true));
      }
      throw new ClassCastException(o.getClass()+" != (IndexEntry or Variable)");
    }
  }

  class IndexRegistryEntry implements Comparable {

    private OctetString context;
    private VariableBinding indexType;
    private SortedMap indexValues = new TreeMap(new IndexComparator());
    private SortedMap usedValues = new TreeMap(new IndexComparator());

    public IndexRegistryEntry(OctetString context, VariableBinding indexType) {
      this.context = (context == null) ? new OctetString() : context;
      this.indexType = indexType;
    }

    public synchronized int allocate(int sessionID,
                                     Variable indexValue, boolean testOnly) {
      if (indexValue.getSyntax() != indexType.getSyntax()) {
        return AgentXProtocol.AGENTX_INDEX_WRONG_TYPE;
      }
      else if (indexValues.get(indexValue) != null) {
        return AgentXProtocol.AGENTX_INDEX_ALREADY_ALLOCATED;
      }
      else {
        if (!testOnly) {
          IndexEntry newEntry = new IndexEntry(sessionID, indexValue);
          indexValues.put(newEntry, newEntry);
        }
        return AgentXProtocol.AGENTX_SUCCESS;
      }
    }

    public synchronized int release(int sessionID,
                                    Variable indexValue, boolean testOnly) {
      IndexEntry removeKey = new IndexEntry(sessionID, indexValue);
      IndexEntry contained = (IndexEntry) indexValues.get(removeKey);
      if ((contained != null) && (contained.getSessionID() == sessionID)) {
        if (!testOnly) {
          Object r = indexValues.remove(contained);
          usedValues.put(r,r);
        }
        return AgentXProtocol.AGENTX_SUCCESS;
      }
      return AgentXProtocol.AGENTX_INDEX_NOT_ALLOCATED;
    }

    public synchronized void release(int sessionID) {
      for (Iterator it = indexValues.values().iterator(); it.hasNext();) {
        IndexEntry entry = (IndexEntry) it.next();
        if (entry.getSessionID() == sessionID) {
          it.remove();
          usedValues.put(entry, entry);
        }
      }
    }

    public int compareTo(Object o) {
      IndexRegistryEntry other = (IndexRegistryEntry)o;
      int c = context.compareTo(other.context);
      if (c == 0) {
        c = indexType.getOid().compareTo(other.indexType.getOid());
      }
      return c;
    }

    public int hashCode() {
      return indexType.getOid().hashCode()+
          ((context == null)?0:context.hashCode());
    }

    public boolean equals(Object o) {
      if (o instanceof IndexRegistryEntry) {
        return indexType.getOid().equals(
            ((IndexRegistryEntry)o).indexType.getOid());
      }
      return false;
    }

    public VariableBinding getIndexType() {
      return indexType;
    }

    public OctetString getContext() {
      return context;
    }

    public synchronized Variable newIndex(int sessionID, boolean testOnly) {
      try {
        IndexEntry last = null;
        if (!usedValues.isEmpty()) {
          last = (IndexEntry) usedValues.lastKey();
        }
        if (!indexValues.isEmpty()) {
          IndexEntry lastAllocated = (IndexEntry) indexValues.lastKey();
          if (last == null) {
            last = lastAllocated;
          }
          else if (lastAllocated.compareTo(last) > 0) {
            last = lastAllocated;
          }
        }
        else if (last == null) {
          return anyIndex(sessionID, testOnly);
        }
        OID nextIndex = last.getIndexValue().toSubIndex(true);
        nextIndex = nextIndex.nextPeer();
        Variable nextIndexValue = (Variable)last.getIndexValue().clone();
        nextIndexValue.fromSubIndex(nextIndex, true);
        int status = allocate(sessionID, nextIndexValue, testOnly);
        if (status != AgentXProtocol.AGENTX_SUCCESS) {
          return null;
        }
        return nextIndexValue;
      }
      catch (Exception ex) {
        LOGGER.error("Exception occurred while creating/allocating new index:"+
                     ex.getMessage(), ex);
        return null;
      }
    }

    public synchronized Variable anyIndex(int sessionID, boolean testOnly) {
      try {
        OID nextIndex;
        if (usedValues.isEmpty()) {
          if (indexValues.isEmpty()) {
            nextIndex = indexType.getVariable().toSubIndex(true);
          }
          else {
            nextIndex = ((IndexEntry)indexValues.lastKey()).
                getIndexValue().toSubIndex(true);
          }
        }
        else {
          IndexEntry last = (IndexEntry) usedValues.firstKey();
          nextIndex = last.getIndexValue().toSubIndex(true);
        }
        nextIndex = nextIndex.nextPeer();
        Variable nextIndexValue = (Variable) indexType.getVariable().clone();
        nextIndexValue.fromSubIndex(nextIndex, true);
        int status = allocate(sessionID, nextIndexValue, testOnly);
        if (status != AgentXProtocol.AGENTX_SUCCESS) {
          return null;
        }
        return nextIndexValue;
      }
      catch (Exception ex) {
        LOGGER.error("Exception occurred while creating/allocating"+
                     " any new index:"+ex.getMessage(), ex);
        return null;
      }
    }

    private class IndexComparator implements Comparator {

      public int compare(Object o1, Object o2) {
        Variable c1,c2;
        if (o1 instanceof IndexEntry) {
          c1 = ((IndexEntry)o1).getIndexValue();
        }
        else {
          c1 = (Variable)o1;
        }
        if (o2 instanceof IndexEntry) {
          c2 = ((IndexEntry)o2).getIndexValue();
        }
        else {
          c2 = (Variable)o2;
        }
        return c1.compareTo(c2);
      }

    }
  }
}
TOP

Related Classes of org.snmp4j.agent.agentx.master.index.AgentXIndexRegistry

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.