001    /*
002     * JBoss DNA (http://www.jboss.org/dna)
003     * See the COPYRIGHT.txt file distributed with this work for information
004     * regarding copyright ownership.  Some portions may be licensed
005     * to Red Hat, Inc. under one or more contributor license agreements.
006     * See the AUTHORS.txt file in the distribution for a full listing of 
007     * individual contributors. 
008     *
009     * JBoss DNA is free software. Unless otherwise indicated, all code in JBoss DNA
010     * is licensed to you under the terms of the GNU Lesser General Public License as
011     * published by the Free Software Foundation; either version 2.1 of
012     * the License, or (at your option) any later version.
013     *
014     * JBoss DNA is distributed in the hope that it will be useful,
015     * but WITHOUT ANY WARRANTY; without even the implied warranty of
016     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
017     * Lesser General Public License for more details.
018     *
019     * You should have received a copy of the GNU Lesser General Public
020     * License along with this software; if not, write to the Free
021     * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
022     * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
023     */
024    package org.jboss.dna.common.text;
025    
026    import java.text.CharacterIterator;
027    import java.text.StringCharacterIterator;
028    
029    /**
030     * Encoder that escapes characters that are not allowed in JCR names. The mapping defined in Section 3.6.3 of the JSR-283 public
031     * review document: <table cellspacing="0" cellpadding="1" border="1">
032     * <tr>
033     * <th>Non-JCR character<br/>(Unicode code point)</th>
034     * <th>Private use<br/>Unicode code point </th>
035     * </tr>
036     * <tr>
037     * <td>* (U+002A)</td>
038     * <td> U+F02A </td>
039     * </tr>
040     * <tr>
041     * <td>/ (U+002F)</td>
042     * <td> U+F02F </td>
043     * </tr>
044     * <tr>
045     * <td>: (U+003A)</td>
046     * <td> U+F03A </td>
047     * </tr>
048     * <tr>
049     * <td>[ (U+005B)</td>
050     * <td> U+F05B </td>
051     * </tr>
052     * <tr>
053     * <td>] (U+005D)</td>
054     * <td> U+F05D </td>
055     * </tr>
056     * <tr>
057     * <td>| (U+007C)</td>
058     * <td> U+F07C </td>
059     * </tr>
060     * </table>
061     * </p>
062     * 
063     * @author Randall Hauch
064     */
065    public class Jsr283Encoder implements TextEncoder, TextDecoder {
066    
067        /**
068         * {@inheritDoc}
069         */
070        public String encode( String publicName ) {
071            if (publicName == null) return null;
072            StringBuilder sb = new StringBuilder();
073            CharacterIterator iter = new StringCharacterIterator(publicName);
074            for (char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) {
075                char mapped = c;
076                if (c == '*') {
077                    mapped = '\uF02A';
078                } else if (c == '/') {
079                    mapped = '\uF02F';
080                } else if (c == ':') {
081                    mapped = '\uF03A';
082                } else if (c == '[') {
083                    mapped = '\uF05B';
084                } else if (c == ']') {
085                    mapped = '\uF05D';
086                } else if (c == '|') {
087                    mapped = '\uF07C';
088                }
089                sb.append(mapped);
090            }
091            return sb.toString();
092        }
093    
094        /**
095         * {@inheritDoc}
096         */
097        public String decode( String jcrNodeName ) {
098            if (jcrNodeName == null) return null;
099            StringBuilder sb = new StringBuilder();
100            CharacterIterator iter = new StringCharacterIterator(jcrNodeName);
101            for (char c = iter.first(); c != CharacterIterator.DONE; c = iter.next()) {
102                char mapped = c;
103                if (c == '\uF02A') {
104                    mapped = '*';
105                } else if (c == '\uF02F') {
106                    mapped = '/';
107                } else if (c == '\uF03A') {
108                    mapped = ':';
109                } else if (c == '\uF05B') {
110                    mapped = '[';
111                } else if (c == '\uF05D') {
112                    mapped = ']';
113                } else if (c == '\uF07C') {
114                    mapped = '|';
115                }
116                sb.append(mapped);
117    
118            }
119            return sb.toString();
120        }
121    
122    }