• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

LearnLib / automatalib / 10220057657

02 Aug 2024 06:06PM UTC coverage: 90.366% (+0.3%) from 90.072%
10220057657

push

github

mtf90
overhaul serizalition code

* unify access to Input(De)Serializers behind facades to leverage the default methods for various input/output channels
* drop implicit buffering/decompressing as this should be decided where the stream are constructed (user-land)
* remove/cleanup the (now) unused code

300 of 349 new or added lines in 33 files covered. (85.96%)

9 existing lines in 3 files now uncovered.

15927 of 17625 relevant lines covered (90.37%)

1.67 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

62.5
/serialization/taf/src/main/java/net/automatalib/serialization/taf/parser/AbstractTAFBuilder.java
1
/* Copyright (C) 2013-2024 TU Dortmund University
2
 * This file is part of AutomataLib, http://www.automatalib.net/.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
package net.automatalib.serialization.taf.parser;
17

18
import java.util.ArrayList;
19
import java.util.Collection;
20
import java.util.HashMap;
21
import java.util.HashSet;
22
import java.util.List;
23
import java.util.Map;
24
import java.util.Objects;
25
import java.util.Set;
26
import java.util.regex.Pattern;
27

28
import net.automatalib.alphabet.Alphabet;
29
import net.automatalib.automaton.MutableDeterministic;
30
import net.automatalib.common.util.string.StringUtil;
31

32
@SuppressWarnings("nullness")
33
abstract class AbstractTAFBuilder<S, T, SP, TP, M extends MutableDeterministic<S, String, T, SP, TP>>
34
        implements TAFBuilder {
35

36
    private static final Pattern ID_PATTERN = Pattern.compile("[a-zA-Z_][a-zA-Z0-9_]*");
2✔
37

38
    private final InternalTAFParser parser;
39
    private final Map<String, S> stateMap = new HashMap<>();
2✔
40
    private final Set<String> declaredStates = new HashSet<>();
2✔
41
    protected M automaton;
42
    private Alphabet<String> alphabet;
43

44
    AbstractTAFBuilder(InternalTAFParser parser) {
2✔
45
        this.parser = parser;
2✔
46
    }
2✔
47

48
    @Override
49
    public void init(Alphabet<String> alphabet) {
50
        if (automaton != null) {
2✔
51
            throw new IllegalStateException();
×
52
        }
53
        automaton = createAutomaton(alphabet);
2✔
54
        this.alphabet = alphabet;
2✔
55
    }
2✔
56

57
    @Override
58
    public void declareState(String identifier, Set<String> options) {
59
        if (!declaredStates.add(identifier)) {
2✔
60
            error("State {0} declared twice", identifier);
×
61
        }
62

63
        boolean init = options.remove("initial") | options.remove("init");
2✔
64
        if (init && automaton.getInitialState() != null) {
2✔
65
            error("Duplicate initial state {0}", identifier);
×
66
            init = false;
×
67
        }
68

69
        S state = stateMap.get(identifier);
2✔
70
        SP property = getStateProperty(options);
2✔
71
        if (state == null) {
2✔
72
            state = init ? automaton.addInitialState(property) : automaton.addState(property);
2✔
73
            stateMap.put(identifier, state);
2✔
74
        } else {
75
            automaton.setStateProperty(state, property);
2✔
76
            if (init) {
2✔
77
                automaton.setInitialState(state);
2✔
78
            }
79
        }
80

81
        if (!options.isEmpty()) {
2✔
82
            warning("Unrecognized options for state {0}: {1}", identifier, options);
×
83
        }
84
    }
2✔
85

86
    @Override
87
    public M finish() {
88
        checkState();
2✔
89

90
        stateMap.clear();
2✔
91
        declaredStates.clear();
2✔
92
        M result = automaton;
2✔
93
        automaton = null;
2✔
94
        alphabet = null;
2✔
95
        return result;
2✔
96
    }
97

98
    protected void checkState() {
99
        if (automaton == null) {
2✔
100
            throw new IllegalStateException();
×
101
        }
102
    }
2✔
103

104
    protected void error(String msgFmt, Object... args) {
105
        parser.error(msgFmt, args);
×
106
    }
×
107

108
    protected abstract M createAutomaton(Alphabet<String> stringAlphabet);
109

110
    protected abstract SP getStateProperty(Set<String> options);
111

112
    protected void warning(String msgFmt, Object... args) {
113
        parser.warning(msgFmt, args);
×
114
    }
×
115

116
    protected void doAddTransitions(String source, Collection<String> symbols, String target, TP transProperty) {
117
        S src = lookupState(source);
2✔
118
        S tgt = lookupState(target);
2✔
119
        List<String> invalidSymbols = new ArrayList<>();
2✔
120
        for (String input : symbols) {
2✔
121
            if (!alphabet.containsSymbol(input)) {
2✔
NEW
122
                invalidSymbols.add(StringUtil.enquoteIfNecessary(input, ID_PATTERN));
×
UNCOV
123
                continue;
×
124
            }
125
            T exTrans = automaton.getTransition(src, input);
2✔
126
            if (exTrans != null) {
2✔
127
                if (!Objects.equals(tgt, automaton.getSuccessor(exTrans))) {
×
128
                    error("Duplicate transition from {0} on input {1} to differing target {2}" +
×
NEW
129
                          " would introduce non-determinism", source, StringUtil.enquoteIfNecessary(input, ID_PATTERN), tgt);
×
130
                } else if (!Objects.equals(transProperty, automaton.getTransitionProperty(exTrans))) {
×
131
                    error("Duplicate transition from {0} on input {1} to {2} with " +
×
132
                          "differing property '{3}' would introduce non-determinism",
133
                          source,
NEW
134
                          StringUtil.enquoteIfNecessary(input, ID_PATTERN),
×
135
                          tgt,
136
                          transProperty);
137
                }
138
            } else {
139
                automaton.addTransition(src, input, tgt, transProperty);
2✔
140
            }
141
        }
2✔
142
        if (!invalidSymbols.isEmpty()) {
2✔
143
            error("Invalid symbols for transition from {0} to {1}: {2}", source, target, invalidSymbols);
×
144
        }
145
    }
2✔
146

147
    protected S lookupState(String identifier) {
148
        return stateMap.computeIfAbsent(identifier, k -> automaton.addState());
2✔
149
    }
150

151
    protected void doAddWildcardTransitions(String source, String target, TP transProperty) {
UNCOV
152
        S src = lookupState(source);
×
153
        S tgt = lookupState(target);
×
NEW
154
        for (String input : alphabet) {
×
155
            T exTrans = automaton.getTransition(src, input);
×
156
            if (exTrans == null) {
×
157
                automaton.addTransition(src, input, tgt, transProperty);
×
158
            }
159
        }
×
160
    }
×
161

162
    protected Alphabet<String> getAlphabet() {
163
        return alphabet;
2✔
164
    }
165
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc