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