/*
 * JBoss, Home of Professional Open Source.
 * Copyright 2015, Red Hat, Inc., and individual contributors
 * as indicated by the @author tags. See the copyright.txt file in the
 * distribution for a full listing of individual contributors.
 *
 * This is free software; you can redistribute it and/or modify it
 * under the terms of the GNU Lesser General Public License as
 * published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This software is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this software; if not, write to the Free
 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
 */

package org.jboss.as.clustering.controller.transform;

import org.jboss.as.controller.PathAddress;
import org.jboss.as.controller.transform.TransformationContext;
import org.jboss.as.controller.transform.description.DiscardPolicy;
import org.jboss.as.controller.transform.description.DynamicDiscardPolicy;
import org.jboss.dmr.ModelNode;
import org.jboss.dmr.Property;

/**
 * Implementation of a generic {@link DynamicDiscardPolicy} that discards child resources which have all their
 * attributes undefined, conditionally rejects or leaves resource for further transformation. It is to be used for required child
 * resources that are auto-created.
 *
 * @author Radoslav Husar
 * @version Sep 2015
 */
public enum RequiredChildResourceDiscardPolicy implements DynamicDiscardPolicy {

    /**
     * Policy that discards if all attributes are undefined; rejects otherwise.
     */
    REJECT_AND_WARN(DiscardPolicy.REJECT_AND_WARN),

    /**
     * Policy that discards if all attributes are undefined; never discards otherwise ({@link DiscardPolicy#NEVER}) in order to proceed with
     * resource transformations.
     */
    NEVER(DiscardPolicy.NEVER);

    private final DiscardPolicy policy;

    RequiredChildResourceDiscardPolicy(DiscardPolicy policy) {
        this.policy = policy;
    }

    /**
     * @return {@link DiscardPolicy#REJECT_AND_WARN} if any of the attributes are defined; {@link DiscardPolicy#SILENT} otherwise
     */
    @Override
    public DiscardPolicy checkResource(TransformationContext context, PathAddress address) {
        ModelNode model = context.readResource(PathAddress.EMPTY_ADDRESS).getModel();

        if (model.isDefined()) {
            for (Property entry : model.asPropertyList()) {
                if (entry.getValue().isDefined()) {
                    return policy;
                }
            }
        }

        return DiscardPolicy.SILENT;
    }

}

@@ -1116,16 +1116,191 @@
 ddress;%0A
+import org.jboss.as.controller.PathElement;%0Aimport org.jboss.as.controller.registry.ImmutableManagementResourceRegistration;%0Aimport org.jboss.as.controller.registry.Resource;%0A
 import o
@@ -1533,39 +1533,8 @@
 ode;
-%0Aimport org.jboss.dmr.Property;
 %0A%0A/*
@@ -1645,19 +1645,16 @@
 ll their
-%0A *
  attribu
@@ -1655,17 +1655,16 @@
 ttribute
-s
  undefin
@@ -1669,11 +1669,35 @@
 ined
-, c
+ and have no children.%0A * C
 ondi
@@ -1795,19 +1795,16 @@
 ed child
-%0A *
  resourc
@@ -1862,29 +1862,8 @@
 sar%0A
- * @version Sep 2015%0A
  */%0A
@@ -2011,16 +2011,45 @@
 ndefined
+ and resource has no children
 ; reject
@@ -2189,17 +2189,53 @@
 ndefined
-;
+ and resource has no children;%0A     *
  never d
@@ -2306,23 +2306,16 @@
 eed with
-%0A     *
  resourc
@@ -2371,18 +2371,23 @@
 y.NEVER)
+,%0A    
 ;
-%0A
 %0A    pri
@@ -2547,53 +2547,41 @@
 urn 
-%7B@link D
+contextual d
 iscard
-P
+ p
 olicy
-#REJECT_AND_WARN%7D
  if any 
 of t
@@ -2576,21 +2576,23 @@
  if any 
-of th
+resourc
 e attrib
@@ -2600,23 +2600,45 @@
 tes are 
+un
 defined
+ and has no children
 ; %7B@link
@@ -2669,16 +2669,17 @@
 therwise
+.
 %0A     */
@@ -2798,23 +2798,137 @@
     
-ModelNode model
+Resource resource = context.readResource(PathAddress.EMPTY_ADDRESS);%0A        ImmutableManagementResourceRegistration registration
  = c
@@ -2930,36 +2930,35 @@
 n = context.
-read
+get
 Resource
 (PathAddress
@@ -2937,32 +2937,44 @@
 text.getResource
+Registration
 (PathAddress.EMP
@@ -2984,16 +2984,52 @@
 ADDRESS)
+;%0A        ModelNode model = resource
 .getMode
@@ -3088,98 +3088,134 @@
 or (
-Property entry : model.asPropertyList()) %7B%0A                if (entry.getValue().isDefined(
+String attribute : registration.getAttributeNames(PathAddress.EMPTY_ADDRESS)) %7B%0A                if (model.hasDefined(attribute
 )) %7B
@@ -3242,16 +3242,21 @@
  return 
+this.
 policy;%0A
@@ -3294,24 +3294,279 @@
 %0A        %7D%0A%0A
+        for (PathElement path : registration.getChildAddresses(PathAddress.EMPTY_ADDRESS)) %7B%0A            if (path.isWildcard() ? resource.hasChildren(path.getKey()) : resource.hasChild(path)) %7B%0A                return this.policy;%0A            %7D%0A        %7D%0A%0A
         retu
@@ -3596,11 +3596,10 @@
 ;%0A    %7D%0A
-%0A
 %7D%0A

Enhance RequiredChildResourceDiscardPolicy to additionally check for the existence of child resources.