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