001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau.dto.html5; 014 015import static org.apache.juneau.xml.annotation.XmlFormat.*; 016 017import java.util.*; 018 019import org.apache.juneau.*; 020import org.apache.juneau.annotation.*; 021import org.apache.juneau.internal.*; 022import org.apache.juneau.xml.annotation.*; 023 024/** 025 * A subclass of HTML elements that contain mixed content (elements and text). 026 * 027 * <h5 class='section'>See Also:</h5> 028 * <ul class='doctree'> 029 * <li class='link'><a class='doclink' href='../../../../../overview-summary.html#juneau-dto.HTML5'>Overview > juneau-dto > HTML5</a> 030 * </ul> 031 */ 032public class HtmlElementMixed extends HtmlElement { 033 034 private LinkedList<Object> children; 035 036 /** 037 * The children of this element. 038 * 039 * @return The children of this element. 040 */ 041 @Xml(format=MIXED) 042 @BeanProperty(beanDictionary=HtmlBeanDictionary.class, name="c") 043 public LinkedList<Object> getChildren() { 044 return children; 045 } 046 047 /** 048 * Sets the children of this element. 049 * 050 * @param children The new children of this element. 051 * @return This object (for method chaining). 052 */ 053 @BeanProperty("c") 054 public HtmlElement setChildren(LinkedList<Object> children) { 055 this.children = children; 056 return this; 057 } 058 059 /** 060 * Returns the child node at the specified index. 061 * 062 * @param index The index of the node in the list of children. 063 * @return The child node, or <jk>null</jk> if it doesn't exist. 064 */ 065 public Object getChild(int index) { 066 return (children == null || children.size() <= index || index < 0 ? null : children.get(index)); 067 } 068 069 /** 070 * Returns the child node at the specified address. 071 * 072 * <p> 073 * Indexes are zero-indexed. 074 * 075 * <p> 076 * For example, calling <code>getChild(1,2,3);</code> will return the 4th child of the 3rd child of the 2nd child. 077 * 078 * @param index The child indexes. 079 * @return The child node, or <jk>null</jk> if it doesn't point to a valid child. 080 */ 081 public Object getChild(int...index) { 082 if (index.length == 0) 083 return null; 084 if (index.length == 1) 085 return getChild(index[0]); 086 Object c = this; 087 for (int i = 0; i < index.length; i++) { 088 if (c instanceof HtmlElementMixed) 089 c = ((HtmlElementMixed)c).getChild(index[i]); 090 else if (c instanceof HtmlElementContainer) 091 c = ((HtmlElementContainer)c).getChild(index[i]); 092 else 093 return null; 094 } 095 return c; 096 } 097 098 /** 099 * Returns the child node at the specified index. 100 * 101 * @param type The class type of the node. 102 * @param index The index of the node in the list of children. 103 * @return The child node, or <jk>null</jk> if it doesn't exist. 104 * @throws InvalidDataConversionException If node is not the expected type. 105 */ 106 public <T> T getChild(Class<T> type, int index) { 107 return ( 108 children == null || children.size() <= index || index < 0 109 ? null 110 : ObjectUtils.toType(children.get(index), type) 111 ); 112 } 113 114 /** 115 * Adds one or more child elements to this element. 116 * 117 * @param children 118 * The children to add as child elements. 119 * Can be a mixture of strings and {@link HtmlElement} objects. 120 * Can also be containers of strings and elements. 121 * @return This object (for method chaining). 122 */ 123 public HtmlElement children(Object...children) { 124 if (children.length != 0) 125 for (Object c : children) 126 child(c); 127 return this; 128 } 129 130 /** 131 * Adds a child element to this element. 132 * 133 * @param child 134 * The child to add as a child element. 135 * Can be a string or {@link HtmlElement}. 136 * Can also be a container of strings and elements. 137 * @return This object (for method chaining). 138 */ 139 public HtmlElement child(Object child) { 140 if (this.children == null) 141 this.children = new LinkedList<>(); 142 if (child instanceof Collection) 143 this.children.addAll((Collection<?>)child); 144 else 145 this.children.add(child); 146 return this; 147 } 148}