Example usage for java.lang StringBuilder replace

List of usage examples for java.lang StringBuilder replace

Introduction

In this page you can find the example usage for java.lang StringBuilder replace.

Prototype

@Override
public StringBuilder replace(int start, int end, String str) 

Source Link

Usage

From source file:dk.dma.ais.abnormal.event.db.jpa.JpaEventRepository.java

@Override
public List<Event> findEventsByFromAndToAndTypeAndVesselAndArea(Date from, Date to, String type, String vessel,
        Double north, Double east, Double south, Double west) {
    Session session = getSession();/* ww  w.  j  a  va  2s .  com*/

    boolean usesFrom = false, usesTo = false, usesType = false, usesVessel = false, usesArea = false;

    List events = null;
    try {
        StringBuilder hql = new StringBuilder();

        hql.append("SELECT DISTINCT e FROM Event e ");

        if (!StringUtils.isBlank(vessel)) {
            hql.append("LEFT JOIN e.behaviours AS b ");
        }

        if (north != null && east != null && south != null && west != null) {
            hql.append(
                    "LEFT JOIN e.behaviours AS b LEFT JOIN b.trackingPoints AS tp WHERE e.suppressed=false AND latitude<:north AND latitude>:south AND longitude<:east AND longitude>:west AND ");
            usesArea = true;
        } else {
            hql.append("WHERE e.suppressed=false AND ");
        }

        // from
        if (from != null) {
            hql.append("(e.startTime >= :from OR e.endTime >= :from) AND ");
            usesFrom = true;
        }

        // to
        if (to != null) {
            hql.append("(e.startTime <= :to OR e.endTime <= :to) AND ");
            usesTo = true;
        }

        // type
        if (!StringUtils.isBlank(type)) {
            hql.append("TYPE(e) IN (:classes) AND ");
            usesType = true;
        }

        // vessel
        if (!StringUtils.isBlank(vessel)) {
            hql.append("(");
            hql.append("b.vessel.callsign LIKE :vessel OR ");
            hql.append("b.vessel.name LIKE :vessel OR ");
            try {
                Long vesselAsLong = Long.valueOf(vessel);
                hql.append("b.vessel.mmsi = :vessel OR ");
                hql.append("b.vessel.imo = :vessel OR ");
            } catch (NumberFormatException e) {
            }
            hql.replace(hql.length() - 3, hql.length(), ")"); // "OR " -> ")"
            if (!vessel.startsWith("%")) {
                vessel = "%" + vessel;
            }
            if (!vessel.endsWith("%")) {
                vessel = vessel + "%";
            }
            usesVessel = true;
        }

        //
        String hqlAsString = hql.toString().trim();
        if (hqlAsString.endsWith("AND")) {
            hqlAsString = hqlAsString.substring(0, hqlAsString.lastIndexOf("AND"));
        }

        //
        Query query = session.createQuery(hqlAsString);
        if (usesArea) {
            query.setParameter("north", north);
            query.setParameter("east", east);
            query.setParameter("south", south);
            query.setParameter("west", west);
        }
        if (usesFrom) {
            query.setParameter("from", from);
        }
        if (usesTo) {
            query.setParameter("to", to);
        }
        if (usesType) {
            String className = "dk.dma.ais.abnormal.event.db.domain." + type;
            try {
                Class clazz = Class.forName(className);
                query.setParameter("classes", clazz);
            } catch (ClassNotFoundException e) {
                throw new IllegalArgumentException("Class " + className + " not found.");
            }
        }
        if (usesVessel) {
            query.setParameter("vessel", vessel);
        }

        LOG.debug("Query: " + query.toString());
        final long t0 = currentTimeMillis();
        events = query.list();
        final long t1 = currentTimeMillis();
        LOG.debug("Found " + events.size() + " matching events in " + (t1 - t0) + " msecs.");
    } finally {
        session.close();
        LOG.debug("Database session closed: " + session);
    }

    return events;
}

From source file:org.moe.natjgen.XcodeFullDocumentation.java

