001/* 002 * SPDX-FileCopyrightText: none 003 * SPDX-License-Identifier: CC0-1.0 004 */ 005 006package gov.nist.secauto.oscal.lib; 007 008import gov.nist.secauto.metaschema.core.util.ObjectUtils; 009import gov.nist.secauto.oscal.lib.model.BackMatter.Resource; 010import gov.nist.secauto.oscal.lib.model.BackMatter.Resource.Rlink; 011 012import java.net.URI; 013import java.util.List; 014import java.util.regex.Matcher; 015import java.util.regex.Pattern; 016 017import edu.umd.cs.findbugs.annotations.NonNull; 018import edu.umd.cs.findbugs.annotations.Nullable; 019 020public final class OscalUtils { 021 private static final Pattern INTERNAL_REFERENCE_FRAGMENT_PATTERN = Pattern.compile("^#(.+)$"); 022 023 private OscalUtils() { 024 // disable construction 025 } 026 027 @SuppressWarnings("PMD.OnlyOneReturn") // readability 028 public static boolean isInternalReference(@NonNull URI uri) { 029 if (uri.isAbsolute()) { 030 return false; 031 } 032 033 String schemeSpecificPart = uri.getSchemeSpecificPart(); 034 return uri.getScheme() == null && (schemeSpecificPart == null || schemeSpecificPart.isEmpty()) 035 && uri.getFragment() != null; 036 } 037 038 /** 039 * Get the id based on a URI's fragment. 040 * 041 * @param fragment 042 * the URI to extract the identifier from 043 * @return the identifier 044 * @throws IllegalArgumentException 045 * if the fragment does not contain an identifier 046 */ 047 @NonNull 048 public static String internalReferenceFragmentToId(@NonNull URI fragment) { 049 return internalReferenceFragmentToId(ObjectUtils.notNull(fragment.toString())); 050 } 051 052 /** 053 * Get the id based on a URI's fragment. 054 * 055 * @param fragment 056 * the URI to extract the identifier from 057 * @return the identifier 058 * @throws IllegalArgumentException 059 * if the fragment does not contain an identifier 060 */ 061 @NonNull 062 public static String internalReferenceFragmentToId(@NonNull String fragment) { 063 Matcher matcher = INTERNAL_REFERENCE_FRAGMENT_PATTERN.matcher(fragment); 064 String retval; 065 if (matcher.matches()) { 066 retval = ObjectUtils.notNull(matcher.group(1)); 067 } else { 068 throw new IllegalArgumentException(String.format("The fragment '%s' does not match the pattern '%s'", fragment, 069 INTERNAL_REFERENCE_FRAGMENT_PATTERN.pattern())); 070 } 071 return retval; 072 } 073 074 @Nullable 075 public static Rlink findMatchingRLink(@NonNull Resource resource, @Nullable String preferredMediaType) { 076 // find a suitable rlink reference 077 List<Rlink> rlinks = resource.getRlinks(); 078 079 Rlink retval = null; 080 if (rlinks != null) { 081 // check if there is a matching rlink for the mime type 082 if (preferredMediaType != null) { 083 // find preferred mime type first 084 retval = rlinks.stream().filter(rlink -> preferredMediaType.equals(rlink.getMediaType())).findFirst() 085 .orElse(null); 086 } else { 087 // use the first one instead 088 retval = rlinks.stream().findFirst().orElse(null); 089 } 090 } 091 return retval; 092 } 093}