/** * Parse the SQL fragment and generate SQL with parameter placeholders and list of getters. * * @param types parameter types * @param builder builder for output SQL * @param mappers parameters mapping configs */ private List<ParameterMappingConfig> configureTypes(Type[] types, StringBuilder builder) { List<ParameterMappingConfig> mappers = new ArrayList<ParameterMappingConfig>(); int pos = 0; while (pos < sql.length()) { // TODO: Add support for out parameters! int start = sql.indexOf("${", pos); if (start == -1) { builder.append(sql.substring(pos)); break; } int end = sql.indexOf("}", start + 2); if (end == -1) { builder.append(sql.substring(pos)); break; } builder.append(sql.substring(pos, start)); String parameter = sql.substring(start + 2, end); // TODO: Add support for lists, which should expand into something // like (?, ?, ?, ?) // For, example ${prop[]} with prop = int[] { 1, 2, 3} will expand // into ?, ?, ? with // parameters 1, 2 and 3. builder.append('?'); try { // TODO: Remove this code to separate class (parameter config?) boolean in = true; boolean out = false; String prop; int comma = parameter.indexOf(','); if (comma != -1) { prop = parameter.substring(0, comma); String type = parameter.substring(comma + 1); if ("type=IN".equals(type)) { // Nothing, the default } else if ("type=INOUT".equals(type)) { out = true; } else if ("type=OUT".equals(type)) { out = true; in = false; } else { throw new IllegalArgumentException("Invalid parameter: " + parameter); } } else { prop = parameter; } Getter getter = introspectionFactory.buildParameterGetter(types, prop); Type type = getter.getType(); Setter setter = out ? introspectionFactory.buildParameterSetter(types, prop) : null; ParameterMappingConfig paramMapper = new ParameterMappingConfig(type, in ? getter : null, setter); mappers.add(paramMapper); } catch (IllegalArgumentException e) { throw new IllegalArgumentException( "Failed to create parameter getter for " + " (failed property marked by $[]): " + sql.substring(0, start) + "$[" + parameter + ']' + sql.substring(end), e); } pos = end + 1; } return mappers; }