24
24
import java .util .Arrays ;
25
25
import java .util .HashMap ;
26
26
import java .util .Map ;
27
+
27
28
import org .exist .Namespaces ;
28
29
import org .exist .dom .QName ;
29
30
import org .exist .xquery .value .FunctionParameterSequenceType ;
33
34
/**
34
35
* Describes the signature of a built-in or user-defined function, i.e.
35
36
* its name, the type and cardinality of its arguments and its return type.
36
- *
37
+ *
37
38
* @author wolf
38
39
* @author lcahlander
39
40
* @version 1.3
@@ -43,25 +44,20 @@ public class FunctionSignature {
43
44
/**
44
45
* Default sequence type for function parameters.
45
46
*/
46
- public final static SequenceType DEFAULT_TYPE = new SequenceType (Type .ITEM , Cardinality .ZERO_OR_MORE );
47
+ public static final SequenceType DEFAULT_TYPE = new SequenceType (Type .ITEM , Cardinality .ZERO_OR_MORE );
47
48
48
49
/**
49
50
* Empty array to specify if a function doesn't take any arguments.
50
51
*/
51
- public final static SequenceType [] NO_ARGS = new SequenceType [0 ];
52
+ public static final SequenceType [] NO_ARGS = new SequenceType [0 ];
52
53
53
54
private static final String DEPRECATION_REMOVAL_MESSAGE = "\n This function could be removed in the next major release version." ;
54
-
55
- public static SequenceType [] singleArgument (final SequenceType arg ) {
56
- return new SequenceType [] { arg };
57
- }
58
-
59
- private Annotation [] annotations ;
60
55
private final QName name ;
56
+ private Annotation [] annotations ;
61
57
private SequenceType [] arguments ;
62
58
private SequenceType returnType ;
63
- private boolean isVariadic = false ;
64
- private String description = null ;
59
+ private boolean isVariadic ;
60
+ private String description ;
65
61
private String deprecated = null ;
66
62
private Map <String , String > metadata = null ;
67
63
@@ -89,17 +85,13 @@ public FunctionSignature(final QName name, final SequenceType[] arguments, final
89
85
}
90
86
91
87
public FunctionSignature (final QName name , final String description , final SequenceType [] arguments , final SequenceType returnType ) {
92
- this (name , description , arguments , returnType , false );
88
+ this (name , description , arguments , returnType , false );
93
89
}
94
90
95
91
public FunctionSignature (final QName name , final String description , final SequenceType [] arguments , final SequenceType returnType , final String deprecated ) {
96
92
this (name , description , arguments , returnType , false );
97
93
setDeprecated (deprecated );
98
94
}
99
-
100
- // public FunctionSignature(final QName name, final String description, final SequenceType[] arguments, final SequenceType returnType, final FunctionSignature deprecatedBy) {
101
- // this(name, description, arguments, returnType, false, "Moved to the module: " + deprecatedBy.getName().getNamespaceURI() + ", you should now use '" + deprecatedBy.getName().getPrefix() + ":" + deprecatedBy.getName().getLocalPart() + "' instead!");
102
- // }
103
95
104
96
public FunctionSignature (final QName name , final String description , final SequenceType [] arguments , final SequenceType returnType , final boolean variadic , final String deprecated ) {
105
97
this (name , description , arguments , returnType , variadic );
@@ -108,13 +100,13 @@ public FunctionSignature(final QName name, final String description, final Seque
108
100
109
101
/**
110
102
* Create a new function signature.
111
- *
112
- * @param name the QName of the function.
103
+ *
104
+ * @param name the QName of the function.
113
105
* @param description documentation string describing the function
114
- * @param arguments the sequence types of all expected arguments
115
- * @param returnType the sequence type returned by the function
116
- * @param variadic set to true if the function may expect additional parameters
117
- */
106
+ * @param arguments the sequence types of all expected arguments
107
+ * @param returnType the sequence type returned by the function
108
+ * @param variadic set to true if the function may expect additional parameters
109
+ */
118
110
public FunctionSignature (final QName name , final String description , final SequenceType [] arguments , final SequenceType returnType , final boolean variadic ) {
119
111
this .name = name ;
120
112
this .arguments = arguments ;
@@ -126,22 +118,26 @@ public FunctionSignature(final QName name, final String description, final Seque
126
118
public Annotation [] getAnnotations () {
127
119
return annotations ;
128
120
}
129
-
121
+
122
+ public void setAnnotations (final Annotation [] annotations ) {
123
+ this .annotations = annotations ;
124
+ }
125
+
130
126
public QName getName () {
131
127
return name ;
132
128
}
133
129
134
130
public int getArgumentCount () {
135
- if (isVariadic ) {
131
+ if (isVariadic ) {
136
132
return -1 ;
137
133
}
138
134
return arguments != null ? arguments .length : 0 ;
139
135
}
140
-
136
+
141
137
public FunctionId getFunctionId () {
142
138
return new FunctionId (name , getArgumentCount ());
143
139
}
144
-
140
+
145
141
public SequenceType getReturnType () {
146
142
return returnType ;
147
143
}
@@ -157,29 +153,23 @@ public SequenceType[] getArgumentTypes() {
157
153
public void setArgumentTypes (final SequenceType [] types ) {
158
154
this .arguments = types ;
159
155
}
160
-
161
- public void setAnnotations (final Annotation [] annotations ) {
162
- this .annotations = annotations ;
163
- }
164
-
156
+
165
157
public String getDescription () {
166
- return description ;
158
+ return description ;
167
159
}
168
160
169
161
public void setDescription (final String description ) {
170
162
this .description = description ;
171
163
}
172
164
173
- public void addMetadata (final String key , String value ) {
174
- if (metadata == null ) {
165
+ public void addMetadata (final String key , final String value ) {
166
+ if (metadata == null ) {
175
167
metadata = new HashMap <>(5 );
176
168
}
177
169
final String old = metadata .get (key );
178
- if (old != null ) {
179
- // if the key exists, simply append the new value
180
- value = old + ", " + value ;
181
- }
182
- metadata .put (key , value );
170
+ // if the key exists, append the new value
171
+ final String newValue = old == null ? value : old + ", " + value ;
172
+ metadata .put (key , newValue );
183
173
}
184
174
185
175
public String getMetadata (final String key ) {
@@ -208,17 +198,17 @@ public String getDeprecated() {
208
198
return null ;
209
199
}
210
200
}
211
-
201
+
212
202
public final void setDeprecated (final String message ) {
213
203
deprecated = message ;
214
204
}
215
205
216
206
public boolean isPrivate () {
217
207
final Annotation [] annotations = getAnnotations ();
218
- if (annotations != null ) {
219
- for (final Annotation annot : annotations ) {
208
+ if (annotations != null ) {
209
+ for (final Annotation annot : annotations ) {
220
210
final QName qn = annot .getName ();
221
- if (qn .getNamespaceURI ().equals (Namespaces .XPATH_FUNCTIONS_NS ) && "private" .equals (qn .getLocalPart ())) {
211
+ if (qn .getNamespaceURI ().equals (Namespaces .XPATH_FUNCTIONS_NS ) && "private" .equals (qn .getLocalPart ())) {
222
212
return true ;
223
213
}
224
214
}
@@ -231,50 +221,53 @@ public String toString() {
231
221
final StringBuilder buf = new StringBuilder ();
232
222
buf .append (name .getStringValue ());
233
223
buf .append ('(' );
234
- if (arguments != null ) {
235
- final char var = 'a' ;
236
- for (int i = 0 ; i < arguments .length ; i ++) {
237
- if (i > 0 ) {
224
+ if (arguments != null ) {
225
+ final char ANON_VAR = 'a' ;
226
+ for (int i = 0 ; i < arguments .length ; i ++) {
227
+ if (i > 0 ) {
238
228
buf .append (", " );
239
229
}
240
230
buf .append ('$' );
241
- if (arguments [i ] instanceof FunctionParameterSequenceType ) {
242
- buf .append (((FunctionParameterSequenceType )arguments [i ]).getAttributeName ());
231
+ if (arguments [i ] instanceof FunctionParameterSequenceType ) {
232
+ buf .append (((FunctionParameterSequenceType ) arguments [i ]).getAttributeName ());
243
233
} else {
244
- buf .append ((char )( var + i ));
234
+ buf .append ((char ) ( ANON_VAR + i ));
245
235
}
246
236
buf .append (" as " );
247
237
buf .append (arguments [i ].toString ());
248
238
}
249
-
250
- if (isVariadic ) {
239
+
240
+ if (isVariadic ) {
251
241
buf .append (", ..." );
252
242
}
253
243
}
254
- buf .append (") " );
244
+ buf .append (") as " );
255
245
buf .append (returnType .toString ());
256
-
246
+
257
247
return buf .toString ();
258
248
}
259
249
260
250
@ Override
261
251
public boolean equals (final Object obj ) {
262
- if ( obj == null || !(obj instanceof FunctionSignature other )) {
252
+ if ( !(obj instanceof FunctionSignature other )) {
263
253
return false ;
264
254
}
265
-
266
- if (name == null ) {
267
- if (other .name != null ) {
268
- return false ;
269
- }
270
- return getArgumentCount () == other .getArgumentCount ();
255
+ // quick comparison by object identity
256
+ if (this == other ) {
257
+ return true ;
271
258
}
272
-
273
- if (name .equals (other .name )) {
274
- return getArgumentCount () == other .getArgumentCount ();
259
+
260
+ // anonymous functions cannot be compared by name and argument count
261
+ if (
262
+ name == null || other .name == null ||
263
+ name .getLocalPart ().equals ("" ) ||
264
+ other .name .getLocalPart ().equals ("" )
265
+ ) {
266
+ return false ;
275
267
}
276
-
277
- return false ;
268
+
269
+ // compare by QName and arity
270
+ return (name .equals (other .name ) && getArgumentCount () == other .getArgumentCount ());
278
271
}
279
272
280
273
/**
0 commit comments