001/**
002 *
003 * Copyright © 2014-2021 Florian Schmaus
004 *
005 * Licensed under the Apache License, Version 2.0 (the "License");
006 * you may not use this file except in compliance with the License.
007 * You may obtain a copy of the License at
008 *
009 *     http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.jxmpp.stringprep;
018
019import org.jxmpp.JxmppContext;
020import org.jxmpp.XmppAddressParttype;
021import org.jxmpp.util.cache.Cache;
022import org.jxmpp.util.cache.LruCache;
023
024public class XmppStringPrepUtil {
025
026        private static final Cache<String, String> NODEPREP_CACHE = new LruCache<String, String>(100);
027        private static final Cache<String, String> DOMAINPREP_CACHE = new LruCache<String, String>(100);
028        private static final Cache<String, String> RESOURCEPREP_CACHE = new LruCache<String, String>(100);
029
030        /**
031         * Perform localprep on the input String.
032         *
033         * @param string the input String.
034         * @return the localpreped String.
035         * @throws XmppStringprepException if the input String can not be transformed.
036         */
037        public static String localprep(String string) throws XmppStringprepException {
038                return localprep(string, JxmppContext.getDefaultContext());
039        }
040
041        /**
042         * Perform localprep on the input String.
043         *
044         * @param string the input String.
045         * @param context the JXMPP JID context.
046         * @return the localpreped String.
047         * @throws XmppStringprepException if the input String can not be transformed.
048         */
049        public static String localprep(String string, JxmppContext context) throws XmppStringprepException {
050                throwIfNullOrEmpty(string, XmppAddressParttype.localpart);
051                String res;
052                if (context.isCachingEnabled()) {
053                        res = NODEPREP_CACHE.lookup(string);
054                        if (res != null) {
055                                return res;
056                        }
057                }
058
059                res = context.xmppStringprep.localprep(string);
060
061                if (context.isCachingEnabled()) {
062                        NODEPREP_CACHE.put(string, res);
063                }
064                return res;
065        }
066
067        /**
068         * Perform domainprep on the input String.
069         *
070         * @param string the input String.
071         * @return the domainprep String.
072         * @throws XmppStringprepException if the input String can not be transformed.
073         */
074        public static String domainprep(String string) throws XmppStringprepException {
075                return domainprep(string, JxmppContext.getDefaultContext());
076        }
077
078
079        /**
080         * Perform domainprep on the input String.
081         *
082         * @param string the input String.
083         * @param context the JXMPP JID context.
084         * @return the domainprep String.
085         * @throws XmppStringprepException if the input String can not be transformed.
086         */
087        public static String domainprep(String string, JxmppContext context) throws XmppStringprepException {
088                throwIfNullOrEmpty(string, XmppAddressParttype.domainpart);
089                String res;
090                if (context.isCachingEnabled()) {
091                        res = DOMAINPREP_CACHE.lookup(string);
092                        if (res != null) {
093                                return res;
094                        }
095                }
096
097                res = context.xmppStringprep.domainprep(string);
098
099                if (context.isCachingEnabled()) {
100                        DOMAINPREP_CACHE.put(string, res);
101                }
102                return res;
103        }
104
105        /**
106         * Perform resourceprep on the input String.
107         *
108         * @param string the input String.
109         * @return the resourceprep String.
110         * @throws XmppStringprepException if the input String can not be transformed.
111         */
112        public static String resourceprep(String string) throws XmppStringprepException {
113                return resourceprep(string, JxmppContext.getDefaultContext());
114        }
115
116        /**
117         * Perform resourceprep on the input String.
118         *
119         * @param string the input String.
120         * @param context the JXMPP JID context.
121         * @return the resourceprep String.
122         * @throws XmppStringprepException if the input String can not be transformed.
123         */
124        public static String resourceprep(String string, JxmppContext context) throws XmppStringprepException {
125                throwIfNullOrEmpty(string, XmppAddressParttype.resourcepart);
126                String res;
127                if (context.isCachingEnabled()) {
128                        res = RESOURCEPREP_CACHE.lookup(string);
129                        if (res != null) {
130                                return res;
131                        }
132                }
133
134                res = context.xmppStringprep.resourceprep(string);
135
136                if (context.isCachingEnabled()) {
137                        RESOURCEPREP_CACHE.put(string, res);
138                }
139                return res;
140        }
141
142        /**
143         * Set the maximum cache sizes.
144         *
145         * @param size the maximum cache size.
146         */
147        public static void setMaxCacheSizes(int size) {
148                NODEPREP_CACHE.setMaxCacheSize(size);
149                DOMAINPREP_CACHE.setMaxCacheSize(size);
150                RESOURCEPREP_CACHE.setMaxCacheSize(size);
151        }
152
153        /**
154         * Throws a XMPP Stringprep exception if string is the empty string.
155         *
156         * @param string the string to check
157         * @throws XmppStringprepException exception telling that the argument was the empty string
158         */
159        private static void throwIfNullOrEmpty(String string, XmppAddressParttype type) throws XmppStringprepException {
160                if (string == null) {
161                        throw new XmppStringprepException(string, type + " can't be null");
162                }
163                if (string.isEmpty()) {
164                        throw new XmppStringprepException(string, type + " can't be the empty string");
165                }
166        }
167}