fr.arakne.swflangloader.parser.AssignationParser   A
last analyzed

Complexity

Total Complexity 20

Size/Duplication

Total Lines 138
Duplicated Lines 0 %

Test Coverage

Coverage 97.22%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 47
c 1
b 0
f 0
dl 0
loc 138
ccs 35
cts 36
cp 0.9722
rs 10
wmc 20

10 Methods

Rating   Name   Duplication   Size   Complexity  
A declareStringMap(String,Class) 0 2 1
A declareIntegerMap(String,Class) 0 2 1
A declareMap(String,Type,Class) 0 2 1
A declareSimple(String,Class) 0 2 1
A declare(String,AssignationType) 0 4 1
A parseAssoc(String,String) 0 11 2
B parseLine(String) 0 26 6
A removeCastFunctions(String) 0 8 5
A handleConcatenation(String) 0 2 1
A parseSimple(String,String) 0 2 1
1
/*
2
 * This file is part of ArakneLangLoader.
3
 *
4
 * ArakneLangLoader is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU Lesser General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * ArakneLangLoader is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public License
15
 * along with ArakneLangLoader.  If not, see <https://www.gnu.org/licenses/>.
16
 *
17
 * Copyright (c) 2020 Vincent Quatrevieux
18
 */
19
20
package fr.arakne.swflangloader.parser;
21
22
import java.lang.reflect.Type;
23
import java.util.HashMap;
24
import java.util.Map;
25
26
/**
27
 * Parse action script assignations
28
 * Some variable type can be declared
29
 */
30 1
final public class AssignationParser {
31 1
    final static private String[] CAST_FUNCTIONS = new String[] {"Boolean", "String", "Number"};
32
33 1
    final private Map<String, AssignationType> declaredTypes = new HashMap<>();
34 1
    final private AssignationType defaultType = new DefaultAssignationType();
35
36
    /**
37
     * Declare a variable
38
     *
39
     * @param varName The variable name
40
     * @param type The variable type
41
     *
42
     * @return this
43
     */
44
    public AssignationParser declare(String varName, AssignationType type) {
45 1
        declaredTypes.put(varName, type);
46
47 1
        return this;
48
    }
49
50
    /**
51
     * Declare a simple variable (not associative)
52
     *
53
     * @param varName The variable name
54
     * @param type The variable type
55
     *
56
     * @return this
57
     */
58
    public AssignationParser declareSimple(String varName, Class<?> type) {
59 1
        return declare(varName, new SimpleAssignationType(type));
60
    }
61
62
    /**
63
     * Declare a map variable (associative)
64
     *
65
     * @param varName The variable name
66
     * @param keyType The map key type
67
     * @param type The map value type
68
     *
69
     * @return this
70
     */
71
    public AssignationParser declareMap(String varName, Type keyType, Class<?> type) {
72 1
        return declare(varName, new MapAssignationType(keyType, type));
73
    }
74
75
    /**
76
     * Declare an integer map variable
77
     *
78
     * @param varName The variable name
79
     * @param type The map value type
80
     *
81
     * @return this
82
     */
83
    public AssignationParser declareIntegerMap(String varName, Class<?> type) {
84 1
        return declareMap(varName, Integer.class, type);
85
    }
86
87
    /**
88
     * Declare an string map variable
89
     *
90
     * @param varName The variable name
91
     * @param type The map value type
92
     *
93
     * @return this
94
     */
95
    public AssignationParser declareStringMap(String varName, Class<?> type) {
96 1
        return declareMap(varName, String.class, type);
97
    }
98
99
    /**
100
     * Parse an action script line to get the assignation
101
     *
102
     * @param line Line to parse
103
     *
104
     * @return The assignation
105
     */
106
    public Assignation parseLine(String line) {
107 1
        if (!line.endsWith(";")) {
108 1
            return Assignation.NULL;
109
        }
110
111 1
        final int eqPos = line.indexOf('=');
112
113 1
        if (eqPos == -1) {
114 1
            return Assignation.NULL;
115
        }
116
117 1
        final String left = line.substring(0, eqPos).trim();
118 1
        final String right = handleConcatenation(
119 1
            removeCastFunctions(
120 1
                line.substring(eqPos + 1, line.length() - 1).trim()
121
            )
122
        );
123
124 1
        if (left.isEmpty() || right.isEmpty()) {
125 1
            return Assignation.NULL;
126
        }
127
128 1
        if (left.endsWith("]")) {
129 1
            return parseAssoc(left, right);
130
        } else {
131 1
            return parseSimple(left, right);
132
        }
133
    }
134
135
    private Assignation parseAssoc(String left, String right) {
136 1
        final int assocOpen = left.indexOf('[');
137
138 1
        if (assocOpen == -1) {
139
            return Assignation.NULL;
140
        }
141
142 1
        final String varName = left.substring(0, assocOpen);
143 1
        final String key = left.substring(assocOpen + 1, left.length() - 1);
144
145 1
        return declaredTypes.getOrDefault(varName, defaultType).parseAssociative(varName, key, right);
146
    }
147
148
    private Assignation parseSimple(String varName, String value) {
149 1
        return declaredTypes.getOrDefault(varName, defaultType).parseSimple(varName, value);
150
    }
151
152
    private String removeCastFunctions(String value) {
153 1
        for (String func : CAST_FUNCTIONS) {
154 1
            if (value.startsWith(func) && value.charAt(func.length()) == '(' && value.charAt(value.length() - 1) == ')') {
155 1
                value = value.substring(func.length() + 1, value.length() - 1);
156
            }
157
        }
158
159 1
        return value;
160
    }
161
162
    /**
163
     * Remove simple string concatenation
164
     * See: https://github.com/Arakne/SwfLangLoader/issues/1
165
     */
166
    private String handleConcatenation(String value) {
167 1
        return value.replaceAll("\" \\+ \"", "");
168
    }
169
}
170