2121import java .nio .file .Path ;
2222import java .util .Collections ;
2323import java .util .LinkedHashMap ;
24+ import java .util .List ;
2425import java .util .Map ;
2526import java .util .Map .Entry ;
2627import java .util .Objects ;
3637import org .pkl .executor .spi .v1 .ExecutorSpi ;
3738import org .pkl .executor .spi .v1 .ExecutorSpiException ;
3839import org .pkl .executor .spi .v1 .ExecutorSpiOptions ;
40+ import org .pkl .executor .spi .v2 .ExecutorSpi2 ;
41+ import org .pkl .executor .spi .v2 .ExecutorSpiException2 ;
42+ import org .pkl .executor .spi .v2 .ExecutorSpiOptions2 ;
3943
40- public class ExecutorSpiImpl implements ExecutorSpi {
44+ public class ExecutorSpiImpl implements ExecutorSpi , ExecutorSpi2 {
4145 private static final int MAX_HTTP_CLIENTS = 3 ;
4246
4347 // Don't create a new HTTP client for every executor request.
@@ -66,33 +70,94 @@ public String getPklVersion() {
6670
6771 @ Override
6872 public String evaluatePath (Path modulePath , ExecutorSpiOptions options ) {
69- var allowedModules =
70- options .getAllowedModules ().stream ().map (Pattern ::compile ).collect (Collectors .toList ());
73+ var builder =
74+ createEvaluatorBuilder (
75+ options .getAllowedModules (),
76+ options .getAllowedResources (),
77+ options .getRootDir (),
78+ options .getModulePath (),
79+ options .getEnvironmentVariables (),
80+ options .getExternalProperties (),
81+ options .getTimeout (),
82+ options .getOutputFormat (),
83+ options .getModuleCacheDir (),
84+ options .getProjectDir (),
85+ List .of (),
86+ List .of ());
7187
72- var allowedResources =
73- options .getAllowedResources ().stream ().map (Pattern ::compile ).collect (Collectors .toList ());
88+ try (var evaluator = builder .build ()) {
89+ return evaluator .evaluateOutputText (ModuleSource .path (modulePath ));
90+ } catch (PklException e ) {
91+ throw new ExecutorSpiException (e .getMessage (), e .getCause ());
92+ } finally {
93+ ModuleKeyFactories .closeQuietly (builder .getModuleKeyFactories ());
94+ }
95+ }
96+
97+ @ Override
98+ public String evaluatePath (Path modulePath , ExecutorSpiOptions2 options ) {
99+ var builder =
100+ createEvaluatorBuilder (
101+ options .getAllowedModules (),
102+ options .getAllowedResources (),
103+ options .getRootDir (),
104+ options .getModulePath (),
105+ options .getEnvironmentVariables (),
106+ options .getExternalProperties (),
107+ options .getTimeout (),
108+ options .getOutputFormat (),
109+ options .getModuleCacheDir (),
110+ options .getProjectDir (),
111+ options .getCertificateFiles (),
112+ options .getCertificateUris ());
113+
114+ try (var evaluator = builder .build ()) {
115+ return evaluator .evaluateOutputText (ModuleSource .path (modulePath ));
116+ } catch (PklException e ) {
117+ throw new ExecutorSpiException2 (e .getMessage (), e .getCause ());
118+ } finally {
119+ ModuleKeyFactories .closeQuietly (builder .getModuleKeyFactories ());
120+ }
121+ }
122+
123+ private EvaluatorBuilder createEvaluatorBuilder (
124+ List <String > allowedModules ,
125+ List <String > allowedResources ,
126+ Path rootDir ,
127+ List <Path > modulePath ,
128+ Map <String , String > environmentVariables ,
129+ Map <String , String > externalProperties ,
130+ java .time .Duration timeout ,
131+ String outputFormat ,
132+ Path moduleCacheDir ,
133+ Path projectDir ,
134+ List <Path > certificateFiles ,
135+ List <URI > certificateUris ) {
136+ var allowedModulePatterns =
137+ allowedModules .stream ().map (Pattern ::compile ).collect (Collectors .toList ());
138+
139+ var allowedResourcePatterns =
140+ allowedResources .stream ().map (Pattern ::compile ).collect (Collectors .toList ());
74141
75142 var securityManager =
76143 SecurityManagers .standard (
77- allowedModules ,
78- allowedResources ,
144+ allowedModulePatterns ,
145+ allowedResourcePatterns ,
79146 SecurityManagers .defaultTrustLevels ,
80- options . getRootDir () );
147+ rootDir );
81148
82149 var transformer = StackFrameTransformers .defaultTransformer ;
83- if (options . getRootDir () != null ) {
150+ if (rootDir != null ) {
84151 transformer =
85- transformer .andThen (
86- StackFrameTransformers .relativizeModuleUri (options .getRootDir ().toUri ()));
152+ transformer .andThen (StackFrameTransformers .relativizeModuleUri (rootDir .toUri ()));
87153 }
88154
89- var resolver = new ModulePathResolver (options .getModulePath ());
90-
155+ var resolver = new ModulePathResolver (modulePath );
91156 var builder =
92157 EvaluatorBuilder .unconfigured ()
93158 .setStackFrameTransformer (transformer )
94159 .setSecurityManager (securityManager )
95- .setHttpClient (getOrCreateHttpClient (options ))
160+ .setHttpClient (getOrCreateHttpClient (certificateFiles , certificateUris ))
96161 .addResourceReader (ResourceReaders .environmentVariable ())
97162 .addResourceReader (ResourceReaders .externalProperty ())
98163 .addResourceReader (ResourceReaders .modulePath (resolver ))
@@ -108,27 +173,22 @@ public String evaluatePath(Path modulePath, ExecutorSpiOptions options) {
108173 .addModuleKeyFactory (ModuleKeyFactories .projectpackage )
109174 .addModuleKeyFactory (ModuleKeyFactories .file )
110175 .addModuleKeyFactory (ModuleKeyFactories .genericUrl )
111- .setEnvironmentVariables (options .getEnvironmentVariables ())
112- .setExternalProperties (options .getExternalProperties ())
113- .setTimeout (options .getTimeout ())
114- .setOutputFormat (options .getOutputFormat ())
115- .setModuleCacheDir (options .getModuleCacheDir ());
116- if (options .getProjectDir () != null ) {
117- var project = Project .loadFromPath (options .getProjectDir ().resolve (PKL_PROJECT_FILENAME ));
176+ .setEnvironmentVariables (environmentVariables )
177+ .setExternalProperties (externalProperties )
178+ .setTimeout (timeout )
179+ .setOutputFormat (outputFormat )
180+ .setModuleCacheDir (moduleCacheDir );
181+
182+ if (projectDir != null ) {
183+ var project = Project .loadFromPath (projectDir .resolve (PKL_PROJECT_FILENAME ));
118184 builder .setProjectDependencies (project .getDependencies ());
119185 }
120186
121- try (var evaluator = builder .build ()) {
122- return evaluator .evaluateOutputText (ModuleSource .path (modulePath ));
123- } catch (PklException e ) {
124- throw new ExecutorSpiException (e .getMessage (), e .getCause ());
125- } finally {
126- ModuleKeyFactories .closeQuietly (builder .getModuleKeyFactories ());
127- }
187+ return builder ;
128188 }
129189
130- private HttpClient getOrCreateHttpClient (ExecutorSpiOptions options ) {
131- var clientKey = new HttpClientKey (options );
190+ private HttpClient getOrCreateHttpClient (List < Path > certificateFiles , List < URI > certificateUris ) {
191+ var clientKey = new HttpClientKey (certificateFiles , certificateUris );
132192 return httpClients .computeIfAbsent (
133193 clientKey ,
134194 (key ) -> {
@@ -140,7 +200,7 @@ private HttpClient getOrCreateHttpClient(ExecutorSpiOptions options) {
140200 builder .addCertificates (uri );
141201 }
142202 // If the above didn't add any certificates,
143- // builder will fall back to Pkl 's built-in certificates .
203+ // builder will use the JVM 's default SSL context .
144204 return builder .build ();
145205 });
146206 }
@@ -149,10 +209,10 @@ private static final class HttpClientKey {
149209 final Set <Path > certificateFiles ;
150210 final Set <URI > certificateUris ;
151211
152- HttpClientKey (ExecutorSpiOptions options ) {
153- // make defensive copies
154- certificateFiles = Set .copyOf (options . getCertificateFiles () );
155- certificateUris = Set .copyOf (options . getCertificateUris () );
212+ HttpClientKey (List < Path > certificateFiles , List < URI > certificateUris ) {
213+ // also serve as defensive copies
214+ this . certificateFiles = Set .copyOf (certificateFiles );
215+ this . certificateUris = Set .copyOf (certificateUris );
156216 }
157217
158218 @ Override
0 commit comments