001    /*
002     * Licensed to the Apache Software Foundation (ASF) under one or more
003     * contributor license agreements. See the NOTICE file distributed with
004     * this work for additional information regarding copyright ownership.
005     * The ASF licenses this file to You under the Apache license, Version 2.0
006     * (the "License"); you may not use this file except in compliance with
007     * the License. You may obtain a copy of the License at
008     *
009     *      http://www.apache.org/licenses/LICENSE-2.0
010     *
011     * Unless required by applicable law or agreed to in writing, software
012     * distributed under the License is distributed on an "AS IS" BASIS,
013     * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014     * See the license for the specific language governing permissions and
015     * limitations under the license.
016     */
017    package org.apache.logging.log4j.core.config;
018    
019    import java.util.ArrayList;
020    import java.util.HashMap;
021    import java.util.List;
022    import java.util.Map;
023    
024    import org.apache.logging.log4j.core.config.plugins.util.PluginType;
025    
026    /**
027     * A Configuration node.
028     */
029    public class Node {
030    
031        /**
032         * Main plugin category for plugins which are represented as a configuration node. Such plugins tend to be
033         * available as XML elements in a configuration file.
034         *
035         * @since 2.1
036         */
037        public static final String CATEGORY = "Core";
038    
039        private final Node parent;
040        private final String name;
041        private String value;
042        private final PluginType<?> type;
043        private final Map<String, String> attributes = new HashMap<String, String>();
044        private final List<Node> children = new ArrayList<Node>();
045        private Object object;
046    
047    
048        /**
049         * Creates a new instance of {@code Node} and initializes it
050         * with a name and the corresponding XML element.
051         *
052         * @param parent the node's parent.
053         * @param name the node's name.
054         * @param type The Plugin Type associated with the node.
055         */
056        public Node(final Node parent, final String name, final PluginType<?> type) {
057            this.parent = parent;
058            this.name = name;
059            this.type = type;
060        }
061    
062        public Node() {
063            this.parent = null;
064            this.name = null;
065            this.type = null;
066        }
067    
068        public Node(final Node node) {
069            this.parent = node.parent;
070            this.name = node.name;
071            this.type = node.type;
072            this.attributes.putAll(node.getAttributes());
073            this.value = node.getValue();
074            for (final Node child : node.getChildren()) {
075                this.children.add(new Node(child));
076            }
077            this.object = node.object;
078        }
079    
080        public Map<String, String> getAttributes() {
081            return attributes;
082        }
083    
084        public List<Node> getChildren() {
085            return children;
086        }
087    
088        public boolean hasChildren() {
089            return !children.isEmpty();
090        }
091    
092        public String getValue() {
093            return value;
094        }
095    
096        public void setValue(final String value) {
097            this.value = value;
098        }
099    
100        public Node getParent() {
101            return parent;
102        }
103    
104        public String getName() {
105            return name;
106        }
107    
108        public boolean isRoot() {
109            return parent == null;
110        }
111    
112        public void setObject(final Object obj) {
113            object = obj;
114        }
115    
116        @SuppressWarnings("unchecked")
117        public <T> T getObject() {
118            return (T) object;
119        }
120    
121        /**
122         * Returns this node's object cast to the given class.
123         *
124         * @param clazz the class to cast this node's object to.
125         * @param <T>   the type to cast to.
126         * @return this node's object.
127         * @since 2.1
128         */
129        public <T> T getObject(final Class<T> clazz) {
130            return clazz.cast(object);
131        }
132    
133        /**
134         * Determines if this node's object is an instance of the given class.
135         *
136         * @param clazz the class to check.
137         * @return {@code true} if this node's object is an instance of the given class.
138         * @since 2.1
139         */
140        public boolean isInstanceOf(final Class<?> clazz) {
141            return clazz.isInstance(object);
142        }
143    
144        public PluginType<?> getType() {
145            return type;
146        }
147    
148        @Override
149        public String toString() {
150            if (object == null) {
151                return "null";
152            }
153            return type.isObjectPrintable() ? object.toString() :
154                type.getPluginClass().getName() + " with name " + name;
155        }
156    }