/* The contents of this file are subject to the license and copyright terms * detailed in the license directory at the root of the source tree (also * available online at http://fedora-commons.org/license/). */ package org.fcrepo.server.utilities; import java.io.PrintWriter; import java.util.StringTokenizer; /** * A utility class for common string operations. * * @author Ross Wayland */ public class StringUtility { public StringUtility() { } /** * Method that attempts to break a string up into lines no longer than the * specified line length. * * <p>The string is assumed to consist of tokens separated by a delimeter. * The default delimiter is a space. If the last token to be added to a * line exceeds the specified line length, it is written on the next line * so actual line length is approximate given the specified line length * and the length of tokens in the string. * * @param in * The input string to be split into lines. * @param lineLength * The maximum length of each line. * @param delim * The character delimiter separating each token in the input string; * if null, defaults to the space character. * @return A string split into multiple lines whose length is less than the * specified length. Actual length is approximate depending on line * length, token size, and how many complete tokens will fit into * the specified line length. */ public static String prettyPrint(String in, int lineLength, String delim) { // make a guess about resulting length to minimize copying StringBuilder sb = new StringBuilder(in.length() + in.length()/lineLength); if (delim == null) { delim = " "; } StringTokenizer st = new StringTokenizer(in, delim); int charCount = 0; while (st.hasMoreTokens()) { String s = st.nextToken(); charCount = charCount + s.length(); if (charCount < lineLength) { sb.append(s); sb.append(' '); charCount++; } else { sb.append('\n'); sb.append(s); sb.append(' '); charCount = s.length() + 1; } } return sb.toString(); } /** * Method that attempts to break a string up into lines no longer than the * specified line length. * * <p>The string is assumed to a large chunk of undifferentiated text such * as base 64 encoded binary data. * * @param str * The input string to be split into lines. * @param indent * The number of spaces to insert at the start of each line. * @param numChars * The maximum length of each line (not counting the indent spaces). * @return A string split into multiple indented lines whose length is less * than the specified length + indent amount. */ @Deprecated public static String splitAndIndent(String str, int indent, int numChars) { final int inputLength = str.length(); // to prevent resizing, we can predict the size of the indented string // the formatting addition is the indent spaces plus a newline // this length is added once for each line boolean perfectFit = (inputLength % numChars == 0); int fullLines = (inputLength / numChars); int formatLength = perfectFit ? (indent + 1) * fullLines : (indent + 1) * (fullLines + 1); int outputLength = inputLength + formatLength; StringBuilder sb = new StringBuilder(outputLength); for (int offset = 0; offset < inputLength; offset += numChars) { SpaceCharacters.indent(indent, sb); sb.append(str, offset, Math.min(offset + numChars,inputLength)); sb.append('\n'); } return sb.toString(); } /** * Method that attempts to break a string up into lines no longer than the * specified line length. * * <p>The string is assumed to a large chunk of undifferentiated text such * as base 64 encoded binary data. * * @param str * The input string to be split into lines. * @param indent * The number of spaces to insert at the start of each line. * @param numChars * The maximum length of each line (not counting the indent spaces). * @param writer * The character stream to print the output to. */ public static void splitAndIndent(String str, int indent, int numChars, PrintWriter writer) { final int inputLength = str.length(); for (int offset = 0; offset < inputLength; offset += numChars) { SpaceCharacters.indent(indent, writer); writer.append(str, offset, Math.min(offset + numChars,inputLength)); writer.print('\n'); } } private static final char[] HEX_CHARS = new char[]{ '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'a', 'b', 'c', 'd', 'e', 'f' }; public static String byteArraytoHexString(byte[] array) { char[] chars = new char[array.length * 2]; int pos = 0; for (int i=0; i< array.length; i++) { int v1 = array[i] >>> 4 & 0x0f; int v2 = array[i] & 0x0f; chars[pos++] = HEX_CHARS[v1]; chars[pos++] = HEX_CHARS[v2]; } return new String(chars); } public static byte[] hexStringtoByteArray(String str) { int sLen = str.length(); if ((sLen & 0x01) != 0) { throw new NumberFormatException(); } byte ret[] = new byte[sLen / 2]; for (int i = 0; i < sLen; i+=2) { ret[i/2] = (byte) ((Character.digit(str.charAt(i), 16) << 4) + Character.digit(str.charAt(i+1), 16)); } return ret; } public static void main(String[] args) { new StringUtility(); String pid = "demo:1"; String in = "org.apache.cxf.binding.soap.SoapFault: The digital object \"" + pid + "\" is used by one or more other objects " + "in the repository. All related objects must be removed " + "before this object may be deleted. Use the search " + "interface with the query \"bDef~" + pid + "\" to obtain a list of dependent objects."; System.out .println("123456789+123456789+123456789+123456789+123456789+123456789+123456789+123456789+"); System.out.println(StringUtility.prettyPrint(in, 70, null)); byte test[] = {0x04, 0x5a, -0x69/* 0x97 */, -0x44 /* 0xbc */, -0x10/* 0xf0 */, -0x7e/* 0x82 */, -0x12/* 0xee */, -0x2f/* 0xd1 */, 0x63}; String testStr = byteArraytoHexString(test); System.out.println(testStr); byte result[] = hexStringtoByteArray(testStr); for (byte element : result) { System.out.println(element); } } }