Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/main/java/com/CDPrintable/Constants.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

public class Constants {
// MAJOR MINOR PATCH
public static final String VERSION = "1.5.3";
public static final String VERSION = "1.6.4";

public static final boolean USER_AGENT_EMAIL_CHANGED = false;
}
20 changes: 18 additions & 2 deletions src/main/java/com/CDPrintable/MusicBrainzResources/Gender.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,22 @@ public enum Gender {
MALE,
FEMALE,
NON_BINARY,
OTHER,
UNKNOWN
UNKNOWN;

/**
* Converts a string to a Gender enum.
* @param genderString The input string.
* @return The corresponding Gender enum, or UNKNOWN if no match is found.
*/
public static Gender fromString(String genderString) {
if (genderString == null) {
return UNKNOWN;
}
return switch (genderString.toLowerCase()) {
case "male" -> MALE;
case "female" -> FEMALE;
case "non-binary", "nonbinary" -> NON_BINARY;
default -> UNKNOWN;
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,34 +12,40 @@

public class MusicBrainzArtist {
private String name;
private String dateOrganized;
private String dateOrganized; // May only be present for groups
private String birthDate; // May only be present for people
private String id;
private String sortName;
private Gender gender;
private String type; // Band, Person, etc.
private String disambiguation;
private String lifeSpan;
private String country;

public MusicBrainzArtist(String name, String dateOrganized, String id, String sortName, Gender gender, String type, String disambiguation, String lifeSpan) {
public MusicBrainzArtist(String name, String dateOrganized, String birthDate, String id, String sortName, Gender gender, String type, String disambiguation, String lifeSpan, String country) {
this.name = name;
this.dateOrganized = dateOrganized;
this.birthDate = birthDate;
this.id = id;
this.sortName = sortName;
this.gender = gender;
this.type = type;
this.disambiguation = disambiguation;
this.lifeSpan = lifeSpan;
this.country = country;
}

public MusicBrainzArtist() {
this.name = "";
this.dateOrganized = "";
this.birthDate = "";
this.id = "";
this.sortName = "";
this.gender = Gender.UNKNOWN;
this.type = "";
this.disambiguation = "";
this.lifeSpan = "";
this.country = "";
}

public String getName() {
Expand Down Expand Up @@ -105,4 +111,20 @@ public String getLifeSpan() {
public void setLifeSpan(String lifeSpan) {
this.lifeSpan = lifeSpan;
}

public String getBirthDate() {
return birthDate;
}

public void setBirthDate(String birthDate) {
this.birthDate = birthDate;
}

public String getCountry() {
return country;
}

public void setCountry(String country) {
this.country = country;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@

import com.google.gson.*;

import java.util.Locale;

import javax.swing.table.DefaultTableModel;
import java.lang.reflect.Array;

Expand Down Expand Up @@ -109,6 +111,94 @@ public MusicBrainzCDStub[] getCDStubs() {
}, new MusicBrainzCDStub[0]);
}

/**
* Gets Artists from the JSON.
* @return An array of the artists.
*/
public MusicBrainzArtist[] getArtists() {
return parseJsonArray("artists", jsonObject -> {
String name = null;
if (jsonHasAndIsNotNull(jsonObject, "name")) {
JsonElement nameElement = jsonObject.get("name");
if (nameElement != null && !nameElement.isJsonNull()) {
name = nameElement.getAsString();
}
}
String type = jsonHasAndIsNotNull(jsonObject, "type") ? jsonObject.get("type").getAsString() : null;

// THE CODE BELOW MAY CAUSE FUTURE BUGS, THOUGH UNLIKELY.
// Keep in mind that the life-span.begin JSON for artists is
// either the date organized or the birthdate, depending on if
// the artist is a group or a person.
String birthDate;
String organizedDate;
if (jsonHasAndIsNotNull(jsonObject, "life-span")) {
JsonObject lifeSpanObject = jsonObject.getAsJsonObject("life-span");
if("Group".equals(type)) {
organizedDate = jsonHasAndIsNotNull(lifeSpanObject, "begin") ? lifeSpanObject.get("begin").getAsString() : null;
birthDate = null;
} else if ("Person".equals(type)) {
birthDate = jsonHasAndIsNotNull(lifeSpanObject, "begin") ? lifeSpanObject.get("begin").getAsString() : null;
organizedDate = null;
} else {
birthDate = null;
organizedDate = null;
}
} else {
birthDate = null;
organizedDate = null;
}

String id = jsonHasAndIsNotNull(jsonObject, "id") ? jsonObject.get("id").getAsString() : null;
String sortName = jsonHasAndIsNotNull(jsonObject, "sort-name") ? jsonObject.get("sort-name").getAsString() : null;
// Groups do not have genders in this API.
Gender gender = Gender.fromString(jsonHasAndIsNotNull(jsonObject, "gender") ? jsonObject.get("gender").getAsString() : null);

String disambiguation;
// The code below MAY also be problematic, although VERY unlikely.
if (jsonHasAndIsNotNull(jsonObject, "tags")) {
JsonArray tagsArray = jsonObject.getAsJsonArray("tags");
if (!tagsArray.isEmpty()) {
JsonObject firstTagObject = tagsArray.get(0).getAsJsonObject();
disambiguation = jsonHasAndIsNotNull(firstTagObject, "name") ? firstTagObject.get("name").getAsString() : null;
int highestCount = 0;
for (JsonElement tagElement : tagsArray) {
JsonObject tagObject = tagElement.getAsJsonObject();
int count = jsonHasAndIsNotNull(tagObject, "count") ? tagObject.get("count").getAsInt() : -1;
if (count > highestCount) {
highestCount = count;
disambiguation = jsonHasAndIsNotNull(tagObject, "name") ? tagObject.get("name").getAsString() : null;
}
}
} else {
disambiguation = null;
}
} else {
disambiguation = null;
}

String lifeSpan;
if (jsonHasAndIsNotNull(jsonObject, "life-span")) {
JsonObject lifeSpanObject = jsonObject.getAsJsonObject("life-span");
if (jsonHasAndIsNotNull(lifeSpanObject, "begin") && jsonHasAndIsNotNull(lifeSpanObject, "end")) {
lifeSpan = lifeSpanObject.get("begin").getAsString() + " - " + lifeSpanObject.get("end").getAsString();
} else {
lifeSpan = null;
}
} else {
lifeSpan = null;
}

String country = jsonHasAndIsNotNull(jsonObject, "country") ? jsonObject.get("country").getAsString() : null;
if (country != null) {
Locale locale = new Locale.Builder().setRegion(country).build();
country = locale.getDisplayCountry();
}

return new MusicBrainzArtist(name, organizedDate, birthDate, id, sortName, gender, type, disambiguation, lifeSpan, country);
}, new MusicBrainzArtist[0]);
}

/**
* Creates a table model from an array of items.
* @param items The array of items. Usually a MusicBrainzRelease, MusicBrainzCDStub, etc.
Expand Down Expand Up @@ -166,6 +256,30 @@ public DefaultTableModel getCDStubsAsTableModel(MusicBrainzCDStub[] cdStubArray)
});
}

/**
* Gets the artists as a table model.
* @param artistArray The array of artists.
* @return The table model.
*/
public DefaultTableModel getArtistsAsTableModel(MusicBrainzArtist[] artistArray) {
String[] columnNames = {"Name", "Date Organised", "Birthdate", "Sort Name", "Gender", "Type", "Disambiguation", "Life Span", "Country", ""};
return createTableModel(artistArray, columnNames, item -> {
MusicBrainzArtist artist = (MusicBrainzArtist) item;
return new String[] {
getOrDefault(artist.getName()),
getOrDefault(artist.getDateOrganized()),
getOrDefault(artist.getBirthDate()),
getOrDefault(artist.getSortName()),
getOrDefault(artist.getGender().toString().toLowerCase(Locale.ROOT)),
getOrDefault(artist.getType()),
getOrDefault(artist.getDisambiguation()),
getOrDefault(artist.getLifeSpan()),
getOrDefault(artist.getCountry()),
""
};
});
}

/**
* Functional interface for extracting data from an item.
*/
Expand Down Expand Up @@ -199,7 +313,7 @@ private boolean jsonHasAndIsNotNull(JsonObject jsonObject, String memberName) {
* @return The value or "n/a" if the value is null.
*/
private String getOrDefault(String value) {
return value != null ? value : "n/a";
return value != null ? value : "";
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,9 @@ public String buildRequestURL() {
url.append(otherParams);
}

return url.toString().replace(" ", "%20");
return url.toString()
.replace(" ", "%20")
.replace("\"", "%22");
}

/**
Expand Down
38 changes: 31 additions & 7 deletions src/main/java/com/CDPrintable/ProgramWindow.java
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,13 @@

package com.CDPrintable;

import com.CDPrintable.MusicBrainzResources.MusicBrainzCDStub;
import com.CDPrintable.MusicBrainzResources.MusicBrainzJSONReader;
import com.CDPrintable.MusicBrainzResources.MusicBrainzRelease;
import com.CDPrintable.MusicBrainzResources.MusicBrainzRequest;
import com.CDPrintable.MusicBrainzResources.*;

import javax.swing.*;
import javax.swing.event.DocumentEvent;
import javax.swing.event.DocumentListener;
import javax.swing.table.DefaultTableModel;
import javax.swing.table.TableColumn;
import java.awt.*;
import java.util.Objects;

Expand Down Expand Up @@ -111,7 +109,11 @@ private JPanel searchPanel() {
MusicBrainzCDStub[] cdStubs = reader.getCDStubs();
searchTable.setModel(reader.getCDStubsAsTableModel(cdStubs));
} else if (searchTypeComboBox.getSelectedItem().equals("Artist")) {
searchTable.setModel(getArtistModel()); // Default model
MusicBrainzJSONReader reader = sendRequest("artist", searchField.getText());

// Get Artists and set the table model
MusicBrainzArtist[] artists = reader.getArtists();
searchTable.setModel(reader.getArtistsAsTableModel(artists));
} else if (searchTypeComboBox.getSelectedItem().equals("Release")) {
MusicBrainzJSONReader reader = sendRequest("release", searchField.getText());

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

cdSearchPanel.setLayout(new FlowLayout());
Expand Down Expand Up @@ -175,8 +178,8 @@ private DefaultTableModel getCDStubModel() {
* @return A DefaultTableModel with the correct columns.
*/
private DefaultTableModel getArtistModel() {
String[] columnNames = {"Artist Name", "Date Organised", ""};
String[][] data = {{"", "", ""}};
String[] columnNames = {"Name", "Date Organised", "Birthdate", "Sort Name", "Gender", "Type", "Disambiguation", "Life Span", "Country", ""};
String[][] data = {{"", "", "", "", "", "", "", ""}};
return new javax.swing.table.DefaultTableModel(data, columnNames);
}

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

return panel;
}

/**
* Helper method to resize a tables columns to fit the largest element.
* @param table The table to resize.
*/
private void resizeColumnWidths(JTable table) {
for (int column = 0; column < table.getColumnCount(); column++) {
TableColumn tableColumn = table.getColumnModel().getColumn(column);
int preferredWidth = table.getTableHeader().getDefaultRenderer()
.getTableCellRendererComponent(table, tableColumn.getHeaderValue(), false, false, -1, column)
.getPreferredSize().width;

for (int row = 0; row < table.getRowCount(); row++) {
Component cellRenderer = table.getCellRenderer(row, column)
.getTableCellRendererComponent(table, table.getValueAt(row, column), false, false, row, column);
preferredWidth = Math.max(preferredWidth, cellRenderer.getPreferredSize().width);
}

tableColumn.setPreferredWidth(preferredWidth + 2); // Add padding
}
}
}
Loading