001/* 002 * BioJava development code 003 * 004 * This code may be freely distributed and modified under the 005 * terms of the GNU Lesser General Public Licence. This should 006 * be distributed with the code. If you do not have a copy, 007 * see: 008 * 009 * http://www.gnu.org/copyleft/lesser.html 010 * 011 * Copyright for this code is held jointly by the individual 012 * authors. These should be listed in @author doc comments. 013 * 014 * For more information on the BioJava project and its aims, 015 * or to join the biojava-l mailing list, visit the home page 016 * at: 017 * 018 * http://www.biojava.org/ 019 * 020 * Created on Sep 14, 2011 021 * Author: Amr AL-Hossary 022 * 023 */ 024package org.biojava.nbio.core.util; 025 026import org.slf4j.Logger; 027import org.slf4j.LoggerFactory; 028import org.w3c.dom.Document; 029import org.w3c.dom.DocumentType; 030import org.w3c.dom.NamedNodeMap; 031import org.w3c.dom.Node; 032import org.xml.sax.SAXException; 033 034import javax.xml.parsers.DocumentBuilder; 035import javax.xml.parsers.DocumentBuilderFactory; 036import javax.xml.parsers.ParserConfigurationException; 037import java.io.*; 038import java.util.AbstractCollection; 039import java.util.Iterator; 040import java.util.Scanner; 041 042 043/** 044 * A utility class for common {@link String} manipulation tasks. 045 * All functions are static methods. 046 * 047 * @author Amr AL-Hossary 048 */ 049public class StringManipulationHelper { 050 051 private final static Logger logger = LoggerFactory.getLogger(StringManipulationHelper.class); 052 053 /** 054 * we are using Unix endline here, since this is used for testing XML and it 055 * is part of the XML recommendations: <a href 056 * ="http://www.w3.org/TR/REC-xml/#sec-line-ends" 057 * >http://www.w3.org/TR/REC-xml/#sec-line-ends</a> 058 */ 059 private static final String UNIX_NEWLINE = "\n"; 060 061 private StringManipulationHelper() { 062 // to prevent instantiation 063 } 064 065 066 067 068 069 /** 070 * @author andreas 071 * @param stream 072 * @return 073 */ 074 public static String convertStreamToString(InputStream stream) { 075 BufferedReader reader = new BufferedReader(new InputStreamReader(stream)); 076 StringBuilder sb = new StringBuilder(); 077 078 String line = null; 079 try { 080 while ((line = reader.readLine()) != null) { 081 082 sb.append(line).append(UNIX_NEWLINE); 083 } 084 } catch (IOException e) { 085 // logger.error("Exception: ", e); 086 } finally { 087 try { 088 stream.close(); 089 } catch (IOException e) { 090 logger.error("Exception: ", e); 091 } 092 } 093 094 return sb.toString(); 095 } 096 097 /** 098 * compares two strings for equality, line by line, ignoring any difference 099 * of end line delimiters contained within the 2 Strings. This method should 100 * be used if and only if two Strings are considered identical when all nodes 101 * are identical including their relative order. Generally useful when 102 * asserting identity of <b>automatically regenerated</b> XML or PDB. 103 * 104 * @param expected 105 * @param actual 106 */ 107 public static boolean equalsToIgnoreEndline(String expected, String actual) { 108 if (expected == null && actual == null) { 109 return true; 110 } 111 if (expected != null ^ actual != null) { 112 return false; 113 } 114 Scanner scanner1 = new Scanner(expected); 115 Scanner scanner2 = new Scanner(actual); 116 String line1, line2; 117 while (scanner1.hasNextLine()) { 118 line1 = scanner1.nextLine(); 119 line2 = scanner2.nextLine(); 120 if (! line1.equals(line2)) { 121 scanner1.close(); 122 scanner2.close(); 123 return false; 124 } 125 } 126 if (scanner2.hasNextLine()) { 127 scanner1.close(); 128 scanner2.close(); 129 return false; 130 } 131 132 scanner1.close(); 133 scanner2.close(); 134 return true; 135 } 136 137 138 public static boolean equalsToXml(String expected, String actual) { 139 Document expectedDocument=null; 140 Document actualDocument=null; 141 try { 142 DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance(); 143 DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder(); 144 expectedDocument = documentBuilder.parse(new ByteArrayInputStream(expected.getBytes())); 145 actualDocument = documentBuilder.parse(new ByteArrayInputStream(actual.getBytes())); 146 } catch (ParserConfigurationException e) { 147 logger.error("Exception: ", e); 148 throw new RuntimeException("Couldn't Parse XML", e); 149 } catch (SAXException e) { 150 logger.error("Exception: ", e); 151 throw new RuntimeException("Couldn't Parse XML", e); 152 } catch (IOException e) { 153 logger.error("Exception: ", e); 154 throw new RuntimeException("Couldn't Parse XML", e); 155 } 156 final DocumentType doctype1 = expectedDocument.getDoctype(); 157 final DocumentType doctype2 = actualDocument.getDoctype(); 158 if (doctype1==null ^ doctype2 == null) { 159 return false; 160 }else if (doctype1!= null /*&& doctype2 != null*/) { 161 NamedNodeMap expectedNotations = doctype1.getNotations(); 162 NamedNodeMap actualNotations = doctype2.getNotations(); 163 if (expectedNotations.getLength() == actualNotations.getLength()) { 164 for (int i = 0; i < expectedNotations.getLength(); i++) { 165 Node node= expectedNotations.item(i); 166 node.isEqualNode(null); 167 } 168 }else{ 169 return false; 170 } 171 172 } 173 174 throw new UnsupportedOperationException("not yet implemented"); 175 } 176 177 public static String padLeft(String s, int n) { 178 return String.format("%1$" + n + "s", s); 179 } 180 181 public static String padRight(String s, int n) { 182 return String.format("%1$-" + n + "s", s); 183 } 184 185 public static String join(AbstractCollection<String> s, String delimiter) { 186 if (s == null || s.isEmpty()) return ""; 187 Iterator<String> iter = s.iterator(); 188 StringBuilder builder = new StringBuilder(iter.next()); 189 while( iter.hasNext() ) 190 { 191 builder.append(delimiter).append(iter.next()); 192 } 193 return builder.toString(); 194 } 195 196}