Skip to content

Commit 321ded1

Browse files
Merge pull request #38 from EatSleepProgramRepeat/37-integrate-the-artist-class
37-integrate-the-artist-class
2 parents 35ad779 + 5f4c5b2 commit 321ded1

7 files changed

Lines changed: 281 additions & 21 deletions

File tree

src/main/java/com/CDPrintable/Constants.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212

1313
public class Constants {
1414
// MAJOR MINOR PATCH
15-
public static final String VERSION = "1.5.3";
15+
public static final String VERSION = "1.6.4";
1616

1717
public static final boolean USER_AGENT_EMAIL_CHANGED = false;
1818
}

src/main/java/com/CDPrintable/MusicBrainzResources/Gender.java

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,22 @@ public enum Gender {
1414
MALE,
1515
FEMALE,
1616
NON_BINARY,
17-
OTHER,
18-
UNKNOWN
17+
UNKNOWN;
18+
19+
/**
20+
* Converts a string to a Gender enum.
21+
* @param genderString The input string.
22+
* @return The corresponding Gender enum, or UNKNOWN if no match is found.
23+
*/
24+
public static Gender fromString(String genderString) {
25+
if (genderString == null) {
26+
return UNKNOWN;
27+
}
28+
return switch (genderString.toLowerCase()) {
29+
case "male" -> MALE;
30+
case "female" -> FEMALE;
31+
case "non-binary", "nonbinary" -> NON_BINARY;
32+
default -> UNKNOWN;
33+
};
34+
}
1935
}

src/main/java/com/CDPrintable/MusicBrainzResources/MusicBrainzArtist.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,34 +12,40 @@
1212

