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-2009 Sun Microsystems, Inc. 015 * Portions Copyright 2014-2015 ForgeRock AS. 016 */ 017package org.opends.server.admin.client.spi; 018 019import static org.opends.server.admin.PropertyException.*; 020 021import java.util.ArrayList; 022import java.util.Collection; 023import java.util.Collections; 024import java.util.LinkedList; 025import java.util.List; 026import java.util.SortedSet; 027 028import org.forgerock.i18n.LocalizableMessage; 029import org.opends.server.admin.AbsoluteInheritedDefaultBehaviorProvider; 030import org.opends.server.admin.AbstractManagedObjectDefinition; 031import org.opends.server.admin.AliasDefaultBehaviorProvider; 032import org.opends.server.admin.Configuration; 033import org.opends.server.admin.ConfigurationClient; 034import org.opends.server.admin.Constraint; 035import org.opends.server.admin.DefaultBehaviorProviderVisitor; 036import org.opends.server.admin.DefinedDefaultBehaviorProvider; 037import org.opends.server.admin.DefinitionDecodingException; 038import org.opends.server.admin.DefinitionDecodingException.Reason; 039import org.opends.server.admin.InstantiableRelationDefinition; 040import org.opends.server.admin.ManagedObjectNotFoundException; 041import org.opends.server.admin.ManagedObjectPath; 042import org.opends.server.admin.OptionalRelationDefinition; 043import org.opends.server.admin.PropertyDefinition; 044import org.opends.server.admin.PropertyException; 045import org.opends.server.admin.PropertyNotFoundException; 046import org.opends.server.admin.PropertyOption; 047import org.opends.server.admin.RelationDefinition; 048import org.opends.server.admin.RelativeInheritedDefaultBehaviorProvider; 049import org.opends.server.admin.SetRelationDefinition; 050import org.opends.server.admin.UndefinedDefaultBehaviorProvider; 051import org.opends.server.admin.client.AuthorizationException; 052import org.opends.server.admin.client.ClientConstraintHandler; 053import org.opends.server.admin.client.CommunicationException; 054import org.opends.server.admin.client.ManagedObject; 055import org.opends.server.admin.client.ManagedObjectDecodingException; 056import org.opends.server.admin.client.ManagementContext; 057import org.opends.server.admin.client.OperationRejectedException; 058import org.opends.server.admin.client.OperationRejectedException.OperationType; 059import org.opends.server.admin.std.client.RootCfgClient; 060 061/** 062 * An abstract management connection context driver which should form 063 * the basis of driver implementations. 064 */ 065public abstract class Driver { 066 067 /** 068 * A default behavior visitor used for retrieving the default values 069 * of a property. 070 * 071 * @param <T> 072 * The type of the property. 073 */ 074 private class DefaultValueFinder<T> implements 075 DefaultBehaviorProviderVisitor<T, Collection<T>, Void> { 076 077 /** Any exception that occurred whilst retrieving inherited default values. */ 078 private PropertyException exception; 079 080 /** The path of the managed object containing the first property. */ 081 private final ManagedObjectPath<?, ?> firstPath; 082 083 /** Indicates whether the managed object has been created yet. */ 084 private final boolean isCreate; 085 086 /** The path of the managed object containing the next property. */ 087 private ManagedObjectPath<?, ?> nextPath; 088 089 /** The next property whose default values were required. */ 090 private PropertyDefinition<T> nextProperty; 091 092 /** Private constructor. */ 093 private DefaultValueFinder(ManagedObjectPath<?, ?> p, boolean isCreate) { 094 this.firstPath = p; 095 this.isCreate = isCreate; 096 } 097 098 /** {@inheritDoc} */ 099 @Override 100 public Collection<T> visitAbsoluteInherited( 101 AbsoluteInheritedDefaultBehaviorProvider<T> d, Void p) { 102 try { 103 return getInheritedProperty(d.getManagedObjectPath(), d 104 .getManagedObjectDefinition(), d.getPropertyName()); 105 } catch (PropertyException e) { 106 exception = e; 107 return Collections.emptySet(); 108 } 109 } 110 111 /** {@inheritDoc} */ 112 @Override 113 public Collection<T> visitAlias(AliasDefaultBehaviorProvider<T> d, Void p) { 114 return Collections.emptySet(); 115 } 116 117 /** {@inheritDoc} */ 118 @Override 119 public Collection<T> visitDefined(DefinedDefaultBehaviorProvider<T> d, 120 Void p) { 121 Collection<String> stringValues = d.getDefaultValues(); 122 List<T> values = new ArrayList<>(stringValues.size()); 123 124 for (String stringValue : stringValues) { 125 try { 126 values.add(nextProperty.decodeValue(stringValue)); 127 } catch (PropertyException e) { 128 exception = defaultBehaviorException(nextProperty, e); 129 break; 130 } 131 } 132 133 return values; 134 } 135 136 /** {@inheritDoc} */ 137 @Override 138 public Collection<T> visitRelativeInherited( 139 RelativeInheritedDefaultBehaviorProvider<T> d, Void p) { 140 try { 141 return getInheritedProperty(d.getManagedObjectPath(nextPath), d 142 .getManagedObjectDefinition(), d.getPropertyName()); 143 } catch (PropertyException e) { 144 exception = e; 145 return Collections.emptySet(); 146 } 147 } 148 149 /** {@inheritDoc} */ 150 @Override 151 public Collection<T> visitUndefined(UndefinedDefaultBehaviorProvider<T> d, 152 Void p) { 153 return Collections.emptySet(); 154 } 155 156 /** Find the default values for the next path/property. */ 157 private Collection<T> find(ManagedObjectPath<?, ?> p, 158 PropertyDefinition<T> pd) throws PropertyException { 159 this.nextPath = p; 160 this.nextProperty = pd; 161 162 Collection<T> values = nextProperty.getDefaultBehaviorProvider().accept( 163 this, null); 164 165 if (exception != null) { 166 throw exception; 167 } 168 169 if (values.size() > 1 && !pd.hasOption(PropertyOption.MULTI_VALUED)) { 170 throw PropertyException.defaultBehaviorException(pd, 171 PropertyException.propertyIsSingleValuedException(pd)); 172 } 173 174 return values; 175 } 176 177 /** Get an inherited property value. */ 178 @SuppressWarnings("unchecked") 179 private Collection<T> getInheritedProperty(ManagedObjectPath target, 180 AbstractManagedObjectDefinition<?, ?> d, String propertyName) 181 throws PropertyException { 182 // First check that the requested type of managed object 183 // corresponds to the path. 184 AbstractManagedObjectDefinition<?, ?> actualType = target 185 .getManagedObjectDefinition(); 186 if (!d.isParentOf(actualType)) { 187 throw PropertyException.defaultBehaviorException( 188 nextProperty, new DefinitionDecodingException(d, 189 Reason.WRONG_TYPE_INFORMATION)); 190 } 191 192 // Save the current property in case of recursion. 193 PropertyDefinition<T> pd1 = nextProperty; 194 195 try { 196 // Determine the requested property definition. 197 PropertyDefinition<T> pd2; 198 try { 199 // FIXME: we use the definition taken from the default 200 // behavior here when we should really use the exact 201 // definition of the component being created. 202 PropertyDefinition<?> pdTmp = d.getPropertyDefinition(propertyName); 203 pd2 = pd1.getClass().cast(pdTmp); 204 } catch (IllegalArgumentException e) { 205 throw new PropertyNotFoundException(propertyName); 206 } catch (ClassCastException e) { 207 // FIXME: would be nice to throw a better exception here. 208 throw new PropertyNotFoundException(propertyName); 209 } 210 211 // If the path relates to the current managed object and the 212 // managed object is in the process of being created it won't 213 // exist, so we should just use the default values of the 214 // referenced property. 215 if (isCreate && firstPath.equals(target)) { 216 // Recursively retrieve this property's default values. 217 Collection<T> tmp = find(target, pd2); 218 Collection<T> values = new ArrayList<>(tmp.size()); 219 for (T value : tmp) { 220 pd1.validateValue(value); 221 values.add(value); 222 } 223 return values; 224 } else { 225 // FIXME: issue 2481 - this is broken if the referenced property 226 // inherits its defaults from the newly created managed object. 227 return getPropertyValues(target, pd2); 228 } 229 } catch (PropertyException | DefinitionDecodingException | PropertyNotFoundException 230 | AuthorizationException | ManagedObjectNotFoundException | CommunicationException e) { 231 throw PropertyException.defaultBehaviorException(pd1, e); 232 } 233 } 234 } 235 236 /** Creates a new abstract management context. */ 237 protected Driver() { 238 // No implementation required. 239 } 240 241 /** Closes any context associated with this management context driver. */ 242 public void close() { 243 // do nothing by default 244 } 245 246 /** 247 * Deletes the named instantiable child managed object from the 248 * named parent managed object. 249 * 250 * @param <C> 251 * The type of client managed object configuration that the 252 * relation definition refers to. 253 * @param <S> 254 * The type of server managed object configuration that the 255 * relation definition refers to. 256 * @param parent 257 * The path of the parent managed object. 258 * @param rd 259 * The instantiable relation definition. 260 * @param name 261 * The name of the child managed object to be removed. 262 * @return Returns <code>true</code> if the named instantiable 263 * child managed object was found, or <code>false</code> 264 * if it was not found. 265 * @throws IllegalArgumentException 266 * If the relation definition is not associated with the 267 * parent managed object's definition. 268 * @throws ManagedObjectNotFoundException 269 * If the parent managed object could not be found. 270 * @throws OperationRejectedException 271 * If the managed object cannot be removed due to some 272 * client-side or server-side constraint which cannot be 273 * satisfied (for example, if it is referenced by another 274 * managed object). 275 * @throws AuthorizationException 276 * If the server refuses to remove the managed objects 277 * because the client does not have the correct 278 * privileges. 279 * @throws CommunicationException 280 * If the client cannot contact the server due to an 281 * underlying communication problem. 282 */ 283 public final <C extends ConfigurationClient, S extends Configuration> 284 boolean deleteManagedObject( 285 ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd, 286 String name) throws IllegalArgumentException, 287 ManagedObjectNotFoundException, OperationRejectedException, 288 AuthorizationException, CommunicationException { 289 validateRelationDefinition(parent, rd); 290 ManagedObjectPath<?, ?> child = parent.child(rd, name); 291 return doDeleteManagedObject(child); 292 } 293 294 /** 295 * Deletes the optional child managed object from the named parent 296 * managed object. 297 * 298 * @param <C> 299 * The type of client managed object configuration that the 300 * relation definition refers to. 301 * @param <S> 302 * The type of server managed object configuration that the 303 * relation definition refers to. 304 * @param parent 305 * The path of the parent managed object. 306 * @param rd 307 * The optional relation definition. 308 * @return Returns <code>true</code> if the optional child managed 309 * object was found, or <code>false</code> if it was not 310 * found. 311 * @throws IllegalArgumentException 312 * If the relation definition is not associated with the 313 * parent managed object's definition. 314 * @throws ManagedObjectNotFoundException 315 * If the parent managed object could not be found. 316 * @throws OperationRejectedException 317 * If the managed object cannot be removed due to some 318 * client-side or server-side constraint which cannot be 319 * satisfied (for example, if it is referenced by another 320 * managed object). 321 * @throws AuthorizationException 322 * If the server refuses to remove the managed objects 323 * because the client does not have the correct 324 * privileges. 325 * @throws CommunicationException 326 * If the client cannot contact the server due to an 327 * underlying communication problem. 328 */ 329 public final <C extends ConfigurationClient, S extends Configuration> 330 boolean deleteManagedObject( 331 ManagedObjectPath<?, ?> parent, OptionalRelationDefinition<C, S> rd) 332 throws IllegalArgumentException, ManagedObjectNotFoundException, 333 OperationRejectedException, AuthorizationException, 334 CommunicationException { 335 validateRelationDefinition(parent, rd); 336 ManagedObjectPath<?, ?> child = parent.child(rd); 337 return doDeleteManagedObject(child); 338 } 339 340 /** 341 * Deletes the named instantiable child managed object from the 342 * named parent managed object. 343 * 344 * @param <C> 345 * The type of client managed object configuration that the 346 * relation definition refers to. 347 * @param <S> 348 * The type of server managed object configuration that the 349 * relation definition refers to. 350 * @param parent 351 * The path of the parent managed object. 352 * @param rd 353 * The instantiable relation definition. 354 * @param name 355 * The name of the child managed object to be removed. 356 * @return Returns <code>true</code> if the named instantiable 357 * child managed object was found, or <code>false</code> 358 * if it was not found. 359 * @throws IllegalArgumentException 360 * If the relation definition is not associated with the 361 * parent managed object's definition. 362 * @throws ManagedObjectNotFoundException 363 * If the parent managed object could not be found. 364 * @throws OperationRejectedException 365 * If the managed object cannot be removed due to some 366 * client-side or server-side constraint which cannot be 367 * satisfied (for example, if it is referenced by another 368 * managed object). 369 * @throws AuthorizationException 370 * If the server refuses to remove the managed objects 371 * because the client does not have the correct 372 * privileges. 373 * @throws CommunicationException 374 * If the client cannot contact the server due to an 375 * underlying communication problem. 376 */ 377 public final <C extends ConfigurationClient, S extends Configuration> 378 boolean deleteManagedObject( 379 ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd, 380 String name) throws IllegalArgumentException, 381 ManagedObjectNotFoundException, OperationRejectedException, 382 AuthorizationException, CommunicationException { 383 validateRelationDefinition(parent, rd); 384 ManagedObjectPath<?, ?> child = parent.child(rd, name); 385 return doDeleteManagedObject(child); 386 } 387 388 /** 389 * Gets the named managed object. The path is guaranteed to be 390 * non-empty, so implementations do not need to worry about handling 391 * this special case. 392 * 393 * @param <C> 394 * The type of client managed object configuration that the 395 * path definition refers to. 396 * @param <S> 397 * The type of server managed object configuration that the 398 * path definition refers to. 399 * @param path 400 * The non-empty path of the managed object. 401 * @return Returns the named managed object. 402 * @throws DefinitionDecodingException 403 * If the managed object was found but its type could not 404 * be determined. 405 * @throws ManagedObjectDecodingException 406 * If the managed object was found but one or more of its 407 * properties could not be decoded. 408 * @throws ManagedObjectNotFoundException 409 * If the requested managed object could not be found on 410 * the server. 411 * @throws AuthorizationException 412 * If the server refuses to retrieve the managed object 413 * because the client does not have the correct 414 * privileges. 415 * @throws CommunicationException 416 * If the client cannot contact the server due to an 417 * underlying communication problem. 418 */ 419 public abstract <C extends ConfigurationClient, S extends Configuration> 420 ManagedObject<? extends C> getManagedObject( 421 ManagedObjectPath<C, S> path) throws DefinitionDecodingException, 422 ManagedObjectDecodingException, ManagedObjectNotFoundException, 423 AuthorizationException, CommunicationException; 424 425 /** 426 * Gets the effective values of a property in the named managed 427 * object. 428 * <p> 429 * Implementations MUST NOT not use 430 * {@link #getManagedObject(ManagedObjectPath)} to read the 431 * referenced managed object in its entirety. Specifically, 432 * implementations MUST only attempt to resolve the default values 433 * for the requested property and its dependencies (if it uses 434 * inherited defaults). This is to avoid infinite recursion where a 435 * managed object contains a property which inherits default values 436 * from another property in the same managed object. 437 * 438 * @param <C> 439 * The type of client managed object configuration that the 440 * path definition refers to. 441 * @param <S> 442 * The type of server managed object configuration that the 443 * path definition refers to. 444 * @param <PD> 445 * The type of the property to be retrieved. 446 * @param path 447 * The path of the managed object containing the property. 448 * @param pd 449 * The property to be retrieved. 450 * @return Returns the property's effective values, or an empty set 451 * if there are no values defined. 452 * @throws IllegalArgumentException 453 * If the property definition is not associated with the 454 * referenced managed object's definition. 455 * @throws DefinitionDecodingException 456 * If the managed object was found but its type could not 457 * be determined. 458 * @throws PropertyException 459 * If the managed object was found but the requested 460 * property could not be decoded. 461 * @throws ManagedObjectNotFoundException 462 * If the requested managed object could not be found on 463 * the server. 464 * @throws AuthorizationException 465 * If the server refuses to retrieve the managed object 466 * because the client does not have the correct 467 * privileges. 468 * @throws CommunicationException 469 * If the client cannot contact the server due to an 470 * underlying communication problem. 471 */ 472 public abstract <C extends ConfigurationClient, S extends Configuration, PD> 473 SortedSet<PD> getPropertyValues( 474 ManagedObjectPath<C, S> path, PropertyDefinition<PD> pd) 475 throws IllegalArgumentException, DefinitionDecodingException, 476 AuthorizationException, ManagedObjectNotFoundException, 477 CommunicationException, PropertyException; 478 479 /** 480 * Gets the root configuration managed object associated with this 481 * management context driver. 482 * 483 * @return Returns the root configuration managed object associated 484 * with this management context driver. 485 */ 486 public abstract 487 ManagedObject<RootCfgClient> getRootConfigurationManagedObject(); 488 489 /** 490 * Lists the child managed objects of the named parent managed 491 * object which are a sub-type of the specified managed object 492 * definition. 493 * 494 * @param <C> 495 * The type of client managed object configuration that the 496 * relation definition refers to. 497 * @param <S> 498 * The type of server managed object configuration that the 499 * relation definition refers to. 500 * @param parent 501 * The path of the parent managed object. 502 * @param rd 503 * The instantiable relation definition. 504 * @param d 505 * The managed object definition. 506 * @return Returns the names of the child managed objects which are 507 * a sub-type of the specified managed object definition. 508 * @throws IllegalArgumentException 509 * If the relation definition is not associated with the 510 * parent managed object's definition. 511 * @throws ManagedObjectNotFoundException 512 * If the parent managed object could not be found. 513 * @throws AuthorizationException 514 * If the server refuses to list the managed objects 515 * because the client does not have the correct 516 * privileges. 517 * @throws CommunicationException 518 * If the client cannot contact the server due to an 519 * underlying communication problem. 520 */ 521 public abstract <C extends ConfigurationClient, S extends Configuration> 522 String[] listManagedObjects( 523 ManagedObjectPath<?, ?> parent, InstantiableRelationDefinition<C, S> rd, 524 AbstractManagedObjectDefinition<? extends C, ? extends S> d) 525 throws IllegalArgumentException, ManagedObjectNotFoundException, 526 AuthorizationException, CommunicationException; 527 528 /** 529 * Lists the child managed objects of the named parent managed 530 * object which are a sub-type of the specified managed object 531 * definition. 532 * 533 * @param <C> 534 * The type of client managed object configuration that the 535 * relation definition refers to. 536 * @param <S> 537 * The type of server managed object configuration that the 538 * relation definition refers to. 539 * @param parent 540 * The path of the parent managed object. 541 * @param rd 542 * The set relation definition. 543 * @param d 544 * The managed object definition. 545 * @return Returns the names of the child managed objects which are 546 * a sub-type of the specified managed object definition. 547 * @throws IllegalArgumentException 548 * If the relation definition is not associated with the 549 * parent managed object's definition. 550 * @throws ManagedObjectNotFoundException 551 * If the parent managed object could not be found. 552 * @throws AuthorizationException 553 * If the server refuses to list the managed objects 554 * because the client does not have the correct 555 * privileges. 556 * @throws CommunicationException 557 * If the client cannot contact the server due to an 558 * underlying communication problem. 559 */ 560 public abstract <C extends ConfigurationClient, S extends Configuration> 561 String[] listManagedObjects( 562 ManagedObjectPath<?, ?> parent, SetRelationDefinition<C, S> rd, 563 AbstractManagedObjectDefinition<? extends C, ? extends S> d) 564 throws IllegalArgumentException, ManagedObjectNotFoundException, 565 AuthorizationException, CommunicationException; 566 567 /** 568 * Determines whether or not the named managed object exists. 569 * <p> 570 * Implementations should always return <code>true</code> when the 571 * provided path is empty. 572 * 573 * @param path 574 * The path of the named managed object. 575 * @return Returns <code>true</code> if the named managed object 576 * exists, <code>false</code> otherwise. 577 * @throws ManagedObjectNotFoundException 578 * If the parent managed object could not be found. 579 * @throws AuthorizationException 580 * If the server refuses to make the determination because 581 * the client does not have the correct privileges. 582 * @throws CommunicationException 583 * If the client cannot contact the server due to an 584 * underlying communication problem. 585 */ 586 public abstract boolean managedObjectExists(ManagedObjectPath<?, ?> path) 587 throws ManagedObjectNotFoundException, AuthorizationException, 588 CommunicationException; 589 590 /** 591 * Deletes the named managed object. 592 * <p> 593 * Implementations do not need check whether the named managed 594 * object exists, nor do they need to enforce client constraints. 595 * 596 * @param <C> 597 * The type of client managed object configuration that the 598 * relation definition refers to. 599 * @param <S> 600 * The type of server managed object configuration that the 601 * relation definition refers to. 602 * @param path 603 * The path of the managed object to be deleted. 604 * @throws OperationRejectedException 605 * If the managed object cannot be removed due to some 606 * server-side constraint which cannot be satisfied (for 607 * example, if it is referenced by another managed 608 * object). 609 * @throws AuthorizationException 610 * If the server refuses to remove the managed objects 611 * because the client does not have the correct 612 * privileges. 613 * @throws CommunicationException 614 * If the client cannot contact the server due to an 615 * underlying communication problem. 616 */ 617 protected abstract <C extends ConfigurationClient, S extends Configuration> 618 void deleteManagedObject( 619 ManagedObjectPath<C, S> path) throws OperationRejectedException, 620 AuthorizationException, CommunicationException; 621 622 /** 623 * Gets the default values for the specified property. 624 * 625 * @param <PD> 626 * The type of the property. 627 * @param p 628 * The managed object path of the current managed object. 629 * @param pd 630 * The property definition. 631 * @param isCreate 632 * Indicates whether the managed object has been created 633 * yet. 634 * @return Returns the default values for the specified property. 635 * @throws PropertyException 636 * If the default values could not be retrieved or decoded 637 * properly. 638 */ 639 protected final <PD> Collection<PD> findDefaultValues( 640 ManagedObjectPath<?, ?> p, PropertyDefinition<PD> pd, boolean isCreate) 641 throws PropertyException { 642 DefaultValueFinder<PD> v = new DefaultValueFinder<>(p, isCreate); 643 return v.find(p, pd); 644 } 645 646 /** 647 * Gets the management context associated with this driver. 648 * 649 * @return Returns the management context associated with this 650 * driver. 651 */ 652 protected abstract ManagementContext getManagementContext(); 653 654 /** 655 * Validate that a relation definition belongs to the managed object 656 * referenced by the provided path. 657 * 658 * @param path 659 * The parent managed object path. 660 * @param rd 661 * The relation definition. 662 * @throws IllegalArgumentException 663 * If the relation definition does not belong to the 664 * managed object definition. 665 */ 666 protected final void validateRelationDefinition(ManagedObjectPath<?, ?> path, 667 RelationDefinition<?, ?> rd) throws IllegalArgumentException { 668 AbstractManagedObjectDefinition<?, ?> d = path.getManagedObjectDefinition(); 669 RelationDefinition<?, ?> tmp = d.getRelationDefinition(rd.getName()); 670 if (tmp != rd) { 671 throw new IllegalArgumentException("The relation " + rd.getName() 672 + " is not associated with a " + d.getName()); 673 } 674 } 675 676 /** 677 * Remove a managed object, first ensuring that the parent exists, 678 * then ensuring that the child exists, before ensuring that any 679 * constraints are satisfied. 680 */ 681 private <C extends ConfigurationClient, S extends Configuration> 682 boolean doDeleteManagedObject( 683 ManagedObjectPath<C, S> path) throws ManagedObjectNotFoundException, 684 OperationRejectedException, AuthorizationException, 685 CommunicationException { 686 // First make sure that the parent exists. 687 if (!managedObjectExists(path.parent())) { 688 throw new ManagedObjectNotFoundException(); 689 } 690 691 // Make sure that the targeted managed object exists. 692 if (!managedObjectExists(path)) { 693 return false; 694 } 695 696 // The targeted managed object is guaranteed to exist, so enforce 697 // any constraints. 698 AbstractManagedObjectDefinition<?, ?> d = path.getManagedObjectDefinition(); 699 List<LocalizableMessage> messages = new LinkedList<>(); 700 boolean isAcceptable = true; 701 702 for (Constraint constraint : d.getAllConstraints()) { 703 for (ClientConstraintHandler handler : constraint 704 .getClientConstraintHandlers()) { 705 ManagementContext context = getManagementContext(); 706 if (!handler.isDeleteAcceptable(context, path, messages)) { 707 isAcceptable = false; 708 } 709 } 710 if (!isAcceptable) { 711 break; 712 } 713 } 714 715 if (!isAcceptable) { 716 throw new OperationRejectedException(OperationType.DELETE, d 717 .getUserFriendlyName(), messages); 718 } 719 720 deleteManagedObject(path); 721 return true; 722 } 723}