1/*
2 * Copyright (C) 2007-2010 Júlio Vilmar Gesser.
3 * Copyright (C) 2011, 2013-2016 The JavaParser Team.
4 *
5 * This file is part of JavaParser.
6 *
7 * JavaParser can be used either under the terms of
8 * a) the GNU Lesser General Public License as published by
9 *     the Free Software Foundation, either version 3 of the License, or
10 *     (at your option) any later version.
11 * b) the terms of the Apache License
12 *
13 * You should have received a copy of both licenses in LICENCE.LGPL and
14 * LICENCE.APACHE. Please refer to those files for details.
15 *
16 * JavaParser is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19 * GNU Lesser General Public License for more details.
20 */
21
22package com.github.javaparser.printer.concretesyntaxmodel;
23
24import com.github.javaparser.ast.Node;
25import com.github.javaparser.ast.NodeList;
26import com.github.javaparser.ast.observer.ObservableProperty;
27import com.github.javaparser.printer.SourcePrinter;
28
29import java.util.Arrays;
30import java.util.List;
31
32public class CsmConditional implements CsmElement {
33    private final Condition condition;
34    private final List<ObservableProperty> properties;
35    private final CsmElement thenElement;
36    private final CsmElement elseElement;
37
38    public Condition getCondition() {
39        return condition;
40    }
41
42    public ObservableProperty getProperty() {
43        if (properties.size() > 1) {
44            throw new IllegalStateException();
45        }
46        return properties.get(0);
47    }
48
49    public CsmElement getThenElement() {
50        return thenElement;
51    }
52
53    public CsmElement getElseElement() {
54        return elseElement;
55    }
56
57    public enum Condition {
58        IS_EMPTY,
59        IS_NOT_EMPTY,
60        IS_PRESENT,
61        FLAG;
62
63        boolean evaluate(Node node, ObservableProperty property){
64            if (this == IS_PRESENT) {
65                return !property.isNullOrNotPresent(node);
66            }
67            if (this == FLAG) {
68                return property.getValueAsBooleanAttribute(node);
69            }
70            if (this == IS_EMPTY) {
71                NodeList value = property.getValueAsMultipleReference(node);
72                return value == null || value.isEmpty();
73            }
74            if (this == IS_NOT_EMPTY) {
75                NodeList value = property.getValueAsMultipleReference(node);
76                return value != null && !value.isEmpty();
77            }
78            throw new UnsupportedOperationException(name());
79        }
80    }
81
82    public CsmConditional(ObservableProperty property, Condition condition, CsmElement thenElement, CsmElement elseElement) {
83        this.properties = Arrays.asList(property);
84        this.condition = condition;
85        this.thenElement = thenElement;
86        this.elseElement = elseElement;
87    }
88
89    public CsmConditional(List<ObservableProperty> properties, Condition condition, CsmElement thenElement, CsmElement elseElement) {
90        if (properties.size() < 1) {
91            throw new IllegalArgumentException();
92        }
93        this.properties = properties;
94        this.condition = condition;
95        this.thenElement = thenElement;
96        this.elseElement = elseElement;
97    }
98
99    public CsmConditional(ObservableProperty property, Condition condition, CsmElement thenElement) {
100        this(property, condition, thenElement, new CsmNone());
101    }
102
103    @Override
104    public void prettyPrint(Node node, SourcePrinter printer) {
105        boolean test = false;
106        for (ObservableProperty prop : properties) {
107            test = test || condition.evaluate(node, prop);
108        }
109        if (test) {
110            thenElement.prettyPrint(node, printer);
111        } else {
112            elseElement.prettyPrint(node, printer);
113        }
114    }
115}
116