private String prettyString(StringBuilder capture) {
    if (capture.length() == 0)
        return null;

    // Remove heading new-lines
    while (capture.length() == 0 && (capture.charAt(0) == '\n' || capture.charAt(0) == '\r')) {
        capture.deleteCharAt(0);/*ww  w.  j  a v a  2 s.c  o  m*/
    }

    // Remove trailing new-lines
    while (capture.length() == 0
            && (capture.charAt(capture.length() - 1) == '\n' || capture.charAt(capture.length() - 1) == '\r')) {
        capture.deleteCharAt(capture.length() - 1);
    }

    String htmlencoded = StringEscapeUtils.escapeHtml4(capture.toString());
    String[] words = htmlencoded.split("\\s+");

    // Try to create lines with the maximum length of MAX_LINE_WIDTH
    capture.setLength(0);
    int lineLength = 0;
    for (String word : words) {
        if (lineLength > 0) {
            if (lineLength + word.length() > MAX_LINE_WIDTH) {
                capture.append("\n");
                lineLength = 0;
            } else {
                capture.append(" ");
            }
        }
        capture.append(word);
        lineLength += word.length();
    }

    for (HTMLTagReplacement replacement : replacements) {
        replaceAll(capture, replacement.openPlaceholder, replacement.openHtml);
        replaceAll(capture, replacement.closePlaceholder, replacement.closeHtml);
    }
    replaceAll(capture, "/*", "&#47;*");
    replaceAll(capture, "*/", "*&#47;");

    for (int i = 0; i < capture.length(); ++i) {
        char c = capture.charAt(i);
        if (!CharUtils.isAscii(c)) {
            capture.replace(i, i + 1, "&#x;");
            capture.insert(i + 3, String.format("%04X", new Integer(c)));
            i += 7;
        }
    }

    return capture.toString();
}

From source file:org.apache.drill.common.expression.fn.JodaDateValidator.java

/**
 * Replaces all postgres patterns from {@param pattern},
 * available in postgresToJodaMap keys to jodaTime equivalents.
 *
 * @param pattern date pattern in postgres format
 * @return date pattern with replaced patterns in joda format
 *///from  ww w . j a  v a  2s .  c  o m
public static String toJodaFormat(String pattern) {
    // replaces escape character for text delimiter
    StringBuilder builder = new StringBuilder(
            pattern.replaceAll(POSTGRES_ESCAPE_CHARACTER, JODA_ESCAPE_CHARACTER));

    int start = 0; // every time search of postgres token in pattern will start from this index.
    int minPos; // min position of the longest postgres token
    do {
        // finds first value with max length
        minPos = builder.length();
        PostgresDateTimeConstant firstMatch = null;
        for (PostgresDateTimeConstant postgresPattern : postgresToJodaMap.keySet()) {
            // keys sorted in length decreasing
            // at first search longer tokens to consider situation where some tokens are the parts of large tokens
            // example: if pattern contains a token "DDD", token "DD" would be skipped, as a part of "DDD".
            int pos;
            // some tokens can't be in upper camel casing, so we ignore them here.
            // example: DD, DDD, MM, etc.
            if (postgresPattern.hasCamelCasing()) {
                // finds postgres tokens in upper camel casing
                // example: Month, Mon, Day, Dy, etc.
                pos = builder.indexOf(StringUtils.capitalize(postgresPattern.getName()), start);
                if (pos >= 0 && pos < minPos) {
                    firstMatch = postgresPattern;
                    minPos = pos;
                    if (minPos == start) {
                        break;
                    }
                }
            }
            // finds postgres tokens in lower casing
            pos = builder.indexOf(postgresPattern.getName().toLowerCase(), start);
            if (pos >= 0 && pos < minPos) {
                firstMatch = postgresPattern;
                minPos = pos;
                if (minPos == start) {
                    break;
                }
            }
            // finds postgres tokens in upper casing
            pos = builder.indexOf(postgresPattern.getName().toUpperCase(), start);
            if (pos >= 0 && pos < minPos) {
                firstMatch = postgresPattern;
                minPos = pos;
                if (minPos == start) {
                    break;
                }
            }
        }
        // replaces postgres token, if found and it does not escape character
        if (minPos < builder.length() && firstMatch != null) {
            String jodaToken = postgresToJodaMap.get(firstMatch);
            // checks that token is not a part of escape sequence
            if (StringUtils.countMatches(builder.subSequence(0, minPos), JODA_ESCAPE_CHARACTER) % 2 == 0) {
                int offset = minPos + firstMatch.getName().length();
                builder.replace(minPos, offset, jodaToken);
                start = minPos + jodaToken.length();
            } else {
                int endEscapeCharacter = builder.indexOf(JODA_ESCAPE_CHARACTER, minPos);
                if (endEscapeCharacter >= 0) {
                    start = endEscapeCharacter;
                } else {
                    break;
                }
            }
        }
    } while (minPos < builder.length());
    return builder.toString();
}

