1 /* 2 * ModeShape (http://www.modeshape.org) 3 * See the COPYRIGHT.txt file distributed with this work for information 4 * regarding copyright ownership. Some portions may be licensed 5 * to Red Hat, Inc. under one or more contributor license agreements. 6 * See the AUTHORS.txt file in the distribution for a full listing of 7 * individual contributors. 8 * 9 * ModeShape is free software. Unless otherwise indicated, all code in ModeShape 10 * is licensed to you under the terms of the GNU Lesser General Public License as 11 * published by the Free Software Foundation; either version 2.1 of 12 * the License, or (at your option) any later version. 13 * 14 * ModeShape is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 17 * Lesser General Public License for more details. 18 * 19 * You should have received a copy of the GNU Lesser General Public 20 * License along with this software; if not, write to the Free 21 * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 22 * 02110-1301 USA, or see the FSF site: http://www.fsf.org. 23 */ 24 package org.modeshape.common.text; 25 26 import java.text.CharacterIterator; 27 import java.text.StringCharacterIterator; 28 import net.jcip.annotations.Immutable; 29 30 /** 31 * Encoder that escapes characters that are not allowed in JCR names. The mapping defined in Section 3.6.3 of the JSR-283 public 32 * review document: 33 * <table cellspacing="0" cellpadding="1" border="1"> 34 * <tr> 35 * <th>Non-JCR character<br/>(Unicode code point)</th> 36 * <th>Private use<br/>Unicode code point</th> 37 * </tr> 38 * <tr> 39 * <td>(U+002A)</td> 40 * <td>U+F02A</td> 41 * </tr> 42 * <tr> 43 * <td>/ (U+002F)</td> 44 * <td>U+F02F</td> 45 * </tr> 46 * <tr> 47 * <td>: (U+003A)</td> 48 * <td>U+F03A</td> 49 * </tr> 50 * <tr> 51 * <td>[ (U+005B)</td> 52 * <td>U+F05B</td> 53 * </tr> 54 * <tr> 55 * <td>] (U+005D)</td> 56 * <td>U+F05D</td> 57 * </tr> 58 * <tr> 59 * <td>| (U+007C)</td> 60 * <td>U+F07C</td> 61 * </tr> 62 * </table> 63 * </p> 64 */ 65 @Immutable 66 public class Jsr283Encoder implements TextEncoder, TextDecoder { 67 68 /** 69 * {@inheritDoc} 70 */ 71 public String encode( String publicName ) { 72 if (publicName == null) return null; 73 StringBuilder sb = new StringBuilder(); 74 CharacterIterator iter = new StringCharacterIterator(publicName); 75 for (char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) { 76 char mapped = c; 77 if (c == '*') { 78 mapped = '\uF02A'; 79 } else if (c == '/') { 80 mapped = '\uF02F'; 81 } else if (c == ':') { 82 mapped = '\uF03A'; 83 } else if (c == '[') { 84 mapped = '\uF05B'; 85 } else if (c == ']') { 86 mapped = '\uF05D'; 87 } else if (c == '|') { 88 mapped = '\uF07C'; 89 } 90 sb.append(mapped); 91 } 92 return sb.toString(); 93 } 94 95 /** 96 * {@inheritDoc} 97 */ 98 public String decode( String jcrNodeName ) { 99 if (jcrNodeName == null) return null; 100 StringBuilder sb = new StringBuilder(); 101 CharacterIterator iter = new StringCharacterIterator(jcrNodeName); 102 for (char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) { 103 char mapped = c; 104 if (c == '\uF02A') { 105 mapped = '*'; 106 } else if (c == '\uF02F') { 107 mapped = '/'; 108 } else if (c == '\uF03A') { 109 mapped = ':'; 110 } else if (c == '\uF05B') { 111 mapped = '['; 112 } else if (c == '\uF05D') { 113 mapped = ']'; 114 } else if (c == '\uF07C') { 115 mapped = '|'; 116 } 117 sb.append(mapped); 118 119 } 120 return sb.toString(); 121 } 122 123 }