1 /* 2 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.jndi.ldap; 27 28 import javax.naming.directory.SearchControls; 29 import javax.naming.event.*; 30 31 /** 32 * This class holds the information in an event registration/deregistration 33 * request. This includes the name, filter, search controls and 34 * the different interfaces that the listener implements. This last piece 35 * of information determines which event(s) the listener is interested in. 36 *<p> 37 * It overrides equals() and hashCode() to use all these pieces of 38 * information so that it can be used correctly in a hashtable. 39 * 40 * @author Rosanna Lee 41 */ 42 final class NotifierArgs { 43 static final int ADDED_MASK = 0x1; 44 static final int REMOVED_MASK = 0x2; 45 static final int CHANGED_MASK = 0x4; 46 static final int RENAMED_MASK = 0x8; 47 48 // these fields are package private; used by NamingEventNotifier 49 String name; 50 String filter; 51 SearchControls controls; 52 int mask; 53 54 // package private 55 NotifierArgs(String name, int scope, NamingListener l) { 56 this(name, "(objectclass=*)", null, l); 57 58 // if scope is not default, create search ctl and set it 59 if (scope != EventContext.ONELEVEL_SCOPE) { 60 controls = new SearchControls(); 61 controls.setSearchScope(scope); 62 } 63 } 64 65 // package private 66 NotifierArgs(String name, String filter, SearchControls ctls, 67 NamingListener l) { 68 this.name = name; 69 this.filter = filter; 70 this.controls = ctls; 71 72 if (l instanceof NamespaceChangeListener) { 73 mask |= ADDED_MASK|REMOVED_MASK|RENAMED_MASK; 74 } 75 if (l instanceof ObjectChangeListener) { 76 mask |= CHANGED_MASK; 77 } 78 } 79 80 // checks name, filter, controls 81 public boolean equals(Object obj) { 82 if (obj instanceof NotifierArgs) { 83 NotifierArgs target = (NotifierArgs)obj; 84 return mask == target.mask && 85 name.equals(target.name) && filter.equals(target.filter) && 86 checkControls(target.controls); 87 } 88 return false; 89 } 90 91 private boolean checkControls(SearchControls ctls) { 92 if ((controls == null || ctls == null)) { 93 return ctls == controls; 94 } 95 // ctls are nonempty 96 97 return (controls.getSearchScope() == ctls.getSearchScope()) && 98 (controls.getTimeLimit() == ctls.getTimeLimit()) && 99 (controls.getDerefLinkFlag() == ctls.getDerefLinkFlag()) && 100 (controls.getReturningObjFlag() == ctls.getReturningObjFlag()) && 101 (controls.getCountLimit() == ctls.getCountLimit()) && 102 checkStringArrays(controls.getReturningAttributes(), 103 ctls.getReturningAttributes()); 104 } 105 106 private static boolean checkStringArrays(String[] s1, String[] s2) { 107 if ((s1 == null) || (s2 == null)) { 108 return s1 == s2; 109 } 110 111 // both are nonnull 112 if (s1.length != s2.length) { 113 return false; 114 } 115 116 for (int i = 0; i < s1.length; i++) { 117 if (!s1[i].equals(s2[i])) { 118 return false; 119 } 120 } 121 return true; 122 } 123 124 // save from having to recalculate each time 125 private int sum = -1; 126 public int hashCode() { 127 if (sum == -1) 128 sum = mask + name.hashCode() + filter.hashCode() + controlsCode(); 129 return sum; 130 } 131 132 // used in calculating hash code 133 private int controlsCode() { 134 if (controls == null) return 0; 135 136 int total = controls.getTimeLimit() + (int)controls.getCountLimit() + 137 (controls.getDerefLinkFlag() ? 1 : 0) + 138 (controls.getReturningObjFlag() ? 1 : 0); 139 140 String[] attrs = controls.getReturningAttributes(); 141 if (attrs != null) { 142 for (int i = 0; i < attrs.length; i++) { 143 total += attrs[i].hashCode(); 144 } 145 } 146 147 return total; 148 } 149 }