From source file:com.cimpoint.mes.server.services.RoutingServiceImpl.java

@Override
public String findAllModelNamesAsJSON() throws Exception {
    StringBuilder buffer = new StringBuilder();
    buffer.append("[" + NL);

    Set<String> siteNames = findAllSiteNames();
    buildJSONBuffer(siteNames, buffer);/*  w ww  .  j  ava 2  s.co m*/

    Set<String> areaNames = findAllAreaNames();
    buildJSONBuffer(areaNames, buffer);

    Set<String> productionLineNames = findAllProductionLineNames();
    buildJSONBuffer(productionLineNames, buffer);

    Set<String> workCenterNames = findAllWorkCenterNames();
    buildJSONBuffer(workCenterNames, buffer);

    Set<String> equipmentNames = findAllEquipmentNames();
    buildJSONBuffer(equipmentNames, buffer);

    Set<String> routingNames = findAllRoutingNames();
    buildJSONBuffer(routingNames, buffer);

    //remove the last commas
    if (buffer.length() > 1 && buffer.substring(buffer.length() - 1, buffer.length()).equals(",")) {
        buffer.replace(buffer.length() - 1, buffer.length(), "");
    }

    buffer.append("]" + NL);

    return buffer.toString();
}

From source file:com.opensource.frameworks.processframework.utils.PropertyPlaceholderHelper.java

protected String parseStringValue(String strVal, PlaceholderResolver placeholderResolver,
        Set<String> visitedPlaceholders) {

    StringBuilder buf = new StringBuilder(strVal);

    int startIndex = strVal.indexOf(this.placeholderPrefix);
    while (startIndex != -1) {
        int endIndex = findPlaceholderEndIndex(buf, startIndex);
        if (endIndex != -1) {
            String placeholder = buf.substring(startIndex + this.placeholderPrefix.length(), endIndex);
            if (!visitedPlaceholders.add(placeholder)) {
                throw new IllegalArgumentException(
                        "Circular placeholder reference '" + placeholder + "' in property definitions");
            }/*from   w w w.  j  a v  a2  s.  c om*/
            // Recursive invocation, parsing placeholders contained in the placeholder key.
            placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);

            // Now obtain the value for the fully resolved key...
            String propVal = placeholderResolver.resolvePlaceholder(placeholder);
            if (propVal == null && this.valueSeparator != null) {
                int separatorIndex = placeholder.indexOf(this.valueSeparator);
                if (separatorIndex != -1) {
                    String actualPlaceholder = placeholder.substring(0, separatorIndex);
                    String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length());
                    propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder);
                    if (propVal == null) {
                        propVal = defaultValue;
                    }
                }
            }
            if (propVal != null) {
                // Recursive invocation, parsing placeholders contained in the
                // previously resolved placeholder value.
                propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);
                buf.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
                if (logger.isTraceEnabled()) {
                    logger.trace("Resolved placeholder '" + placeholder + "'");
                }
                startIndex = buf.indexOf(this.placeholderPrefix, startIndex + propVal.length());
            } else if (this.ignoreUnresolvablePlaceholders) {
                // Proceed with unprocessed value.
                startIndex = buf.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());
            } else {
                throw new IllegalArgumentException("Could not resolve placeholder '" + placeholder + "'");
            }

            visitedPlaceholders.remove(placeholder);
        } else {
            startIndex = -1;
        }
    }

    return buf.toString();
}

From source file:sapience.injectors.stax.inject.StringBasedStaxStreamInjector.java

/**
 * Helper method, taking a XML string like <ows:Metadata xmlns:ows=\"http://ogc.org/ows\" xmlns:xlink=\"http://wrc.org/xlink\" 
 * xlink:href=\"http://dude.com\"></ows:Metadata> from the reference 
 * and checks if //from w w  w  .j  a  va2 s . com
 * a  the used prefixes match the globally used ones and
 * b) any of the declared namespaces are redundant 
 * 
 * The same is true for the XPath definition
 * 
 * @param resultingXMLString
 * @param context
 */
