/* * Copyright (c) 2011 Lockheed Martin Corporation * * 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.eurekastreams.server.service.utility; import java.util.ArrayList; import java.util.List; /** * Breaks a text string into multiple segments based on size. */ public class TextSplitter { /** Maximum size of first piece. */ private final int firstBlockSize; /** Maximum size of remaining pieces. */ private final int blockSize; // decrement by 3 /** Text placed at start of a continued piece. */ private final String continuedFromMark; /** Text placed at end of a piece to be continued. */ private final String continueToMark; /** Length of continueToMark. */ private final int continueToMarkLength; /** * Constructor. * * @param inFirstBlockSize * Maximum size of first piece. * @param inBlockSize * Maximum size of remaining pieces. */ public TextSplitter(final int inFirstBlockSize, final int inBlockSize) { this(inFirstBlockSize, inBlockSize, "...", "..."); } /** * Constructor. * * @param inFirstBlockSize * Maximum size of first piece. * @param inBlockSize * Maximum size of remaining pieces. * @param inContinuedFromMark * Text placed at start of a continued piece. * @param inContinueToMark * Text placed at end of a piece to be continued. */ public TextSplitter(final int inFirstBlockSize, final int inBlockSize, final String inContinuedFromMark, final String inContinueToMark) { firstBlockSize = inFirstBlockSize; blockSize = inBlockSize - inContinuedFromMark.length(); continuedFromMark = inContinuedFromMark; continueToMark = inContinueToMark; continueToMarkLength = continueToMark.length(); } /** * Splits a string into multiple pieces on size and places continuation marks on them. * * @param originalInputText * Single string to split. * @return List of pieces. */ public List<String> split(final String originalInputText) { List<String> piecesList = new ArrayList<String>(); if (originalInputText == null) { return piecesList; } int startIdx = 0; String inputText = originalInputText.trim(); int inputLength = inputText.length(); while (startIdx < inputLength) { // skip any whitespace at start of a piece if (Character.isWhitespace(inputText.charAt(startIdx))) { startIdx++; continue; } int useBlockSize = piecesList.isEmpty() ? firstBlockSize : blockSize; int remainingSize = inputLength - startIdx; if (remainingSize > useBlockSize) { // look backward from the end of the block for a break int scanIdx = startIdx + useBlockSize - continueToMarkLength; while (scanIdx > startIdx && !Character.isWhitespace(inputText.charAt(scanIdx))) { scanIdx--; } // if no break found, just chop mid-word if (scanIdx == startIdx) { scanIdx = startIdx + useBlockSize - continueToMarkLength; } // build text segment // Note: trim off any extra whitespace at end (in case the break found was multiple chars long) piecesList.add((piecesList.isEmpty() ? "" : continuedFromMark) + inputText.substring(startIdx, scanIdx).trim() + continueToMark); // move to next start position startIdx = scanIdx; } else { piecesList.add((piecesList.isEmpty() ? "" : continuedFromMark) + inputText.substring(startIdx)); break; } } return piecesList; } }