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.metapath.StaticContext;
009import gov.nist.secauto.metaschema.core.model.MetaschemaException;
010import gov.nist.secauto.metaschema.core.util.ObjectUtils;
011import gov.nist.secauto.metaschema.databind.DefaultBindingContext;
012import gov.nist.secauto.metaschema.databind.IBindingContext;
013import gov.nist.secauto.metaschema.databind.SimpleModuleLoaderStrategy;
014import gov.nist.secauto.oscal.lib.model.AssessmentPlan;
015import gov.nist.secauto.oscal.lib.model.AssessmentResults;
016import gov.nist.secauto.oscal.lib.model.Catalog;
017import gov.nist.secauto.oscal.lib.model.ComponentDefinition;
018import gov.nist.secauto.oscal.lib.model.OscalCompleteModule;
019import gov.nist.secauto.oscal.lib.model.PlanOfActionAndMilestones;
020import gov.nist.secauto.oscal.lib.model.Profile;
021import gov.nist.secauto.oscal.lib.model.SystemSecurityPlan;
022
023import java.io.File;
024import java.io.IOException;
025import java.net.URISyntaxException;
026import java.net.URL;
027import java.nio.file.Path;
028
029import edu.umd.cs.findbugs.annotations.NonNull;
030import nl.talsmasoftware.lazy4j.Lazy;
031
032public class OscalBindingContext
033    extends DefaultBindingContext {
034
035  @NonNull
036  public static final StaticContext OSCAL_STATIC_METAPATH_CONTEXT = StaticContext.builder()
037      .defaultModelNamespace(OscalModelConstants.NS_OSCAL)
038      .build();
039  private static final Lazy<OscalBindingContext> SINGLETON = Lazy.of(OscalBindingContext::new);
040
041  @NonNull
042  public static OscalBindingContext instance() {
043    return ObjectUtils.notNull(SINGLETON.get());
044  }
045
046  /**
047   * Get a new builder that can produce a new, configured OSCAL-flavored binding
048   * context.
049   *
050   * @return the builder
051   * @since 2.0.0
052   */
053  public static IBindingContext.BindingContextBuilder builder() {
054    return new IBindingContext.BindingContextBuilder(OscalBindingContext::new);
055  }
056
057  /**
058   * Get a new OSCAL-flavored {@link IBindingContext} instance, which can be used
059   * to load information that binds a model to a set of Java classes.
060   *
061   * @return a new binding context
062   * @since 2.0.0
063   */
064  @NonNull
065  public static OscalBindingContext newInstance() {
066    return new OscalBindingContext();
067  }
068
069  /**
070   * Get a new OSCAL-flavored {@link IBindingContext} instance, which can be used
071   * to load information that binds a model to a set of Java classes.
072   *
073   * @param strategy
074   *          the loader strategy to use when loading Metaschema modules
075   * @return a new binding context
076   * @since 2.0.0
077   */
078  @NonNull
079  public static OscalBindingContext newInstance(@NonNull IBindingContext.IModuleLoaderStrategy strategy) {
080    return new OscalBindingContext(strategy);
081  }
082
083  /**
084   * Construct a new OSCAL-flavored binding context.
085   */
086  protected OscalBindingContext() {
087    this(new SimpleModuleLoaderStrategy());
088  }
089
090  /**
091   * Construct a new OSCAL-flavored binding context.
092   *
093   * @param strategy
094   *          the behavior class to use for loading Metaschema modules
095   * @since 2.0.0
096   */
097  @SuppressWarnings("PMD.ConstructorCallsOverridableMethod") // false positive
098  public OscalBindingContext(@NonNull IBindingContext.IModuleLoaderStrategy strategy) {
099    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}