private void processNamespace(StringBuilder sb, NamespaceContext global, LocalNamespaceContext local) {

    Matcher prefixMatcher = prefixPattern.matcher(sb);
    Matcher nsMatcher = nsPattern.matcher(sb);
    String prefix;
    String uri;

    /* process the local namespaces */
    while (nsMatcher.find()) {
        int start = nsMatcher.start();
        int end = nsMatcher.end();
        StringBuilder sbu = new StringBuilder(sb.substring(start, end));
        String thisPrefix = sbu.substring(sbu.indexOf(":") + 1, sbu.lastIndexOf("="));
        String thisUri = sbu.substring(sbu.indexOf("\"") + 1, sbu.lastIndexOf("\""));
        // add to local namespace context
        local.put(thisPrefix, thisUri);

        if ((prefix = global.getPrefix(thisUri)) != null) {
            // namespace is registered, let's remove it
            sb.delete(start - 1, end);

            // we have to reset, since we changed the state of the matched string with the deletion
            nsMatcher.reset();
        }

    }

    /* change the prefixes */
    try {
        while (prefixMatcher.find()) {
            int start = prefixMatcher.start();
            int end = prefixMatcher.end();

            String localprefix = sb.substring(start + 1, end - 1);
            if ((global.getNamespaceURI(localprefix) == null)
                    && (uri = local.getNamespaceURI(localprefix)) != null) {
                // get the other prefix
                prefix = global.getPrefix(uri);

                if ((prefix != null) && (!(localprefix.contentEquals(prefix)))) {
                    sb.replace(start + 1, end - 1, prefix);
                    prefixMatcher.reset();
                }
            }
        }
    } catch (StringIndexOutOfBoundsException e) {
        // we do nothing here
    }

}

From source file:com.harrywu.springweb.common.PropertyPlaceholderHelper.java

protected String parseStringValue(String strVal, StringValueResolver placeholderResolver,
        Set<String> visitedPlaceholders) {

    StringBuilder buf = new StringBuilder(strVal);

    int startIndex = strVal.indexOf(this.placeholderPrefix);
    while (startIndex != -1) {
        int endIndex = findPlaceholderEndIndex(buf, startIndex);
        if (endIndex != -1) {
            String placeholder = buf.substring(startIndex + this.placeholderPrefix.length(), endIndex);
            if (!visitedPlaceholders.add(placeholder)) {
                throw new IllegalArgumentException(
                        "Circular placeholder reference '" + placeholder + "' in property definitions");
            }/* w w  w . j  av  a 2s.  c om*/
            // Recursive invocation, parsing placeholders contained in the placeholder key.
            placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);

            // Now obtain the value for the fully resolved key...
            String propVal = placeholderResolver.resolveStringValue(placeholder);
            if (propVal == null && this.valueSeparator != null) {
                int separatorIndex = placeholder.indexOf(this.valueSeparator);
                if (separatorIndex != -1) {
                    String actualPlaceholder = placeholder.substring(0, separatorIndex);
                    String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length());
                    propVal = placeholderResolver.resolveStringValue(actualPlaceholder);
                    if (propVal == null) {
                        propVal = defaultValue;
                    }
                }
            }
            if (propVal != null) {
                // Recursive invocation, parsing placeholders contained in the
                // previously resolved placeholder value.
                propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);
                buf.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);

                if (logger.isTraceEnabled()) {
                    logger.trace("Resolved placeholder '" + placeholder + "'");
                }

                startIndex = buf.indexOf(this.placeholderPrefix, startIndex + propVal.length());
            } else if (this.ignoreUnresolvablePlaceholders) {
                // Proceed with unprocessed value.
                startIndex = buf.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());
            } else {
                throw new IllegalArgumentException("Could not resolve placeholder '" + placeholder + "'");
            }

            visitedPlaceholders.remove(placeholder);
        } else {
            startIndex = -1;
        }
    }

    return buf.toString();
}

From source file:it.unibas.spicy.model.algebra.query.operators.xquery.GenerateXQueryForSourceToTargetExchange.java

