Skip to content

Commit 89e4026

Browse files
committed
Corrected exceptions and added alphabet methods
1 parent 7b7993b commit 89e4026

File tree

12 files changed

+259
-69
lines changed

12 files changed

+259
-69
lines changed

src/main/java/com/mapcode/Alphabet.java

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,10 @@
1717
package com.mapcode;
1818

1919
import javax.annotation.Nonnull;
20+
import java.util.HashSet;
21+
import java.util.Set;
22+
23+
import static com.mapcode.CheckArgs.checkNonnull;
2024

2125
/**
2226
* This enum defines all alphabets supported for mapcodes. Mapcodes can be safely converted between
@@ -38,12 +42,16 @@ public enum Alphabet {
3842
GURMUKHI(12),
3943
TIBETAN(13);
4044

41-
public final int code;
45+
private final int code;
4246

4347
private Alphabet(final int code) {
4448
this.code = code;
4549
}
4650

51+
public int getCode() {
52+
return code;
53+
}
54+
4755
@Nonnull
4856
public static Alphabet fromCode(final int code) throws UnknownAlphabetException {
4957
for (final Alphabet alphabet : values()) {
@@ -54,12 +62,47 @@ public static Alphabet fromCode(final int code) throws UnknownAlphabetException
5462
throw new UnknownAlphabetException(code);
5563
}
5664

57-
public static class UnknownAlphabetException extends RuntimeException {
58-
final int code;
65+
/**
66+
* Return alphabet from a string, which can be a numeric or alpha code.
67+
*
68+
* @param numericOrAlpha Alphabet. May be a numeric or alphanumeric code.
69+
* @return Alphabet.
70+
* @throws UnknownAlphabetException Thrown if incorrect numeric or alphanumeric code.
71+
*/
72+
@Nonnull
73+
public static Alphabet fromString(@Nonnull final String numericOrAlpha) throws UnknownAlphabetException {
74+
checkNonnull("name", numericOrAlpha);
75+
final String trimmed = numericOrAlpha.trim().toUpperCase();
76+
try {
77+
return fromCode(Integer.valueOf(numericOrAlpha));
78+
} catch (final IllegalArgumentException ignored) {
79+
// Ignore. Re-try as alpha code.
80+
}
81+
try {
82+
return valueOf(trimmed);
83+
} catch (final IllegalArgumentException ignored) {
84+
throw new UnknownAlphabetException(trimmed);
85+
}
86+
}
87+
88+
/**
89+
* Static checking of the static data structures.
90+
*/
91+
static {
92+
final String errorPrefix = "Initializing error: ";
93+
final Set<Integer> alphabetCodeList = new HashSet<>();
94+
95+
for (final Alphabet alphabet : Alphabet.values()) {
96+
final int alphabetCode = alphabet.getCode();
97+
if ((alphabetCode < 0) || (alphabetCode >= Alphabet.values().length)) {
98+
throw new ExceptionInInitializerError(errorPrefix + "alphabet code out of range: " + alphabetCode);
5999

60-
public UnknownAlphabetException(final int code) {
61-
super();
62-
this.code = code;
100+
}
101+
if (alphabetCodeList.contains(alphabetCode)) {
102+
throw new ExceptionInInitializerError(errorPrefix + "non-unique alphabet code: " + alphabetCode);
103+
}
104+
alphabetCodeList.add(alphabet.getCode());
63105
}
106+
assert alphabetCodeList.size() == Alphabet.values().length;
64107
}
65108
}

src/main/java/com/mapcode/Decoder.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ static Point decode(@Nonnull final String argMapcode,
7979
}
8080
}
8181

82-
final int ccode = territory.getTerritoryCode();
82+
final int ccode = territory.getCode();
8383

