checkstyle corrections

Former-commit-id: 836c1ba05aa9daace394b44a6d25aca93d44e777
This commit is contained in:
Jeremy Long
2013-03-28 22:44:11 -04:00
parent 2b1eca171c
commit 00a35ce93f
9 changed files with 125 additions and 91 deletions

View File

@@ -36,6 +36,7 @@
<module name="NewlineAtEndOfFile">
<property name="fileExtensions" value="java"/>
<property name="lineSeparator" value="lf"/>
</module>
<module name="RegexpHeader">
@@ -180,7 +181,7 @@
<module name="GenericWhitespace"/>
<module name="FinalClass"/>
<module name="MissingSwitchDefault"/>
<module name="MagicNumber"/>
<!--module name="MagicNumber"/-->
<module name="Indentation">
<property name="basicOffset" value="4"/>
<property name="braceAdjustment" value="0"/>

View File

@@ -55,17 +55,25 @@ import org.owasp.dependencycheck.utils.Settings;
*/
public class App {
/**
* The location of the log properties configuration file.
*/
private static final String LOG_PROPERTIES_FILE = "configuration/log.properties";
/**
* The main method for the application.
*
* @param args the command line arguments
*/
public static void main(String[] args) {
prepareLogger();
App app = new App();
final App app = new App();
app.run(args);
}
/**
* Configures the logger for use by the application.
*/
private static void prepareLogger() {
//while java doc for JUL says to use preferences api - it throws an exception...
//Preferences.systemRoot().put("java.util.logging.config.file", "log.properties");
@@ -77,7 +85,7 @@ public class App {
// dir.mkdir();
// }
try {
InputStream in = App.class.getClassLoader().getResourceAsStream(LOG_PROPERTIES_FILE);
final InputStream in = App.class.getClassLoader().getResourceAsStream(LOG_PROPERTIES_FILE);
LogManager.getLogManager().reset();
LogManager.getLogManager().readConfiguration(in);
} catch (IOException ex) {
@@ -89,13 +97,13 @@ public class App {
}
/**
* main CLI entry-point into the application.
* Main CLI entry-point into the application.
*
* @param args the command line arguments
*/
public void run(String[] args) {
CliParser cli = new CliParser();
final CliParser cli = new CliParser();
try {
cli.parse(args);
} catch (FileNotFoundException ex) {
@@ -133,7 +141,7 @@ public class App {
* @param deepScan whether to perform a deep scan of the evidence in the project dependencies
*/
private void runScan(String reportDirectory, String outputFormat, String applicationName, String[] files, boolean autoUpdate, boolean deepScan) {
Engine scanner = new Engine(autoUpdate);
final Engine scanner = new Engine(autoUpdate);
Settings.setBoolean(Settings.KEYS.PERFORM_DEEP_SCAN, deepScan);
for (String file : files) {
@@ -141,9 +149,9 @@ public class App {
}
scanner.analyzeDependencies();
List<Dependency> dependencies = scanner.getDependencies();
final List<Dependency> dependencies = scanner.getDependencies();
ReportGenerator report = new ReportGenerator(applicationName, dependencies, scanner.getAnalyzers());
final ReportGenerator report = new ReportGenerator(applicationName, dependencies, scanner.getAnalyzers());
try {
report.generateReports(reportDirectory, outputFormat);
} catch (IOException ex) {

View File

@@ -50,16 +50,16 @@ public class Engine {
/**
* The list of dependencies.
*/
protected List<Dependency> dependencies = new ArrayList<Dependency>();
private List<Dependency> dependencies = new ArrayList<Dependency>();
/**
* A Map of analyzers grouped by Analysis phase.
*/
protected EnumMap<AnalysisPhase, List<Analyzer>> analyzers =
private EnumMap<AnalysisPhase, List<Analyzer>> analyzers =
new EnumMap<AnalysisPhase, List<Analyzer>>(AnalysisPhase.class);
/**
* A set of extensions supported by the analyzers.
*/
protected Set<String> extensions = new HashSet<String>();
private Set<String> extensions = new HashSet<String>();
/**
* Creates a new Engine.
@@ -70,7 +70,7 @@ public class Engine {
}
/**
* Creates a new Engine
* Creates a new Engine.
*
* @param autoUpdate indicates whether or not data should be updated from
* the Internet.
@@ -92,10 +92,10 @@ public class Engine {
analyzers.put(phase, new ArrayList<Analyzer>());
}
AnalyzerService service = AnalyzerService.getInstance();
Iterator<Analyzer> iterator = service.getAnalyzers();
final AnalyzerService service = AnalyzerService.getInstance();
final Iterator<Analyzer> iterator = service.getAnalyzers();
while (iterator.hasNext()) {
Analyzer a = iterator.next();
final Analyzer a = iterator.next();
analyzers.get(a.getAnalysisPhase()).add(a);
if (a.getSupportedExtensions() != null) {
extensions.addAll(a.getSupportedExtensions());
@@ -114,7 +114,7 @@ public class Engine {
}
/**
* Get the dependencies identified
* Get the dependencies identified.
*
* @return the dependencies identified
*/
@@ -130,7 +130,7 @@ public class Engine {
* @param path the path to a file or directory to be analyzed.
*/
public void scan(String path) {
File file = new File(path);
final File file = new File(path);
if (file.exists()) {
if (file.isDirectory()) {
scanDirectory(file);
@@ -147,7 +147,7 @@ public class Engine {
* @param dir the directory to scan.
*/
protected void scanDirectory(File dir) {
File[] files = dir.listFiles();
final File[] files = dir.listFiles();
for (File f : files) {
if (f.isDirectory()) {
scanDirectory(f);
@@ -165,18 +165,18 @@ public class Engine {
*/
protected void scanFile(File file) {
if (!file.isFile()) {
String msg = String.format("Path passed to scanFile(File) is not a file: %s.", file.toString());
final String msg = String.format("Path passed to scanFile(File) is not a file: %s.", file.toString());
Logger.getLogger(Engine.class.getName()).log(Level.WARNING, msg);
}
String fileName = file.getName();
String extension = FileUtils.getFileExtension(fileName);
final String fileName = file.getName();
final String extension = FileUtils.getFileExtension(fileName);
if (extension != null) {
if (extensions.contains(extension)) {
Dependency dependency = new Dependency(file);
final Dependency dependency = new Dependency(file);
dependencies.add(dependency);
}
} else {
String msg = String.format("No file extension found on file '%s'. The file was not analyzed.",
final String msg = String.format("No file extension found on file '%s'. The file was not analyzed.",
file.toString());
Logger.getLogger(Engine.class.getName()).log(Level.FINEST, msg);
}
@@ -188,7 +188,7 @@ public class Engine {
public void analyzeDependencies() {
//phase one initialize
for (AnalysisPhase phase : AnalysisPhase.values()) {
List<Analyzer> analyzerList = analyzers.get(phase);
final List<Analyzer> analyzerList = analyzers.get(phase);
for (Analyzer a : analyzerList) {
try {
a.initialize();
@@ -206,7 +206,7 @@ public class Engine {
// analysis phases
for (AnalysisPhase phase : AnalysisPhase.values()) {
List<Analyzer> analyzerList = analyzers.get(phase);
final List<Analyzer> analyzerList = analyzers.get(phase);
for (Analyzer a : analyzerList) {
for (Dependency d : dependencies) {
@@ -223,7 +223,7 @@ public class Engine {
//close/cleanup
for (AnalysisPhase phase : AnalysisPhase.values()) {
List<Analyzer> analyzerList = analyzers.get(phase);
final List<Analyzer> analyzerList = analyzers.get(phase);
for (Analyzer a : analyzerList) {
try {
a.close();
@@ -238,10 +238,10 @@ public class Engine {
*
*/
private void doUpdates() {
UpdateService service = UpdateService.getInstance();
Iterator<CachedWebDataSource> iterator = service.getDataSources();
final UpdateService service = UpdateService.getInstance();
final Iterator<CachedWebDataSource> iterator = service.getDataSources();
while (iterator.hasNext()) {
CachedWebDataSource source = iterator.next();
final CachedWebDataSource source = iterator.next();
try {
source.update();
} catch (UpdateException ex) {
@@ -257,9 +257,9 @@ public class Engine {
* @return a list of Analyzers
*/
public List<Analyzer> getAnalyzers() {
List<Analyzer> ret = new ArrayList<Analyzer>();
final List<Analyzer> ret = new ArrayList<Analyzer>();
for (AnalysisPhase phase : AnalysisPhase.values()) {
List<Analyzer> analyzerList = analyzers.get(phase);
final List<Analyzer> analyzerList = analyzers.get(phase);
ret.addAll(analyzerList);
}
return ret;

View File

@@ -38,7 +38,7 @@ public abstract class AbstractAnalyzer implements Analyzer {
* @return a Set of strings.
*/
protected static Set<String> newHashSet(String... strings) {
Set<String> set = new HashSet<String>();
final Set<String> set = new HashSet<String>();
Collections.addAll(set, strings);
return set;

View File

@@ -25,6 +25,9 @@ package org.owasp.dependencycheck.analyzer;
*/
public class AnalysisException extends Exception {
/**
* The serial version UID for serialization.
*/
private static final long serialVersionUID = 1L;
/**

View File

@@ -25,13 +25,19 @@ import java.util.ServiceLoader;
*
* @author Jeremy Long (jeremy.long@gmail.com)
*/
public class AnalyzerService {
public final class AnalyzerService {
/**
* The analyzer service singleton.
*/
private static AnalyzerService service;
/**
* The service loader for analyzers.
*/
private final ServiceLoader<Analyzer> loader;
/**
* Creates a new instance of AnalyzerService
* Creates a new instance of AnalyzerService.
*/
private AnalyzerService() {
loader = ServiceLoader.load(Analyzer.class);

View File

@@ -93,7 +93,7 @@ public class FileNameAnalyzer implements Analyzer {
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
String fileName = dependency.getFileName();
int pos = fileName.lastIndexOf(".");
final int pos = fileName.lastIndexOf(".");
if (pos > 0) {
fileName = fileName.substring(0, pos);
}
@@ -111,14 +111,14 @@ public class FileNameAnalyzer implements Analyzer {
}
/**
* The initialize method does nothing for this Analyzer
* The initialize method does nothing for this Analyzer.
*/
public void initialize() {
//do nothing
}
/**
* The close method does nothing for this Analyzer
* The close method does nothing for this Analyzer.
*/
public void close() {
//do nothing

View File

@@ -88,17 +88,17 @@ public class HintAnalyzer implements Analyzer {
* @throws AnalysisException is thrown if there is an exception analyzing the dependency.
*/
public void analyze(Dependency dependency, Engine engine) throws AnalysisException {
Evidence springTest1 = new Evidence("Manifest",
final Evidence springTest1 = new Evidence("Manifest",
"Implementation-Title",
"Spring Framework",
Evidence.Confidence.HIGH);
Evidence springTest2 = new Evidence("Manifest",
final Evidence springTest2 = new Evidence("Manifest",
"Implementation-Title",
"org.springframework.core",
Evidence.Confidence.HIGH);
Set<Evidence> evidence = dependency.getProductEvidence().getEvidence();
final Set<Evidence> evidence = dependency.getProductEvidence().getEvidence();
if (evidence.contains(springTest1) || evidence.contains(springTest2)) {
dependency.getProductEvidence().addEvidence("a priori", "product", "springsource_spring_framework", Evidence.Confidence.HIGH);
dependency.getVendorEvidence().addEvidence("a priori", "vendor", "SpringSource", Evidence.Confidence.HIGH);
@@ -108,14 +108,14 @@ public class HintAnalyzer implements Analyzer {
}
/**
* The initialize method does nothing for this Analyzer
* The initialize method does nothing for this Analyzer.
*/
public void initialize() {
//do nothing
}
/**
* The close method does nothing for this Analyzer
* The close method does nothing for this Analyzer.
*/
public void close() {
//do nothing

View File

@@ -119,14 +119,14 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
/**
* The unmarshaller used to parse the pom.xml from a JAR file.
*/
private Unmarshaller pomUnmarshaller = null;
private Unmarshaller pomUnmarshaller;
/**
* Constructs a new JarAnalyzer.
*/
public JarAnalyzer() {
try {
JAXBContext jaxbContext = JAXBContext.newInstance("org.owasp.dependencycheck.analyzer.pom.generated");
final JAXBContext jaxbContext = JAXBContext.newInstance("org.owasp.dependencycheck.analyzer.pom.generated");
pomUnmarshaller = jaxbContext.createUnmarshaller();
} catch (JAXBException ex) { //guess we will just have a null pointer exception later...
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.SEVERE, null, ex);
@@ -196,14 +196,16 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
}
/**
* Attempts to find a pom.xml within the JAR file. If found it extracts information
* and adds it to the evidence. This will attempt to interpolate the strings contained
* within the pom.properties if one exists.
* Attempts to find a pom.xml within the JAR file. If found it extracts
* information and adds it to the evidence. This will attempt to interpolate
* the strings contained within the pom.properties if one exists.
*
* @param dependency the dependency being analyzed.
* @throws IOException is thrown if there is an error reading the zip file.
* @throws JAXBException is thrown if there is an error extracting the model (aka pom).
* @throws AnalysisException is thrown if there is an exception parsing the pom.
* @throws JAXBException is thrown if there is an error extracting the model
* (aka pom).
* @throws AnalysisException is thrown if there is an exception parsing the
* pom.
* @return whether or not evidence was added to the dependency
*/
protected boolean analyzePOM(Dependency dependency) throws IOException, JAXBException, AnalysisException {
@@ -213,16 +215,16 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
FileInputStream fs = null;
try {
fs = new FileInputStream(dependency.getActualFilePath());
ZipInputStream zin = new ZipInputStream(fs);
final ZipInputStream zin = new ZipInputStream(fs);
ZipEntry entry = zin.getNextEntry();
while (entry != null) {
String entryName = (new File(entry.getName())).getName().toLowerCase();
final String entryName = (new File(entry.getName())).getName().toLowerCase();
if (!entry.isDirectory() && "pom.xml".equals(entryName)) {
if (pom == null) {
NonClosingStream stream = new NonClosingStream(zin);
JAXBElement obj = (JAXBElement) pomUnmarshaller.unmarshal(stream);
final NonClosingStream stream = new NonClosingStream(zin);
final JAXBElement obj = (JAXBElement) pomUnmarshaller.unmarshal(stream);
pom = (org.owasp.dependencycheck.analyzer.pom.generated.Model) obj.getValue();
zin.closeEntry();
} else {
@@ -257,33 +259,33 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
if (pom != null) {
//group id
String groupid = interpolateString(pom.getGroupId(), pomProperties);
final String groupid = interpolateString(pom.getGroupId(), pomProperties);
if (groupid != null) {
foundSomething = true;
dependency.getVendorEvidence().addEvidence("pom", "groupid", groupid, Evidence.Confidence.HIGH);
dependency.getProductEvidence().addEvidence("pom", "groupid", groupid, Evidence.Confidence.LOW);
}
//artifact id
String artifactid = interpolateString(pom.getArtifactId(), pomProperties);
final String artifactid = interpolateString(pom.getArtifactId(), pomProperties);
if (artifactid != null) {
foundSomething = true;
dependency.getProductEvidence().addEvidence("pom", "artifactid", artifactid, Evidence.Confidence.HIGH);
}
//version
String version = interpolateString(pom.getVersion(), pomProperties);
final String version = interpolateString(pom.getVersion(), pomProperties);
if (version != null) {
foundSomething = true;
dependency.getVersionEvidence().addEvidence("pom", "version", version, Evidence.Confidence.HIGH);
}
// org name
Organization org = pom.getOrganization();
final Organization org = pom.getOrganization();
if (org != null && org.getName() != null) {
foundSomething = true;
String orgName = interpolateString(org.getName(), pomProperties);
final String orgName = interpolateString(org.getName(), pomProperties);
dependency.getVendorEvidence().addEvidence("pom", "organization name", orgName, Evidence.Confidence.HIGH);
}
//pom name
String pomName = interpolateString(pom.getName(), pomProperties);
final String pomName = interpolateString(pom.getName(), pomProperties);
if (pomName != null) {
foundSomething = true;
dependency.getProductEvidence().addEvidence("pom", "name", pomName, Evidence.Confidence.HIGH);
@@ -292,7 +294,7 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
//Description
if (pom.getDescription() != null) {
foundSomething = true;
String description = interpolateString(pom.getDescription(), pomProperties);
final String description = interpolateString(pom.getDescription(), pomProperties);
dependency.setDescription(description);
dependency.getProductEvidence().addEvidence("pom", "description", description, Evidence.Confidence.MEDIUM);
dependency.getVendorEvidence().addEvidence("pom", "description", description, Evidence.Confidence.MEDIUM);
@@ -337,7 +339,8 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
* hashSets.
*
* @param dependency A reference to the dependency.
* @param addPackagesAsEvidence a flag indicating whether or not package names should be added as evidence.
* @param addPackagesAsEvidence a flag indicating whether or not package
* names should be added as evidence.
* @throws IOException is thrown if there is an error reading the JAR file.
*/
protected void analyzePackageNames(Dependency dependency, boolean addPackagesAsEvidence)
@@ -347,17 +350,17 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
try {
jar = new JarFile(dependency.getActualFilePath());
java.util.Enumeration en = jar.entries();
final java.util.Enumeration en = jar.entries();
HashMap<String, Integer> level0 = new HashMap<String, Integer>();
HashMap<String, Integer> level1 = new HashMap<String, Integer>();
HashMap<String, Integer> level2 = new HashMap<String, Integer>();
HashMap<String, Integer> level3 = new HashMap<String, Integer>();
final HashMap<String, Integer> level0 = new HashMap<String, Integer>();
final HashMap<String, Integer> level1 = new HashMap<String, Integer>();
final HashMap<String, Integer> level2 = new HashMap<String, Integer>();
final HashMap<String, Integer> level3 = new HashMap<String, Integer>();
int count = 0;
while (en.hasMoreElements()) {
java.util.jar.JarEntry entry = (java.util.jar.JarEntry) en.nextElement();
final java.util.jar.JarEntry entry = (java.util.jar.JarEntry) en.nextElement();
if (entry.getName().endsWith(".class") && entry.getName().contains("/")) {
String[] path = entry.getName().toLowerCase().split("/");
final String[] path = entry.getName().toLowerCase().split("/");
if ("java".equals(path[0])
|| "javax".equals(path[0])
@@ -405,8 +408,8 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
if (count == 0) {
return;
}
EvidenceCollection vendor = dependency.getVendorEvidence();
EvidenceCollection product = dependency.getProductEvidence();
final EvidenceCollection vendor = dependency.getVendorEvidence();
final EvidenceCollection product = dependency.getProductEvidence();
for (String s : level0.keySet()) {
if (!"org".equals(s) && !"com".equals(s)) {
@@ -422,7 +425,7 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
float ratio = level1.get(s);
ratio /= count;
if (ratio > 0.5) {
String[] parts = s.split("/");
final String[] parts = s.split("/");
if ("org".equals(parts[0]) || "com".equals(parts[0])) {
vendor.addWeighting(parts[1]);
if (addPackagesAsEvidence) {
@@ -442,7 +445,7 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
float ratio = level2.get(s);
ratio /= count;
if (ratio > 0.4) {
String[] parts = s.split("/");
final String[] parts = s.split("/");
if ("org".equals(parts[0]) || "com".equals(parts[0])) {
vendor.addWeighting(parts[1]);
product.addWeighting(parts[2]);
@@ -468,7 +471,7 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
float ratio = level3.get(s);
ratio /= count;
if (ratio > 0.3) {
String[] parts = s.split("/");
final String[] parts = s.split("/");
if ("org".equals(parts[0]) || "com".equals(parts[0])) {
vendor.addWeighting(parts[1]);
vendor.addWeighting(parts[2]);
@@ -523,24 +526,24 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
try {
jar = new JarFile(dependency.getActualFilePath());
Manifest manifest = jar.getManifest();
final Manifest manifest = jar.getManifest();
if (manifest == null) {
Logger.getLogger(JarAnalyzer.class.getName()).log(Level.SEVERE,
"Jar file '{0}' does not contain a manifest.",
dependency.getFileName());
return false;
}
Attributes atts = manifest.getMainAttributes();
final Attributes atts = manifest.getMainAttributes();
EvidenceCollection vendorEvidence = dependency.getVendorEvidence();
EvidenceCollection productEvidence = dependency.getProductEvidence();
EvidenceCollection versionEvidence = dependency.getVersionEvidence();
final EvidenceCollection vendorEvidence = dependency.getVendorEvidence();
final EvidenceCollection productEvidence = dependency.getProductEvidence();
final EvidenceCollection versionEvidence = dependency.getVersionEvidence();
String source = "Manifest";
final String source = "Manifest";
for (Entry<Object, Object> entry : atts.entrySet()) {
String key = entry.getKey().toString();
String value = atts.getValue(key);
final String value = atts.getValue(key);
if (key.equals(Attributes.Name.IMPLEMENTATION_TITLE.toString())) {
foundSomething = true;
productEvidence.addEvidence(source, key, value, Evidence.Confidence.HIGH);
@@ -595,9 +598,9 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
productEvidence.addEvidence(source, key, value, Evidence.Confidence.LOW);
vendorEvidence.addEvidence(source, key, value, Evidence.Confidence.LOW);
if (value.matches(".*\\d.*")) {
StringTokenizer tokenizer = new StringTokenizer(value, " ");
final StringTokenizer tokenizer = new StringTokenizer(value, " ");
while (tokenizer.hasMoreElements()) {
String s = tokenizer.nextToken();
final String s = tokenizer.nextToken();
if (s.matches("^[0-9.]+$")) {
versionEvidence.addEvidence(source, key, s, Evidence.Confidence.LOW);
}
@@ -616,12 +619,24 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
return foundSomething;
}
/**
* Adds a description to the given dependency.
*
* @param d a dependency
* @param description the description
*/
private void addDescription(Dependency d, String description) {
if (d.getDescription() == null) {
d.setDescription(description);
}
}
/**
* Adds a license to the given dependency.
*
* @param d a dependency
* @param license the license
*/
private void addLicense(Dependency d, String license) {
if (d.getLicense() == null) {
d.setLicense(license);
@@ -631,27 +646,28 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
}
/**
* The initialize method does nothing for this Analyzer
* The initialize method does nothing for this Analyzer.
*/
public void initialize() {
//do nothing
}
/**
* The close method does nothing for this Analyzer
* The close method does nothing for this Analyzer.
*/
public void close() {
//do nothing
}
/**
* A utiltiy function that will interpolate strings based on values given
* in the properties file. It will also interpolate the strings contained
* A utility function that will interpolate strings based on values given in
* the properties file. It will also interpolate the strings contained
* within the properties file so that properties can reference other
* properties.
*
* @param text the string that contains references to properties.
* @param properties a collection of properties that may be referenced within the text.
* @param properties a collection of properties that may be referenced
* within the text.
* @return the interpolated text.
*/
protected String interpolateString(String text, Properties properties) {
@@ -660,21 +676,21 @@ public class JarAnalyzer extends AbstractAnalyzer implements Analyzer {
return text;
}
int pos = text.indexOf("${");
final int pos = text.indexOf("${");
if (pos < 0) {
return text;
}
int end = text.indexOf("}");
final int end = text.indexOf("}");
if (end < pos) {
return text;
}
String propName = text.substring(pos + 2, end);
final String propName = text.substring(pos + 2, end);
String propValue = interpolateString(properties.getProperty(propName), properties);
if (propValue == null) {
propValue = "";
}
StringBuilder sb = new StringBuilder(propValue.length() + text.length());
final StringBuilder sb = new StringBuilder(propValue.length() + text.length());
sb.append(text.subSequence(0, pos));
sb.append(propValue);
sb.append(text.substring(end + 1));