1313
public class MusicBrainzArtist {
1414
private String name;
15-
private String dateOrganized;
15+
private String dateOrganized; // May only be present for groups
16+
private String birthDate; // May only be present for people
1617
private String id;
1718
private String sortName;
1819
private Gender gender;
1920
private String type; // Band, Person, etc.
2021
private String disambiguation;
2122
private String lifeSpan;
23+
private String country;
2224

23-
public MusicBrainzArtist(String name, String dateOrganized, String id, String sortName, Gender gender, String type, String disambiguation, String lifeSpan) {
25+
public MusicBrainzArtist(String name, String dateOrganized, String birthDate, String id, String sortName, Gender gender, String type, String disambiguation, String lifeSpan, String country) {
2426
this.name = name;
2527
this.dateOrganized = dateOrganized;
28+
this.birthDate = birthDate;
2629
this.id = id;
2730
this.sortName = sortName;
2831
this.gender = gender;
2932
this.type = type;
3033
this.disambiguation = disambiguation;
3134
this.lifeSpan = lifeSpan;
35+
this.country = country;
3236
}
3337

3438
public MusicBrainzArtist() {
3539
this.name = "";
3640
this.dateOrganized = "";
41+
this.birthDate = "";
3742
this.id = "";
3843
this.sortName = "";
3944
this.gender = Gender.UNKNOWN;
4045
this.type = "";
4146
this.disambiguation = "";
4247
this.lifeSpan = "";
48+
this.country = "";
4349
}
4450

4551
public String getName() {
@@ -105,4 +111,20 @@ public String getLifeSpan() {
105111
public void setLifeSpan(String lifeSpan) {
106112
this.lifeSpan = lifeSpan;
107113
}
114+
115+
public String getBirthDate() {
116+
return birthDate;
117+
}
118+
119+
public void setBirthDate(String birthDate) {
120+
this.birthDate = birthDate;
121+
}
122+
123+
public String getCountry() {
124+
return country;
125+
}
126+
127+
public void setCountry(String country) {
128+
this.country = country;
129+
}
108130
}

src/main/java/com/CDPrintable/MusicBrainzResources/MusicBrainzJSONReader.java

Lines changed: 115 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212

1313
import com.google.gson.*;
1414

15+
import java.util.Locale;
16+
1517
import javax.swing.table.DefaultTableModel;
1618
import java.lang.reflect.Array;
1719

@@ -109,6 +111,94 @@ public MusicBrainzCDStub[] getCDStubs() {
109111
}, new MusicBrainzCDStub[0]);
110112
}
111113

114+
/**
115+
* Gets Artists from the JSON.
116+
* @return An array of the artists.
117+
*/
118+
public MusicBrainzArtist[] getArtists() {
119+
return parseJsonArray("artists", jsonObject -> {
120+
String name = null;
121+
if (jsonHasAndIsNotNull(jsonObject, "name")) {
122+
JsonElement nameElement = jsonObject.get("name");
123+
if (nameElement != null && !nameElement.isJsonNull()) {
124+
name = nameElement.getAsString();
125+
}
126+
}
127+
String type = jsonHasAndIsNotNull(jsonObject, "type") ? jsonObject.get("type").getAsString() : null;
128+
129+
// THE CODE BELOW MAY CAUSE FUTURE BUGS, THOUGH UNLIKELY.
130+
// Keep in mind that the life-span.begin JSON for artists is
131+
// either the date organized or the birthdate, depending on if
132+
// the artist is a group or a person.
133+
String birthDate;
134+
String organizedDate;
135+
if (jsonHasAndIsNotNull(jsonObject, "life-span")) {
136+
JsonObject lifeSpanObject = jsonObject.getAsJsonObject("life-span");
137+
if("Group".equals(type)) {
138+
organizedDate = jsonHasAndIsNotNull(lifeSpanObject, "begin") ? lifeSpanObject.get("begin").getAsString() : null;
139+
birthDate = null;
140+
} else if ("Person".equals(type)) {
141+
birthDate = jsonHasAndIsNotNull(lifeSpanObject, "begin") ? lifeSpanObject.get("begin").getAsString() : null;
142+
organizedDate = null;
143+
} else {
144+
birthDate = null;
145+
organizedDate = null;
146+
}
147+
} else {
148+
birthDate = null;
149+
organizedDate = null;
150+
}
151+
152+
String id = jsonHasAndIsNotNull(jsonObject, "id") ? jsonObject.get("id").getAsString() : null;
153+
String sortName = jsonHasAndIsNotNull(jsonObject, "sort-name") ? jsonObject.get("sort-name").getAsString() : null;
154+
// Groups do not have genders in this API.
155+
Gender gender = Gender.fromString(jsonHasAndIsNotNull(jsonObject, "gender") ? jsonObject.get("gender").getAsString() : null);
156+
157+
String disambiguation;
158+
// The code below MAY also be problematic, although VERY unlikely.
159+
if (jsonHasAndIsNotNull(jsonObject, "tags")) {
160+
JsonArray tagsArray = jsonObject.getAsJsonArray("tags");
161+
if (!tagsArray.isEmpty()) {
162+
JsonObject firstTagObject = tagsArray.get(0).getAsJsonObject();
163+
disambiguation = jsonHasAndIsNotNull(firstTagObject, "name") ? firstTagObject.get("name").getAsString() : null;
164+
int highestCount = 0;
165+
for (JsonElement tagElement : tagsArray) {
166+
JsonObject tagObject = tagElement.getAsJsonObject();
167+
int count = jsonHasAndIsNotNull(tagObject, "count") ? tagObject.get("count").getAsInt() : -1;
168+
if (count > highestCount) {
169+
highestCount = count;
170+
disambiguation = jsonHasAndIsNotNull(tagObject, "name") ? tagObject.get("name").getAsString() : null;
171+
}
172+
}
173+
} else {
174+
disambiguation = null;
175+
}
176+
} else {
177+
disambiguation = null;
178+
}
179+
180+
String lifeSpan;
181+
if (jsonHasAndIsNotNull(jsonObject, "life-span")) {
182+
JsonObject lifeSpanObject = jsonObject.getAsJsonObject("life-span");
183+
if (jsonHasAndIsNotNull(lifeSpanObject, "begin") && jsonHasAndIsNotNull(lifeSpanObject, "end")) {
184+
lifeSpan = lifeSpanObject.get("begin").getAsString() + " - " + lifeSpanObject.get("end").getAsString();
185+
} else {
186+
lifeSpan = null;
187+
}
188+
} else {
189+
lifeSpan = null;
190+
}
191+
192+
String country = jsonHasAndIsNotNull(jsonObject, "country") ? jsonObject.get("country").getAsString() : null;
193+
if (country != null) {
194+
Locale locale = new Locale.Builder().setRegion(country).build();
195+
country = locale.getDisplayCountry();
196+
}
197+
198+
return new MusicBrainzArtist(name, organizedDate, birthDate, id, sortName, gender, type, disambiguation, lifeSpan, country);
199+
}, new MusicBrainzArtist[0]);
200+
}
201+
112202
/**
113203
* Creates a table model from an array of items.
114204
* @param items The array of items. Usually a MusicBrainzRelease, MusicBrainzCDStub, etc.
@@ -166,6 +256,30 @@ public DefaultTableModel getCDStubsAsTableModel(MusicBrainzCDStub[] cdStubArray)
166256
});
167257
}
168258

259+
/**
260+
* Gets the artists as a table model.
261+
* @param artistArray The array of artists.
262+
* @return The table model.
263+
*/
264+
public DefaultTableModel getArtistsAsTableModel(MusicBrainzArtist[] artistArray) {
265+
String[] columnNames = {"Name", "Date Organised", "Birthdate", "Sort Name", "Gender", "Type", "Disambiguation", "Life Span", "Country", ""};
266+
return createTableModel(artistArray, columnNames, item -> {
267+
MusicBrainzArtist artist = (MusicBrainzArtist) item;
268+
return new String[] {
269+
getOrDefault(artist.getName()),
270+
getOrDefault(artist.getDateOrganized()),
271+
getOrDefault(artist.getBirthDate()),
272+
getOrDefault(artist.getSortName()),
273+
getOrDefault(artist.getGender().toString().toLowerCase(Locale.ROOT)),
274+
getOrDefault(artist.getType()),
275+
getOrDefault(artist.getDisambiguation()),
276+
getOrDefault(artist.getLifeSpan()),
277+
getOrDefault(artist.getCountry()),
278+
""
279+
};
280+
});
281+
}
282+
169283
/**
170284
* Functional interface for extracting data from an item.
171285
*/
@@ -199,7 +313,7 @@ private boolean jsonHasAndIsNotNull(JsonObject jsonObject, String memberName) {
199313
* @return The value or "n/a" if the value is null.
200314
*/
201315
private String getOrDefault(String value) {
202-
return value != null ? value : "n/a";
316+
return value != null ? value : "";
203317
}
204318

205319
@Override

src/main/java/com/CDPrintable/MusicBrainzResources/MusicBrainzRequest.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,9 @@ public String buildRequestURL() {
7070
url.append(otherParams);
7171
}
7272

73-
return url.toString().replace(" ", "%20");
73+
return url.toString()
74+
.replace(" ", "%20")
75+
.replace("\"", "%22");
7476
}
7577

7678
/**

src/main/java/com/CDPrintable/ProgramWindow.java

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -10,15 +10,13 @@
1010

1111
package com.CDPrintable;
1212

13-
import com.CDPrintable.MusicBrainzResources.MusicBrainzCDStub;
14-
import com.CDPrintable.MusicBrainzResources.MusicBrainzJSONReader;
15-
import com.CDPrintable.MusicBrainzResources.MusicBrainzRelease;
16-
import com.CDPrintable.MusicBrainzResources.MusicBrainzRequest;
13+
import com.CDPrintable.MusicBrainzResources.*;
1714

1815
import javax.swing.*;
1916
import javax.swing.event.DocumentEvent;
2017
import javax.swing.event.DocumentListener;
2118
import javax.swing.table.DefaultTableModel;
19+
import javax.swing.table.TableColumn;
2220
import java.awt.*;
2321
import java.util.Objects;
2422

@@ -111,7 +109,11 @@ private JPanel searchPanel() {
111109
MusicBrainzCDStub[] cdStubs = reader.getCDStubs();
112110
searchTable.setModel(reader.getCDStubsAsTableModel(cdStubs));
113111
} else if (searchTypeComboBox.getSelectedItem().equals("Artist")) {
114-
searchTable.setModel(getArtistModel()); // Default model
112+
MusicBrainzJSONReader reader = sendRequest("artist", searchField.getText());
113+
114+
// Get Artists and set the table model
115+
MusicBrainzArtist[] artists = reader.getArtists();
116+
searchTable.setModel(reader.getArtistsAsTableModel(artists));
115117
} else if (searchTypeComboBox.getSelectedItem().equals("Release")) {
116118
MusicBrainzJSONReader reader = sendRequest("release", searchField.getText());
117119

@@ -122,6 +124,7 @@ private JPanel searchPanel() {
122124
// how does this even happen
123125
JOptionPane.showMessageDialog(panel, "Please select a search type.");
124126
}
127+
resizeColumnWidths(searchTable);
125128
});
126129

127130
cdSearchPanel.setLayout(new FlowLayout());
@@ -175,8 +178,8 @@ private DefaultTableModel getCDStubModel() {
175178
* @return A DefaultTableModel with the correct columns.
176179
*/
177180
private DefaultTableModel getArtistModel() {
178-
String[] columnNames = {"Artist Name", "Date Organised", ""};
179-
String[][] data = {{"", "", ""}};
181+
String[] columnNames = {"Name", "Date Organised", "Birthdate", "Sort Name", "Gender", "Type", "Disambiguation", "Life Span", "Country", ""};
182+
String[][] data = {{"", "", "", "", "", "", "", ""}};
180183
return new javax.swing.table.DefaultTableModel(data, columnNames);
181184
}
182185

@@ -289,4 +292,25 @@ public void changedUpdate(DocumentEvent e) {} // Not used
289292

290293
return panel;
291294
}
295+
296+
/**
297+
* Helper method to resize a tables columns to fit the largest element.
298+
* @param table The table to resize.
299+
*/
300+
private void resizeColumnWidths(JTable table) {
301+
for (int column = 0; column < table.getColumnCount(); column++) {
302+
TableColumn tableColumn = table.getColumnModel().getColumn(column);
303+
int preferredWidth = table.getTableHeader().getDefaultRenderer()
304+
.getTableCellRendererComponent(table, tableColumn.getHeaderValue(), false, false, -1, column)
305+
.getPreferredSize().width;
306+
307+
for (int row = 0; row < table.getRowCount(); row++) {
308+
Component cellRenderer = table.getCellRenderer(row, column)
309+
.getTableCellRendererComponent(table, table.getValueAt(row, column), false, false, row, column);
310+
preferredWidth = Math.max(preferredWidth, cellRenderer.getPreferredSize().width);
311+
}
312+
313+
tableColumn.setPreferredWidth(preferredWidth + 2); // Add padding
314+
}
315+
}
292316
}

0 commit comments

Comments
 (0)