/* * Copyright (C) 2011 Laurent Caillette * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation, either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ package org.novelang.rendering.xslt; import org.w3c.dom.Node; import org.w3c.dom.NodeList; import org.novelang.logger.Logger; import org.novelang.logger.LoggerFactory; /** * @author Laurent Caillette */ public class Length { private static final Logger LOGGER = LoggerFactory.getLogger( Length.class ) ; private Length() { } public static Number positionUnderCharacterRemainderThreshold( final NodeList nodeList, final int characterCountThreshold ) { LOGGER.debug( "Finding position of node with less than ", characterCountThreshold, " characters in list of ", nodeList.getLength(), " nodes" ) ; int total = 0 ; int lastMatchingNodeIndex = -1 ; for( int i = nodeList.getLength() - 1 ; i >= 0 ; i-- ) { final Node node = nodeList.item( i ) ; LOGGER.debug( " Node[ ", i, " ] = ", node.getNodeName() ) ; final int count = countCharacters( node ) ; if( characterCountThreshold < total + count ) { break ; } else { total += count ; lastMatchingNodeIndex = i ; } } LOGGER.debug( " Returning position ", lastMatchingNodeIndex ) ; return lastMatchingNodeIndex ; } /** * Counts all the character of given node and following siblings. * @param node a non-null object. * @return -1 if something got wrong, a zero-or-positive integer otherwise. */ public static Number countCharactersOfSelfAndFollowingSiblings( Node node ) { // LOGGER.debug( "Counting characters until end for %s", node.getNodeName() ) ; final Node parent = node.getParentNode() ; int characters ; if( null == parent ) { characters = -1 ; } else { characters = 0 ; do { characters += countCharacters( node ) ; node = node.getNextSibling() ; } while( node != null ) ; } // LOGGER.debug( "Returning characterCount: %s", characters ) ; return characters ; } private static int countCharacters( final Node node ) { int count = 0 ; final String textContent = node.getTextContent() ; // LOGGER.debug( "Node[ %s ].textContent = '%s'", node.getNodeName(), textContent ) ; if( null != textContent ) { count += textContent.length() ; } count += countCharacters( node.getChildNodes() ) ; return count ; } private static int countCharacters( final NodeList nodeList ) { int count = 0 ; for( int i = 0 ; i < nodeList.getLength() ; i++ ) { final Node node = nodeList.item( i ) ; count += countCharacters( node ) ; } return count ; } }