OpenConcerto

Dépôt officiel du code source de l'ERP OpenConcerto
sonarqube

svn://code.openconcerto.org/openconcerto

Rev

Rev 73 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
17 ilm 1
/*
2
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
3
 *
4
 * Copyright 2011 OpenConcerto, by ILM Informatique. All rights reserved.
5
 *
6
 * The contents of this file are subject to the terms of the GNU General Public License Version 3
7
 * only ("GPL"). You may not use this file except in compliance with the License. You can obtain a
8
 * copy of the License at http://www.gnu.org/licenses/gpl-3.0.html See the License for the specific
9
 * language governing permissions and limitations under the License.
10
 *
11
 * When distributing the software, include this License Header Notice in each file.
12
 */
13
 
14
 package org.openconcerto.xml;
15
 
180 ilm 16
import org.openconcerto.utils.Tuple2.List2;
17 ilm 17
import org.openconcerto.utils.cc.IPredicate;
18
import org.openconcerto.xml.SimpleXMLPath.Node;
19
 
20
import java.util.ArrayList;
21
import java.util.Collections;
22
import java.util.List;
23
 
24
import org.jdom.Attribute;
25
import org.jdom.Element;
26
import org.jdom.Namespace;
27
 
28
/**
29
 * A step in {@link SimpleXMLPath}. There's only 2 types of step, those which go to {@link Element}
73 ilm 30
 * and those which go to {@link Attribute}. Thread-safe if its {@link #getPredicate() predicate} is.
17 ilm 31
 *
32
 * @author Sylvain CUAZ
33
 *
34
 * @param <T> type of items after the step.
35
 */
36
public final class Step<T> {
37
 
38
    public enum Axis {
39
        attribute, child, ancestor, descendantOrSelf
40
    }
41
 
73 ilm 42
    private static final Step<Attribute> ANY_ATTRIBUTE = createAttributeStep(null, null);
43
    private static final Step<Element> ANY_CHILD_ELEMENT = createElementStep(Axis.child, null, null);
44
 
45
    /**
46
     * Return a step that match any attribute.
47
     *
48
     * @return the equivalent of <code>@*</code>.
49
     */
50
    public static Step<Attribute> getAnyAttributeStep() {
51
        return ANY_ATTRIBUTE;
52
    }
53
 
180 ilm 54
    public static Step<Attribute> createAttributeStepFromQualifiedName(final String qName) {
55
        final List2<String> splitName = XMLUtils.splitQualifiedName(qName);
56
        return createAttributeStep(splitName.get1(), splitName.get0());
57
    }
58
 
17 ilm 59
    public static Step<Attribute> createAttributeStep(final String name, final String ns) {
60
        return createAttributeStep(name, ns, null);
61
    }
62
 
63
    public static Step<Attribute> createAttributeStep(final String name, final String ns, final IPredicate<Attribute> pred) {
64
        return new Step<Attribute>(Axis.attribute, name, ns, Attribute.class, pred);
65
    }
66
 
73 ilm 67
    /**
68
     * Return a step that match any child element.
69
     *
70
     * @return the equivalent of <code>*</code>.
71
     */
72
    public static Step<Element> getAnyChildElementStep() {
73
        return ANY_CHILD_ELEMENT;
74
    }
75
 
180 ilm 76
    public static Step<Element> createElementStepFromQualifiedName(final String qName) {
77
        final List2<String> splitName = XMLUtils.splitQualifiedName(qName);
78
        return createElementStep(splitName.get1(), splitName.get0());
79
    }
80
 
17 ilm 81
    public static Step<Element> createElementStep(final String name, final String ns) {
82
        return createElementStep(name, ns, null);
83
    }
84
 
85
    public static Step<Element> createElementStep(final String name, final String ns, final IPredicate<Element> pred) {
86
        return createElementStep(Axis.child, name, ns, pred);
87
    }
88
 
89
    public static Step<Element> createElementStep(final Axis axis, final String name) {
90
        return createElementStep(axis, name, null);
91
    }
92
 
93
    public static Step<Element> createElementStep(final Axis axis, final String name, final String ns) {
94
        return createElementStep(axis, name, ns, null);
95
    }
96
 
97
    public static Step<Element> createElementStep(final Axis axis, final String name, final String ns, final IPredicate<Element> pred) {
98
        return new Step<Element>(axis, name, ns, Element.class, pred);
99
    }
100
 
101
    private final Axis axis;
102
    private final String name;
103
    private final String ns;
104
    private final Class<T> clazz;
105
    private final Node<T> node;
106
    private final IPredicate<T> pred;
107
 
108
    private Step(Axis axis, final String name, final String ns, final Class<T> clazz, IPredicate<T> pred) {
109
        super();
110
        this.axis = axis;
111
        this.name = name;
112
        this.ns = ns;
113
        this.clazz = clazz;
114
        this.node = Node.get(this.clazz);
115
        this.pred = pred;
116
    }
117
 
118
    public final Axis getAxis() {
119
        return this.axis;
120
    }
121
 
122
    public final String getName() {
123
        return this.name;
124
    }
125
 
73 ilm 126
    public final IPredicate<T> getPredicate() {
127
        return this.pred;
128
    }
129
 
17 ilm 130
    protected final Namespace getNS(final Element elem) {
131
        return this.ns == null ? Namespace.NO_NAMESPACE : elem.getNamespace(this.ns);
132
    }
133
 
134
    protected final T evaluate(final Object node) {
135
        if (node == null)
136
            return null;
137
        final T n = this.clazz.cast(node);
138
        final T filtered = this.node.filter(n, this.getName(), this.ns);
139
        if (filtered == null)
140
            return null;
141
        return this.pred == null || this.pred.evaluateChecked(filtered) ? filtered : null;
142
    }
143
 
144
    protected final void add(final Object node, final List<T> l) {
145
        final T filtered = evaluate(node);
146
        if (filtered != null)
147
            l.add(filtered);
148
    }
149
 
150
    final <U> List<T> nextNodes(final Node<U> n, final U jdom) {
151
        return this.nextNodes(new ArrayList<T>(), n, jdom);
152
    }
153
 
154
    final <U> List<T> nextNodes(final List<T> res, final Node<U> n, final U jdom) {
155
        n.nextNodes(res, jdom, this);
156
        return res;
157
    }
158
 
159
    final <U> List<T> nextNodes(List<U> jdom) {
160
        final int stop = jdom.size();
161
        if (stop == 0)
162
            return Collections.emptyList();
163
 
164
        final Node<U> n = Node.get(jdom.get(0));
165
        // nextNodes adding to res is far speedier than creating a list each call
166
        final List<T> res = new ArrayList<T>();
167
        // since we're using ArrayList it is faster to use for than to use iterator
168
        for (int i = 0; i < stop; i++) {
169
            nextNodes(res, n, jdom.get(i));
170
        }
171
        return res;
172
    }
173
 
180 ilm 174
    final List<String> getValues(List<T> jdom) {
175
        final List<String> res = new ArrayList<>();
176
        for (final T n : jdom)
177
            res.add(this.node.getValue(n));
178
        return res;
179
    }
180
 
17 ilm 181
    @Override
182
    public final String toString() {
183
        return this.getClass().getSimpleName() + " " + this.getAxis() + " " + this.ns + ":" + this.name;
184
    }
185
}