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