OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 73 | Go to most recent revision | Details | 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
 
16
import org.openconcerto.utils.cc.IPredicate;
17
import org.openconcerto.xml.SimpleXMLPath.Node;
18
 
19
import java.util.ArrayList;
20
import java.util.Collections;
21
import java.util.List;
22
 
23
import org.jdom.Attribute;
24
import org.jdom.Element;
25
import org.jdom.Namespace;
26
 
27
/**
28
 * A step in {@link SimpleXMLPath}. There's only 2 types of step, those which go to {@link Element}
29
 * and those which go to {@link Attribute}.
30
 *
31
 * @author Sylvain CUAZ
32
 *
33
 * @param <T> type of items after the step.
34
 */
35
public final class Step<T> {
36
 
37
    public enum Axis {
38
        attribute, child, ancestor, descendantOrSelf
39
    }
40
 
41
    public static Step<Attribute> createAttributeStep(final String name, final String ns) {
42
        return createAttributeStep(name, ns, null);
43
    }
44
 
45
    public static Step<Attribute> createAttributeStep(final String name, final String ns, final IPredicate<Attribute> pred) {
46
        return new Step<Attribute>(Axis.attribute, name, ns, Attribute.class, pred);
47
    }
48
 
49
    public static Step<Element> createElementStep(final String name, final String ns) {
50
        return createElementStep(name, ns, null);
51
    }
52
 
53
    public static Step<Element> createElementStep(final String name, final String ns, final IPredicate<Element> pred) {
54
        return createElementStep(Axis.child, name, ns, pred);
55
    }
56
 
57
    public static Step<Element> createElementStep(final Axis axis, final String name) {
58
        return createElementStep(axis, name, null);
59
    }
60
 
61
    public static Step<Element> createElementStep(final Axis axis, final String name, final String ns) {
62
        return createElementStep(axis, name, ns, null);
63
    }
64
 
65
    public static Step<Element> createElementStep(final Axis axis, final String name, final String ns, final IPredicate<Element> pred) {
66
        return new Step<Element>(axis, name, ns, Element.class, pred);
67
    }
68
 
69
    private final Axis axis;
70
    private final String name;
71
    private final String ns;
72
    private final Class<T> clazz;
73
    private final Node<T> node;
74
    private final IPredicate<T> pred;
75
 
76
    private Step(Axis axis, final String name, final String ns, final Class<T> clazz, IPredicate<T> pred) {
77
        super();
78
        this.axis = axis;
79
        this.name = name;
80
        this.ns = ns;
81
        this.clazz = clazz;
82
        this.node = Node.get(this.clazz);
83
        this.pred = pred;
84
    }
85
 
86
    public final Axis getAxis() {
87
        return this.axis;
88
    }
89
 
90
    public final String getName() {
91
        return this.name;
92
    }
93
 
94
    protected final Namespace getNS(final Element elem) {
95
        return this.ns == null ? Namespace.NO_NAMESPACE : elem.getNamespace(this.ns);
96
    }
97
 
98
    protected final T evaluate(final Object node) {
99
        if (node == null)
100
            return null;
101
        final T n = this.clazz.cast(node);
102
        final T filtered = this.node.filter(n, this.getName(), this.ns);
103
        if (filtered == null)
104
            return null;
105
        return this.pred == null || this.pred.evaluateChecked(filtered) ? filtered : null;
106
    }
107
 
108
    protected final void add(final Object node, final List<T> l) {
109
        final T filtered = evaluate(node);
110
        if (filtered != null)
111
            l.add(filtered);
112
    }
113
 
114
    final <U> List<T> nextNodes(final Node<U> n, final U jdom) {
115
        return this.nextNodes(new ArrayList<T>(), n, jdom);
116
    }
117
 
118
    final <U> List<T> nextNodes(final List<T> res, final Node<U> n, final U jdom) {
119
        n.nextNodes(res, jdom, this);
120
        return res;
121
    }
122
 
123
    final <U> List<T> nextNodes(List<U> jdom) {
124
        final int stop = jdom.size();
125
        if (stop == 0)
126
            return Collections.emptyList();
127
 
128
        final Node<U> n = Node.get(jdom.get(0));
129
        // nextNodes adding to res is far speedier than creating a list each call
130
        final List<T> res = new ArrayList<T>();
131
        // since we're using ArrayList it is faster to use for than to use iterator
132
        for (int i = 0; i < stop; i++) {
133
            nextNodes(res, n, jdom.get(i));
134
        }
135
        return res;
136
    }
137
 
138
    @Override
139
    public final String toString() {
140
        return this.getClass().getSimpleName() + " " + this.getAxis() + " " + this.ns + ":" + this.name;
141
    }
142
}