/* * EntityEncoder.java * Copyright 2002 (C) Thomas Behr <ravenlock@gmx.de> * * This library 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 2.1 of the License, or (at your option) any later version. * * This library 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 * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Created on September 09, 2002, 0:00 AM */ package pcgen.io; import java.util.HashMap; import java.util.Map; import java.util.NoSuchElementException; import java.util.StringTokenizer; /** * {@code EntityEncoder}<br> * Encodes reserved characters and escape sequences as entities<br> * Decodes entities as reserved characters and escape sequences * * @author Thomas Behr */ public final class EntityEncoder { private static final String ENCODE = "\\\n\r\f:|[]&"; private static final EntityMap ENTITIES; private static final String ENCODE_LIGHT = "\\\n\r\f|&"; private static final EntityMap ENTITIES_LIGHT; static { ENTITIES = new EntityMap(); ENTITIES.put("\n", "&nl;"); ENTITIES.put("\r", "&cr;"); ENTITIES.put("\f", "&lf;"); ENTITIES.put(":", ":"); ENTITIES.put("|", "&pipe;"); ENTITIES.put("[", "&lbracket;"); ENTITIES.put("]", "&rbracket;"); ENTITIES.put("&", "&"); ENTITIES_LIGHT = new EntityMap(); ENTITIES_LIGHT.put("\n", "&nl;"); ENTITIES_LIGHT.put("\r", "&cr;"); ENTITIES_LIGHT.put("\f", "&lf;"); ENTITIES_LIGHT.put("|", "&pipe;"); ENTITIES_LIGHT.put("&", "&"); } /** * Private constructor to disable instantiation. */ private EntityEncoder() { } /** * decode characters. * {@literal * "\n" <- "&nl;" * "\r" <- "&cr;" * "\f" <- "&lf;" * ":" <- ":" * "|" <- "&pipe;" * "[" <- "&lbracket;" * "]" <- "&rbracket;" * "&" <- "&" * } * <br>author: Thomas Behr 09-09-02 * * @param s the String to decode * @return the decoded String */ public static String decode(String s) { final StringBuilder buffer = new StringBuilder(); final StringTokenizer tokens = new StringTokenizer(s, "&;", true); String cToken; while (tokens.hasMoreTokens()) { cToken = tokens.nextToken(); if ("&".equals(cToken)) { String tok1 = null; String tok2 = null; try { tok1 = tokens.nextToken(); tok2 = tokens.nextToken(); buffer.append(ENTITIES.get(cToken + tok1 + tok2)); } catch (NoSuchElementException exc) { buffer.append(cToken); if (tok1 != null) { buffer.append(tok1); if (tok2 != null) { buffer.append(tok2); } } } } else { buffer.append(cToken); } } return buffer.toString(); } /** * encode characters. * {@literal * "\n" -> "&nl;" * "\r" -> "&cr;" * "\f" -> "&lf;" * ":" -> ":" * "|" -> "&pipe;" * "[" -> "&lbracket;" * "]" -> "&rbracket;" * "&" -> "&" * } * <br>author: Thomas Behr 09-09-02 * * @param s the String to encode * @return the encoded String */ public static String encode(String s) { final StringBuilder buffer = new StringBuilder(); if (s != null) { final StringTokenizer tokens = new StringTokenizer(s, ENCODE, true); while (tokens.hasMoreTokens()) { buffer.append(ENTITIES.get(tokens.nextToken())); } } return buffer.toString(); } /** * Encode the characters. * {@literal * "\n" -> "&nl;" * "\r" -> "&cr;" * "\f" -> "&lf;" * "|" -> "&pipe;" * "&" -> "&" * } *Note that this must be a subset of the encode function as *the same decode function is used to decode these values. * * @param s the String to encode * @return the encoded String */ public static String encodeLight(String s) { final StringBuilder buffer = new StringBuilder(); if (s != null) { final StringTokenizer tokens = new StringTokenizer(s, ENCODE_LIGHT, true); while (tokens.hasMoreTokens()) { buffer.append(ENTITIES_LIGHT.get(tokens.nextToken())); } } return buffer.toString(); } } final class EntityMap { private final Map<String, String> map = new HashMap<>(); /** * Get value * @param key * @return value */ public String get(String key) { final Object value = map.get(key); return (value == null) ? key : (String) value; } /** * Put value in map * * @param key * @param value */ public void put(String key, String value) { map.put(key, value); map.put(value, key); } }