001/** 002 * 003 * Copyright © 2014-2019 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.stringprep.simple.SimpleXmppStringprep; 022import org.jxmpp.util.cache.Cache; 023import org.jxmpp.util.cache.LruCache; 024 025public class XmppStringPrepUtil { 026 027 static { 028 // Ensure that there is always at least the simple XMPP stringprep implementation active 029 SimpleXmppStringprep.setup(); 030 } 031 032 private static final Cache<String, String> NODEPREP_CACHE = new LruCache<String, String>(100); 033 private static final Cache<String, String> DOMAINPREP_CACHE = new LruCache<String, String>(100); 034 private static final Cache<String, String> RESOURCEPREP_CACHE = new LruCache<String, String>(100); 035 036 /** 037 * Set the XMPP Stringprep implementation to use. 038 * 039 * @param xmppStringprep the XMPP Stringprep implementation to use. 040 * @deprecated use {@link JxmppContext#setDefaultXmppStringprep(XmppStringprep)} instead. 041 */ 042 @Deprecated 043 // TODO: Remove in JXMPP 0.8. 044 public static void setXmppStringprep(XmppStringprep xmppStringprep) { 045 JxmppContext.setDefaultXmppStringprep(xmppStringprep); 046 } 047 048 /** 049 * Perform localprep on the input String. 050 * 051 * @param string the input String. 052 * @return the localpreped String. 053 * @throws XmppStringprepException if the input String can not be transformed. 054 */ 055 public static String localprep(String string) throws XmppStringprepException { 056 return localprep(string, JxmppContext.getDefaultContext()); 057 } 058 059 /** 060 * Perform localprep on the input String. 061 * 062 * @param string the input String. 063 * @param context the JXMPP JID context. 064 * @return the localpreped String. 065 * @throws XmppStringprepException if the input String can not be transformed. 066 */ 067 public static String localprep(String string, JxmppContext context) throws XmppStringprepException { 068 throwIfNullOrEmpty(string, XmppAddressParttype.localpart); 069 String res; 070 if (context.isCachingEnabled()) { 071 res = NODEPREP_CACHE.lookup(string); 072 if (res != null) { 073 return res; 074 } 075 } 076 077 res = context.xmppStringprep.localprep(string); 078 079 if (context.isCachingEnabled()) { 080 NODEPREP_CACHE.put(string, res); 081 } 082 return res; 083 } 084 085 /** 086 * Perform domainprep on the input String. 087 * 088 * @param string the input String. 089 * @return the domainprep String. 090 * @throws XmppStringprepException if the input String can not be transformed. 091 */ 092 public static String domainprep(String string) throws XmppStringprepException { 093 return domainprep(string, JxmppContext.getDefaultContext()); 094 } 095 096 097 /** 098 * Perform domainprep on the input String. 099 * 100 * @param string the input String. 101 * @param context the JXMPP JID context. 102 * @return the domainprep String. 103 * @throws XmppStringprepException if the input String can not be transformed. 104 */ 105 public static String domainprep(String string, JxmppContext context) throws XmppStringprepException { 106 throwIfNullOrEmpty(string, XmppAddressParttype.domainpart); 107 String res; 108 if (context.isCachingEnabled()) { 109 res = DOMAINPREP_CACHE.lookup(string); 110 if (res != null) { 111 return res; 112 } 113 } 114 115 res = context.xmppStringprep.domainprep(string); 116 117 if (context.isCachingEnabled()) { 118 DOMAINPREP_CACHE.put(string, res); 119 } 120 return res; 121 } 122 123 /** 124 * Perform resourceprep on the input String. 125 * 126 * @param string the input String. 127 * @return the resourceprep String. 128 * @throws XmppStringprepException if the input String can not be transformed. 129 */ 130 public static String resourceprep(String string) throws XmppStringprepException { 131 return resourceprep(string, JxmppContext.getDefaultContext()); 132 } 133 134 /** 135 * Perform resourceprep on the input String. 136 * 137 * @param string the input String. 138 * @param context the JXMPP JID context. 139 * @return the resourceprep String. 140 * @throws XmppStringprepException if the input String can not be transformed. 141 */ 142 public static String resourceprep(String string, JxmppContext context) throws XmppStringprepException { 143 throwIfNullOrEmpty(string, XmppAddressParttype.resourcepart); 144 String res; 145 if (context.isCachingEnabled()) { 146 res = RESOURCEPREP_CACHE.lookup(string); 147 if (res != null) { 148 return res; 149 } 150 } 151 152 res = context.xmppStringprep.resourceprep(string); 153 154 if (context.isCachingEnabled()) { 155 RESOURCEPREP_CACHE.put(string, res); 156 } 157 return res; 158 } 159 160 /** 161 * Set the maximum cache sizes. 162 * 163 * @param size the maximum cache size. 164 */ 165 public static void setMaxCacheSizes(int size) { 166 NODEPREP_CACHE.setMaxCacheSize(size); 167 DOMAINPREP_CACHE.setMaxCacheSize(size); 168 RESOURCEPREP_CACHE.setMaxCacheSize(size); 169 } 170 171 /** 172 * Throws a XMPP Stringprep exception if string is the empty string. 173 * 174 * @param string the string to check 175 * @throws XmppStringprepException exception telling that the argument was the empty string 176 */ 177 private static void throwIfNullOrEmpty(String string, XmppAddressParttype type) throws XmppStringprepException { 178 if (string == null) { 179 throw new XmppStringprepException(string, type + " can't be null"); 180 } 181 if (string.isEmpty()) { 182 throw new XmppStringprepException(string, type + " can't be the empty string"); 183 } 184 } 185}