Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adapt parsing Bagit Profile due to specification. #128

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
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
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
public class BagInfoRequirement {
private boolean required;
private List<String> acceptableValues = new ArrayList<>();
private boolean repeatable;
private boolean repeatable = true;
VolkerHartmann marked this conversation as resolved.
Show resolved Hide resolved

@Override
public boolean equals(final Object other) {
Expand All @@ -31,12 +31,28 @@ public int hashCode() {
public BagInfoRequirement(){
//intentionally left empty
}

/**
* Constructs a new BagInfoRequirement setting {@link #repeatable} to true (default).
* @param required Indicates whether or not the tag is required.
* @param acceptableValues List of acceptable values.
*/
public BagInfoRequirement(final boolean required, final List<String> acceptableValues){
this.required = required;
this.acceptableValues = acceptableValues;
}

/**
* Constructs a new BagInfoRequirement.
* @param required Indicates whether or not the tag is required.
* @param acceptableValues List of acceptable values.
* @param repeatable Indicates whether or not the tag is repeatable.
*/
public BagInfoRequirement(final boolean required, final List<String> acceptableValues, final boolean repeatable){
this.required = required;
this.acceptableValues = acceptableValues;
this.repeatable = repeatable;
}

@Override
public String toString() {
return "[required=" + required + ", acceptableValues=" + acceptableValues + ", repeatable=" + repeatable + "]";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ public class BagitProfile {
private String externalDescription = "";
private String contactName = "";
private String contactEmail = "";
private String contactPhone = "";
private String version = "";

private Map<String, BagInfoRequirement> bagInfoRequirements = new HashMap<>();
Expand All @@ -38,6 +39,7 @@ public boolean equals(final Object other) {
&& Objects.equals(sourceOrganization, castOther.sourceOrganization)
&& Objects.equals(externalDescription, castOther.externalDescription)
&& Objects.equals(contactName, castOther.contactName) && Objects.equals(contactEmail, castOther.contactEmail)
&& Objects.equals(contactPhone, castOther.contactPhone)
&& Objects.equals(version, castOther.version)
&& Objects.equals(bagInfoRequirements, castOther.bagInfoRequirements)
&& Objects.equals(manifestTypesRequired, castOther.manifestTypesRequired)
Expand All @@ -50,15 +52,14 @@ public boolean equals(final Object other) {
}
@Override
public int hashCode() {
return Objects.hash(bagitProfileIdentifier, sourceOrganization, externalDescription, contactName, contactEmail,
version, bagInfoRequirements, manifestTypesRequired, fetchFileAllowed, serialization,
return Objects.hash(bagitProfileIdentifier, sourceOrganization, externalDescription, contactName, contactEmail, contactPhone, version, bagInfoRequirements, manifestTypesRequired, fetchFileAllowed, serialization,
acceptableMIMESerializationTypes, acceptableBagitVersions, tagManifestTypesRequired, tagFilesRequired);
}
@Override
public String toString() {
return "BagitProfile [bagitProfileIdentifier=" + bagitProfileIdentifier + ", sourceOrganization="
+ sourceOrganization + ", externalDescription=" + externalDescription + ", contactName=" + contactName
+ ", contactEmail=" + contactEmail + ", version=" + version + ", bagInfoRequirements=" + bagInfoRequirements
+ ", contactEmail=" + contactEmail + ", contactPhone=" + contactPhone + ", version=" + version + ", bagInfoRequirements=" + bagInfoRequirements
+ ", manifestTypesRequired=" + manifestTypesRequired + ", fetchFileAllowed=" + fetchFileAllowed
+ ", serialization=" + serialization + ", acceptableMIMESerializationTypes=" + acceptableMIMESerializationTypes
+ ", acceptableBagitVersions=" + acceptableBagitVersions + ", tagManifestTypesRequired="
Expand Down Expand Up @@ -143,6 +144,12 @@ public String getContactEmail() {
public void setContactEmail(final String contactEmail) {
this.contactEmail = contactEmail;
}
public String getContactPhone() {
return contactPhone;
}
public void setContactPhone(final String contactPhone) {
this.contactPhone = contactPhone;
}
public String getVersion() {
return version;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,10 @@
import com.fasterxml.jackson.databind.deser.std.StdDeserializer;

/**
* Deserialize bagit profile json to a {@link BagitProfile}
* Deserialize bagit profile json to a {@link BagitProfile}
*/
public class BagitProfileDeserializer extends StdDeserializer<BagitProfile> {

private static final long serialVersionUID = 1L;
private static final Logger logger = LoggerFactory.getLogger(BagitProfileDeserializer.class);
private static final ResourceBundle messages = ResourceBundle.getBundle("MessageBundle");
Expand All @@ -36,149 +37,200 @@ public BagitProfileDeserializer(final Class<?> vc) {

@Override
public BagitProfile deserialize(final JsonParser p, final DeserializationContext ctxt)
throws IOException, JsonProcessingException {
throws IOException, JsonProcessingException {
final BagitProfile profile = new BagitProfile();
final JsonNode node = p.getCodec().readTree(p);

parseBagitProfileInfo(node, profile);

profile.setBagInfoRequirements(parseBagInfo(node));

profile.getManifestTypesRequired().addAll(parseManifestTypesRequired(node));

profile.setFetchFileAllowed(node.get("Allow-Fetch.txt").asBoolean());
logger.debug(messages.getString("fetch_allowed"), profile.isFetchFileAllowed());

profile.setSerialization(Serialization.valueOf(node.get("Serialization").asText()));
logger.debug(messages.getString("serialization_allowed"),profile.getSerialization());
logger.debug(messages.getString("serialization_allowed"), profile.getSerialization());

profile.getAcceptableMIMESerializationTypes().addAll(parseAcceptableSerializationFormats(node));

profile.getTagManifestTypesRequired().addAll(parseRequiredTagmanifestTypes(node));

profile.getTagFilesRequired().addAll(parseRequiredTagFiles(node));

profile.getAcceptableBagitVersions().addAll(parseAcceptableVersions(node));

return profile;
}

private static void parseBagitProfileInfo(final JsonNode node, final BagitProfile profile){
final JsonNode bagitProfileInfoNode = node.get("BagIt-Profile-Info");

private static void parseBagitProfileInfo(final JsonNode node, final BagitProfile profile) {
logger.debug(messages.getString("parsing_bagit_profile_info_section"));

final JsonNode bagitProfileInfoNode = node.get("BagIt-Profile-Info");
parseMandatoryTagsOfBagitProfileInfo(bagitProfileInfoNode, profile);
parseOptionalTagsOfBagitProfileInfo(bagitProfileInfoNode, profile);
}

/**
* Parse required tags due to specification defined at
* {@link https://github.com/bagit-profiles/bagit-profiles}
* Note: If one of the tags is missing, a NullPointerException is thrown.
*
* @param bagitProfileInfoNode Root node of the bagit profile info section.
* @param profile Representation of bagit profile.
*/
private static void parseMandatoryTagsOfBagitProfileInfo(final JsonNode bagitProfileInfoNode, final BagitProfile profile) {
logger.debug(messages.getString("parsing_mandatory_tags_of_bagit_profile_info_section"));

final String profileIdentifier = bagitProfileInfoNode.get("BagIt-Profile-Identifier").asText();
logger.debug(messages.getString("identifier"), profileIdentifier);
profile.setBagitProfileIdentifier(profileIdentifier);

final String sourceOrg = bagitProfileInfoNode.get("Source-Organization").asText();
logger.debug(messages.getString("source_organization"), sourceOrg);
profile.setSourceOrganization(sourceOrg);

final String contactName = bagitProfileInfoNode.get("Contact-Name").asText();
logger.debug(messages.getString("contact_name"), contactName);
profile.setContactName(contactName);

final String contactEmail = bagitProfileInfoNode.get("Contact-Email").asText();
logger.debug(messages.getString("contact_email"), contactEmail);
profile.setContactEmail(contactEmail);


final String extDescript = bagitProfileInfoNode.get("External-Description").asText();
logger.debug(messages.getString("external_description"), extDescript);
profile.setExternalDescription(extDescript);

final String version = bagitProfileInfoNode.get("Version").asText();
logger.debug(messages.getString("version"), version);
profile.setVersion(version);
}


/**
* Parse optional tags due to specification defined at
* {@link https://github.com/bagit-profiles/bagit-profiles}
*
* @param bagitProfileInfoNode Root node of the bagit profile info section.
* @param profile Representation of bagit profile .
*/
private static void parseOptionalTagsOfBagitProfileInfo(final JsonNode bagitProfileInfoNode, final BagitProfile profile) {
logger.debug(messages.getString("parsing_optional_tags_of_bagit_profile_info_section"));

final JsonNode contactNameNode = bagitProfileInfoNode.get("Contact-Name");
if (contactNameNode != null) {
final String contactName = contactNameNode.asText();
logger.debug(messages.getString("contact_name"), contactName);
profile.setContactName(contactName);
}

final JsonNode contactEmailNode = bagitProfileInfoNode.get("Contact-Email");
if (contactEmailNode != null) {
final String contactEmail = contactEmailNode.asText();
logger.debug(messages.getString("contact_email"), contactEmail);
profile.setContactEmail(contactEmail);
}

final JsonNode contactPhoneNode = bagitProfileInfoNode.get("Contact-Phone");
if (contactPhoneNode != null) {
final String contactPhone = contactPhoneNode.asText();
logger.debug(messages.getString("contact_phone"), contactPhone);
profile.setContactPhone(contactPhone);
}
}

@SuppressWarnings("PMD.AvoidInstantiatingObjectsInLoops")
private static Map<String, BagInfoRequirement> parseBagInfo(final JsonNode rootNode){
private static Map<String, BagInfoRequirement> parseBagInfo(final JsonNode rootNode) {
final JsonNode bagInfoNode = rootNode.get("Bag-Info");
logger.debug(messages.getString("parsing_bag_info"));
final Map<String, BagInfoRequirement> bagInfo = new HashMap<>();
final Map<String, BagInfoRequirement> bagInfo = new HashMap<>();

final Iterator<Entry<String, JsonNode>> nodes = bagInfoNode.fields(); //stuck in java 6...
while(nodes.hasNext()){

while (nodes.hasNext()) {
final Entry<String, JsonNode> node = nodes.next();

final BagInfoRequirement entry = new BagInfoRequirement();
entry.setRequired(node.getValue().get("required").asBoolean());

// due to specification required is false by default.
final JsonNode requiredNode = node.getValue().get("required");
if (requiredNode != null) {
entry.setRequired(requiredNode.asBoolean());
}

final JsonNode valuesNode = node.getValue().get("values");
if(valuesNode != null){
for(final JsonNode value : valuesNode){
if (valuesNode != null) {
for (final JsonNode value : valuesNode) {
entry.getAcceptableValues().add(value.asText());
}
}


final JsonNode repeatableNode = node.getValue().get("repeatable");
if (repeatableNode != null) {
entry.setRepeatable(repeatableNode.asBoolean());
}

logger.debug("{}: {}", node.getKey(), entry);
bagInfo.put(node.getKey(), entry);
}

return bagInfo;
}
private static List<String> parseManifestTypesRequired(final JsonNode node){

private static List<String> parseManifestTypesRequired(final JsonNode node) {
final JsonNode manifests = node.get("Manifests-Required");

final List<String> manifestTypes = new ArrayList<>();

for (final JsonNode manifestName : manifests) {
manifestTypes.add(manifestName.asText());
}

logger.debug(messages.getString("required_manifest_types"), manifestTypes);

return manifestTypes;
}
private static List<String> parseAcceptableSerializationFormats(final JsonNode node){

private static List<String> parseAcceptableSerializationFormats(final JsonNode node) {
final JsonNode serialiationFormats = node.get("Accept-Serialization");
final List<String> serialTypes = new ArrayList<>();

for (final JsonNode serialiationFormat : serialiationFormats) {
serialTypes.add(serialiationFormat.asText());
}
logger.debug(messages.getString("acceptable_serialization_mime_types"), serialTypes);

return serialTypes;
}
private static List<String> parseRequiredTagmanifestTypes(final JsonNode node){

private static List<String> parseRequiredTagmanifestTypes(final JsonNode node) {
final JsonNode tagManifestsRequiredNodes = node.get("Tag-Manifests-Required");
final List<String> requiredTagmanifestTypes = new ArrayList<>();

for(final JsonNode tagManifestsRequiredNode : tagManifestsRequiredNodes){
requiredTagmanifestTypes.add(tagManifestsRequiredNode.asText());
if (tagManifestsRequiredNodes != null) {
for (final JsonNode tagManifestsRequiredNode : tagManifestsRequiredNodes) {
requiredTagmanifestTypes.add(tagManifestsRequiredNode.asText());
}
}
logger.debug(messages.getString("required_tagmanifest_types"), requiredTagmanifestTypes);

return requiredTagmanifestTypes;
}
private static List<String> parseRequiredTagFiles(final JsonNode node){

private static List<String> parseRequiredTagFiles(final JsonNode node) {
final JsonNode tagFilesRequiredNodes = node.get("Tag-Files-Required");
final List<String> requiredTagFiles = new ArrayList<>();

for(final JsonNode tagFilesRequiredNode : tagFilesRequiredNodes){
requiredTagFiles.add(tagFilesRequiredNode.asText());

if (tagFilesRequiredNodes != null) {
for (final JsonNode tagFilesRequiredNode : tagFilesRequiredNodes) {
requiredTagFiles.add(tagFilesRequiredNode.asText());
}
}
logger.debug(messages.getString("tag_files_required"), requiredTagFiles);

return requiredTagFiles;
}
private static List<String> parseAcceptableVersions(final JsonNode node){

private static List<String> parseAcceptableVersions(final JsonNode node) {
final JsonNode acceptableVersionsNodes = node.get("Accept-BagIt-Version");
final List<String> acceptableVersions = new ArrayList<>();
for(final JsonNode acceptableVersionsNode : acceptableVersionsNodes){

for (final JsonNode acceptableVersionsNode : acceptableVersionsNodes) {
acceptableVersions.add(acceptableVersionsNode.asText());
}
logger.debug(messages.getString("acceptable_bagit_versions"), acceptableVersions);

return acceptableVersions;
}
}
3 changes: 3 additions & 0 deletions src/main/resources/MessageBundle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,13 @@
fetch_allowed=Are fetch files allowed? [{}]
serialization_allowed=Serialization is: [{}]
parsing_bagit_profile_info_section=Parsing the BagIt-Profile-Info section
parsing_mandatory_tags_of_bagit_profile_info_section=Parsing mandatory tags of the BagIt-Profile-Info section
parsing_optional_tags_of_bagit_profile_info_section=Parsing optional tags of the BagIt-Profile-Info section
identifier=Identifier is [{}]
source_organization=Source-Organization is [{}]
contact_name=Contact-Name is [{}]
contact_email=Contact-Email is [{}]
contact_phone=Contact-Phone is [{}]
external_description=External-Description is [{}]
version=Version is [{}]
parsing_bag_info=Parsing the Bag-Info section
Expand Down
3 changes: 3 additions & 0 deletions src/main/resources/MessageBundle_ar.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,13 @@
fetch_allowed=Are fetch files allowed? [{}]
serialization_allowed=Serialization is\: [{}]
parsing_bagit_profile_info_section=Parsing the BagIt-Profile-Info section
parsing_mandatory_tags_of_bagit_profile_info_section=Parsing mandatory tags of the BagIt-Profile-Info section
parsing_optional_tags_of_bagit_profile_info_section=Parsing optional tags of the BagIt-Profile-Info section
identifier=Identifier is [{}]
source_organization=Source-Organization is [{}]
contact_name=Contact-Name is [{}]
contact_email=Contact-Email is [{}]
contact_phone=Contact-Phone is [{}]
external_description=External-Description is [{}]
version=Version is [{}]
parsing_bag_info=Parsing the Bag-Info section
Expand Down
Loading