Skip to content

Commit 4c77620

Browse files
committed
[refactor] Simplify fn:replace; no need for it to extend fn:matches since it was changed to use Saxon
1 parent 3892ebe commit 4c77620

File tree

2 files changed

+39
-106
lines changed

2 files changed

+39
-106
lines changed

exist-core/src/main/java/org/exist/xquery/functions/fn/FnModule.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -181,8 +181,8 @@ public class FnModule extends AbstractInternalModule {
181181
new FunctionDef(FunPosition.signature, FunPosition.class),
182182
new FunctionDef(FunQName.signature, FunQName.class),
183183
new FunctionDef(FunRemove.signature, FunRemove.class),
184-
new FunctionDef(FunReplace.signatures[0], FunReplace.class),
185-
new FunctionDef(FunReplace.signatures[1], FunReplace.class),
184+
new FunctionDef(FunReplace.FS_REPLACE[0], FunReplace.class),
185+
new FunctionDef(FunReplace.FS_REPLACE[1], FunReplace.class),
186186
new FunctionDef(FunReverse.signature, FunReverse.class),
187187
new FunctionDef(FunResolveURI.signatures[0], FunResolveURI.class),
188188
new FunctionDef(FunResolveURI.signatures[1], FunResolveURI.class),

exist-core/src/main/java/org/exist/xquery/functions/fn/FunReplace.java

Lines changed: 37 additions & 104 deletions
Original file line numberDiff line numberDiff line change
@@ -28,44 +28,29 @@
2828
import net.sf.saxon.functions.Replace;
2929
import net.sf.saxon.regex.RegularExpression;
3030
import org.exist.dom.QName;
31-
import org.exist.xquery.Atomize;
32-
import org.exist.xquery.Cardinality;
33-
import org.exist.xquery.Dependency;
34-
import org.exist.xquery.DynamicCardinalityCheck;
35-
import org.exist.xquery.ErrorCodes;
36-
import org.exist.xquery.Expression;
37-
import org.exist.xquery.Function;
38-
import org.exist.xquery.FunctionSignature;
39-
import org.exist.xquery.Profiler;
40-
import org.exist.xquery.XPathException;
41-
import org.exist.xquery.XQueryContext;
42-
import org.exist.xquery.util.Error;
31+
import org.exist.xquery.*;
4332
import org.exist.xquery.value.FunctionParameterSequenceType;
44-
import org.exist.xquery.value.FunctionReturnSequenceType;
45-
import org.exist.xquery.value.Item;
4633
import org.exist.xquery.value.Sequence;
47-
import org.exist.xquery.value.SequenceType;
4834
import org.exist.xquery.value.StringValue;
4935
import org.exist.xquery.value.Type;
5036

37+
import static org.exist.xquery.FunctionDSL.*;
5138
import static org.exist.xquery.regex.RegexUtil.*;
5239

5340
/**
5441
* @author <a href="mailto:[email protected]">Adam Retter</a>
5542
* @author <a href="mailto:[email protected]">Wolfgang Meier</a>
5643
*/
57-
public class FunReplace extends FunMatches {
58-
59-
private static final String FUNCTION_DESCRIPTION_3_PARAM =
60-
"The function returns the xs:string that is obtained by replacing each non-overlapping substring " +
61-
"of $input that matches the given $pattern with an occurrence of the $replacement string.\n\n";
62-
private static final String FUNCTION_DESCRIPTION_4_PARAM =
44+
public class FunReplace extends BasicFunction {
45+
46+
private static final QName FS_REPLACE_NAME = new QName("replace", Function.BUILTIN_FUNCTION_NS);
47+
48+
private static final String FS_REPLACE_DESCRIPTION =
6349
"The function returns the xs:string that is obtained by replacing each non-overlapping substring " +
6450
"of $input that matches the given $pattern with an occurrence of the $replacement string.\n\n" +
6551
"The $flags argument is interpreted in the same manner as for the fn:matches() function.\n\n" +
6652
"Calling the four argument version with the $flags argument set to a " +
67-
"zero-length string gives the same effect as using the three argument version.\n\n";
68-
private static final String FUNCTION_DESCRIPTION_COMMON =
53+
"zero-length string gives the same effect as using the three argument version.\n\n" +
6954
"If $input is the empty sequence, it is interpreted as the zero-length string.\n\nIf two overlapping " +
7055
"substrings of $input both match the $pattern, then only the first one (that is, the one whose first " +
7156
"character comes first in the $input string) is replaced.\n\nWithin the $replacement string, a variable " +
@@ -85,96 +70,49 @@ public class FunReplace extends FunMatches {
8570
"included \"as is\" in the replacement string, and the rules are reapplied using the number N " +
8671
"formed by stripping off this last digit.";
8772

88-
protected static final FunctionParameterSequenceType INPUT_ARG = new FunctionParameterSequenceType("input", Type.STRING, Cardinality.ZERO_OR_ONE, "The input string");
89-
protected static final FunctionParameterSequenceType PATTERN_ARG = new FunctionParameterSequenceType("pattern", Type.STRING, Cardinality.EXACTLY_ONE, "The pattern to match");
90-
protected static final FunctionParameterSequenceType REPLACEMENT_ARG = new FunctionParameterSequenceType("replacement", Type.STRING, Cardinality.EXACTLY_ONE, "The string to replace the pattern with");
91-
protected static final FunctionParameterSequenceType FLAGS_ARG = new FunctionParameterSequenceType("flags", Type.STRING, Cardinality.EXACTLY_ONE, "The flags");
92-
protected static final FunctionReturnSequenceType RETURN_TYPE = new FunctionReturnSequenceType(Type.STRING, Cardinality.EXACTLY_ONE, "the altered string");
93-
94-
public final static FunctionSignature[] signatures = {
95-
new FunctionSignature(
96-
new QName("replace", Function.BUILTIN_FUNCTION_NS),
97-
FUNCTION_DESCRIPTION_3_PARAM + FUNCTION_DESCRIPTION_COMMON,
98-
new SequenceType[] { INPUT_ARG, PATTERN_ARG, REPLACEMENT_ARG },
99-
RETURN_TYPE
100-
),
101-
new FunctionSignature(
102-
new QName("replace", Function.BUILTIN_FUNCTION_NS),
103-
FUNCTION_DESCRIPTION_4_PARAM + FUNCTION_DESCRIPTION_COMMON,
104-
new SequenceType[] { INPUT_ARG, PATTERN_ARG, REPLACEMENT_ARG, FLAGS_ARG },
105-
RETURN_TYPE
106-
)
107-
};
73+
private static final FunctionParameterSequenceType FS_TOKENIZE_PARAM_INPUT = optParam("input", Type.STRING, "The input string");
74+
private static final FunctionParameterSequenceType FS_TOKENIZE_PARAM_PATTERN = param("pattern", Type.STRING, "The pattern to match");
75+
private static final FunctionParameterSequenceType FS_TOKENIZE_PARAM_REPLACEMENT = param("replacement", Type.STRING, "The string to replace the pattern with");
76+
77+
static final FunctionSignature [] FS_REPLACE = functionSignatures(
78+
FS_REPLACE_NAME,
79+
FS_REPLACE_DESCRIPTION,
80+
returns(Type.STRING, "the altered string"),
81+
arities(
82+
arity(
83+
FS_TOKENIZE_PARAM_INPUT,
84+
FS_TOKENIZE_PARAM_PATTERN,
85+
FS_TOKENIZE_PARAM_REPLACEMENT
86+
),
87+
arity(
88+
FS_TOKENIZE_PARAM_INPUT,
89+
FS_TOKENIZE_PARAM_PATTERN,
90+
FS_TOKENIZE_PARAM_REPLACEMENT,
91+
param("flags", Type.STRING, Cardinality.EXACTLY_ONE, "The flags")
92+
)
93+
)
94+
);
10895

10996
public FunReplace(final XQueryContext context, final FunctionSignature signature) {
11097
super(context, signature);
11198
}
112-
113-
@Override
114-
public void setArguments(List<Expression> arguments) {
115-
steps.clear();
116-
Expression arg = arguments.get(0);
117-
arg = new DynamicCardinalityCheck(context, Cardinality.ZERO_OR_ONE, arg,
118-
new Error(Error.FUNC_PARAM_CARDINALITY, "1", getSignature()));
119-
if(!Type.subTypeOf(arg.returnsType(), Type.ATOMIC))
120-
{arg = new Atomize(context, arg);}
121-
steps.add(arg);
122-
123-
arg = arguments.get(1);
124-
arg = new DynamicCardinalityCheck(context, Cardinality.EXACTLY_ONE, arg,
125-
new Error(Error.FUNC_PARAM_CARDINALITY, "2", getSignature()));
126-
if(!Type.subTypeOf(arg.returnsType(), Type.ATOMIC))
127-
{arg = new Atomize(context, arg);}
128-
steps.add(arg);
129-
130-
arg = arguments.get(2);
131-
arg = new DynamicCardinalityCheck(context, Cardinality.EXACTLY_ONE, arg,
132-
new Error(Error.FUNC_PARAM_CARDINALITY, "3", getSignature()));
133-
if(!Type.subTypeOf(arg.returnsType(), Type.ATOMIC))
134-
{arg = new Atomize(context, arg);}
135-
steps.add(arg);
136-
137-
if (arguments.size() == 4) {
138-
arg = arguments.get(3);
139-
arg = new DynamicCardinalityCheck(context, Cardinality.EXACTLY_ONE, arg,
140-
new Error(Error.FUNC_PARAM_CARDINALITY, "4", getSignature()));
141-
if(!Type.subTypeOf(arg.returnsType(), Type.ATOMIC))
142-
{arg = new Atomize(context, arg);}
143-
steps.add(arg);
144-
}
145-
}
14699

147100
@Override
148-
public Sequence eval(final Sequence contextSequence, final Item contextItem) throws XPathException {
149-
if (context.getProfiler().isEnabled()) {
150-
context.getProfiler().start(this);
151-
context.getProfiler().message(this, Profiler.DEPENDENCIES, "DEPENDENCIES", Dependency.getDependenciesName(this.getDependencies()));
152-
if (contextSequence != null) {
153-
context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT SEQUENCE", contextSequence);
154-
}
155-
if (contextItem != null) {
156-
context.getProfiler().message(this, Profiler.START_SEQUENCES, "CONTEXT ITEM", contextItem.toSequence());
157-
}
158-
}
159-
101+
public Sequence eval(final Sequence[] args, final Sequence contextSequence) throws XPathException {
160102
final Sequence result;
161-
final Sequence stringArg = getArgument(0).eval(contextSequence, contextItem);
103+
final Sequence stringArg = args[0];
162104
if (stringArg.isEmpty()) {
163105
result = StringValue.EMPTY_STRING;
164106
} else {
165107
final String flags;
166-
if (getSignature().getArgumentCount() == 4) {
167-
flags = getArgument(3).eval(contextSequence, contextItem).getStringValue();
108+
if (args.length == 4) {
109+
flags = args[3].itemAt(0).getStringValue();
168110
} else {
169111
flags = "";
170112
}
171-
172113
final String string = stringArg.getStringValue();
173-
final Sequence patternSeq = getArgument(1).eval(contextSequence, contextItem);
174-
final String pattern = patternSeq.getStringValue();
175-
176-
final Sequence replaceSeq = getArgument(2).eval(contextSequence, contextItem);
177-
final String replace = replaceSeq.getStringValue();
114+
final String pattern = args[1].itemAt(0).getStringValue();
115+
final String replace = args[2].itemAt(0).getStringValue();
178116

179117
final Configuration config = context.getBroker().getBrokerPool().getSaxonConfiguration();
180118

@@ -210,11 +148,6 @@ public Sequence eval(final Sequence contextSequence, final Item contextItem) thr
210148
}
211149
}
212150

213-
if (context.getProfiler().isEnabled()) {
214-
context.getProfiler().end(this, "", result);
215-
}
216-
217-
return result;
218-
151+
return result;
219152
}
220153
}

0 commit comments

Comments
 (0)