7070import org .exist .test .ExistWebServer ;
7171import org .exist .util .*;
7272import org .exist .xmldb .XmldbURI ;
73+ import org .exist .xquery .XPathException ;
74+ import org .exist .xquery .value .Type ;
7375import org .w3c .dom .Attr ;
7476import org .xml .sax .InputSource ;
7577import org .xml .sax .SAXException ;
99101import static org .junit .Assert .assertFalse ;
100102import static org .junit .Assert .assertNotNull ;
101103import static org .junit .Assert .assertTrue ;
104+ import static org .junit .Assert .fail ;
102105import static org .junit .Assume .assumeThat ;
103106
104107/**
@@ -963,6 +966,158 @@ public void queryPostWithExternalVariableStringzSuppliedUntypeds() throws IOExce
963966 queryPostWithExternalVariable (HttpStatus .OK_200 , expectedResult , "xs:string*" , externalVariable );
964967 }
965968
969+ @ Test
970+ public void queryPostWithExternalVariableUntypedSuppliedUntypedElementValue () throws IOException {
971+ final Tuple2 <String , String > externalVariable = Tuple (null , "<hello>world</hello>" );
972+ queryPostWithExternalVariable (HttpStatus .OK_200 , null , externalVariable );
973+ }
974+
975+ @ Test
976+ public void queryPostWithExternalVariableUntypedSuppliedElement () throws IOException {
977+ final Tuple2 <String , String > externalVariable = Tuple ("element()" , "<hello>world</hello>" );
978+ queryPostWithExternalVariable (HttpStatus .OK_200 , null , externalVariable );
979+ }
980+
981+ @ Test
982+ public void queryPostWithExternalVariableElementNotSupplied () throws IOException {
983+ queryPostWithExternalVariable (HttpStatus .BAD_REQUEST_400 , "element()" , null );
984+ }
985+
986+ @ Test
987+ public void queryPostWithExternalVariableElementSuppliedEmpty () throws IOException {
988+ final Tuple2 <String , String >[] externalVariable = new Tuple2 [0 ];
989+ queryPostWithExternalVariable (HttpStatus .BAD_REQUEST_400 , "element()" , externalVariable );
990+ }
991+
992+ @ Test
993+ public void queryPostWithExternalVariableElementSuppliedElement () throws IOException {
994+ final Tuple2 <String , String > externalVariable = Tuple ("element()" , "<hello>world</hello>" );
995+ queryPostWithExternalVariable (HttpStatus .OK_200 , "element()" , externalVariable );
996+ }
997+
998+ @ Test
999+ public void queryPostWithExternalVariableElementSuppliedElements () throws IOException {
1000+ final Tuple2 <String , String >[] externalVariable = new Tuple2 []{ Tuple (null , "<hello>world</hello>" ), Tuple (null , "<goodbye>see you soon</goodbye>" ) };
1001+ queryPostWithExternalVariable (HttpStatus .BAD_REQUEST_400 , "element()" , externalVariable );
1002+ }
1003+
1004+ @ Test
1005+ public void queryPostWithExternalVariableElementSuppliedUntyped () throws IOException {
1006+ final Tuple2 <String , String > externalVariable = Tuple (null , "<hello>world</hello>" );
1007+ queryPostWithExternalVariable (HttpStatus .OK_200 , "element()" , externalVariable );
1008+ }
1009+
1010+ @ Test
1011+ public void queryPostWithExternalVariableUntypedSuppliedUntypedElements () throws IOException {
1012+ final Tuple2 <String , String >[] externalVariable = new Tuple2 []{ Tuple (null , "<hello>world</hello>" ), Tuple (null , "<goodbye>see you soon</goodbye>" ) };
1013+ queryPostWithExternalVariable (HttpStatus .OK_200 , null , externalVariable );
1014+ }
1015+
1016+ @ Test
1017+ public void queryPostWithExternalVariableUntypedSuppliedElements () throws IOException {
1018+ final Tuple2 <String , String >[] externalVariable = new Tuple2 []{ Tuple ("element()" , "<hello>world</hello>" ), Tuple ("element()" , "<goodbye>see you soon</goodbye>" ) };
1019+ queryPostWithExternalVariable (HttpStatus .OK_200 , null , externalVariable );
1020+ }
1021+
1022+ @ Test
1023+ public void queryPostWithExternalVariableOptElementNotSupplied () throws IOException {
1024+ queryPostWithExternalVariable (HttpStatus .BAD_REQUEST_400 , "element()?" , null );
1025+ }
1026+
1027+ @ Test
1028+ public void queryPostWithExternalVariableOptElementSuppliedEmpty () throws IOException {
1029+ final Tuple2 <String , String >[] externalVariable = new Tuple2 [0 ];
1030+ queryPostWithExternalVariable (HttpStatus .OK_200 , "element()?" , externalVariable );
1031+ }
1032+
1033+ @ Test
1034+ public void queryPostWithExternalVariableOptElementSuppliedElement () throws IOException {
1035+ final Tuple2 <String , String > externalVariable = Tuple ("element()" , "<hello>world</hello>" );
1036+ queryPostWithExternalVariable (HttpStatus .OK_200 , "element()?" , externalVariable );
1037+ }
1038+
1039+ @ Test
1040+ public void queryPostWithExternalVariableOptElementSuppliedElements () throws IOException {
1041+ final Tuple2 <String , String >[] externalVariable = new Tuple2 []{ Tuple ("element()" , "<hello>world</hello>" ), Tuple ("element()" , "<goodbye>see you soon</goodbye>" ) };
1042+ queryPostWithExternalVariable (HttpStatus .BAD_REQUEST_400 , "element()?" , externalVariable );
1043+ }
1044+
1045+ @ Test
1046+ public void queryPostWithExternalVariableOptElementSuppliedUntyped () throws IOException {
1047+ final Tuple2 <String , String > externalVariable = Tuple (null , "<hello>world</hello>" );
1048+ queryPostWithExternalVariable (HttpStatus .OK_200 , "element()?" , externalVariable );
1049+ }
1050+
1051+ @ Test
1052+ public void queryPostWithExternalVariableElementsNotSupplied () throws IOException {
1053+ queryPostWithExternalVariable (HttpStatus .BAD_REQUEST_400 , "element()+" , null );
1054+ }
1055+
1056+ @ Test
1057+ public void queryPostWithExternalVariableElementsSuppliedEmpty () throws IOException {
1058+ final Tuple2 <String , String >[] externalVariable = new Tuple2 [0 ];
1059+ queryPostWithExternalVariable (HttpStatus .BAD_REQUEST_400 , "element()+" , externalVariable );
1060+ }
1061+
1062+ @ Test
1063+ public void queryPostWithExternalVariableElementsString () throws IOException {
1064+ final Tuple2 <String , String > externalVariable = Tuple ("element()" , "<hello>world</hello>" );
1065+ queryPostWithExternalVariable (HttpStatus .OK_200 , "element()+" , externalVariable );
1066+ }
1067+
1068+ @ Test
1069+ public void queryPostWithExternalVariableElementsSuppliedElements () throws IOException {
1070+ final Tuple2 <String , String >[] externalVariable = new Tuple2 []{ Tuple ("element()" , "<hello>world</hello>" ), Tuple ("element()" , "<goodbye>see you soon</goodbye>" ) };
1071+ queryPostWithExternalVariable (HttpStatus .OK_200 , "element()+" , externalVariable );
1072+ }
1073+
1074+ @ Test
1075+ public void queryPostWithExternalVariableElementsSuppliedUntyped () throws IOException {
1076+ final Tuple2 <String , String >[] externalVariable = new Tuple2 []{ Tuple (null , "<hello>world</hello>" ) };
1077+ queryPostWithExternalVariable (HttpStatus .OK_200 , "element()+" , externalVariable );
1078+ }
1079+
1080+ @ Test
1081+ public void queryPostWithExternalVariableElementsSuppliedUntypeds () throws IOException {
1082+ final Tuple2 <String , String >[] externalVariable = new Tuple2 []{ Tuple (null , "<hello>world</hello>" ), Tuple (null , "<goodbye>see you soon</goodbye>" ) };
1083+ queryPostWithExternalVariable (HttpStatus .OK_200 , "element()+" , externalVariable );
1084+ }
1085+
1086+ @ Test
1087+ public void queryPostWithExternalVariableElementzNotSupplied () throws IOException {
1088+ queryPostWithExternalVariable (HttpStatus .BAD_REQUEST_400 , "element()*" , null );
1089+ }
1090+
1091+ @ Test
1092+ public void queryPostWithExternalVariableElementzSuppliedEmpty () throws IOException {
1093+ final Tuple2 <String , String >[] externalVariable = new Tuple2 [0 ];
1094+ queryPostWithExternalVariable (HttpStatus .OK_200 , "element()*" , externalVariable );
1095+ }
1096+
1097+ @ Test
1098+ public void queryPostWithExternalVariableElementzSuppliedElement () throws IOException {
1099+ final Tuple2 <String , String > externalVariable = Tuple ("element()" , "<hello>world</hello>" );
1100+ queryPostWithExternalVariable (HttpStatus .OK_200 , "element()*" , externalVariable );
1101+ }
1102+
1103+ @ Test
1104+ public void queryPostWithExternalVariableElementzSuppliedElements () throws IOException {
1105+ final Tuple2 <String , String >[] externalVariable = new Tuple2 []{ Tuple ("element()" , "<hello>world</hello>" ), Tuple ("element()" , "<goodbye>see you soon</goodbye>" ) };
1106+ queryPostWithExternalVariable (HttpStatus .OK_200 , "element()*" , externalVariable );
1107+ }
1108+
1109+ @ Test
1110+ public void queryPostWithExternalVariableElementszSuppliedUntyped () throws IOException {
1111+ final Tuple2 <String , String >[] externalVariable = new Tuple2 []{ Tuple (null , "<hello>world</hello>" ) };
1112+ queryPostWithExternalVariable (HttpStatus .OK_200 , "element()*" , externalVariable );
1113+ }
1114+
1115+ @ Test
1116+ public void queryPostWithExternalVariableElementzSuppliedUntypeds () throws IOException {
1117+ final Tuple2 <String , String >[] externalVariable = new Tuple2 []{ Tuple (null , "<hello>world</hello>" ), Tuple (null , "<goodbye>see you soon</goodbye>" ) };
1118+ queryPostWithExternalVariable (HttpStatus .OK_200 , "element()*" , externalVariable );
1119+ }
1120+
9661121 private void queryPostWithExternalVariable (final int expectedResponseCode , @ Nullable final String xqExternalVariableType , final Tuple2 <String , String >... externalVariableSequence ) throws IOException {
9671122 queryPostWithExternalVariable (expectedResponseCode , externalVariableSequence , xqExternalVariableType , externalVariableSequence );
9681123 }
@@ -991,26 +1146,52 @@ private static String buildExistVariableResultSequence(final Tuple2<String, Stri
9911146 final StringBuilder builder = new StringBuilder ();
9921147 builder .append ("<exist:result xmlns:exist=\" http://exist.sourceforge.net/NS/exist\" xmlns:sx=\" http://exist-db.org/xquery/types/serialized\" exist:count=\" " ).append (resultSequence .length ).append ("\" exist:hits=\" " ).append (resultSequence .length ).append ("\" exist:start=\" 1\" >\n " );
9931148 for (final Tuple2 <String , String > resultSequenceItem : resultSequence ) {
994- builder .append ("\t <exist:value" );
995- if (resultSequenceItem ._1 != null ) {
996- builder .append (" exist:type=\" " ).append (resultSequenceItem ._1 ).append ("\" " );
1149+
1150+ // TODO(AR) When wrap="yes" is set for the eXist-db REST API it does not wrap Node Types in <exist:value> - that is probably a bug in eXist-db that should be fixed - https://github.com/eXist-db/exist/issues/5909
1151+ final boolean nodeType ;
1152+ String resultType = resultSequenceItem ._1 ;
1153+ if (resultType == null ) {
1154+ nodeType = resultSequenceItem ._2 .startsWith ("<" );
1155+ } else {
1156+ nodeType = isNodeType (resultType );
1157+ }
1158+
1159+ if (!nodeType ) {
1160+ builder .append ("\t <exist:value" );
1161+ if (resultSequenceItem ._1 != null ) {
1162+ builder .append (" exist:type=\" " ).append (resultSequenceItem ._1 ).append ("\" " );
1163+ }
1164+ builder .append ('>' );
9971165 }
998- builder . append ( '>' );
1166+
9991167 builder .append (resultSequenceItem ._2 );
1000- builder .append ("</exist:value>\n " );
1168+
1169+ if (!nodeType ) {
1170+ builder .append ("</exist:value>\n " );
1171+ }
10011172 }
10021173 builder .append ("</exist:result>" );
10031174 return builder .toString ();
10041175 }
10051176
1177+ private static boolean isNodeType (final String xdmTypeName ) {
1178+ try {
1179+ final int xdmType = Type .getType (xdmTypeName );
1180+ return Type .subTypeOf (xdmType , Type .NODE );
1181+ } catch (final XPathException e ) {
1182+ fail ("Unable to find XDM type value for: " + xdmTypeName );
1183+ return false ;
1184+ }
1185+ }
1186+
10061187 private static String buildQueryExternalVariable (@ Nullable final String xqExternalVariableType , @ Nullable final Tuple2 <String , String >... externalVariableSequence ) {
10071188 final StringBuilder builder = new StringBuilder ();
1008- builder .append ("<query xmlns=\" http://exist.sourceforge.net/NS/exist\" xmlns:sx=\" http://exist-db.org/xquery/types/serialized\" wrap=\" yes\" typed=\" yes\" >\n " );
1189+ builder .append ("<exist: query xmlns:exist =\" http://exist.sourceforge.net/NS/exist\" xmlns:sx=\" http://exist-db.org/xquery/types/serialized\" wrap=\" yes\" typed=\" yes\" >\n " );
10091190
10101191 if (externalVariableSequence != null ) {
1011- builder .append ("\t <variables>\n " );
1012- builder .append ("\t \t <variable>\n " );
1013- builder .append ("\t \t \t <qname><prefix>local</prefix><localname>my-variable</localname></qname>" );
1192+ builder .append ("\t <exist: variables>\n " );
1193+ builder .append ("\t \t <exist: variable>\n " );
1194+ builder .append ("\t \t \t <exist: qname><exist: prefix>local</exist: prefix><exist: localname>my-variable</exist: localname></exist: qname>" );
10141195 builder .append ("\t \t \t <sx:sequence>\n " );
10151196 for (final Tuple2 <String , String > externalVariableSequenceItem : externalVariableSequence ) {
10161197 builder .append ("\t \t \t \t <sx:value" );
@@ -1022,19 +1203,19 @@ private static String buildQueryExternalVariable(@Nullable final String xqExtern
10221203 builder .append ("</sx:value>\n " );
10231204 }
10241205 builder .append ("\t \t \t </sx:sequence>\n " );
1025- builder .append ("\t \t </variable>\n " );
1026- builder .append ("\t </variables>\n " );
1206+ builder .append ("\t \t </exist: variable>\n " );
1207+ builder .append ("\t </exist: variables>\n " );
10271208 }
10281209
1029- builder .append ("\t <text><![CDATA[\n " );
1210+ builder .append ("\t <exist: text><![CDATA[\n " );
10301211 builder .append ("declare variable $local:my-variable" );
10311212 if (xqExternalVariableType != null ) {
10321213 builder .append (" as " ).append (xqExternalVariableType );
10331214 }
10341215 builder .append (" external;\n " );
10351216 builder .append ("$local:my-variable\n " );
1036- builder .append ("\t ]]></text>\n " );
1037- builder .append ("</query>\n " );
1217+ builder .append ("\t ]]></exist: text>\n " );
1218+ builder .append ("</exist: query>\n " );
10381219
10391220 return builder .toString ();
10401221 }
0 commit comments