1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package gov.nist.secauto.oscal.lib;
7   
8   import gov.nist.secauto.metaschema.core.metapath.StaticContext;
9   import gov.nist.secauto.metaschema.core.model.MetaschemaException;
10  import gov.nist.secauto.metaschema.core.util.ObjectUtils;
11  import gov.nist.secauto.metaschema.databind.DefaultBindingContext;
12  import gov.nist.secauto.metaschema.databind.IBindingContext;
13  import gov.nist.secauto.metaschema.databind.SimpleModuleLoaderStrategy;
14  import gov.nist.secauto.oscal.lib.model.AssessmentPlan;
15  import gov.nist.secauto.oscal.lib.model.AssessmentResults;
16  import gov.nist.secauto.oscal.lib.model.Catalog;
17  import gov.nist.secauto.oscal.lib.model.ComponentDefinition;
18  import gov.nist.secauto.oscal.lib.model.OscalCompleteModule;
19  import gov.nist.secauto.oscal.lib.model.PlanOfActionAndMilestones;
20  import gov.nist.secauto.oscal.lib.model.Profile;
21  import gov.nist.secauto.oscal.lib.model.SystemSecurityPlan;
22  
23  import java.io.File;
24  import java.io.IOException;
25  import java.net.URISyntaxException;
26  import java.net.URL;
27  import java.nio.file.Path;
28  
29  import edu.umd.cs.findbugs.annotations.NonNull;
30  import nl.talsmasoftware.lazy4j.Lazy;
31  
32  public class OscalBindingContext
33      extends DefaultBindingContext {
34  
35    @NonNull
36    public static final StaticContext OSCAL_STATIC_METAPATH_CONTEXT = StaticContext.builder()
37        .defaultModelNamespace(OscalModelConstants.NS_OSCAL)
38        .build();
39    private static final Lazy<OscalBindingContext> SINGLETON = Lazy.of(OscalBindingContext::new);
40  
41    @NonNull
42    public static OscalBindingContext instance() {
43      return ObjectUtils.notNull(SINGLETON.get());
44    }
45  
46    /**
47     * Get a new builder that can produce a new, configured OSCAL-flavored binding
48     * context.
49     *
50     * @return the builder
51     * @since 2.0.0
52     */
53    public static IBindingContext.BindingContextBuilder builder() {
54      return new IBindingContext.BindingContextBuilder(OscalBindingContext::new);
55    }
56  
57    /**
58     * Get a new OSCAL-flavored {@link IBindingContext} instance, which can be used
59     * to load information that binds a model to a set of Java classes.
60     *
61     * @return a new binding context
62     * @since 2.0.0
63     */
64    @NonNull
65    public static OscalBindingContext newInstance() {
66      return new OscalBindingContext();
67    }
68  
69    /**
70     * Get a new OSCAL-flavored {@link IBindingContext} instance, which can be used
71     * to load information that binds a model to a set of Java classes.
72     *
73     * @param strategy
74     *          the loader strategy to use when loading Metaschema modules
75     * @return a new binding context
76     * @since 2.0.0
77     */
78    @NonNull
79    public static OscalBindingContext newInstance(@NonNull IBindingContext.IModuleLoaderStrategy strategy) {
80      return new OscalBindingContext(strategy);
81    }
82  
83    /**
84     * Construct a new OSCAL-flavored binding context.
85     */
86    protected OscalBindingContext() {
87      this(new SimpleModuleLoaderStrategy());
88    }
89  
90    /**
91     * Construct a new OSCAL-flavored binding context.
92     *
93     * @param strategy
94     *          the behavior class to use for loading Metaschema modules
95     * @since 2.0.0
96     */
97    @SuppressWarnings("PMD.ConstructorCallsOverridableMethod") // false positive
98    public OscalBindingContext(@NonNull IBindingContext.IModuleLoaderStrategy strategy) {
99      super(strategy);
100     try {
101       registerModule(OscalCompleteModule.class);
102     } catch (MetaschemaException ex) {
103       throw new IllegalStateException("Failed to register OSCAL module", ex);
104     }
105   }
106 
107   @NonNull
108   public Catalog loadCatalog(@NonNull URL url) throws IOException, URISyntaxException {
109     return newBoundLoader().load(Catalog.class, url);
110   }
111 
112   @NonNull
113   public Catalog loadCatalog(@NonNull Path path) throws IOException {
114     return newBoundLoader().load(Catalog.class, path);
115   }
116 
117   @NonNull
118   public Catalog loadCatalog(@NonNull File file) throws IOException {
119     return newBoundLoader().load(Catalog.class, file);
120   }
121 
122   @NonNull
123   public Profile loadProfile(@NonNull URL url) throws IOException, URISyntaxException {
124     return newBoundLoader().load(Profile.class, url);
125   }
126 
127   @NonNull
128   public Profile loadProfile(@NonNull Path path) throws IOException {
129     return newBoundLoader().load(Profile.class, path);
130   }
131 
132   @NonNull
133   public Profile loadProfile(@NonNull File file) throws IOException {
134     return newBoundLoader().load(Profile.class, file);
135   }
136 
137   @NonNull
138   public SystemSecurityPlan loadSystemSecurityPlan(@NonNull URL url) throws IOException, URISyntaxException {
139     return newBoundLoader().load(SystemSecurityPlan.class, url);
140   }
141 
142   @NonNull
143   public SystemSecurityPlan loadSystemSecurityPlan(@NonNull Path path) throws IOException {
144     return newBoundLoader().load(SystemSecurityPlan.class, path);
145   }
146 
147   @NonNull
148   public SystemSecurityPlan loadSystemSecurityPlan(@NonNull File file) throws IOException {
149     return newBoundLoader().load(SystemSecurityPlan.class, file);
150   }
151 
152   @NonNull
153   public ComponentDefinition loadComponentDefinition(@NonNull URL url) throws IOException, URISyntaxException {
154     return newBoundLoader().load(ComponentDefinition.class, url);
155   }
156 
157   @NonNull
158   public ComponentDefinition loadComponentDefinition(@NonNull Path path) throws IOException {
159     return newBoundLoader().load(ComponentDefinition.class, path);
160   }
161 
162   @NonNull
163   public ComponentDefinition loadComponentDefinition(@NonNull File file) throws IOException {
164     return newBoundLoader().load(ComponentDefinition.class, file);
165   }
166 
167   @NonNull
168   public AssessmentPlan loadAssessmentPlan(@NonNull URL url) throws IOException, URISyntaxException {
169     return newBoundLoader().load(AssessmentPlan.class, url);
170   }
171 
172   @NonNull
173   public AssessmentPlan loadAssessmentPlan(@NonNull Path path) throws IOException {
174     return newBoundLoader().load(AssessmentPlan.class, path);
175   }
176 
177   @NonNull
178   public AssessmentPlan loadAssessmentPlan(@NonNull File file) throws IOException {
179     return newBoundLoader().load(AssessmentPlan.class, file);
180   }
181 
182   @NonNull
183   public AssessmentResults loadAssessmentResults(@NonNull URL url) throws IOException, URISyntaxException {
184     return newBoundLoader().load(AssessmentResults.class, url);
185   }
186 
187   @NonNull
188   public AssessmentResults loadAssessmentResults(@NonNull Path path) throws IOException {
189     return newBoundLoader().load(AssessmentResults.class, path);
190   }
191 
192   @NonNull
193   public AssessmentResults loadAssessmentResults(@NonNull File file) throws IOException {
194     return newBoundLoader().load(AssessmentResults.class, file);
195   }
196 
197   @NonNull
198   public PlanOfActionAndMilestones loadPlanOfActionAndMilestones(@NonNull URL url)
199       throws IOException, URISyntaxException {
200     return newBoundLoader().load(PlanOfActionAndMilestones.class, url);
201   }
202 
203   @NonNull
204   public PlanOfActionAndMilestones loadPlanOfActionAndMilestones(@NonNull Path path) throws IOException {
205     return newBoundLoader().load(PlanOfActionAndMilestones.class, path);
206   }
207 
208   @NonNull
209   public PlanOfActionAndMilestones loadPlanOfActionAndMilestones(@NonNull File file) throws IOException {
210     return newBoundLoader().load(PlanOfActionAndMilestones.class, file);
211   }
212 }