@@ -42,26 +42,55 @@ public enum BaseDir {
4242 HOME
4343 }
4444
45+ public enum Platform {
46+ LINUX ,
47+ MACOS ,
48+ WINDOWS ;
49+
50+ private static final Platform current = findCurrent ();
51+
52+ private static Platform findCurrent () {
53+ String os = System .getProperty ("os.name" );
54+ if (os .startsWith ("Linux" )) {
55+ return LINUX ;
56+ } else if (os .startsWith ("Mac OS" )) {
57+ return MACOS ;
58+ } else if (os .startsWith ("Windows" )) {
59+ return WINDOWS ;
60+ } else {
61+ throw new AssertionError ("Unsupported platform [" + os + "]" );
62+ }
63+ }
64+
65+ public boolean isCurrent () {
66+ return this == current ;
67+ }
68+ }
69+
4570 public sealed interface FileData {
4671
4772 Stream <Path > resolvePaths (PathLookup pathLookup );
4873
4974 Mode mode ();
5075
76+ Platform platform ();
77+
78+ FileData withPlatform (Platform platform );
79+
5180 static FileData ofPath (Path path , Mode mode ) {
52- return new AbsolutePathFileData (path , mode );
81+ return new AbsolutePathFileData (path , mode , null );
5382 }
5483
5584 static FileData ofRelativePath (Path relativePath , BaseDir baseDir , Mode mode ) {
56- return new RelativePathFileData (relativePath , baseDir , mode );
85+ return new RelativePathFileData (relativePath , baseDir , mode , null );
5786 }
5887
5988 static FileData ofPathSetting (String setting , Mode mode ) {
60- return new PathSettingFileData (setting , mode );
89+ return new PathSettingFileData (setting , mode , null );
6190 }
6291
6392 static FileData ofRelativePathSetting (String setting , BaseDir baseDir , Mode mode ) {
64- return new RelativePathSettingFileData (setting , baseDir , mode );
93+ return new RelativePathSettingFileData (setting , baseDir , mode , null );
6594 }
6695
6796 /**
@@ -145,32 +174,70 @@ private static Stream<Path> relativePathsCombination(Path[] baseDirs, Stream<Pat
145174 return paths .stream ();
146175 }
147176
148- private record AbsolutePathFileData (Path path , Mode mode ) implements FileData {
177+ private record AbsolutePathFileData (Path path , Mode mode , Platform platform ) implements FileData {
149178 @ Override
150179 public Stream <Path > resolvePaths (PathLookup pathLookup ) {
151180 return Stream .of (path );
152181 }
182+
183+ @ Override
184+ public FileData withPlatform (Platform platform ) {
185+ if (platform == platform ()) {
186+ return this ;
187+ }
188+ return new AbsolutePathFileData (path , mode , platform );
189+ }
153190 }
154191
155- private record RelativePathFileData (Path relativePath , BaseDir baseDir , Mode mode ) implements FileData , RelativeFileData {
192+ private record RelativePathFileData (Path relativePath , BaseDir baseDir , Mode mode , Platform platform )
193+ implements
194+ FileData ,
195+ RelativeFileData {
156196 @ Override
157197 public Stream <Path > resolveRelativePaths (PathLookup pathLookup ) {
158198 return Stream .of (relativePath );
159199 }
200+
201+ @ Override
202+ public FileData withPlatform (Platform platform ) {
203+ if (platform == platform ()) {
204+ return this ;
205+ }
206+ return new RelativePathFileData (relativePath , baseDir , mode , platform );
207+ }
160208 }
161209
162- private record PathSettingFileData (String setting , Mode mode ) implements FileData {
210+ private record PathSettingFileData (String setting , Mode mode , Platform platform ) implements FileData {
163211 @ Override
164212 public Stream <Path > resolvePaths (PathLookup pathLookup ) {
165213 return resolvePathSettings (pathLookup , setting );
166214 }
215+
216+ @ Override
217+ public FileData withPlatform (Platform platform ) {
218+ if (platform == platform ()) {
219+ return this ;
220+ }
221+ return new PathSettingFileData (setting , mode , platform );
222+ }
167223 }
168224
169- private record RelativePathSettingFileData (String setting , BaseDir baseDir , Mode mode ) implements FileData , RelativeFileData {
225+ private record RelativePathSettingFileData (String setting , BaseDir baseDir , Mode mode , Platform platform )
226+ implements
227+ FileData ,
228+ RelativeFileData {
170229 @ Override
171230 public Stream <Path > resolveRelativePaths (PathLookup pathLookup ) {
172231 return resolvePathSettings (pathLookup , setting );
173232 }
233+
234+ @ Override
235+ public FileData withPlatform (Platform platform ) {
236+ if (platform == platform ()) {
237+ return this ;
238+ }
239+ return new RelativePathSettingFileData (setting , baseDir , mode , platform );
240+ }
174241 }
175242
176243 private static Stream <Path > resolvePathSettings (PathLookup pathLookup , String setting ) {
@@ -191,6 +258,18 @@ private static Mode parseMode(String mode) {
191258 }
192259 }
193260
261+ private static Platform parsePlatform (String platform ) {
262+ if (platform .equals ("linux" )) {
263+ return Platform .LINUX ;
264+ } else if (platform .equals ("macos" )) {
265+ return Platform .MACOS ;
266+ } else if (platform .equals ("windows" )) {
267+ return Platform .WINDOWS ;
268+ } else {
269+ throw new PolicyValidationException ("invalid platform: " + platform + ", valid values: [linux, macos, windows]" );
270+ }
271+ }
272+
194273 private static BaseDir parseBaseDir (String baseDir ) {
195274 return switch (baseDir ) {
196275 case "config" -> BaseDir .CONFIG ;
@@ -218,6 +297,7 @@ public static FilesEntitlement build(List<Object> paths) {
218297 String pathSetting = file .remove ("path_setting" );
219298 String relativePathSetting = file .remove ("relative_path_setting" );
220299 String modeAsString = file .remove ("mode" );
300+ String platformAsString = file .remove ("platform" );
221301
222302 if (file .isEmpty () == false ) {
223303 throw new PolicyValidationException ("unknown key(s) [" + file + "] in a listed file for files entitlement" );
@@ -234,36 +314,45 @@ public static FilesEntitlement build(List<Object> paths) {
234314 throw new PolicyValidationException ("files entitlement must contain 'mode' for every listed file" );
235315 }
236316 Mode mode = parseMode (modeAsString );
317+ Platform platform = null ;
318+ if (platformAsString != null ) {
319+ platform = parsePlatform (platformAsString );
320+ }
237321
238322 BaseDir baseDir = null ;
239323 if (relativeTo != null ) {
240324 baseDir = parseBaseDir (relativeTo );
241325 }
242326
327+ final FileData fileData ;
243328 if (relativePathAsString != null ) {
244329 if (baseDir == null ) {
245330 throw new PolicyValidationException ("files entitlement with a 'relative_path' must specify 'relative_to'" );
246331 }
247332
333+ Path relativePath = Path .of (relativePathAsString );
248334 if (FileData .isAbsolutePath (relativePathAsString )) {
249335 throw new PolicyValidationException ("'relative_path' [" + relativePathAsString + "] must be relative" );
250336 }
251- filesData . add ( FileData .ofRelativePath (Path . of ( relativePathAsString ) , baseDir , mode ) );
337+ fileData = FileData .ofRelativePath (relativePath , baseDir , mode );
252338 } else if (pathAsString != null ) {
339+ Path path = Path .of (pathAsString );
253340 if (FileData .isAbsolutePath (pathAsString ) == false ) {
254341 throw new PolicyValidationException ("'path' [" + pathAsString + "] must be absolute" );
255342 }
256- filesData . add ( FileData .ofPath (Path . of ( pathAsString ) , mode ) );
343+ fileData = FileData .ofPath (path , mode );
257344 } else if (pathSetting != null ) {
258- filesData . add ( FileData .ofPathSetting (pathSetting , mode ) );
345+ fileData = FileData .ofPathSetting (pathSetting , mode );
259346 } else if (relativePathSetting != null ) {
260347 if (baseDir == null ) {
261348 throw new PolicyValidationException ("files entitlement with a 'relative_path_setting' must specify 'relative_to'" );
262349 }
263- filesData . add ( FileData .ofRelativePathSetting (relativePathSetting , baseDir , mode ) );
350+ fileData = FileData .ofRelativePathSetting (relativePathSetting , baseDir , mode );
264351 } else {
265352 throw new AssertionError ("File entry validation error" );
266353 }
354+
355+ filesData .add (fileData .withPlatform (platform ));
267356 }
268357 return new FilesEntitlement (filesData );
269358 }
0 commit comments