001/* 002 * The contents of this file are subject to the terms of the Common Development and 003 * Distribution License (the License). You may not use this file except in compliance with the 004 * License. 005 * 006 * You can obtain a copy of the License at legal/CDDLv1.0.txt. See the License for the 007 * specific language governing permission and limitations under the License. 008 * 009 * When distributing Covered Software, include this CDDL Header Notice in each file and include 010 * the License file at legal/CDDLv1.0.txt. If applicable, add the following below the CDDL 011 * Header, with the fields enclosed by brackets [] replaced by your own identifying 012 * information: "Portions Copyright [year] [name of copyright owner]". 013 * 014 * Copyright 2008-2010 Sun Microsystems, Inc. 015 * Portions Copyright 2014-2016 ForgeRock AS. 016 */ 017package org.opends.guitools.controlpanel.ui.nodes; 018 019import javax.swing.Icon; 020import javax.swing.tree.DefaultMutableTreeNode; 021 022import org.forgerock.opendj.ldap.DN; 023import org.forgerock.opendj.ldap.RDN; 024import org.opends.guitools.controlpanel.browser.BasicNodeError; 025import org.opends.server.types.LDAPURL; 026 027/** The basic node used to render entries in the 'Manage Entries' tree. */ 028public class BasicNode extends DefaultMutableTreeNode { 029 030 private static final long serialVersionUID = 5441658731908509872L; 031 private String localDn; 032 private String localRdn; 033 private String localRdnWithAttributeName; 034 private LDAPURL remoteUrl; 035 private String remoteRdn; 036 private String remoteRdnWithAttributeName; 037 038 private boolean isLeaf; 039 private boolean refreshNeededOnExpansion = true; 040 private boolean obsolete; 041 private BasicNodeError error; 042 043 private String[] referral; 044 private int numSubOrdinates; 045 046 /** 047 * This is required for the case where there is an undefined number of 048 * subordinates (for instance in the case of the changelog). 049 */ 050 private boolean hasSubOrdinates; 051 052 private String displayName; 053 private Icon icon; 054 private int fontStyle; 055 056 private boolean sizeLimitReached; 057 058 private String[] objectClassValues; 059 060 /** 061 * Constructor. 062 * @param dn the DN of the entry. 063 */ 064 public BasicNode(String dn) { 065 localDn = dn; 066 localRdn = extractRDN(localDn); 067 localRdnWithAttributeName = extractRDN(localDn, true); 068 isLeaf = true; 069 refreshNeededOnExpansion = true; 070 numSubOrdinates = -1; 071 hasSubOrdinates = false; 072 displayName = ""; 073 } 074 075 076 /** 077 * Returns the DN of the local entry. 078 * @return the DN of the local entry. 079 */ 080 public String getDN() { 081 return localDn; 082 } 083 084 /** 085 * Returns the RDN value of the local entry. 086 * @return the RDN value of the local entry. 087 */ 088 public String getRDN() { 089 return localRdn; 090 } 091 092 /** 093 * Returns the RDN (with the attribute name) of the local entry. 094 * @return the RDN (with the attribute name) of the local entry. 095 */ 096 public String getRDNWithAttributeName() { 097 return localRdnWithAttributeName; 098 } 099 100 /** 101 * Returns the URL of the remote entry (if the node does not represent a 102 * referral it will be <CODE>null</CODE>). 103 * @return the URL of the remote entry (if the node does not represent a 104 * referral it will be <CODE>null</CODE>). 105 */ 106 public LDAPURL getRemoteUrl() { 107 return remoteUrl; 108 } 109 110 /** 111 * Sets the remote URL of the node. 112 * @param url the remote URL of the node. 113 */ 114 public void setRemoteUrl(LDAPURL url) { 115 remoteUrl = url; 116 if (remoteUrl != null) 117 { 118 remoteRdn = extractRDN(remoteUrl.getRawBaseDN()); 119 remoteRdnWithAttributeName = extractRDN(remoteUrl.getRawBaseDN(), true); 120 } 121 else 122 { 123 remoteRdn = null; 124 remoteRdnWithAttributeName = null; 125 } 126 } 127 128 /** 129 * Sets the remote URL of the node. 130 * @param url the remote URL of the node. 131 */ 132 public void setRemoteUrl(String url) { 133 try 134 { 135 if (url == null) 136 { 137 remoteUrl = null; 138 } 139 else 140 { 141 remoteUrl = LDAPURL.decode(url, false); 142 } 143 if (remoteUrl == null) { 144 remoteRdn = null; 145 remoteRdnWithAttributeName = null; 146 } 147 else { 148 remoteRdn = extractRDN(remoteUrl.getRawBaseDN()); 149 remoteRdnWithAttributeName = extractRDN(remoteUrl.getRawBaseDN(), true); 150 } 151 } 152 catch (Throwable t) 153 { 154 throw new IllegalArgumentException( 155 "The provided url: "+url+" is not valid:"+t, t); 156 } 157 } 158 159 /** 160 * Returns the RDN value of the remote entry. If the node does not 161 * represent a referral it will return <CODE>null</CODE>. 162 * @return the RDN value of the remote entry. 163 */ 164 public String getRemoteRDN() { 165 return remoteRdn; 166 } 167 168 /** 169 * Returns the RDN value of the remote entry (with the name of the attribute). 170 * If the node does not represent a referral it will return <CODE>null</CODE>. 171 * @return the RDN value of the remote entry (with the name of the attribute). 172 */ 173 public String getRemoteRDNWithAttributeName() { 174 return remoteRdnWithAttributeName; 175 } 176 177 178 /** 179 * Sets whether the node is a leaf or not. 180 * @param isLeaf whether the node is a leaf or not. 181 */ 182 public void setLeaf(boolean isLeaf) { 183 this.isLeaf = isLeaf; 184 } 185 186 /** 187 * Returns <CODE>true</CODE> if the node is a leaf and <CODE>false</CODE> 188 * otherwise. 189 * @return <CODE>true</CODE> if the node is a leaf and <CODE>false</CODE> 190 * otherwise. 191 */ 192 @Override 193 public boolean isLeaf() { 194 return isLeaf; 195 } 196 197 /** 198 * Returns <CODE>true</CODE> if the node must be refreshed when it is expanded 199 * and <CODE>false</CODE> otherwise. 200 * @return <CODE>true</CODE> if the node must be refreshed when it is expanded 201 * and <CODE>false</CODE> otherwise. 202 */ 203 public boolean isRefreshNeededOnExpansion() { 204 return refreshNeededOnExpansion; 205 } 206 207 /** 208 * Sets whether the node must be refreshed when it is expanded or not. 209 * @param refreshNeededOnExpansion whether the node must be refreshed when it 210 * is expanded or not. 211 */ 212 public void setRefreshNeededOnExpansion(boolean refreshNeededOnExpansion) { 213 this.refreshNeededOnExpansion = refreshNeededOnExpansion; 214 } 215 216 /** 217 * Returns whether the node is obsolete (and must be refreshed) or not. 218 * @return <CODE>true</CODE> if the node is obsolete and <CODE>false</CODE> 219 * otherwise. 220 */ 221 public boolean isObsolete() { 222 return obsolete; 223 } 224 225 /** 226 * Sets whether this is node is obsolete (and must be refreshed) or not. 227 * @param obsolete whether this is node is obsolete (and must be refreshed) or 228 * not. 229 */ 230 public void setObsolete(boolean obsolete) { 231 this.obsolete = obsolete; 232 } 233 234 /** 235 * Returns the error that occurred when updating the node. Returns 236 * <CODE>null</CODE> if no error occurred. 237 * @return the error that occurred when updating the node. Returns 238 * <CODE>null</CODE> if no error occurred. 239 */ 240 public BasicNodeError getError() { 241 return error; 242 } 243 244 /** 245 * Sets the error that occurred when updating the node. 246 * @param error the error. 247 */ 248 public void setError(BasicNodeError error) { 249 this.error = error; 250 } 251 252 253 /** 254 * Cached LDAP attributes 255 */ 256 257 /** 258 * Returns the number of subordinates of the entry. 259 * @return the number of subordinates of the entry. 260 */ 261 public int getNumSubOrdinates() { 262 return numSubOrdinates; 263 } 264 265 /** 266 * Sets the number of subordinates of the entry. 267 * @param number the number of subordinates of the entry. 268 */ 269 public void setNumSubOrdinates(int number) { 270 numSubOrdinates = number; 271 } 272 273 /** 274 * Returns whether the entry has subordinates or not. 275 * @return {@code true} if the entry has subordinates and {@code false} 276 * otherwise. 277 */ 278 public boolean hasSubOrdinates() { 279 return hasSubOrdinates; 280 } 281 282 /** 283 * Sets the whether the entry has subordinates or not. 284 * @param hasSubOrdinates whether the entry has subordinates or not. 285 */ 286 public void setHasSubOrdinates(boolean hasSubOrdinates) { 287 this.hasSubOrdinates = hasSubOrdinates; 288 } 289 290 /** 291 * Returns the referrals of the entry. Returns <CODE>null</CODE> if this node 292 * is not a referral. 293 * @return the referrals of the entry. Returns <CODE>null</CODE> if this node 294 * is not a referral. 295 */ 296 public String[] getReferral() { 297 return referral; 298 } 299 300 /** 301 * Sets the referrals of the entry. 302 * @param referral the referrals of the entry. 303 */ 304 public void setReferral(String[] referral) { 305 this.referral = referral; 306 } 307 308 309 // 310 // Rendering 311 // 312 313 @Override 314 public String toString() { 315 return getDisplayName(); 316 } 317 318 /** 319 * Returns the label that will be used to display the entry. 320 * @return the label that will be used to display the entry. 321 */ 322 public String getDisplayName() { 323 return displayName; 324 } 325 326 /** 327 * Sets the label that will be used to display the entry. 328 * @param name the label that will be used to display the entry. 329 */ 330 public void setDisplayName(String name) { 331 displayName = name; 332 } 333 334 /** 335 * Returns the icon associated with this node. 336 * @return the icon associated with this node. 337 */ 338 public Icon getIcon() { 339 return icon; 340 } 341 342 343 /** 344 * Sets the icon associated with this node. 345 * @param icon the icon associated with this node. 346 */ 347 public void setIcon(Icon icon) { 348 this.icon = icon; 349 } 350 351 /** 352 * Returns the font style to be used to render this node. 353 * @return the font style to be used to render this node. 354 */ 355 public int getFontStyle() { 356 return fontStyle; 357 } 358 359 /** 360 * Sets the font style to be used to render this node. 361 * @param style the font style to be used to render this node. 362 */ 363 public void setFontStyle(int style) { 364 fontStyle = style; 365 } 366 367 368 /** 369 * Returns the object class values associated with the entry. 370 * @return the object class values associated with the entry. 371 */ 372 public String[] getObjectClassValues() { 373 return objectClassValues; 374 } 375 376 /** 377 * Sets the object class values associated with the entry. 378 * @param objectClassValues the object class values associated with the entry. 379 */ 380 public void setObjectClassValues(String[] objectClassValues) { 381 this.objectClassValues = objectClassValues; 382 } 383 384 /** 385 * Extracts the RDN value from a DN. 386 * @param dn the DN. 387 * @param showAttributeName whether the result must include the attribute name 388 * or not. 389 * @return the RDN value from the DN. 390 */ 391 private static String extractRDN(String dn, boolean showAttributeName) 392 { 393 String result; 394 if (dn == null) 395 { 396 result = null; 397 } 398 else 399 { 400 try 401 { 402 DN dnObj = DN.valueOf(dn); 403 if (dnObj.size() >= 1) { 404 RDN rdn = dnObj.rdn(); 405 if (showAttributeName) 406 { 407 result = rdn.toString(); 408 } 409 else 410 { 411 result = rdn.getFirstAVA().getAttributeValue().toString(); 412 } 413 } 414 else { 415 result = ""; 416 } 417 } 418 catch (Throwable t) 419 { 420 throw new IllegalArgumentException( 421 "The provided argument is not a valid dn: "+t, t); 422 } 423 } 424 return result; 425 } 426 427 /** 428 * Extracts the RDN value from the DN. The value does not include the name 429 * of the attribute. 430 * @param dn the DN. 431 * @return the RDN value from the DN. 432 */ 433 private static String extractRDN(String dn) 434 { 435 return extractRDN(dn, false); 436 } 437 438 439 /** 440 * Returns <CODE>true</CODE> if the size limit was reached updating this node 441 * (and searching its children) and <CODE>false</CODE> otherwise. 442 * @return <CODE>true</CODE> if the size limit was reached updating this node 443 * (and searching its children) and <CODE>false</CODE> otherwise. 444 */ 445 public boolean isSizeLimitReached() 446 { 447 return sizeLimitReached; 448 } 449 450 451 /** 452 * Sets whether the size limit was reached updating this node 453 * (and searching its children). 454 * @param sizeLimitReached whether the size limit was reached updating this 455 * node (and searching its children). 456 */ 457 public void setSizeLimitReached(boolean sizeLimitReached) 458 { 459 this.sizeLimitReached = sizeLimitReached; 460 } 461}