1   /*
2    * SPDX-FileCopyrightText: none
3    * SPDX-License-Identifier: CC0-1.0
4    */
5   
6   package gov.nist.secauto.metaschema.core.metapath.impl;
7   
8   import gov.nist.secauto.metaschema.core.metapath.DynamicContext;
9   import gov.nist.secauto.metaschema.core.metapath.IMetapathExpression;
10  import gov.nist.secauto.metaschema.core.metapath.MetapathException;
11  import gov.nist.secauto.metaschema.core.metapath.StaticContext;
12  import gov.nist.secauto.metaschema.core.metapath.item.IItem;
13  import gov.nist.secauto.metaschema.core.metapath.item.ISequence;
14  import gov.nist.secauto.metaschema.core.util.ObjectUtils;
15  
16  import edu.umd.cs.findbugs.annotations.NonNull;
17  import nl.talsmasoftware.lazy4j.Lazy;
18  
19  /**
20   * An implementation of a Metapath expression that is compiled when evaluated.
21   * <p>
22   * Lazy compilation may cause additional {@link MetapathException} errors at
23   * evaluation time, since compilation errors are not raised until evaluation.
24   */
25  public class LazyCompilationMetapathExpression implements IMetapathExpression {
26    @NonNull
27    private final String path;
28    @NonNull
29    private final StaticContext staticContext;
30    @NonNull
31    private final Lazy<IMetapathExpression> compiledMetapath;
32  
33    /**
34     * Construct a new lazy-compiled Metapath expression.
35     *
36     * @param path
37     *          the metapath expression
38     * @param staticContext
39     *          the static evaluation context
40     */
41    public LazyCompilationMetapathExpression(
42        @NonNull String path,
43        @NonNull StaticContext staticContext) {
44      this.path = path;
45      this.staticContext = staticContext;
46      this.compiledMetapath = ObjectUtils.notNull(Lazy.lazy(() -> IMetapathExpression.compile(path, staticContext)));
47    }
48  
49    @Override
50    public String getPath() {
51      return path;
52    }
53  
54    @Override
55    public StaticContext getStaticContext() {
56      return staticContext;
57    }
58  
59    @NonNull
60    private IMetapathExpression getCompiledMetapath() {
61      return ObjectUtils.notNull(compiledMetapath.get());
62    }
63  
64    @Override
65    public <T extends IItem> ISequence<T> evaluate(IItem focus, DynamicContext dynamicContext) {
66      return getCompiledMetapath().evaluate(focus, dynamicContext);
67    }
68  
69    @Override
70    public String toString() {
71      return getPath();
72    }
73  }