下面列出了com.fasterxml.jackson.databind.node.POJONode#com.fasterxml.jackson.databind.node.TextNode 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Activate
public void activate() {
KryoNamespace.Builder kryoBuilder = new KryoNamespace.Builder()
.register(KryoNamespaces.API)
.register(ConfigKey.class, ObjectNode.class, ArrayNode.class,
JsonNodeFactory.class, LinkedHashMap.class,
TextNode.class, BooleanNode.class,
LongNode.class, DoubleNode.class, ShortNode.class, IntNode.class,
NullNode.class);
configs = storageService.<ConfigKey, JsonNode>consistentMapBuilder()
.withSerializer(Serializer.using(kryoBuilder.build()))
.withName("onos-network-configs")
.withRelaxedReadConsistency()
.build();
configs.addListener(listener);
log.info("Started");
}
@Test
public void unknownAttributesAreIgnoredWhenDesserializing() throws Exception {
final EventType eventType = buildDefaultEventType();
final ObjectNode node = (ObjectNode) TestUtils.OBJECT_MAPPER.readTree(
TestUtils.OBJECT_MAPPER.writeValueAsString(eventType));
node.set("unknown_attribute", new TextNode("will just be ignored"));
final String eventTypeName = eventType.getName();
final String insertSQL = "INSERT INTO zn_data.event_type (et_name, et_event_type_object) " +
"VALUES (?, to_json(?::json))";
template.update(insertSQL,
eventTypeName,
TestUtils.OBJECT_MAPPER.writeValueAsString(node));
final EventType persistedEventType = repository.findByName(eventTypeName);
assertThat(persistedEventType, notNullValue());
}
@Override
public JsonNode sample() {
synchronized (this) {
if (dist == null) {
int r = power >= 0 ? Integer.MAX_VALUE : Integer.MIN_VALUE;
if (power >= 0) {
for (int i = 0; i <= power; i++) {
r = Math.min(r, min + base.nextInt(max - min));
}
} else {
int n = -power;
for (int i = 0; i <= n; i++) {
r = Math.max(r, min + base.nextInt(max - min));
}
}
if (format == null) {
return new IntNode(r);
} else {
return new TextNode(String.format(format, r));
}
} else {
return new LongNode(dist.sample());
}
}
}
/**
* Judge Java objects and create JsonNode.
*/
public static JsonNode get( final Object obj ) throws IOException {
if ( obj instanceof PrimitiveObject ) {
return PrimitiveObjectToJsonNode.get( (PrimitiveObject)obj );
} else if ( obj instanceof String ) {
return new TextNode( (String)obj );
} else if ( obj instanceof Boolean ) {
return BooleanNode.valueOf( (Boolean)obj );
} else if ( obj instanceof Short ) {
return IntNode.valueOf( ( (Short)obj ).intValue() );
} else if ( obj instanceof Integer ) {
return IntNode.valueOf( (Integer)obj );
} else if ( obj instanceof Long ) {
return new LongNode( (Long)obj );
} else if ( obj instanceof Float ) {
return new DoubleNode( ( (Float)obj ).doubleValue() );
} else if ( obj instanceof Double ) {
return new DoubleNode( (Double)obj );
} else if ( obj instanceof byte[] ) {
return new BinaryNode( (byte[])obj );
} else if ( obj == null ) {
return NullNode.getInstance();
} else {
return new TextNode( obj.toString() );
}
}
@Override
public InfoDTO deserialize(JsonParser jsonParser, DeserializationContext deserializationContext)
throws IOException {
InfoDTO infoDTO = new InfoDTO();
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
TreeNode treeNode = jsonParser.getCodec().readTree(jsonParser);
TextNode appNameNode = (TextNode) treeNode.get("appName");
infoDTO.setAppName(appNameNode.asText());
TextNode versionNode = (TextNode) treeNode.get("version");
infoDTO.setVersion(versionNode.asText());
TextNode dateNode = (TextNode) treeNode.get("date");
try {
infoDTO.setDate(sdf.parse(dateNode.asText()));
} catch (ParseException e) {
e.printStackTrace();
}
return infoDTO;
}
@SuppressWarnings("BooleanMethodIsAlwaysInverted")
private boolean addTimeFields(ObjectNode x) {
Event e = null;
while (e != Event.ACTION) {
e = step();
// System.out.printf("%8s/%-9s %11s %s %8.2f %8.2f %8.2f %8.2f\n",
// Util.isDaytime(Util.timeOfDay(now), sunriseTime, sunsetTime) ? "day" : "night",
// isActive ? "active" : "inactive",
// e, df.format((long) now),
// (nextQuery - now) / TimeUnit.HOURS.toMillis(1),
// (nextTransition - now) / TimeUnit.HOURS.toMillis(1),
// 24 * Util.fractionalPart((sunriseTime - Util.timeOfDay(now)) / TimeUnit.HOURS.toMillis(24)),
// 24 * Util.fractionalPart((sunsetTime - Util.timeOfDay(now)) / TimeUnit.HOURS.toMillis(24))
// );
if (e == Event.END) {
return false;
}
}
x.set("time", new TextNode(df.format((long) now)));
x.set("timestamp_ms", new LongNode((long) now));
x.set("timestamp_s", new LongNode((long) (now / 1000)));
return true;
}
public JsonNode perform(JsonNode v1, JsonNode v2) {
if (v1.isTextual() || v2.isTextual()) {
// if one operand is string: do string multiplication
String str;
int num;
if (v1.isTextual() && !v2.isTextual()) {
str = v1.asText();
num = v2.intValue();
} else if (v2.isTextual()) {
str = v2.asText();
num = v1.intValue();
} else
throw new JsltException("Can't multiply two strings!");
StringBuilder buf = new StringBuilder();
for ( ; num > 0; num--)
buf.append(str);
return new TextNode(buf.toString());
} else
// do numeric operation
return super.perform(v1, v2);
}
@Test
public void shouldReturnFailedFutureIfStoredBidRequestExtCouldNotBeParsed() {
// given
final ObjectNode ext = mapper.createObjectNode()
.set("prebid", new TextNode("non-ExtBidRequest"));
givenBidRequest(builder -> builder.ext(ext), Imp.builder().build());
// when
final Future<?> future = factory.fromRequest(routingContext, 0L);
// then
assertThat(future.failed()).isTrue();
assertThat(future.cause()).isInstanceOf(InvalidRequestException.class);
assertThat(((InvalidRequestException) future.cause()).getMessages())
.hasSize(1).element(0).asString().startsWith("Error decoding bidRequest.ext:");
}
@Test
public void shouldConvertStringPriceGranularityViewToCustom() {
// given
givenBidRequest(BidRequest.builder()
.imp(singletonList(Imp.builder().ext(mapper.createObjectNode()).build()))
.ext(mapper.valueToTree(ExtBidRequest.of(ExtRequestPrebid.builder()
.targeting(ExtRequestTargeting.builder().pricegranularity(new TextNode("low")).build())
.build())))
.build());
// when
final BidRequest request = factory.fromRequest(routingContext, 0L).result().getBidRequest();
// then
// request was wrapped to list because extracting method works different on iterable and not iterable objects,
// which force to make type casting or exception handling in lambdas
assertThat(singletonList(request))
.extracting(BidRequest::getExt)
.extracting(ext -> mapper.treeToValue(ext, ExtBidRequest.class))
.extracting(ExtBidRequest::getPrebid)
.extracting(ExtRequestPrebid::getTargeting)
.extracting(ExtRequestTargeting::getPricegranularity)
.containsOnly(mapper.valueToTree(ExtPriceGranularity.of(2, singletonList(ExtGranularityRange.of(
BigDecimal.valueOf(5), BigDecimal.valueOf(0.5))))));
}
@Test
public void shouldReturnFailedFutureWithInvalidRequestExceptionWhenStringPriceGranularityInvalid() {
// given
givenBidRequest(BidRequest.builder()
.imp(singletonList(Imp.builder().build()))
.ext(mapper.valueToTree(ExtBidRequest.of(ExtRequestPrebid.builder()
.targeting(ExtRequestTargeting.builder().pricegranularity(new TextNode("invalid")).build())
.build())))
.build());
// when
final Future<?> future = factory.fromRequest(routingContext, 0L);
// then
assertThat(future.failed()).isTrue();
assertThat(future.cause())
.isInstanceOf(InvalidRequestException.class)
.hasMessage("Invalid string price granularity with value: invalid");
}
@Test
public void cacheBidsOpenrtbShouldNotModifyVastXmlWhenBidIdIsNotInToModifyList() throws IOException {
// given
final com.iab.openrtb.response.Bid bid = givenBidOpenrtb(builder ->
builder.id("bid1").impid("impId1").adm("adm"));
final Imp imp1 = givenImp(builder -> builder.id("impId1").video(Video.builder().build()));
// when
cacheService.cacheBidsOpenrtb(singletonList(bid), singletonList(imp1),
CacheContext.builder()
.shouldCacheBids(true)
.shouldCacheVideoBids(true)
.bidderToVideoBidIdsToModify(singletonMap("bidder", singletonList("bid2")))
.bidderToBidIds(singletonMap("bidder", singletonList("bid1")))
.build(), account, eventsContext, timeout);
// then
final BidCacheRequest bidCacheRequest = captureBidCacheRequest();
assertThat(bidCacheRequest.getPuts()).hasSize(2)
.containsOnly(
PutObject.builder().type("json").value(mapper.valueToTree(bid)).build(),
PutObject.builder().type("xml").value(new TextNode("adm")).build());
}
private ObjectNode getComponentMeta(ClassLoader classLoader) {
Properties properties = loadComponentProperties(classLoader);
if (properties == null) {
return null;
}
String components = (String) properties.get("components");
if (components == null) {
return null;
}
String[] part = components.split("\\s", -1);
ObjectNode componentMeta = new ObjectNode(JsonNodeFactory.instance);
for (String scheme : part) {
// find the class name
String javaType = extractComponentJavaType(classLoader, scheme);
if (javaType == null) {
continue;
}
String schemeMeta = loadComponentJSonSchema(classLoader, scheme, javaType);
if (schemeMeta == null) {
continue;
}
componentMeta.set(scheme, new TextNode(schemeMeta));
}
return componentMeta.size() > 0 ? componentMeta : null;
}
@Override
public ObjectNode toJson(JsonProperty jsonProperty) {
Function<Object,JsonNode> nodeCreator = value -> new TextNode((String) value);
final ObjectNode propertyNode = primitiveJsonPropertyBuilder.forProperty(jsonProperty).withType("string").withDefaultAndAllowedValues(nodeCreator).build();
jsonProperty.getSizeConstraints().getMin().ifPresent(x -> propertyNode.put("minLength", x));
jsonProperty.getSizeConstraints().getMax().ifPresent(x -> propertyNode.put("maxLength", x));
if (jsonProperty.getFormat() != null) {
propertyNode.put("format", jsonProperty.getFormat());
}
if (jsonProperty.getPattern() != null) {
propertyNode.put("pattern", jsonProperty.getPattern());
}
return propertyNode;
}
@Test
public void testConvert() {
EnumConverter c = new EnumConverter(E1.class);
assertSame(E1.e11, c.value(new TextNode("e11")));
assertSame(E1.e12, c.value(new TextNode("e12")));
assertNull(c.value(new TextNode("")));
}
@Test
public void unionValue() throws Exception {
doReturn(TextNode.valueOf("bar")).when(obfuscator).apply(TextNode.valueOf("foo"));
JsonNode result = underTest.transform(f1Unnested, singletonList("/0/f1"));
assertThat(result, is(mapper.createObjectNode().put("f1", "bar")));
}
@Test
public void makeHttpRequestsShouldFailIfAdUnitBidParamsCouldNotBeParsed() {
// given
final ObjectNode params = mapper.createObjectNode();
params.set("secure", new TextNode("non-integer"));
adapterRequest = givenBidder(builder -> builder.params(params), identity());
// when and then
assertThatThrownBy(() -> adapter.makeHttpRequests(adapterRequest, preBidRequestContext))
.isExactlyInstanceOf(PreBidException.class)
.hasMessageStartingWith("Cannot deserialize value of type");
}
protected JsonNode resize(Context ctx, JsonNode node, boolean resizeWidth, int requested) {
String[] parts = splitDimensions(node);
if (parts == null || parts.length != 2) {
return new TextNode("Invalid source parameter. Pass in 'originalSize'.");
}
int width = Integer.parseInt(parts[0]);
int height = Integer.parseInt(parts[1]);
int value = 0;
if (resizeWidth) {
value = (int)(width * (requested / (float)height));
} else {
value = (int)(height * (requested / (float)width));
}
return new IntNode(value);
}
@Test
void testCheckJsonFieldValue() throws IOException
{
mockScriptActions(true);
codeSteps.checkJsonFieldValue(SCRIPT, NAME, VALUE);
verify(softAssert).assertNotNull(FIELD_WITH_THE_NAME_NAME_WAS_FOUND_IN_THE_JSON_OBJECT,
TextNode.valueOf(VALUE));
verify(softAssert).assertEquals(FIELD_VALUE_FROM_THE_JSON_OBJECT_IS_EQUAL_TO_VALUE, VALUE, VALUE);
}
void closeScroll(Iterable<String> scrollIds) {
Objects.requireNonNull(scrollIds, "scrollIds");
// delete current scroll
final URI uri = URI.create("/_search/scroll");
// http DELETE with payload
final HttpEntityEnclosingRequestBase request = new HttpEntityEnclosingRequestBase() {
@Override public String getMethod() {
return HttpDelete.METHOD_NAME;
}
};
request.setURI(uri);
final ObjectNode payload = mapper().createObjectNode();
// ES2 expects json array for DELETE scroll API
final ArrayNode array = payload.withArray("scroll_id");
StreamSupport.stream(scrollIds.spliterator(), false)
.map(TextNode::new)
.forEach(array::add);
try {
final String json = mapper().writeValueAsString(payload);
request.setEntity(new StringEntity(json, ContentType.APPLICATION_JSON));
rawHttp().apply(request);
} catch (IOException | UncheckedIOException e) {
LOGGER.warn("Failed to close scroll(s): {}", scrollIds, e);
}
}
private void processValueString() throws IOException {
Level child;
Level parent;
String value = null;
if(stack.isEmpty()) {
generator.writeString( parser.getText() );
return;
}
parent = stack.peek();
if( parent.isArray() ) {
ArrayNode array = (ArrayNode)parent.node;
array.add( parser.getText() );
if( bufferingLevel == null ) {
value = filterStreamValue( parent );
array.set( array.size()-1, new TextNode( value ) );
} else {
array.removeAll();
}
} else {
child = stack.pop();
parent = stack.peek();
((ObjectNode)parent.node ).put( child.field, parser.getText() );
if( bufferingLevel == null ) {
child.node = parent.node; // Populate the JsonNode of the child for filtering.
value = filterStreamValue( child );
}
}
if( bufferingLevel == null ) {
if( parent.node.isArray() ) {
((ArrayNode)parent.node).removeAll();
} else {
((ObjectNode)parent.node).removeAll();
}
generator.writeString( value );
}
}
public void testUpdateContentItem() throws Exception {
String contentItemId = createContentItem("test.pdf", "application/pdf", null,
"12345", null, null, "test", "test2");
ContentItem contentItem = contentService.createContentItemQuery().singleResult();
try {
ObjectNode requestNode = objectMapper.createObjectNode();
requestNode.put("name", "test2.txt");
requestNode.put("mimeType", "application/txt");
requestNode.put("createdBy", "testb");
requestNode.put("lastModifiedBy", "testc");
HttpPut httpPut = new HttpPut(SERVER_URL_PREFIX + ContentRestUrls.createRelativeResourceUrl(
ContentRestUrls.URL_CONTENT_ITEM, contentItemId));
httpPut.setEntity(new StringEntity(requestNode.toString()));
CloseableHttpResponse response = executeRequest(httpPut, HttpStatus.SC_OK);
JsonNode responseNode = objectMapper.readTree(response.getEntity().getContent());
closeResponse(response);
assertThatJson(responseNode)
.when(Option.IGNORING_EXTRA_FIELDS)
.isEqualTo("{"
+ " id: '" + contentItem.getId() + "',"
+ " name: 'test2.txt',"
+ " mimeType: 'application/txt',"
+ " taskId: null,"
+ " tenantId: '',"
+ " processInstanceId: '" + contentItem.getProcessInstanceId() + "',"
+ " created: " + new TextNode(getISODateStringWithTZ(contentItem.getCreated())) + ","
+ " createdBy: 'testb',"
+ " lastModified: " + new TextNode(getISODateStringWithTZ(contentItem.getLastModified())) + ","
+ " lastModifiedBy: 'testc'"
+ "}");
} finally {
contentService.deleteContentItem(contentItemId);
}
}
@Override
public JsonNode sample() {
while (true) {
int i = rand.nextInt(codes.size());
List<String> fields = values.get(codes.get(i));
if (keepTypes.contains(fields.get(names.indexOf("type")))) {
if (verbose) {
ObjectNode rx = new ObjectNode(nodeFactory);
Iterator<String> nx = names.iterator();
for (String field : fields) {
Preconditions.checkState(nx.hasNext());
String fieldName = nx.next();
if (keepFields.contains(fieldName)) {
rx.set(fieldName, new TextNode(field));
}
}
Preconditions.checkState(!nx.hasNext());
if (keepFields.contains("ssn")) {
rx.set("ssn", new TextNode(String.format("%s-%02d-%04d", codes.get(i), rand.nextInt(99) + 1, rand.nextInt(9999) + 1)));
}
return rx;
} else {
return new TextNode(String.format("%s-%02d-%04d", codes.get(i), rand.nextInt(99) + 1, rand.nextInt(9999) + 1));
}
}
}
}
private void consumeLocalReference(
final TextNode ref,
final VirtualFile containingFile,
Consumer<ResolvedRef> refConsumer,
final VirtualFile specFile) {
// We only need to inline references if we are in a referenced file.
if (!containingFile.equals(specFile)) {
final String jsonPointer = StringUtils.substringAfter(ref.asText(), "#");
final ResolvedRef resolvedRef = resolveJsonPointer(jsonPointer, containingFile);
consumeResolvedRef(refConsumer, specFile, resolvedRef);
}
}
/**
* Test getting a single task, spawned by a case. GET cmmn-runtime/tasks/{taskId}
*/
@CmmnDeployment(resources = { "org/flowable/cmmn/rest/service/api/repository/oneHumanTaskCase.cmmn" })
public void testGetCaseTask() throws Exception {
Calendar now = Calendar.getInstance();
cmmnEngineConfiguration.getClock().setCurrentTime(now.getTime());
CaseInstance caseInstance = runtimeService.createCaseInstanceBuilder().caseDefinitionKey("oneHumanTaskCase").start();
Task task = taskService.createTaskQuery().caseInstanceId(caseInstance.getId()).singleResult();
taskService.setDueDate(task.getId(), now.getTime());
taskService.setOwner(task.getId(), "owner");
task = taskService.createTaskQuery().caseInstanceId(caseInstance.getId()).singleResult();
assertThat(task).isNotNull();
String url = buildUrl(CmmnRestUrls.URL_TASK, task.getId());
CloseableHttpResponse response = executeRequest(new HttpGet(url), HttpStatus.SC_OK);
// Check resulting task
JsonNode responseNode = objectMapper.readTree(response.getEntity().getContent());
closeResponse(response);
assertThatJson(responseNode)
.when(Option.IGNORING_EXTRA_FIELDS)
.isEqualTo("{"
+ " id: '" + task.getId() + "',"
+ " assignee: '" + task.getAssignee() + "',"
+ " owner: '" + task.getOwner() + "',"
+ " formKey: '" + task.getFormKey() + "',"
+ " description: '" + task.getDescription() + "',"
+ " name: '" + task.getName() + "',"
+ " priority: " + task.getPriority() + ","
+ " parentTaskId: null,"
+ " delegationState: null,"
+ " tenantId: \"\","
+ " dueDate: " + new TextNode(getISODateStringWithTZ(task.getDueDate())) + ","
+ " createTime: " + new TextNode(getISODateStringWithTZ(task.getCreateTime())) + ","
+ " caseInstanceUrl: '" + buildUrl(CmmnRestUrls.URL_CASE_INSTANCE, task.getScopeId()) + "',"
+ " caseDefinitionUrl: '" + buildUrl(CmmnRestUrls.URL_CASE_DEFINITION, task.getScopeDefinitionId()) + "',"
+ " url: '" + url + "'"
+ "}");
}
@Test
void testMarker() throws Exception {
Marker parent = MarkerFactory.getMarker("parent");
Marker child = MarkerFactory.getMarker("child");
Marker grandchild = MarkerFactory.getMarker("grandchild");
child.add(grandchild);
parent.add(child);
logger.debug(parent, "test");
assertThat(getLastLogLine().get("tags")).contains(
TextNode.valueOf("parent"),
TextNode.valueOf("child"),
TextNode.valueOf("grandchild"));
}
@Override
public TextNode tinkerpopToJson(Object value) throws IOException {
if (value instanceof String) {
JsonNode result = objectMapper.readTree((String) value);
throwIfInvalid(result, this.allowedValues);
return (TextNode) result;
} else {
throw new IOException("should be a string");
}
}
/**
* Merge two JSON documents.
* @param src JsonNode to be merged
* @param target JsonNode to merge to
*/
public static void merge(JsonNode src, JsonNode target) {
Iterator<Map.Entry<String, JsonNode>> fields = src.fields();
while (fields.hasNext()) {
Map.Entry<String, JsonNode> entry = fields.next();
JsonNode subNode = entry.getValue();
switch (subNode.getNodeType()) {
case OBJECT:
writeObject(entry, target);
break;
case ARRAY:
writeArray(entry, target);
break;
case STRING:
updateObject(target, new TextNode(entry.getValue().textValue()), entry);
break;
case NUMBER:
updateObject(target, new IntNode(entry.getValue().intValue()), entry);
break;
case BOOLEAN:
updateObject(target, BooleanNode.valueOf(entry.getValue().booleanValue()), entry);
break;
default:
logger.warn("Unrecognized data type {} "+subNode.getNodeType());
}
}
}
private String dealDefaultConfig(String detail, String defaultConfig) {
try {
ObjectNode defaultNode = (ObjectNode) MAPPER.readTree(defaultConfig);
Iterator<Map.Entry<String, JsonNode>> fields = defaultNode.fields();
Map<String, String> defaults = Maps.newHashMap();
Map<String, String> readonly = Maps.newHashMap();
while (fields.hasNext()) {
Map.Entry<String, JsonNode> field = fields.next();
defaults.put(field.getKey(), field.getValue().get(TemplateContants.DEFAULT).asText());
readonly.put(field.getKey(), field.getValue().get(TemplateContants.READONLY).asText());
}
ObjectNode detailNode = (ObjectNode) MAPPER.readTree(detail);
JsonNode columns = detailNode.get(Constants.COLUMNS);
for (JsonNode node : columns) {
ObjectNode columnNode = (ObjectNode) node;
String name = columnNode.get(TemplateContants.NAME).asText();
if (defaults.containsKey(name)) {
columnNode.set(TemplateContants.DEFAULT, new TextNode(defaults.get(name)));
columnNode.set(TemplateContants.READONLY,
BooleanNode.valueOf(Boolean.parseBoolean(readonly.get(name))));
}
}
return MAPPER.writeValueAsString(detailNode);
} catch (Exception e) {
LOG.error("parse template with default error, default is [%s], detail is [%s]", defaultConfig, detail, e);
throw new IllegalStateException("解析模版失败");
}
}
/**
* Verify that the Helios master generates and returns a hash if the submitted job creation
* request does not include one.
*/
@Test
public void testHashLessJobCreation() throws Exception {
startDefaultMaster();
final Job job = Job.newBuilder()
.setName(testJobName)
.setVersion(testJobVersion)
.setImage(BUSYBOX)
.setCommand(IDLE_COMMAND)
.setCreatingUser(TEST_USER)
.build();
// Remove the hash from the id in the json serialized job
final ObjectNode json = (ObjectNode) Json.reader().readTree(Json.asString(job));
json.set("id", TextNode.valueOf(testJobName + ":" + testJobVersion));
final HttpURLConnection req = post("/jobs?user=" + TEST_USER,
Json.asBytes(json));
assertEquals(req.getResponseCode(), 200);
final CreateJobResponse res = Json.read(toByteArray(req.getInputStream()),
CreateJobResponse.class);
assertEquals(OK, res.getStatus());
assertTrue(res.getErrors().isEmpty());
assertEquals(job.getId().toString(), res.getId());
}
public JsonNode call(JsonNode input, JsonNode[] arguments) {
String string = NodeUtils.toString(arguments[0], true);
if (string == null)
return NullNode.instance;
String regexp = NodeUtils.toString(arguments[1], false);
String sep = NodeUtils.toString(arguments[2], false);
Pattern p = getRegexp(regexp);
Matcher m = p.matcher(string);
char[] buf = new char[string.length() * Math.max(sep.length(), 1)];
int pos = 0; // next untouched character in input
int bufix = 0; // next unwritten character in buf
while (m.find(pos)) {
// we found another match, and now matcher state has been updated
if (m.start() == m.end())
throw new JsltException("Regexp " + regexp + " in replace() matched empty string in '" + arguments[0] + "'");
// if there was text between pos and start of match, copy to output
if (pos < m.start())
bufix = copy(string, buf, bufix, pos, m.start());
// copy sep to output (corresponds with the match)
bufix = copy(sep, buf, bufix, 0, sep.length());
// step over match
pos = m.end();
}
if (pos == 0 && arguments[0].isTextual())
// there were matches, so the string hasn't changed
return arguments[0];
else if (pos < string.length())
// there was text remaining after the end of the last match. must copy
bufix = copy(string, buf, bufix, pos, string.length());
return new TextNode(new String(buf, 0, bufix));
}