@@ -52,11 +52,11 @@ private static void validateUrn(String urn) {
52
52
throw new IllegalArgumentException ("URN cannot be null or empty" );
53
53
}
54
54
if (!urn .matches ("^extension:[^:]+:[^:]+$" )) {
55
- throw new IllegalArgumentException ("URN must follow format 'extension:<namespace>:<name>', got: " + urn );
55
+ throw new IllegalArgumentException (
56
+ "URN must follow format 'extension:<namespace>:<name>', got: " + urn );
56
57
}
57
58
}
58
59
59
-
60
60
private static ObjectMapper objectMapper (String urn ) {
61
61
InjectableValues .Std iv = new InjectableValues .Std ();
62
62
iv .addValue (URN_LOCATOR_KEY , urn );
@@ -551,6 +551,13 @@ public abstract static class ExtensionSignatures {
551
551
@ JsonProperty ("urn" )
552
552
public abstract String urn ();
553
553
554
+ // URI is not from YAML, but from the loading context
555
+ // this only needs to be present temporarily to handle the URI -> URN migration
556
+ @ Value .Default
557
+ public String uri () {
558
+ return "" ;
559
+ }
560
+
554
561
@ JsonProperty ("scalar_functions" )
555
562
public abstract List <ScalarFunction > scalars ();
556
563
@@ -580,6 +587,11 @@ public Stream<SimpleExtension.Function> resolve(String urn) {
580
587
581
588
@ Value .Immutable
582
589
public abstract static class ExtensionCollection {
590
+ @ Value .Default
591
+ BidiMap <String , String > uriUrnMap () {
592
+ return new BidiMap <>();
593
+ }
594
+
583
595
private final Supplier <Set <String >> urnSupplier =
584
596
Util .memoize (
585
597
() -> {
@@ -700,7 +712,55 @@ public WindowFunctionVariant getWindowFunction(FunctionAnchor anchor) {
700
712
anchor .key (), anchor .urn ()));
701
713
}
702
714
715
+ /**
716
+ * Gets the URN for a given URI. This is only useful during the URI -> URN migration, and will
717
+ * be dropped when the migration is complete.
718
+ *
719
+ * @param uri The URI to look up
720
+ * @return The corresponding URN, or null if not found
721
+ */
722
+ public String getUrn (String uri ) {
723
+ return uriUrnMap ().get (uri );
724
+ }
725
+
726
+ /**
727
+ * Gets the URI for a given URN. This is only useful during the URI -> URN migration, and will
728
+ * be dropped when the migration is complete.
729
+ *
730
+ * @param urn The URN to look up
731
+ * @return The corresponding URI, or null if not found
732
+ */
733
+ public String getUri (String urn ) {
734
+ return uriUrnMap ().reverseGet (urn );
735
+ }
736
+
737
+ /**
738
+ * Checks if a URI has a corresponding URN mapping. This is only useful during the URI -> URN
739
+ * migration, and will be dropped when the migration is complete.
740
+ *
741
+ * @param uri The URI to check
742
+ * @return true if the URI has a URN mapping, false otherwise
743
+ */
744
+ public boolean hasUrn (String uri ) {
745
+ return uriUrnMap ().get (uri ) != null ;
746
+ }
747
+
748
+ /**
749
+ * Checks if a URN has a corresponding URI mapping. This is only useful during the URI -> URN
750
+ * migration, and will be dropped when the migration is complete.
751
+ *
752
+ * @param urn The URN to check
753
+ * @return true if the URN has a URI mapping, false otherwise
754
+ */
755
+ public boolean hasUri (String urn ) {
756
+ return uriUrnMap ().reverseGet (urn ) != null ;
757
+ }
758
+
703
759
public ExtensionCollection merge (ExtensionCollection extensionCollection ) {
760
+ BidiMap <String , String > mergedUriUrnMap = new BidiMap <>();
761
+ mergedUriUrnMap .merge (uriUrnMap ());
762
+ mergedUriUrnMap .merge (extensionCollection .uriUrnMap ());
763
+
704
764
return ImmutableSimpleExtension .ExtensionCollection .builder ()
705
765
.addAllAggregateFunctions (aggregateFunctions ())
706
766
.addAllAggregateFunctions (extensionCollection .aggregateFunctions ())
@@ -710,6 +770,7 @@ public ExtensionCollection merge(ExtensionCollection extensionCollection) {
710
770
.addAllWindowFunctions (extensionCollection .windowFunctions ())
711
771
.addAllTypes (types ())
712
772
.addAllTypes (extensionCollection .types ())
773
+ .uriUrnMap (mergedUriUrnMap )
713
774
.build ();
714
775
}
715
776
}
@@ -740,12 +801,12 @@ private static ExtensionCollection load(List<String> resourcePaths) {
740
801
throw new IllegalArgumentException ("Require at least one resource path." );
741
802
}
742
803
743
- List <ExtensionCollection > extensions =
804
+ List <ExtensionCollection > extensions =
744
805
resourcePaths .stream ()
745
806
.map (
746
807
path -> {
747
808
try (InputStream stream = ExtensionCollection .class .getResourceAsStream (path )) {
748
- return load (stream );
809
+ return load (path , stream );
749
810
} catch (IOException e ) {
750
811
throw new UncheckedIOException (e );
751
812
}
@@ -758,40 +819,48 @@ private static ExtensionCollection load(List<String> resourcePaths) {
758
819
return complete ;
759
820
}
760
821
761
- public static ExtensionCollection load (String content ) {
822
+ public static ExtensionCollection load (String uri , String content ) {
762
823
try {
763
- // Parse with basic YAML mapper first to extract URN (if present)
824
+ // Parse with basic YAML mapper first to extract URN
764
825
ObjectMapper basicYamlMapper = new ObjectMapper (new YAMLFactory ());
765
826
com .fasterxml .jackson .databind .JsonNode rootNode = basicYamlMapper .readTree (content );
766
-
767
- // URN is required
768
827
com .fasterxml .jackson .databind .JsonNode urnNode = rootNode .get ("urn" );
769
828
if (urnNode == null ) {
770
829
throw new IllegalArgumentException ("Extension YAML file must contain a 'urn' field" );
771
830
}
772
831
String urn = urnNode .asText ();
773
832
validateUrn (urn );
774
833
775
- // Then parse with URN-aware mapper
776
- ExtensionSignatures doc = objectMapper (urn ).readValue (content , ExtensionSignatures .class );
777
- return buildExtensionCollection (urn , doc );
834
+ ExtensionSignatures docWithoutUri =
835
+ objectMapper (urn ).readValue (content , ExtensionSignatures .class );
836
+
837
+ ExtensionSignatures doc =
838
+ ImmutableSimpleExtension .ExtensionSignatures .builder ()
839
+ .from (docWithoutUri )
840
+ .uri (uri )
841
+ .build ();
842
+
843
+ return buildExtensionCollection (uri , doc );
778
844
} catch (IOException e ) {
779
845
throw new IllegalStateException (e );
780
846
}
781
847
}
782
848
783
- public static ExtensionCollection load (InputStream stream ) {
784
- try (Scanner scanner = new Scanner (stream )) {
785
- scanner .useDelimiter ("\\ A" );
786
- String content = scanner .next ();
787
- return load (content );
788
- }
849
+ public static ExtensionCollection load (String uri , InputStream stream ) {
850
+ try (Scanner scanner = new Scanner (stream )) {
851
+ scanner .useDelimiter ("\\ A" );
852
+ String content = scanner .next ();
853
+ return load (uri , content );
789
854
}
790
-
855
+ }
791
856
792
857
public static ExtensionCollection buildExtensionCollection (
793
- String urn , ExtensionSignatures extensionSignatures ) {
858
+ String uri , ExtensionSignatures extensionSignatures ) {
859
+ String urn = extensionSignatures .urn ();
794
860
validateUrn (urn );
861
+ if (uri == null || uri == "" ) {
862
+ throw new IllegalArgumentException ("URI cannot be null or empty" );
863
+ }
795
864
List <ScalarFunctionVariant > scalarFunctionVariants =
796
865
extensionSignatures .scalars ().stream ()
797
866
.flatMap (t -> t .resolve (urn ))
@@ -824,23 +893,23 @@ public static ExtensionCollection buildExtensionCollection(
824
893
Stream .concat (windowFunctionVariants , windowAggFunctionVariants )
825
894
.collect (Collectors .toList ());
826
895
896
+ BidiMap <String , String > uriUrnMap = new BidiMap <>();
897
+ uriUrnMap .put (uri , urn );
898
+
827
899
ImmutableSimpleExtension .ExtensionCollection collection =
828
900
ImmutableSimpleExtension .ExtensionCollection .builder ()
829
901
.scalarFunctions (scalarFunctionVariants )
830
902
.aggregateFunctions (aggregateFunctionVariants )
831
903
.windowFunctions (allWindowFunctionVariants )
832
904
.addAllTypes (extensionSignatures .types ())
905
+ .uriUrnMap (uriUrnMap )
833
906
.build ();
907
+
834
908
LOGGER .atDebug ().log (
835
909
"Loaded {} aggregate functions and {} scalar functions from {}." ,
836
910
collection .aggregateFunctions ().size (),
837
- collection .scalarFunctions ().size (), extensionSignatures .urn ());
911
+ collection .scalarFunctions ().size (),
912
+ extensionSignatures .urn ());
838
913
return collection ;
839
914
}
840
-
841
- public static ExtensionCollection buildExtensionCollection (
842
- ExtensionSignatures extensionSignatures ) {
843
- String urn = extensionSignatures .urn ();
844
- return buildExtensionCollection (urn , extensionSignatures );
845
- }
846
915
}
0 commit comments