/* * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed with * this work for additional information regarding copyright ownership. * The ASF licenses this file to You under the Apache License, Version 2.0 * (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.solr.util; import org.apache.solr.common.SolrException; import java.util.ArrayList; import java.util.Iterator; import java.util.List; import java.util.Properties; /** * Breaking out some utility methods into a separate class as part of SOLR-4196. These utils have nothing to do with * the DOM (they came from DomUtils) and it's really confusing to see them in something labeled DOM */ public class PropertiesUtil { /* * This method borrowed from Ant's PropertyHelper.replaceProperties: * http://svn.apache.org/repos/asf/ant/core/trunk/src/main/org/apache/tools/ant/PropertyHelper.java */ public static String substituteProperty(String value, Properties coreProperties) { if (value == null || value.indexOf('$') == -1) { return value; } List<String> fragments = new ArrayList<>(); List<String> propertyRefs = new ArrayList<>(); parsePropertyString(value, fragments, propertyRefs); StringBuilder sb = new StringBuilder(); Iterator<String> i = fragments.iterator(); Iterator<String> j = propertyRefs.iterator(); while (i.hasNext()) { String fragment = i.next(); if (fragment == null) { String propertyName = j.next(); String defaultValue = null; int colon_index = propertyName.indexOf(':'); if (colon_index > -1) { defaultValue = propertyName.substring(colon_index + 1); propertyName = propertyName.substring(0, colon_index); } if (coreProperties != null) { fragment = coreProperties.getProperty(propertyName); } if (fragment == null) { fragment = System.getProperty(propertyName, defaultValue); } if (fragment == null) { throw new SolrException(SolrException.ErrorCode.SERVER_ERROR, "No system property or default value specified for " + propertyName + " value:" + value); } } sb.append(fragment); } return sb.toString(); } /* * This method borrowed from Ant's PropertyHelper.parsePropertyStringDefault: * http://svn.apache.org/repos/asf/ant/core/trunk/src/main/org/apache/tools/ant/PropertyHelper.java */ private static void parsePropertyString(String value, List<String> fragments, List<String> propertyRefs) { int prev = 0; int pos; //search for the next instance of $ from the 'prev' position while ((pos = value.indexOf("$", prev)) >= 0) { //if there was any text before this, add it as a fragment //TODO, this check could be modified to go if pos>prev; //seems like this current version could stick empty strings //into the list if (pos > 0) { fragments.add(value.substring(prev, pos)); } //if we are at the end of the string, we tack on a $ //then move past it if (pos == (value.length() - 1)) { fragments.add("$"); prev = pos + 1; } else if (value.charAt(pos + 1) != '{') { //peek ahead to see if the next char is a property or not //not a property: insert the char as a literal /* fragments.addElement(value.substring(pos + 1, pos + 2)); prev = pos + 2; */ if (value.charAt(pos + 1) == '$') { //backwards compatibility two $ map to one mode fragments.add("$"); prev = pos + 2; } else { //new behaviour: $X maps to $X for all values of X!='$' fragments.add(value.substring(pos, pos + 2)); prev = pos + 2; } } else { //property found, extract its name or bail on a typo int endName = value.indexOf('}', pos); if (endName < 0) { throw new RuntimeException("Syntax error in property: " + value); } String propertyName = value.substring(pos + 2, endName); fragments.add(null); propertyRefs.add(propertyName); prev = endName + 1; } } //no more $ signs found //if there is any tail to the string, append it if (prev < value.length()) { fragments.add(value.substring(prev)); } } /** * Parse the given String value as an integer. If the string cannot * be parsed, returns the default * @param value the value to parse * @param defValue the default to return if the value cannot be parsed * @return an integer version of the passed in value */ public static Integer toInteger(String value, Integer defValue) { try { return Integer.parseInt(value); } catch (NumberFormatException e) { return defValue; } } public static boolean toBoolean(String value) { return "true".equalsIgnoreCase(value) || "on".equalsIgnoreCase(value); } }