/** * Goes through SynapsePath argument list, evaluating each by calling stringValueOf and returns a * HashMap String, String array where each item will contain a hash map with key "evaluated * expression" and value "SynapsePath type". * * @param synCtx * @return */ private HashMap<String, String>[] getArgValues(MessageContext synCtx) { HashMap<String, String>[] argValues = new HashMap[pathArgumentList.size()]; HashMap<String, String> valueMap; String value = ""; for (int i = 0; i < pathArgumentList.size(); ++i) { /*ToDo use foreach*/ Argument arg = pathArgumentList.get(i); if (arg.getValue() != null) { value = arg.getValue(); if (!isWellFormedXML(value)) { value = StringEscapeUtils.escapeXml(value); } value = Matcher.quoteReplacement(value); } else if (arg.getExpression() != null) { value = arg.getExpression().stringValueOf(synCtx); if (value != null) { // XML escape the result of an expression that produces a literal, if the target format // of the payload is XML. if (!isWellFormedXML(value) && !arg.getExpression().getPathType().equals(SynapsePath.JSON_PATH) && XML_TYPE.equals(getType())) { value = StringEscapeUtils.escapeXml(value); } value = Matcher.quoteReplacement(value); } else { value = ""; } } else { handleException("Unexpected arg type detected", synCtx); } // value = value.replace(String.valueOf((char) 160), " ").trim(); valueMap = new HashMap<String, String>(); if (null != arg.getExpression()) { valueMap.put(value, arg.getExpression().getPathType()); } else { valueMap.put(value, SynapsePath.X_PATH); } argValues[i] = valueMap; } return argValues; }
/** * Replaces the payload format with SynapsePath arguments which are evaluated using * getArgValues(). * * @param format * @param result * @param synCtx */ private void replace(String format, StringBuffer result, MessageContext synCtx) { HashMap<String, String>[] argValues = getArgValues(synCtx); HashMap<String, String> replacement; Map.Entry<String, String> replacementEntry; String replacementValue = null; Matcher matcher; matcher = pattern.matcher(format); try { while (matcher.find()) { String matchSeq = matcher.group(); int argIndex; try { argIndex = Integer.parseInt(matchSeq.substring(1, matchSeq.length())); } catch (NumberFormatException e) { argIndex = Integer.parseInt(matchSeq.substring(2, matchSeq.length() - 1)); } replacement = argValues[argIndex - 1]; replacementEntry = replacement.entrySet().iterator().next(); if (mediaType.equals(JSON_TYPE) && inferReplacementType(replacementEntry).equals(XML_TYPE)) { // XML to JSON conversion here try { replacementValue = "<jsonObject>" + replacementEntry.getKey() + "</jsonObject>"; OMElement omXML = AXIOMUtil.stringToOM(replacementValue); replacementValue = JsonUtil.toJsonString(omXML) .toString() .replaceAll( ESCAPE_DOUBLE_QUOTE_WITH_FIVE_BACK_SLASHES, ESCAPE_DOUBLE_QUOTE_WITH_NINE_BACK_SLASHES) .replaceAll( ESCAPE_DOLLAR_WITH_TEN_BACK_SLASHES, ESCAPE_DOLLAR_WITH_SIX_BACK_SLASHES); replacementValue = JsonUtil.toJsonString(omXML).toString(); } catch (XMLStreamException e) { handleException( "Error parsing XML for JSON conversion, please check your xPath expressions return valid XML: ", synCtx); } catch (AxisFault e) { handleException("Error converting XML to JSON", synCtx); } } else if (mediaType.equals(XML_TYPE) && inferReplacementType(replacementEntry).equals(JSON_TYPE)) { // JSON to XML conversion here try { OMElement omXML = JsonUtil.toXml(IOUtils.toInputStream(replacementEntry.getKey()), false); if (JsonUtil.isAJsonPayloadElement(omXML)) { // remove <jsonObject/> from result. Iterator children = omXML.getChildElements(); String childrenStr = ""; while (children.hasNext()) { childrenStr += (children.next()).toString().trim(); } replacementValue = childrenStr; } else { /// ~ replacementValue = omXML.toString(); } // replacementValue = omXML.toString(); } catch (AxisFault e) { handleException( "Error converting JSON to XML, please check your JSON Path expressions return valid JSON: ", synCtx); } } else { // No conversion required, as path evaluates to regular String. replacementValue = replacementEntry.getKey(); // This is to replace " with \" and \\ with \\\\ if (mediaType.equals(JSON_TYPE) && inferReplacementType(replacementEntry).equals(STRING_TYPE) && (!replacementValue.startsWith("{") && !replacementValue.startsWith("["))) { replacementValue = replacementValue .replaceAll( Matcher.quoteReplacement("\\\\"), ESCAPE_BACK_SLASH_WITH_SIXTEEN_BACK_SLASHES) .replaceAll("\"", ESCAPE_DOUBLE_QUOTE_WITH_TEN_BACK_SLASHES); } else if ((mediaType.equals(JSON_TYPE) && inferReplacementType(replacementEntry).equals(JSON_TYPE)) && (!replacementValue.startsWith("{") && !replacementValue.startsWith("["))) { // This is to handle only the string value replacementValue = replacementValue.replaceAll("\"", ESCAPE_DOUBLE_QUOTE_WITH_TEN_BACK_SLASHES); } } matcher.appendReplacement(result, replacementValue); } } catch (ArrayIndexOutOfBoundsException e) { log.error("#replace. Mis-match detected between number of formatters and arguments", e); } matcher.appendTail(result); }