PageRenderTime 44ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 0ms

/projects/jboss-5.1.0/varia/src/main/org/jboss/jmx/adaptor/snmp/agent/RequestHandlerImpl.java

https://gitlab.com/essere.lab.public/qualitas.class-corpus
Java | 782 lines | 475 code | 92 blank | 215 comment | 87 complexity | ccddfd2e8e1ca687b8a1e04cb3fc23b4 MD5 | raw file
  1. /*
  2. * JBoss, Home of Professional Open Source.
  3. * Copyright 2008, Red Hat Middleware LLC, and individual contributors
  4. * as indicated by the @author tags. See the copyright.txt file in the
  5. * distribution for a full listing of individual contributors.
  6. *
  7. * This is free software; you can redistribute it and/or modify it
  8. * under the terms of the GNU Lesser General Public License as
  9. * published by the Free Software Foundation; either version 2.1 of
  10. * the License, or (at your option) any later version.
  11. *
  12. * This software is distributed in the hope that it will be useful,
  13. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. *
  17. * You should have received a copy of the GNU Lesser General Public
  18. * License along with this software; if not, write to the Free
  19. * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
  20. * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
  21. */
  22. package org.jboss.jmx.adaptor.snmp.agent;
  23. import java.io.InputStream;
  24. import java.net.InetAddress;
  25. import java.util.Iterator;
  26. import java.util.List;
  27. import java.util.SortedMap;
  28. import java.util.SortedSet;
  29. import java.util.TreeMap;
  30. import java.util.TreeSet;
  31. import javax.management.Attribute;
  32. import javax.management.MBeanServer;
  33. import javax.management.ObjectName;
  34. import org.jboss.jmx.adaptor.snmp.config.attribute.AttributeMappings;
  35. import org.jboss.jmx.adaptor.snmp.config.attribute.ManagedBean;
  36. import org.jboss.jmx.adaptor.snmp.config.attribute.MappedAttribute;
  37. import org.jboss.logging.Logger;
  38. import org.jboss.xb.binding.ObjectModelFactory;
  39. import org.jboss.xb.binding.Unmarshaller;
  40. import org.jboss.xb.binding.UnmarshallerFactory;
  41. import org.opennms.protocols.snmp.SnmpAgentSession;
  42. import org.opennms.protocols.snmp.SnmpInt32;
  43. import org.opennms.protocols.snmp.SnmpNull;
  44. import org.opennms.protocols.snmp.SnmpObjectId;
  45. import org.opennms.protocols.snmp.SnmpOctetString;
  46. import org.opennms.protocols.snmp.SnmpPduPacket;
  47. import org.opennms.protocols.snmp.SnmpPduRequest;
  48. import org.opennms.protocols.snmp.SnmpSyntax;
  49. import org.opennms.protocols.snmp.SnmpUInt32;
  50. import org.opennms.protocols.snmp.SnmpVarBind;
  51. /**
  52. * Implement RequestHandler with mapping of snmp get/set requests
  53. * to JMX mbean attribute gets/sets
  54. *
  55. * @author <a href="mailto:hwr@pilhuhn.de>">Heiko W. Rupp</a>
  56. * @author <a href="mailto:dimitris@jboss.org">Dimitris Andreadis</a>
  57. * @version $Revision: 81038 $
  58. */
  59. public class RequestHandlerImpl extends RequestHandlerSupport
  60. implements Reconfigurable
  61. {
  62. // Protected Data ------------------------------------------------
  63. private static final String NO_ENTRY_FOUND_FOR_OID = "No entry found for oid ";
  64. private static final String SKIP_ENTRY = " - skipping entry";
  65. /** Bindings from oid to mbean */
  66. protected SortedMap bindings = new TreeMap();
  67. private SortedSet oidKeys = null;
  68. /** Has this RequestHandler instance been initialized? */
  69. private boolean initialized = false;
  70. // Constructors --------------------------------------------------
  71. /**
  72. * Default CTOR
  73. */
  74. public RequestHandlerImpl()
  75. {
  76. bindings = new TreeMap();
  77. oidKeys = new TreeSet();
  78. }
  79. // RequestHandler Implementation ---------------------------------
  80. /**
  81. * Initialize
  82. *
  83. * @param resourceName A file containing get/set mappings
  84. * @param server Our MBean-Server
  85. * @param log The logger we use
  86. * @param uptime The uptime of the snmp-agent subsystem.
  87. */
  88. public void initialize(String resourceName, MBeanServer server, Logger log, Clock uptime)
  89. throws Exception
  90. {
  91. log.debug("initialize() with res=" + resourceName);
  92. super.initialize(resourceName, server, log, uptime);
  93. if (resourceName != null)
  94. initializeBindings();
  95. else
  96. log.warn("No RequestHandlerResName configured, disabling snmp-get");
  97. initialized = true;
  98. }
  99. // Reconfigurable Implementation ---------------------------------
  100. /**
  101. * Reconfigures the RequestHandler
  102. */
  103. public void reconfigure(String resName) throws Exception
  104. {
  105. if (resName == null || resName.equals(""))
  106. throw new IllegalArgumentException("Null or empty resName, cannot reconfigure");
  107. if (initialized == false)
  108. throw new IllegalStateException("Cannot reconfigure, not initialized yet");
  109. this.resourceName = resName;
  110. // Wipe out old entries
  111. bindings.clear();
  112. // Fetch them again
  113. initializeBindings();
  114. }
  115. // SnmpAgentHandler Implementation -------------------------------
  116. /**
  117. * <P>
  118. * This method is defined to handle SNMP Get requests that are received by
  119. * the session. The request has already been validated by the system. This
  120. * routine will build a response and pass it back to the caller.
  121. * </P>
  122. *
  123. * @param pdu
  124. * The SNMP pdu
  125. * @param getNext
  126. * The agent is requesting the lexically NEXT item after each
  127. * item in the pdu.
  128. *
  129. * @return SnmpPduRequest filled in with the proper response, or null if
  130. * cannot process NOTE: this might be changed to throw an exception.
  131. */
  132. public SnmpPduRequest snmpReceivedGet(SnmpPduPacket pdu, boolean getNext)
  133. {
  134. try
  135. {
  136. SnmpPduRequest response = null;
  137. int pduLength = pdu.getLength();
  138. final boolean trace = log.isTraceEnabled();
  139. if (trace)
  140. log.trace("requestId=" + pdu.getRequestId() + ", pduLength="
  141. + pduLength + ", getNext=" + getNext);
  142. SnmpVarBind[] vblist = new SnmpVarBind[pduLength];
  143. int errorStatus = SnmpPduPacket.ErrNoError;
  144. int errorIndex = 0;
  145. // Process for each varibind in the request
  146. for (int i = 0; i < pduLength; i++)
  147. {
  148. boolean good = true;
  149. SnmpVarBind vb = pdu.getVarBindAt(i);
  150. SnmpObjectId oid = vb.getName();
  151. if (getNext)
  152. {
  153. /*
  154. * We call getNextOid() to find out what is the next valid OID
  155. * instance in the supported MIB (sub-)tree. Assign that OID to the
  156. * VB List and then proceed same as that of get request. If the
  157. * passed oid is already the last, we flag it.
  158. */
  159. ComparableSnmpObjectId coid = new ComparableSnmpObjectId(oid);
  160. oid = getNextOid(coid, true);
  161. if (oid == null)
  162. {
  163. good = false;
  164. }
  165. else
  166. {
  167. pdu.setVarBindAt(i, new SnmpVarBind(oid));
  168. }
  169. }
  170. if (oid!=null)
  171. vblist[i] = new SnmpVarBind(oid);
  172. else
  173. vblist[i] = new SnmpVarBind(vb.getName()); // oid passed in
  174. if (trace)
  175. log.trace("oid=" + oid);
  176. SnmpSyntax result = null;
  177. if (good && bindings != null)
  178. result = getValueFor(oid);
  179. if (trace)
  180. log.trace("got result of " + result);
  181. if (result == null || !good)
  182. {
  183. errorStatus = SnmpPduPacket.ErrNoSuchName;
  184. errorIndex = i + 1;
  185. log.debug("Error Occured " + vb.getName().toString());
  186. }
  187. else
  188. {
  189. vblist[i].setValue(result);
  190. log.debug("Varbind[" + i + "] := "
  191. + vblist[i].getName().toString());
  192. log.debug(" --> " + vblist[i].getValue().toString());
  193. }
  194. } // for ...
  195. response = new SnmpPduRequest(SnmpPduPacket.RESPONSE, vblist);
  196. response.setErrorStatus(errorStatus);
  197. response.setErrorIndex(errorIndex);
  198. return response;
  199. } catch (Exception e)
  200. {
  201. // TODO Auto-generated catch block
  202. e.printStackTrace();
  203. return null;
  204. }
  205. }
  206. /**
  207. * <P>
  208. * This method is defined to handle SNMP Set requests that are received by
  209. * the session. The request has already been validated by the system. This
  210. * routine will build a response and pass it back to the caller.
  211. * </P>
  212. *
  213. * @param pdu
  214. * The SNMP pdu
  215. *
  216. * @return SnmpPduRequest filled in with the proper response, or null if
  217. * cannot process NOTE: this might be changed to throw an exception.
  218. */
  219. public SnmpPduRequest snmpReceivedSet(SnmpPduPacket pdu)
  220. {
  221. final boolean trace = log.isTraceEnabled();
  222. SnmpPduRequest response = null;
  223. int errorStatus = SnmpPduPacket.ErrNoError;
  224. int errorIndex = 0;
  225. int k = pdu.getLength();
  226. SnmpVarBind[] vblist = new SnmpVarBind[k];
  227. for (int i = 0; i < k; i++)
  228. {
  229. SnmpVarBind vb = pdu.getVarBindAt(i);
  230. vblist[i] = new SnmpVarBind(vb);
  231. SnmpObjectId oid = vb.getName();
  232. SnmpSyntax newVal = vb.getValue();
  233. if (trace)
  234. log.trace("set: received oid " + oid.toString() + " with value " + newVal.toString());
  235. SnmpSyntax result = null;
  236. try
  237. {
  238. result = setValueFor(oid,newVal);
  239. }
  240. catch (ReadOnlyException e)
  241. {
  242. errorStatus = SnmpPduPacket.ErrReadOnly;
  243. errorIndex = i + 1;
  244. }
  245. if (result != null)
  246. {
  247. errorStatus = SnmpPduPacket.ErrReadOnly;
  248. errorIndex = i + 1;
  249. log.debug("Error occured " + vb.getName().toString());
  250. }
  251. if (trace)
  252. {
  253. log.trace("Varbind[" + i + "] := " + vb.getName().toString());
  254. log.trace(" --> " + vb.getValue().toString());
  255. }
  256. }
  257. response = new SnmpPduRequest(SnmpPduPacket.RESPONSE, vblist);
  258. response.setErrorStatus(errorStatus);
  259. response.setErrorIndex(errorIndex);
  260. return response;
  261. }
  262. /**
  263. * <P>
  264. * This method is defined to handle SNMP requests that are received by the
  265. * session. The parameters allow the handler to determine the host, port,
  266. * and community string of the received PDU
  267. * </P>
  268. *
  269. * @param session
  270. * The SNMP session
  271. * @param manager
  272. * The remote sender
  273. * @param port
  274. * The remote senders port
  275. * @param community
  276. * The community string
  277. * @param pdu
  278. * The SNMP pdu
  279. *
  280. */
  281. public void snmpReceivedPdu(SnmpAgentSession session, InetAddress manager,
  282. int port, SnmpOctetString community, SnmpPduPacket pdu)
  283. {
  284. log.error("Message from manager " + manager.toString() + " on port " + port);
  285. int cmd = pdu.getCommand();
  286. log.error("Unsupported PDU command......... " + cmd);
  287. }
  288. /**
  289. * <P>
  290. * This method is invoked if an error occurs in the session. The error code
  291. * that represents the failure will be passed in the second parameter,
  292. * 'error'. The error codes can be found in the class SnmpAgentSession
  293. * class.
  294. * </P>
  295. *
  296. * <P>
  297. * If a particular PDU is part of the error condition it will be passed in
  298. * the third parameter, 'pdu'. The pdu will be of the type SnmpPduRequest or
  299. * SnmpPduTrap object. The handler should use the "instanceof" operator to
  300. * determine which type the object is. Also, the object may be null if the
  301. * error condition is not associated with a particular PDU.
  302. * </P>
  303. *
  304. * @param session
  305. * The SNMP Session
  306. * @param error
  307. * The error condition value.
  308. * @param ref
  309. * The PDU reference, or potentially null. It may also be an
  310. * exception.
  311. */
  312. public void SnmpAgentSessionError(SnmpAgentSession session, int error, Object ref)
  313. {
  314. log.error("An error occured in the trap session");
  315. log.error("Session error code = " + error);
  316. if (ref != null)
  317. {
  318. log.error("Session error reference: " + ref.toString());
  319. }
  320. if (error == SnmpAgentSession.ERROR_EXCEPTION)
  321. {
  322. synchronized (session)
  323. {
  324. session.notify(); // close the session
  325. }
  326. }
  327. }
  328. // Private -------------------------------------------------------
  329. /**
  330. * Initialize the bindings from the file given in resourceName
  331. */
  332. private void initializeBindings() throws Exception
  333. {
  334. log.debug("Reading resource: '" + resourceName + "'");
  335. ObjectModelFactory omf = new AttributeMappingsBinding();
  336. InputStream is = null;
  337. AttributeMappings mappings = null;
  338. try
  339. {
  340. // locate resource
  341. is = getClass().getResourceAsStream(resourceName);
  342. // create unmarshaller
  343. Unmarshaller unmarshaller = UnmarshallerFactory.newInstance().newUnmarshaller();
  344. // let JBossXB do it's magic using the AttributeMappingsBinding
  345. mappings = (AttributeMappings)unmarshaller.unmarshal(is, omf, null);
  346. }
  347. catch (Exception e)
  348. {
  349. log.error("Accessing resource '" + resourceName + "'");
  350. throw e;
  351. }
  352. finally
  353. {
  354. if (is != null)
  355. {
  356. // close the XML stream
  357. is.close();
  358. }
  359. }
  360. if (mappings == null)
  361. {
  362. log.warn("No bindings found in " + resourceName);
  363. return;
  364. }
  365. log.debug("Found " + mappings.size() + " attribute mappings");
  366. /**
  367. * We have the MBeans now. Put them into the bindungs.
  368. */
  369. Iterator it = mappings.iterator();
  370. while (it.hasNext())
  371. {
  372. ManagedBean mmb = (ManagedBean)it.next();
  373. String oidPrefix = mmb.getOidPrefix();
  374. List attrs = mmb.getAttributes();
  375. Iterator aIt = attrs.iterator();
  376. while (aIt.hasNext())
  377. {
  378. MappedAttribute ma = (MappedAttribute)aIt.next();
  379. String oid;
  380. if (oidPrefix != null)
  381. oid = oidPrefix + ma.getOid();
  382. else
  383. oid = ma.getOid();
  384. BindEntry be = new BindEntry(oid, mmb.getName(), ma.getName());
  385. be.isReadWrite = ma.isReadWrite();
  386. ComparableSnmpObjectId coid = new ComparableSnmpObjectId(oid);
  387. if (log.isTraceEnabled())
  388. log.trace("New bind entry " + be);
  389. if (bindings.containsKey(coid)) {
  390. log.info("Duplicate oid " + oid + SKIP_ENTRY);
  391. continue;
  392. }
  393. if (mmb.getName() == null || mmb.getName().equals(""))
  394. {
  395. log.info("Invalid mbean name for oid " + oid + SKIP_ENTRY);
  396. continue;
  397. }
  398. if (ma.getName() == null || ma.getName().equals(""))
  399. {
  400. log.info("Invalid attribute name " + ma.getName() + " for oid " + oid + SKIP_ENTRY);
  401. continue;
  402. }
  403. bindings.put(coid, be);
  404. oidKeys.add(coid);
  405. }
  406. }
  407. }
  408. /**
  409. * Return the current value for the given oid
  410. *
  411. * @param oid
  412. * The oid we want a value for
  413. * @return SnmpNull if no value present
  414. */
  415. private SnmpSyntax getValueFor(final SnmpObjectId oid) {
  416. BindEntry be = findBindEntryForOid(oid);
  417. SnmpSyntax ssy = null;
  418. if (be != null)
  419. {
  420. if (log.isTraceEnabled())
  421. log.trace("Found entry " + be.toString() + " for oid " + oid);
  422. try
  423. {
  424. Object val = server.getAttribute(be.mbean, be.attr.getName());
  425. if (val instanceof Long)
  426. {
  427. Long uin = (Long) val;
  428. ssy = new SnmpUInt32(uin);
  429. }
  430. else if (val instanceof String)
  431. {
  432. String in = (String) val;
  433. ssy = new SnmpOctetString(in.getBytes());
  434. }
  435. else if (val instanceof Integer)
  436. {
  437. Integer in = (Integer) val;
  438. ssy = new SnmpInt32(in);
  439. }
  440. else if (val instanceof SnmpObjectId)
  441. {
  442. ssy = (SnmpObjectId)val;
  443. }
  444. else
  445. log.info("Unknown type for " + be);
  446. }
  447. catch (Exception e)
  448. {
  449. log.warn("getValueFor (" + be.mbean.toString() + ", "
  450. + be.attr.getName() + ": " + e.toString());
  451. }
  452. }
  453. else
  454. {
  455. ssy = new SnmpNull();
  456. log.info(NO_ENTRY_FOUND_FOR_OID + oid);
  457. }
  458. return ssy;
  459. }
  460. /**
  461. * Set a jmx attribute
  462. * @param oid The oid to set. This is translated into a mbean / attribute pair
  463. * @param newVal The new value to set
  464. * @return null on success, non-null on failure
  465. * @throws ReadOnlyException If the referred entry is read only.
  466. */
  467. private SnmpSyntax setValueFor(final SnmpObjectId oid, final SnmpSyntax newVal) throws ReadOnlyException
  468. {
  469. final boolean trace = log.isTraceEnabled();
  470. BindEntry be = findBindEntryForOid(oid);
  471. if (trace)
  472. log.trace("setValueFor: found bind entry for " + oid);
  473. SnmpSyntax ssy = null;
  474. if (be != null)
  475. {
  476. if (trace)
  477. log.trace("setValueFor: " + be.toString());
  478. if (be.isReadWrite == false)
  479. {
  480. if (trace)
  481. log.trace("setValueFor: this is marked read only");
  482. throw new ReadOnlyException(oid);
  483. }
  484. try
  485. {
  486. Object val = null;
  487. if (newVal instanceof SnmpOctetString)
  488. {
  489. val = newVal.toString();
  490. }
  491. else if (newVal instanceof SnmpInt32)
  492. {
  493. val = new Integer(((SnmpInt32)newVal).getValue());
  494. }
  495. else if (newVal instanceof SnmpUInt32)
  496. {
  497. val = new Long(((SnmpUInt32)newVal).getValue());
  498. }
  499. // TODO do more mumbo jumbo for type casting / changing
  500. if (val != null)
  501. {
  502. Attribute at = new Attribute(be.attr.getName(), val);
  503. server.setAttribute(be.mbean, at);
  504. if (trace)
  505. log.trace("setValueFor: set attribute in mbean-Server");
  506. }
  507. else
  508. {
  509. log.debug("Did not find a suitable data type for newVal " + newVal);
  510. ssy = new SnmpNull();
  511. }
  512. // TODO
  513. }
  514. catch (Exception e )
  515. {
  516. log.debug("setValueFor: exception " + e.getMessage());
  517. ssy = new SnmpNull();
  518. }
  519. }
  520. else
  521. {
  522. ssy = new SnmpNull();
  523. log.info(NO_ENTRY_FOUND_FOR_OID + oid);
  524. }
  525. return ssy;
  526. }
  527. /**
  528. * Lookup a BinEntry on the given oid. If the oid ends in .0,
  529. * then the .0 will be stripped of before the search.
  530. * @param oid The oid look up.
  531. * @return a bind entry or null.
  532. */
  533. private BindEntry findBindEntryForOid(final SnmpObjectId oid) {
  534. ComparableSnmpObjectId coid= new ComparableSnmpObjectId(oid);
  535. if (coid.isLeaf())
  536. {
  537. coid = coid.removeLastPart();
  538. }
  539. BindEntry be = (BindEntry)bindings.get(coid);
  540. return be;
  541. }
  542. /**
  543. * Return the next oid that is larger than ours.
  544. * @param oid the starting oid
  545. * @param stayInSubtree if true, the next oid will not have a different prefix than the one of oid.
  546. * @return the next oid or null if none found.
  547. */
  548. private ComparableSnmpObjectId getNextOid(final ComparableSnmpObjectId oid, boolean stayInSubtree) {
  549. ComparableSnmpObjectId coid = new ComparableSnmpObjectId(oid);
  550. if (coid.isLeaf())
  551. coid = coid.removeLastPart();
  552. SortedSet ret;
  553. ret= oidKeys.tailSet(oid); // get oids >= oid
  554. Iterator it = ret.iterator();
  555. ComparableSnmpObjectId roid=null;
  556. /*
  557. * If there are elements in the tail set, then
  558. * - get first one.
  559. * - if first is input (which it is supposed to be according to the contract of
  560. * SortedSet.tailSet() , then get next, which is the
  561. * one we look for.
  562. */
  563. if (it.hasNext())
  564. {
  565. roid = (ComparableSnmpObjectId)it.next(); // oid
  566. }
  567. if (roid == null)
  568. {
  569. return null; // roid is null,
  570. }
  571. if (roid.compareTo(coid)==0) // input elment
  572. {
  573. // if there is a next element, then it is ours.
  574. if (it.hasNext())
  575. {
  576. roid = (ComparableSnmpObjectId)it.next();
  577. }
  578. else
  579. {
  580. roid = null; // end of list
  581. }
  582. }
  583. /*
  584. * Check if still in subtree if requested to stay within
  585. */
  586. if (stayInSubtree && roid != null)
  587. {
  588. ComparableSnmpObjectId parent = coid.removeLastPart();
  589. if (!parent.isRootOf(roid))
  590. roid = null;
  591. }
  592. return roid;
  593. }
  594. // Inner Class ---------------------------------------------------
  595. /**
  596. * An entry containing the mapping between oid and mbean/attribute
  597. *
  598. * @author <a href="mailto:pilhuhn@user.sf.net>">Heiko W. Rupp</a>
  599. */
  600. private class BindEntry implements Comparable {
  601. private final ComparableSnmpObjectId oid;
  602. private ObjectName mbean;
  603. private Attribute attr;
  604. private String mName;
  605. private String aName;
  606. private boolean isReadWrite = false;
  607. /**
  608. * Constructs a new BindEntry
  609. *
  610. * @param oid
  611. * The SNMP-oid, this entry will use.
  612. * @param mbName
  613. * The name of an MBean with attribute to query
  614. * @param attrName
  615. * The name of the attribute to query
  616. */
  617. BindEntry(final String oidString, final String mbName, final String attrName) {
  618. this(new ComparableSnmpObjectId(oidString),
  619. mbName,
  620. attrName);
  621. }
  622. /**
  623. * Constructs a new BindEntry.
  624. * @param coid The SNMP-oid, this entry will use.
  625. * @param mbName The name of an MBean with attribute to query
  626. * @param attrName The name of the attribute to query
  627. */
  628. BindEntry(final ComparableSnmpObjectId coid, final String mbName, final String attrName) {
  629. oid = coid;
  630. this.mName = mbName;
  631. this.aName = attrName;
  632. try
  633. {
  634. mbean = new ObjectName(mbName);
  635. attr = new Attribute(attrName, null);
  636. }
  637. catch (Exception e)
  638. {
  639. log.warn(e.toString());
  640. mName = "-unset-";
  641. aName = "-unset-";
  642. }
  643. }
  644. /**
  645. * A string representation of this BindEntry
  646. */
  647. public String toString() {
  648. StringBuffer buf = new StringBuffer();
  649. buf.append("[oid=");
  650. buf.append(oid).append(", mbean=");
  651. buf.append(mName).append(", attr=");
  652. buf.append(aName).append(", rw=");
  653. buf.append(isReadWrite).append("]");
  654. return buf.toString();
  655. }
  656. public Attribute getAttr() {
  657. return attr;
  658. }
  659. public ObjectName getMbean()
  660. {
  661. return mbean;
  662. }
  663. public ComparableSnmpObjectId getOid()
  664. {
  665. return oid;
  666. }
  667. /**
  668. * Compare two BindEntries. Ordering is defined at oid-level.
  669. *
  670. * @param other
  671. * The BindEntry to compare to.
  672. * @return 0 on equals, 1 if this is bigger than other
  673. */
  674. public int compareTo(Object other)
  675. {
  676. if (other == null)
  677. throw new NullPointerException("Can't compare to NULL");
  678. if (!(other instanceof BindEntry))
  679. throw new ClassCastException("Parameter is no BindEntry");
  680. // trivial case
  681. if (this.equals(other))
  682. return 0;
  683. BindEntry obe = (BindEntry) other;
  684. if (getOid().equals(obe.getOid()))
  685. return 0;
  686. int res =oid.compare(obe.getOid());
  687. return res;
  688. }
  689. }
  690. }