OpenConcerto

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

svn://code.openconcerto.org/openconcerto

Rev

Rev 73 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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