• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

jscancella / bagging / 00128798-87e2-4f08-98f7-3af2344c0896

pending completion
00128798-87e2-4f08-98f7-3af2344c0896

Pull #74

circleci

John Scancella
chore: add more code coverage and update javadoc to make it clear when fields were added in bagitprofile
Pull Request #74: feat: update bagitprofile parsing for 1.4.0 version

271 of 271 new or added lines in 19 files covered. (100.0%)

1500 of 1571 relevant lines covered (95.48%)

0.95 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.59
/src/main/java/com/github/jscancella/conformance/profile/BagitProfile.java
1
package com.github.jscancella.conformance.profile;
2

3
import java.net.URI;
4
import java.util.ArrayList;
5
import java.util.Collections;
6
import java.util.HashMap;
7
import java.util.List;
8
import java.util.Map;
9
import java.util.Objects;
10

11
/**
12
 * An immutable object for all the bagit profile fields. 
13
 * A bagit profile is used to ensure the bag contains all required elements and optional elements specified
14
 */
15
@SuppressWarnings({"PMD.UseConcurrentHashMap", "PMD.TooManyFields"})
16
public class BagitProfile {
17
  //required elements
18
  private final URI bagitProfileIdentifier;
19
  private final String sourceOrganization;
20
  private final String externalDescription;
21
  private final String version;
22
  private final String bagitProfileVersion;
23
  
24
  //optional elements
25
  private final String contactName;
26
  private final String contactEmail;
27
  private final String contactPhone;
28
  private final Map<String, BagInfoRequirement> bagInfoRequirements;
29
  private final List<String> manifestTypesRequired;
30
  private final List<String> manifestTypesAllowed;
31
  private final boolean fetchFileAllowed; //defaults to true
32
  private final boolean fetchFileRequired; //defaults to false
33
  private final boolean dataDirMustBeEmpty; //defaults to false. i.e. only thing allowed is data/.keep
34
  private final Serialization serialization;
35
  private final List<String> acceptableMIMESerializationTypes;
36
  private final List<String> acceptableBagitVersions;
37
  private final List<String> tagManifestTypesRequired;
38
  private final List<String> tagManifestTypesAllowed;
39
  private final List<String> tagFilesRequired;
40
  private final List<String> tagFilesAllowed; //glob style, defaults to ["*"] which is all
41
  
42
  /**
43
   * An immutable object for all the bagit profile fields. 
44
   * see https://bagit-profiles.github.io/bagit-profiles-specification/#implementation-details
45
   * 
46
   * @param bagitProfileIdentifier the URI where the Profile file is available, and will have the same value as the "BagIt-Profile-Identifier" tag in bag-info.txt
47
   * @param sourceOrganization taken from the reserved tags defined in [RFC8493] section 2.2.2. 
48
   * @param externalDescription taken from the reserved tags defined in [RFC8493] section 2.2.2. 
49
   * @param version the version of the bagit profile specification. Since the tag was introduced after version [v1.1.0], any profile not explicitly defining BagIt-Profile-Version should be treated as conforming to version [1.1.0] of this specification. 
50
   * @param bagitProfileVersion the version of the Profile
51
   * @param contactName as defined in [RFC8493] section 2.2.2
52
   * @param contactEmail as defined in [RFC8493] section 2.2.2 
53
   * @param contactPhone as defined in [RFC8493] section 2.2.2 
54
   * @param bagInfoRequirements Specifies which tags are required, etc. in bag-info.txt
55
   * @param manifestTypesRequired Each manifest type in LIST is required
56
   * @param manifestTypesAllowed If specified, only the manifest types in LIST are permitted
57
   * @param fetchFileAllowed A fetch.txt file is allowed within the bag
58
   * @param fetchFileRequired a fetch.txt file is required to be within the bag
59
   * @param dataDirMustBeEmpty if the data directory must be empty
60
   * @param serialization Allow, forbid or require serialization of Bags
61
   * @param acceptableMIMESerializationTypes A list of MIME types acceptable as serialized formats
62
   * @param acceptableBagitVersions A list of BagIt version numbers that will be accepted
63
   * @param tagManifestTypesRequired Each tag manifest type in LIST is required
64
   * @param tagManifestTypesAllowed If specified, only the tag manifest types in LIST are permitted
65
   * @param tagFilesRequired A list of a tag files that must be included in a conformant Bag
66
   * @param tagFilesAllowed A list of tag files that MAY be included in a conformant Bag
67
   */
68
  @SuppressWarnings("PMD.ExcessiveParameterList")
69
  public BagitProfile(final URI bagitProfileIdentifier, 
70
      final String sourceOrganization, 
71
      final String externalDescription, 
72
      final String version,
73
      final String bagitProfileVersion, 
74
      final String contactName, 
75
      final String contactEmail, 
76
      final String contactPhone,
77
      final Map<String, BagInfoRequirement> bagInfoRequirements, 
78
      final List<String> manifestTypesRequired,
79
      final List<String> manifestTypesAllowed, 
80
      final boolean fetchFileAllowed,
81
      final boolean fetchFileRequired,
82
      final boolean dataDirMustBeEmpty,
83
      final Serialization serialization,
84
      final List<String> acceptableMIMESerializationTypes, 
85
      final List<String> acceptableBagitVersions,
86
      final List<String> tagManifestTypesRequired, 
87
      final List<String> tagManifestTypesAllowed, 
88
      final List<String> tagFilesRequired,
89
      final List<String> tagFilesAllowed) {
1✔
90
    
91
    this.bagitProfileIdentifier = bagitProfileIdentifier;
1✔
92
    this.sourceOrganization = sourceOrganization;
1✔
93
    this.externalDescription = externalDescription;
1✔
94
    this.version = version;
1✔
95
    this.bagitProfileVersion = bagitProfileVersion;
1✔
96
    this.contactName = contactName;
1✔
97
    this.contactEmail = contactEmail;
1✔
98
    this.contactPhone = contactPhone;
1✔
99
    this.bagInfoRequirements = new HashMap<>(bagInfoRequirements);
1✔
100
    this.manifestTypesRequired = new ArrayList<>(manifestTypesRequired);
1✔
101
    this.manifestTypesAllowed = new ArrayList<>(manifestTypesAllowed);
1✔
102
    this.fetchFileAllowed = fetchFileAllowed;
1✔
103
    this.fetchFileRequired = fetchFileRequired;
1✔
104
    this.dataDirMustBeEmpty = dataDirMustBeEmpty;
1✔
105
    this.serialization = serialization;
1✔
106
    this.acceptableMIMESerializationTypes = new ArrayList<>(acceptableMIMESerializationTypes);
1✔
107
    this.acceptableBagitVersions = new ArrayList<>(acceptableBagitVersions);
1✔
108
    this.tagManifestTypesRequired = new ArrayList<>(tagManifestTypesRequired);
1✔
109
    this.tagManifestTypesAllowed = new ArrayList<>(tagManifestTypesAllowed);
1✔
110
    this.tagFilesRequired = new ArrayList<>(tagFilesRequired);
1✔
111
    this.tagFilesAllowed = new ArrayList<>(tagFilesAllowed);
1✔
112
  }
1✔
113

114
  /**
115
   * @return the URI where the Profile file is available, and will have the same value as the "BagIt-Profile-Identifier" tag in bag-info.txt
116
   */
117
  public URI getBagitProfileIdentifier(){
118
    return bagitProfileIdentifier;
1✔
119
  }
120

121
  /**
122
   * @return taken from the reserved tags defined in [RFC8493] section 2.2.2.
123
   */
124
  public String getSourceOrganization(){
125
    return sourceOrganization;
1✔
126
  }
127

128
  /**
129
   * @return taken from the reserved tags defined in [RFC8493] section 2.2.2.
130
   */
131
  public String getExternalDescription(){
132
    return externalDescription;
1✔
133
  }
134

135
  /**
136
   * @return the version of the bagit profile specification. 
137
   * Since the tag was introduced after version [v1.1.0], any profile not explicitly defining BagIt-Profile-Version 
138
   * should be treated as conforming to version [1.1.0] of this specification.
139
   */
140
  public String getVersion(){
141
    return version;
1✔
142
  }
143

144
  /**
145
   * @return the version of this profile
146
   */
147
  public String getBagitProfileVersion(){
148
    return bagitProfileVersion;
1✔
149
  }
150

151
  /**
152
   * @return as defined in [RFC8493] section 2.2.2,
153
   */
154
  public String getContactName(){
155
    return contactName;
1✔
156
  }
157

158
  /**
159
   * @return as defined in [RFC8493] section 2.2.2,
160
   */
161
  public String getContactEmail(){
162
    return contactEmail;
1✔
163
  }
164

165
  /**
166
   * @return as defined in [RFC8493] section 2.2.2,
167
   */
168
  public String getContactPhone(){
169
    return contactPhone;
1✔
170
  }
171

172
  /**
173
   * @return Specifies which tags are required, etc. in bag-info.txt
174
   */
175
  public Map<String, BagInfoRequirement> getBagInfoRequirements(){
176
    return Collections.unmodifiableMap(bagInfoRequirements);
1✔
177
  }
178

179
  /**
180
   * @return Each manifest type in LIST is required. The list contains the type of manifest (not the complete filename), e.g. ["sha1", "md5"]. 
181
   */
182
  public List<String> getManifestTypesRequired(){
183
    return Collections.unmodifiableList(manifestTypesRequired);
1✔
184
  }
185

186
  /**
187
   * @return  If specified, only the manifest types in LIST are permitted. 
188
   * The list contains the type of manifest (not the complete filename), e.g. ["sha1", "md5"]. 
189
   * When specified along with Manifests-Required, Manifests-Allowed must include at least all of the manifest types listed in Manifests-Required. 
190
   * If not specified, all manifest types are permitted.
191
   * 
192
   *  @since bagitprofile version 1.3.0
193
   */
194
  public List<String> getManifestTypesAllowed(){
195
    return Collections.unmodifiableList(manifestTypesAllowed);
1✔
196
  }
197

198
  /**
199
   * @return A fetch.txt file is allowed within the bag. Default: true
200
   */
201
  public boolean isFetchFileAllowed(){
202
    return fetchFileAllowed;
1✔
203
  }
204
  
205
  /**
206
   * @return the fetch.txt file is required to be in the bag
207
   * @since bagitprofile version 1.4.0
208
   */
209
  public boolean isFetchFileRequired() {
210
    return fetchFileRequired;
1✔
211
  }
212
  
213
  /**
214
   * @return the data directory in the bag must be empty. Default: false
215
   * @since bagitprofile version 1.4.0
216
   */
217
  public boolean isDataDirMustBeEmpty() {
218
        return dataDirMustBeEmpty;
1✔
219
  }
220

221
  /**
222
   * @return Allow, forbid or require serialization of Bags. Default is optional. 
223
   */
224
  public Serialization getSerialization(){
225
    return serialization;
1✔
226
  }
227

228
  /**
229
   * @return A list of MIME types acceptable as serialized formats. E.g. "application/zip". 
230
   * If serialization has a value of required or optional, at least one value is needed. 
231
   * If serialization is forbidden, this has no meaning. 
232
   */
233
  public List<String> getAcceptableMIMESerializationTypes(){
234
    return Collections.unmodifiableList(acceptableMIMESerializationTypes);
1✔
235
  }
236

237
  /**
238
   * @return A list of BagIt version numbers that will be accepted. At least one version is required. 
239
   */
240
  public List<String> getAcceptableBagitVersions(){
241
    return Collections.unmodifiableList(acceptableBagitVersions);
1✔
242
  }
243

244
  /**
245
   * @return Each tag manifest type in LIST is required. 
246
   * The list contains the type of manifest (not the complete filename), e.g. ["sha1", "md5"]. 
247
   */
248
  public List<String> getTagManifestTypesRequired(){
249
    return Collections.unmodifiableList(tagManifestTypesRequired);
1✔
250
  }
251

252
  /**
253
   * @return  If specified, only the tag manifest types in LIST are permitted. 
254
   * The list contains the type of manifest (not the complete filename), e.g. ["sha1", "md5"]. 
255
   * When specified along with Tag-Manifests-Required, Tag-Manifests-Allowed must include at least all of the tag manifest 
256
   * types listed in Tag-Manifests-Required. If not specified, all tag manifest types are permitted.
257
   * 
258
   *  @since bagitprofile version 1.3.0
259
   */
260
  public List<String> getTagManifestTypesAllowed(){
261
    return Collections.unmodifiableList(tagManifestTypesAllowed);
1✔
262
  }
263

264
  /**
265
   * @return  A list of a tag files that must be included in a conformant Bag. 
266
   * Entries are full path names relative to the Bag base directory. 
267
   * As per [RFC8493] section 2.2.4, these tag files need not be listed in tag manifiest files. 
268
   * Tag-Files-Required SHOULD NOT include bag-info.txt (which is always required), 
269
   * nor any required manifest files, which instead are required by Manifests-Required and Tag-Manifests-Required.
270
   * Every file in Tag-Files-Required must also be present in Tag-Files-Allowed. 
271
   */
272
  public List<String> getTagFilesRequired(){
273
    return Collections.unmodifiableList(tagFilesRequired);
1✔
274
  }
275

276
  /**
277
   * @return  A list of tag files that MAY be included in a conformant Bag. 
278
   * Entries are either full path names relative to the bag base directory or path name patterns in 
279
   * which asterisks can represent zero or more characters (c.f. glob(7)).
280
   * If Tag-Files-Allowed is not provided, its value is assumed to be ['*'], i.e. all tag files are allowed.
281
   * As per [RFC8493] section 2, these tag files need not be listed in tag manifest files. 
282
   * Tag-Files-Required SHOULD NOT include bag-info.txt (which is always required), nor any required manifest files, 
283
   * which instead are required by Manifests-Required and Tag-Manifests-Required.
284
   * At least all the tag files listed in Tag-Files-Required must be in included in Tag-Files-Allowed. 
285
   * 
286
   * @since bagitprofile version 1.3.0
287
   */
288
  public List<String> getTagFilesAllowed(){
289
    return Collections.unmodifiableList(tagFilesAllowed);
1✔
290
  }
291

292
  @Override
293
  public int hashCode() {
294
    return Objects.hash(acceptableBagitVersions, acceptableMIMESerializationTypes, bagInfoRequirements,
×
295
        bagitProfileIdentifier, bagitProfileVersion, contactEmail, contactName, contactPhone, dataDirMustBeEmpty,
×
296
        externalDescription, fetchFileAllowed, fetchFileRequired, manifestTypesAllowed, manifestTypesRequired,
×
297
        serialization, sourceOrganization, tagFilesAllowed, tagFilesRequired, tagManifestTypesAllowed,
298
        tagManifestTypesRequired, version);
299
  }
300

301
  @Override
302
  public boolean equals(final Object obj) {
303
    boolean isEqual = false;
1✔
304
    if (obj instanceof BagitProfile) {
1✔
305
      final BagitProfile other = (BagitProfile) obj;
1✔
306
      isEqual = Objects.equals(acceptableBagitVersions, other.acceptableBagitVersions)
1✔
307
          && Objects.equals(acceptableMIMESerializationTypes, other.acceptableMIMESerializationTypes)
1✔
308
          && Objects.equals(bagInfoRequirements, other.bagInfoRequirements)
1✔
309
          && Objects.equals(bagitProfileIdentifier, other.bagitProfileIdentifier)
1✔
310
          && Objects.equals(bagitProfileVersion, other.bagitProfileVersion)
1✔
311
          && Objects.equals(contactEmail, other.contactEmail) && Objects.equals(contactName, other.contactName)
1✔
312
          && Objects.equals(contactPhone, other.contactPhone) && dataDirMustBeEmpty == other.dataDirMustBeEmpty
1✔
313
          && Objects.equals(externalDescription, other.externalDescription) && fetchFileAllowed == other.fetchFileAllowed
1✔
314
          && fetchFileRequired == other.fetchFileRequired
315
          && Objects.equals(manifestTypesAllowed, other.manifestTypesAllowed)
1✔
316
          && Objects.equals(manifestTypesRequired, other.manifestTypesRequired) && serialization == other.serialization
1✔
317
          && Objects.equals(sourceOrganization, other.sourceOrganization)
1✔
318
          && Objects.equals(tagFilesAllowed, other.tagFilesAllowed)
1✔
319
          && Objects.equals(tagFilesRequired, other.tagFilesRequired)
1✔
320
          && Objects.equals(tagManifestTypesAllowed, other.tagManifestTypesAllowed)
1✔
321
          && Objects.equals(tagManifestTypesRequired, other.tagManifestTypesRequired)
1✔
322
          && Objects.equals(version, other.version);
1✔
323
    }
324
    
325
    return isEqual;
1✔
326
  }
327

328
  @Override
329
  public String toString() {
330
    return "BagitProfile [bagitProfileIdentifier=" + bagitProfileIdentifier + ", sourceOrganization="
1✔
331
        + sourceOrganization + ", externalDescription=" + externalDescription + ", version=" + version
332
        + ", bagitProfileVersion=" + bagitProfileVersion + ", contactName=" + contactName + ", contactEmail="
333
        + contactEmail + ", contactPhone=" + contactPhone + ", bagInfoRequirements=" + bagInfoRequirements
334
        + ", manifestTypesRequired=" + manifestTypesRequired + ", manifestTypesAllowed=" + manifestTypesAllowed
335
        + ", fetchFileAllowed=" + fetchFileAllowed + ", fetchFileRequired=" + fetchFileRequired
336
        + ", dataDirMustBeEmpty=" + dataDirMustBeEmpty + ", serialization=" + serialization
337
        + ", acceptableMIMESerializationTypes=" + acceptableMIMESerializationTypes + ", acceptableBagitVersions="
338
        + acceptableBagitVersions + ", tagManifestTypesRequired=" + tagManifestTypesRequired
339
        + ", tagManifestTypesAllowed=" + tagManifestTypesAllowed + ", tagFilesRequired=" + tagFilesRequired
340
        + ", tagFilesAllowed=" + tagFilesAllowed + "]";
341
  }
342
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2025 Coveralls, Inc