View Javadoc
1   /*
2    * (c) Copyright 2006-2020 by rapiddweller GmbH & Volker Bergmann. All rights reserved.
3    *
4    * Redistribution and use in source and binary forms, with or without
5    * modification, is permitted under the terms of the
6    * GNU General Public License.
7    *
8    * For redistributing this software or a derivative work under a license other
9    * than the GPL-compatible Free Software License as defined by the Free
10   * Software Foundation or approved by OSI, you must first obtain a commercial
11   * license to this software product from rapiddweller GmbH & Volker Bergmann.
12   *
13   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14   * WITHOUT A WARRANTY OF ANY KIND. ALL EXPRESS OR IMPLIED CONDITIONS,
15   * REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF
16   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE
17   * HEREBY EXCLUDED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24   * POSSIBILITY OF SUCH DAMAGE.
25   */
26  
27  package com.rapiddweller.benerator.engine.parser.xml;
28  
29  import com.rapiddweller.benerator.engine.Statement;
30  import com.rapiddweller.benerator.engine.statement.IfStatement;
31  import com.rapiddweller.benerator.engine.statement.SequentialStatement;
32  import com.rapiddweller.common.CollectionUtil;
33  import com.rapiddweller.common.xml.XMLUtil;
34  import com.rapiddweller.script.Expression;
35  import org.w3c.dom.Element;
36  
37  import java.util.List;
38  import java.util.Objects;
39  import java.util.Set;
40  
41  import static com.rapiddweller.benerator.engine.DescriptorConstants.ATT_TEST;
42  import static com.rapiddweller.benerator.engine.DescriptorConstants.EL_COMMENT;
43  import static com.rapiddweller.benerator.engine.DescriptorConstants.EL_ELSE;
44  import static com.rapiddweller.benerator.engine.DescriptorConstants.EL_IF;
45  import static com.rapiddweller.benerator.engine.DescriptorConstants.EL_THEN;
46  import static com.rapiddweller.benerator.engine.parser.xml.DescriptorParserUtil.parseBooleanExpressionAttribute;
47  
48  /**
49   * Parses an &lt;if&gt; element.<br/><br/>
50   * Created: 19.02.2010 09:07:51
51   *
52   * @author Volker Bergmann
53   * @since 0.6.0
54   */
55  public class IfParser extends AbstractBeneratorDescriptorParser {
56  
57    private static final Set<String> STRICT_CHILDREN = CollectionUtil.toSet(
58        EL_THEN, EL_ELSE, EL_COMMENT);
59  
60    /**
61     * Instantiates a new If parser.
62     */
63    public IfParser() {
64      super(EL_IF, CollectionUtil.toSet(ATT_TEST), null);
65    }
66  
67    @Override
68    public Statementm/rapiddweller/benerator/engine/Statement.html#Statement">Statement doParse(Element ifElement, Statement[] parentPath, BeneratorParseContext context) {
69      Expression<Boolean> condition = parseBooleanExpressionAttribute(ATT_TEST, ifElement);
70      Element[] thenElements = XMLUtil.getChildElements(ifElement, false, "then");
71      if (thenElements.length > 1) {
72        syntaxError("Multiple <then> elements", ifElement);
73      }
74      Element thenElement = (thenElements.length == 1 ? thenElements[0] : null);
75      Element[] elseElements = XMLUtil.getChildElements(ifElement, false, "else");
76      if (elseElements.length > 1) {
77        syntaxError("Multiple <else> elements", ifElement);
78      }
79      Element elseElement = (elseElements.length == 1 ? elseElements[0] : null);
80      List<Statement> thenStatements = null;
81      List<Statement> elseStatements = null;
82      IfStatemente/statement/IfStatement.html#IfStatement">IfStatement ifStatement = new IfStatement(condition);
83      Statement[] ifPath = context.createSubPath(parentPath, ifStatement);
84      if (elseElement != null) {
85        // if there is an 'else' element, there must be an 'if' element too
86        if (thenElement == null) {
87          syntaxError("'else' without 'then'", elseElement);
88        }
89        thenStatements = context.parseChildElementsOf(thenElement, ifPath);
90        elseStatements = context.parseChildElementsOf(elseElement, ifPath);
91        // check that no elements conflict with 'then' and 'else'
92        assertThenElseChildren(ifElement);
93      } else {
94        thenStatements = context.parseChildElementsOf(Objects.requireNonNullElse(thenElement, ifElement), ifPath);
95      }
96      ifStatement.setThenStatement(new SequentialStatement(thenStatements));
97      ifStatement.setElseStatement(new SequentialStatement(elseStatements));
98      return ifStatement;
99    }
100 
101   private static void assertThenElseChildren(Element ifElement) {
102     for (Element child : XMLUtil.getChildElements(ifElement)) {
103       if (!STRICT_CHILDREN.contains(child.getNodeName())) {
104         syntaxError("Illegal child element: ", child);
105       }
106     }
107   }
108 
109 }