001/* 002 * SPDX-FileCopyrightText: none 003 * SPDX-License-Identifier: CC0-1.0 004 */ 005 006package dev.metaschema.oscal.lib; 007 008import java.io.File; 009import java.io.IOException; 010import java.net.URISyntaxException; 011import java.net.URL; 012import java.nio.file.Path; 013 014import dev.metaschema.core.metapath.StaticContext; 015import dev.metaschema.core.model.MetaschemaException; 016import dev.metaschema.core.util.ObjectUtils; 017import dev.metaschema.databind.DefaultBindingContext; 018import dev.metaschema.databind.IBindingContext; 019import dev.metaschema.databind.SimpleModuleLoaderStrategy; 020import dev.metaschema.oscal.lib.model.AssessmentPlan; 021import dev.metaschema.oscal.lib.model.AssessmentResults; 022import dev.metaschema.oscal.lib.model.Catalog; 023import dev.metaschema.oscal.lib.model.ComponentDefinition; 024import dev.metaschema.oscal.lib.model.OscalCompleteModule; 025import dev.metaschema.oscal.lib.model.PlanOfActionAndMilestones; 026import dev.metaschema.oscal.lib.model.Profile; 027import dev.metaschema.oscal.lib.model.SystemSecurityPlan; 028import edu.umd.cs.findbugs.annotations.NonNull; 029import nl.talsmasoftware.lazy4j.Lazy; 030 031public class OscalBindingContext 032 extends DefaultBindingContext { 033 034 @NonNull 035 public static final StaticContext OSCAL_STATIC_METAPATH_CONTEXT = StaticContext.builder() 036 .defaultModelNamespace(OscalModelConstants.NS_OSCAL) 037 .build(); 038 private static final Lazy<OscalBindingContext> SINGLETON = Lazy.of(OscalBindingContext::new); 039 040 @NonNull 041 public static OscalBindingContext instance() { 042 return ObjectUtils.notNull(SINGLETON.get()); 043 } 044 045 /** 046 * Get a new builder that can produce a new, configured OSCAL-flavored binding 047 * context. 048 * 049 * @return the builder 050 * @since 2.0.0 051 */ 052 public static IBindingContext.BindingContextBuilder builder() { 053 return new IBindingContext.BindingContextBuilder(OscalBindingContext::new); 054 } 055 056 /** 057 * Get a new OSCAL-flavored {@link IBindingContext} instance, which can be used 058 * to load information that binds a model to a set of Java classes. 059 * 060 * @return a new binding context 061 * @since 2.0.0 062 */ 063 @NonNull 064 public static OscalBindingContext newInstance() { 065 return new OscalBindingContext(); 066 } 067 068 /** 069 * Get a new OSCAL-flavored {@link IBindingContext} instance, which can be used 070 * to load information that binds a model to a set of Java classes. 071 * 072 * @param strategy 073 * the loader strategy to use when loading Metaschema modules 074 * @return a new binding context 075 * @since 2.0.0 076 */ 077 @NonNull 078 public static OscalBindingContext newInstance(@NonNull IBindingContext.IModuleLoaderStrategy strategy) { 079 return new OscalBindingContext(strategy); 080 } 081 082 /** 083 * Construct a new OSCAL-flavored binding context. 084 */ 085 protected OscalBindingContext() { 086 this(new SimpleModuleLoaderStrategy()); 087 } 088 089 /** 090 * Construct a new OSCAL-flavored binding context. 091 * 092 * @param strategy 093 * the behavior class to use for loading Metaschema modules 094 * @since 2.0.0 095 */ 096 @SuppressWarnings("PMD.ConstructorCallsOverridableMethod") // false positive 097 public OscalBindingContext(@NonNull IBindingContext.IModuleLoaderStrategy strategy) { 098 super(strategy); 099 try { 100 registerModule(OscalCompleteModule.class); 101 } catch (MetaschemaException ex) { 102 throw new IllegalStateException("Failed to register OSCAL module", ex); 103 } 104 } 105 106 @NonNull 107 public Catalog loadCatalog(@NonNull URL url) throws IOException, URISyntaxException { 108 return newBoundLoader().load(Catalog.class, url); 109 } 110 111 @NonNull 112 public Catalog loadCatalog(@NonNull Path path) throws IOException { 113 return newBoundLoader().load(Catalog.class, path); 114 } 115 116 @NonNull 117 public Catalog loadCatalog(@NonNull File file) throws IOException { 118 return newBoundLoader().load(Catalog.class, file); 119 } 120 121 @NonNull 122 public Profile loadProfile(@NonNull URL url) throws IOException, URISyntaxException { 123 return newBoundLoader().load(Profile.class, url); 124 } 125 126 @NonNull 127 public Profile loadProfile(@NonNull Path path) throws IOException { 128 return newBoundLoader().load(Profile.class, path); 129 } 130 131 @NonNull 132 public Profile loadProfile(@NonNull File file) throws IOException { 133 return newBoundLoader().load(Profile.class, file); 134 } 135 136 @NonNull 137 public SystemSecurityPlan loadSystemSecurityPlan(@NonNull URL url) throws IOException, URISyntaxException { 138 return newBoundLoader().load(SystemSecurityPlan.class, url); 139 } 140 141 @NonNull 142 public SystemSecurityPlan loadSystemSecurityPlan(@NonNull Path path) throws IOException { 143 return newBoundLoader().load(SystemSecurityPlan.class, path); 144 } 145 146 @NonNull 147 public SystemSecurityPlan loadSystemSecurityPlan(@NonNull File file) throws IOException { 148 return newBoundLoader().load(SystemSecurityPlan.class, file); 149 } 150 151 @NonNull 152 public ComponentDefinition loadComponentDefinition(@NonNull URL url) throws IOException, URISyntaxException { 153 return newBoundLoader().load(ComponentDefinition.class, url); 154 } 155 156 @NonNull 157 public ComponentDefinition loadComponentDefinition(@NonNull Path path) throws IOException { 158 return newBoundLoader().load(ComponentDefinition.class, path); 159 } 160 161 @NonNull 162 public ComponentDefinition loadComponentDefinition(@NonNull File file) throws IOException { 163 return newBoundLoader().load(ComponentDefinition.class, file); 164 } 165 166 @NonNull 167 public AssessmentPlan loadAssessmentPlan(@NonNull URL url) throws IOException, URISyntaxException { 168 return newBoundLoader().load(AssessmentPlan.class, url); 169 } 170 171 @NonNull 172 public AssessmentPlan loadAssessmentPlan(@NonNull Path path) throws IOException { 173 return newBoundLoader().load(AssessmentPlan.class, path); 174 } 175 176 @NonNull 177 public AssessmentPlan loadAssessmentPlan(@NonNull File file) throws IOException { 178 return newBoundLoader().load(AssessmentPlan.class, file); 179 } 180 181 @NonNull 182 public AssessmentResults loadAssessmentResults(@NonNull URL url) throws IOException, URISyntaxException { 183 return newBoundLoader().load(AssessmentResults.class, url); 184 } 185 186 @NonNull 187 public AssessmentResults loadAssessmentResults(@NonNull Path path) throws IOException { 188 return newBoundLoader().load(AssessmentResults.class, path); 189 } 190 191 @NonNull 192 public AssessmentResults loadAssessmentResults(@NonNull File file) throws IOException { 193 return newBoundLoader().load(AssessmentResults.class, file); 194 } 195 196 @NonNull 197 public PlanOfActionAndMilestones loadPlanOfActionAndMilestones(@NonNull URL url) 198 throws IOException, URISyntaxException { 199 return newBoundLoader().load(PlanOfActionAndMilestones.class, url); 200 } 201 202 @NonNull 203 public PlanOfActionAndMilestones loadPlanOfActionAndMilestones(@NonNull Path path) throws IOException { 204 return newBoundLoader().load(PlanOfActionAndMilestones.class, path); 205 } 206 207 @NonNull 208 public PlanOfActionAndMilestones loadPlanOfActionAndMilestones(@NonNull File file) throws IOException { 209 return newBoundLoader().load(PlanOfActionAndMilestones.class, file); 210 } 211}