private String projectionOnValues(MappingTask mappingTask, FORule tgd) {
    StringBuilder result = new StringBuilder();
    List<VariablePathExpression> generatedAttributes = new ArrayList<VariablePathExpression>();

    List<SetAlias> generators = tgd.getTargetView().getGenerators();
    for (int i = 0; i < generators.size(); i++) {
        SetAlias generator = generators.get(i);
        List<VariablePathExpression> attributes = generator
                .getAttributes(mappingTask.getTargetProxy().getIntermediateSchema());
        for (int j = 0; j < attributes.size(); j++) {
            VariablePathExpression attribute = attributes.get(j);
            if (generatedAttributes.contains(attribute)) {
                continue;
            }/*  w w w . j a  v a  2s.  co  m*/
            generatedAttributes.add(attribute);
            IValueGenerator leafGenerator = getLeafGenerator(attribute, tgd, mappingTask, generator);

            String elementName = XQNames.xQueryNameForPath(attribute);
            result.append(DOUBLE_INDENT).append(DOUBLE_INDENT).append("element ").append(elementName)
                    .append(" {");
            result.append(XQUtility.xqueryValueForLeaf(leafGenerator, attribute, tgd, mappingTask));
            result.append("}");
            result.append(",\n");
        }
    }
    result.replace(result.length() - 2, result.length(), " ");
    result.append("\n");
    return result.toString();
}

From source file:de.tudarmstadt.ukp.clarin.webanno.tsv.WebannoCustomTsvReader.java

/**
 * Iterate through lines and create span annotations accordingly. For multiple span annotation,
 * based on the position of the annotation in the line, update only the end position of the
 * annotation/*from   w  w  w .j a  va  2 s  .c o  m*/
 */
private void setAnnotations(JCas aJcas, InputStream aIs, String aEncoding, StringBuilder text)
        throws IOException {

    // getting header information
    LineIterator lineIterator = IOUtils.lineIterator(aIs, aEncoding);
    int columns = 1;// token number + token columns (minimum required)
    int tokenStart = 0, sentenceStart = 0;
    Map<Type, Set<Feature>> spanLayers = new LinkedHashMap<Type, Set<Feature>>();
    Map<Type, Type> relationayers = new LinkedHashMap<Type, Type>();

    // an annotation for every feature in a layer
    Map<Type, Map<Integer, AnnotationFS>> annotations = new LinkedHashMap<Type, Map<Integer, AnnotationFS>>();

    // store if this is a Begin/Intermediate/End of an annotation
    Map<Type, Map<Integer, String>> beginEndAnno = new LinkedHashMap<Type, Map<Integer, String>>();

    // Store annotations of tokens so that it can be used later for relation annotations
    Map<Type, Map<String, List<AnnotationFS>>> tokenAnnotations = new LinkedHashMap<Type, Map<String, List<AnnotationFS>>>();

    // store target token ids used for a relation
    Map<Type, Map<String, List<String>>> relationTargets = new LinkedHashMap<Type, Map<String, List<String>>>();

    // store tokens indexing with the concat of itsbegin-end so that lemma and pos annotation
    // can be attached, if exists, later
    indexedTokens = new HashMap<String, Token>();

    while (lineIterator.hasNext()) {
        String line = lineIterator.next().trim();
        if (line.trim().equals("") && sentenceStart == tokenStart) {
            continue;
        }
        if (line.trim().equals("")) {
            text.replace(tokenStart - 1, tokenStart, "");
            tokenStart = tokenStart - 1;
            Sentence sentence = new Sentence(aJcas, sentenceStart, tokenStart);
            sentence.addToIndexes();
            tokenStart++;
            sentenceStart = tokenStart;
            text.append("\n");
            continue;
        }
        // sentence
        if (line.startsWith("#text=")) {
            continue;
        }
        if (line.startsWith("#id=")) {
            continue;// it is a comment line
        }
        if (line.startsWith("#")) {
            columns = getLayerAndFeature(aJcas, columns, spanLayers, relationayers, line);
            continue;
        }
        // some times, the sentence in #text= might have a new line which break this reader,
        // so skip such lines
        if (!Character.isDigit(line.split(" ")[0].charAt(0))) {
            continue;
        }

        // If we are still unlucky, the line starts with a number from the sentence but not
        // a token number, check if it didn't in the format NUM-NUM
        if (!Character.isDigit(line.split("-")[1].charAt(0))) {
            continue;
        }

        int count = StringUtils.countMatches(line, "\t");

        if (columns != count) {
            throw new IOException(fileName + " This is not a valid TSV File. check this line: " + line);
        }

        // adding tokens and sentence
        StringTokenizer lineTk = new StringTokenizer(line, "\t");
        String tokenNumberColumn = lineTk.nextToken();
        String tokenColumn = lineTk.nextToken();
        Token token = new Token(aJcas, tokenStart, tokenStart + tokenColumn.length());
        token.addToIndexes();
        Type posType = JCasUtil.getType(aJcas, POS.class);
        Type lemmaType = JCasUtil.getType(aJcas, Lemma.class);
        if (spanLayers.containsKey(posType) || spanLayers.containsKey(lemmaType)) {
            indexedTokens.put(tokenStart + "-" + tokenStart + tokenColumn.length(), token);
        }

        // adding the annotations
        createSpanAnnotation(aJcas, tokenStart, spanLayers, relationayers, annotations, beginEndAnno,
                tokenAnnotations, relationTargets, lineTk, tokenColumn, tokenNumberColumn);

        tokenStart = tokenStart + tokenColumn.length() + 1;
        text.append(tokenColumn + " ");
    }
    if (tokenStart > sentenceStart) {
        Sentence sentence = new Sentence(aJcas, sentenceStart, tokenStart);
        sentence.addToIndexes();
        text.append("\n");
    }

    createRelationLayer(aJcas, relationayers, tokenAnnotations, relationTargets);
}

