/* * Copyright 2014 Red Hat, Inc. and/or its affiliates. * * Licensed 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.drools.workbench.jcr2vfsmigration.xml; import java.util.HashMap; import java.util.Iterator; import java.util.Map; import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import static org.drools.workbench.jcr2vfsmigration.xml.format.XmlFormat.*; public class ExportXmlUtils { private static final Logger logger = LoggerFactory.getLogger(ExportXmlUtils.class); private static final String CDATA_SECTION = "#cdata-section"; public static String formatCdataSection( String content ) { StringBuilder sb = new StringBuilder( CDATA_OPEN ); sb.append( escapeContent( content ) ).append( CDATA_CLOSE ); return sb.toString(); } public static String formatMap( Map<String, String> map ) { StringBuilder sb = new StringBuilder("<map>"); if ( map != null && map.size() > 0 ) { for ( Iterator<Map.Entry<String, String>> mapEntryIt = map.entrySet().iterator(); mapEntryIt.hasNext(); ) { sb.append( "<entry>" ); Map.Entry<String, String> entry = mapEntryIt.next(); sb.append( "<key>" ).append( escapeXml( entry.getKey() ) ).append( "</key>" ); sb.append( "<value>" ).append( escapeXml( entry.getValue() ) ).append( "</value>" ); sb.append( "</entry>" ); } } sb.append( "</map>" ); return sb.toString(); } // A CData parent node can contain several CData sections, if the content contained any nested CData section(s). public static String parseCdataSection( Node cdataParentNode ) { if ( cdataParentNode == null ) return ""; StringBuilder sb = new StringBuilder(); NodeList cdataParentNodeChildren = cdataParentNode.getChildNodes(); if ( cdataParentNodeChildren != null && cdataParentNodeChildren.getLength() > 0 ) { for ( int i = 0; i < cdataParentNodeChildren.getLength(); i++ ) { Node cdataNode = cdataParentNodeChildren.item( i ); if ( CDATA_SECTION.equalsIgnoreCase( cdataNode.getNodeName() ) ) { sb.append( cdataNode.getTextContent() ); } else { logger.warn( "Expecting only CData sections, ignoring: {}", cdataNode.getNodeName() ); } } } return sb.toString(); } public static Map<String, String> parseMap( Node mapNode ) { Map<String, String> map = new HashMap<String, String>(); if ( mapNode != null && "map".equals( mapNode.getNodeName() ) ) { NodeList entriesNodes = mapNode.getChildNodes(); for ( int i = 0; i < entriesNodes.getLength(); i++ ) { Node entriesNode = entriesNodes.item( i ); NodeList entry = entriesNode.getChildNodes(); String key = null; String value = null; for ( int j = 0; j < entry.getLength(); j++ ) { Node keyValueNode = entry.item( j ); if ( "key".equals( keyValueNode.getNodeName() ) ) { key = unEscapeXml( keyValueNode.getTextContent() ); } else if ( "value".equals( keyValueNode.getNodeName() ) ) { value = unEscapeXml( keyValueNode.getTextContent() ); } } map.put( key, value ); } } return map; } public static String escapeXml( String s ) { return org.apache.commons.lang3.StringEscapeUtils.escapeXml( s ); } public static String unEscapeXml( String s ) { return org.apache.commons.lang3.StringEscapeUtils.unescapeXml( s ); } // Transforms possible nested CData sections in successive ones, by replacing the "]]>" end sequence with "]]]]><![CDATA[>", // which effectively stops and restarts the internal cdata sections. private static String escapeContent( String s ) { if ( StringUtils.isBlank( s ) ) return ""; return s.replaceAll( "]]>", "]]]]><![CDATA[>" ); } }