8484
final int from = DataAccess.dataFirstRecord(ccode);
8585
if (DataAccess.dataFlags(from) == 0) {

src/main/java/com/mapcode/Encoder.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -97,12 +97,12 @@ private static List<Mapcode> encode(final double argLatDeg, final double argLonD
9797
continue;
9898
}
9999

100-
final int from = DataAccess.dataFirstRecord(currentEncodeTerritory.getTerritoryCode());
100+
final int from = DataAccess.dataFirstRecord(currentEncodeTerritory.getCode());
101101
final Data mapcoderData = new Data(from);
102102
if (mapcoderData.getFlags() == 0) {
103103
continue;
104104
}
105-
final int upto = DataAccess.dataLastRecord(currentEncodeTerritory.getTerritoryCode());
105+
final int upto = DataAccess.dataLastRecord(currentEncodeTerritory.getCode());
106106

107107

108108
final int i = subArea.getSubAreaID();

src/main/java/com/mapcode/Mapcode.java

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ public Mapcode(
8787

8888
checkMapcodeCode("code", code);
8989
if (containsTerritory(code)) {
90-
throw new IllegalArgumentException("code cannot territory information: " + code);
90+
throw new IllegalArgumentException("Must not contain territory: " + code);
9191
}
9292
final String codeUppercase = code.toUpperCase();
9393
this.codePrecision2 = codeUppercase;
@@ -140,6 +140,7 @@ public String getCode() {
140140
* @param precision Precision. Range: 0..2.
141141
* @param alphabet Alphabet.
142142
* @return Mapcode code.
143+
* @throws IllegalArgumentException Thrown if precision is out of range (must be in [0, 2]).
143144
*/
144145
@Nonnull
145146
public String getCode(final int precision, @Nullable final Alphabet alphabet) {
@@ -156,7 +157,7 @@ public String getCode(final int precision, @Nullable final Alphabet alphabet) {
156157
}
157158

158159
@Nonnull
159-
public String getCode(final int precision) {
160+
public String getCode(final int precision) throws IllegalArgumentException {
160161
return getCode(precision, null);
161162
}
162163

@@ -172,14 +173,15 @@ public String getCode(final int precision) {
172173
* @param precision Precision specifier. Range: [0, 2].
173174
* @param alphabet Alphabet.
174175
* @return Full international mapcode.
176+
* @throws IllegalArgumentException Thrown if precision is out of range (must be in [0, 2]).
175177
*/
176178
@Nonnull
177-
public String getCodeWithTerritoryFullname(final int precision, @Nullable final Alphabet alphabet) {
179+
public String getCodeWithTerritoryFullname(final int precision, @Nullable final Alphabet alphabet) throws IllegalArgumentException {
178180
return territory.getFullName() + ' ' + getCode(precision, alphabet);
179181
}
180182

181183
@Nonnull
182-
public String getCodeWithTerritoryFullname(final int precision) {
184+
public String getCodeWithTerritoryFullname(final int precision) throws IllegalArgumentException {
183185
return getCodeWithTerritoryFullname(precision, null);
184186
}
185187

@@ -206,14 +208,15 @@ public String getCodeWithTerritoryFullname() {
206208
* @param precision Precision specifier. Range: [0, 2].
207209
* @param alphabet Alphabet.
208210
* @return Short-hand international mapcode.
211+
* @throws IllegalArgumentException Thrown if precision is out of range (must be in [0, 2]).
209212
*/
210213
@Nonnull
211-
public String getCodeWithTerritory(final int precision, @Nullable final Alphabet alphabet) {
214+
public String getCodeWithTerritory(final int precision, @Nullable final Alphabet alphabet) throws IllegalArgumentException {
212215
return territory.toString() + ' ' + getCode(precision, alphabet);
213216
}
214217

215218
@Nonnull
216-
public String getCodeWithTerritory(final int precision) {
219+
public String getCodeWithTerritory(final int precision) throws IllegalArgumentException {
217220
return getCodeWithTerritory(precision, null);
218221
}
219222

@@ -389,12 +392,12 @@ static String convertMapcodeToPlainAscii(@Nonnull final String mapcode) {
389392
* @param mapcode Mapcode (optionally with a territory) to be converted.
390393
* @param alphabet Alphabet to convert to, may contain Unicode characters.
391394
* @return Converted mapcode.
392-
* @throws IllegalArgumentException If mapcode has incorrect syntax.
395+
* @throws IllegalArgumentException Thrown if mapcode has incorrect syntax.
393396
*/
394397
@Nonnull
395398
static String convertMapcodeToAlphabet(@Nonnull final String mapcode, @Nullable final Alphabet alphabet) throws IllegalArgumentException {
396399
checkMapcodeCode("mapcode", mapcode);
397-
return (alphabet != null) ? Decoder.encodeUTF16(mapcode.toUpperCase(), alphabet.code) : mapcode.toUpperCase();
400+
return (alphabet != null) ? Decoder.encodeUTF16(mapcode.toUpperCase(), alphabet.getCode()) : mapcode.toUpperCase();
398401
}
399402

400403
/**

src/main/java/com/mapcode/SubArea.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ class SubArea {
4545

4646
static {
4747
for (final Territory territory : Territory.values()) {
48-
final int territoryCode = territory.getTerritoryCode();
48+
final int territoryCode = territory.getCode();
4949
final int first = DataAccess.dataFirstRecord(territoryCode);
5050
final int last = DataAccess.dataLastRecord(territoryCode);
5151

0 commit comments

Comments
 (0)