From source file:com.dianping.resource.io.util.PropertyPlaceholderHelper.java

protected String parseStringValue(String strVal, PlaceholderResolver placeholderResolver,
        Set<String> visitedPlaceholders) {

    StringBuilder buf = new StringBuilder(strVal);

    int startIndex = strVal.indexOf(this.placeholderPrefix);
    while (startIndex != -1) {
        int endIndex = findPlaceholderEndIndex(buf, startIndex);
        if (endIndex != -1) {
            String placeholder = buf.substring(startIndex + this.placeholderPrefix.length(), endIndex);
            String originalPlaceholder = placeholder;
            if (!visitedPlaceholders.add(originalPlaceholder)) {
                throw new IllegalArgumentException(
                        "Circular placeholder reference '" + originalPlaceholder + "' in property definitions");
            }/*from   w w  w .  j a  v  a2s . c o m*/
            // Recursive invocation, parsing placeholders contained in the placeholder key.
            placeholder = parseStringValue(placeholder, placeholderResolver, visitedPlaceholders);
            // Now obtain the value for the fully resolved key...
            String propVal = placeholderResolver.resolvePlaceholder(placeholder);
            if (propVal == null && this.valueSeparator != null) {
                int separatorIndex = placeholder.indexOf(this.valueSeparator);
                if (separatorIndex != -1) {
                    String actualPlaceholder = placeholder.substring(0, separatorIndex);
                    String defaultValue = placeholder.substring(separatorIndex + this.valueSeparator.length());
                    propVal = placeholderResolver.resolvePlaceholder(actualPlaceholder);
                    if (propVal == null) {
                        propVal = defaultValue;
                    }
                }
            }
            if (propVal != null) {
                // Recursive invocation, parsing placeholders contained in the
                // previously resolved placeholder value.
                propVal = parseStringValue(propVal, placeholderResolver, visitedPlaceholders);
                buf.replace(startIndex, endIndex + this.placeholderSuffix.length(), propVal);
                if (logger.isTraceEnabled()) {
                    logger.trace("Resolved placeholder '" + placeholder + "'");
                }
                startIndex = buf.indexOf(this.placeholderPrefix, startIndex + propVal.length());
            } else if (this.ignoreUnresolvablePlaceholders) {
                // Proceed with unprocessed value.
                startIndex = buf.indexOf(this.placeholderPrefix, endIndex + this.placeholderSuffix.length());
            } else {
                throw new IllegalArgumentException("Could not resolve placeholder '" + placeholder + "'"
                        + " in string value \"" + strVal + "\"");
            }
            visitedPlaceholders.remove(originalPlaceholder);
        } else {
            startIndex = -1;
        }
    }

    return buf.toString();
}