1 /* 2 * Copyright (c) 2010, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. Oracle designates this 8 * particular file as subject to the "Classpath" exception as provided 9 * by Oracle in the LICENSE file that accompanied this code. 10 * 11 * This code is distributed in the hope that it will be useful, but WITHOUT 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 14 * version 2 for more details (a copy is included in the LICENSE file that 15 * accompanied this code). 16 * 17 * You should have received a copy of the GNU General Public License version 18 * 2 along with this work; if not, write to the Free Software Foundation, 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 20 * 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 22 * or visit www.oracle.com if you need additional information or have any 23 * questions. 24 */ 25 26 package com.sun.javafx.css; 27 28 import com.sun.javafx.scene.layout.region.CornerRadiiConverter; 29 import com.sun.javafx.util.Logging; 30 import javafx.css.CssMetaData; 31 import javafx.css.ParsedValue; 32 import javafx.css.StyleConverter; 33 import javafx.css.Styleable; 34 import sun.util.logging.PlatformLogger; 35 import sun.util.logging.PlatformLogger.Level; 36 37 import java.io.DataInputStream; 38 import java.io.DataOutputStream; 39 import java.io.IOException; 40 import java.util.HashMap; 41 import java.util.Map; 42 import java.util.WeakHashMap; 43 44 /** 45 * Converter converts ParsedValueImpl<F,T> from type F to type T. 46 * F is the type of the parsed value, T is the converted type of 47 * the ParsedValueImpl. For example, a converter from String to Color would 48 * be declared 49 * <p> 50 * <code>public Color convert(ParsedValueImpl<String,Color> value, Font font)</code> 51 * </p> 52 */ 53 public class StyleConverterImpl<F, T> extends StyleConverter<F, T> { 54 55 /** 56 * Convert from the constituent values to the target property type. 57 * Implemented by Types that have Keys with subKeys. 58 */ 59 public T convert(Map<CssMetaData<? extends Styleable, ?>,Object> convertedValues) { 60 return null; 61 } 62 63 protected StyleConverterImpl() { 64 super(); 65 } 66 67 public void writeBinary(DataOutputStream os, StringStore sstore) 68 throws IOException { 69 70 String cname = getClass().getName(); 71 int index = sstore.addString(cname); 72 os.writeShort(index); 73 } 74 75 private static Map<ParsedValue, Object> cache; 76 77 static void clearCache() { if (cache != null) cache.clear(); } 78 79 protected T getCachedValue(ParsedValue key) { 80 if (cache != null) { 81 return (T)cache.get(key); 82 } 83 return null; 84 } 85 86 protected void cacheValue(ParsedValue key, Object value) { 87 if (cache == null) cache = new WeakHashMap<>(); 88 cache.put(key, value); 89 } 90 91 // map of StyleConverter class name to StyleConverter 92 private static Map<String,StyleConverter<?, ?>> tmap; 93 94 @SuppressWarnings("rawtypes") 95 public static StyleConverter<?,?> readBinary(DataInputStream is, String[] strings) 96 throws IOException { 97 98 int index = is.readShort(); 99 String cname = strings[index]; 100 101 if (cname == null || cname.isEmpty()) return null; 102 103 if (cname.startsWith("com.sun.javafx.css.converters.EnumConverter")) { 104 return (StyleConverter)com.sun.javafx.css.converters.EnumConverter.readBinary(is, strings); 105 } 106 107 // Make a new entry in tmap, if necessary 108 if (tmap == null || !tmap.containsKey(cname)) { 109 StyleConverter<?,?> converter = getInstance(cname); 110 if (converter == null) { 111 final PlatformLogger logger = Logging.getCSSLogger(); 112 if (logger.isLoggable(Level.SEVERE)) { 113 logger.severe("could not deserialize " + cname); 114 } 115 } 116 if (converter == null) { 117 System.err.println("could not deserialize " + cname); 118 } 119 if (tmap == null) tmap = new HashMap<String,StyleConverter<?,?>>(); 120 tmap.put(cname, converter); 121 return converter; 122 } 123 return tmap.get(cname); 124 } 125 126 // package for unit test purposes 127 static StyleConverter<?,?> getInstance(final String converterClass) { 128 129 StyleConverter<?,?> styleConverter = null; 130 131 switch(converterClass) { 132 case "com.sun.javafx.css.converters.BooleanConverter" : 133 styleConverter = com.sun.javafx.css.converters.BooleanConverter.getInstance(); 134 break; 135 case "com.sun.javafx.css.converters.ColorConverter" : 136 styleConverter = com.sun.javafx.css.converters.ColorConverter.getInstance(); 137 break; 138 case "com.sun.javafx.css.converters.CursorConverter" : 139 styleConverter = com.sun.javafx.css.converters.CursorConverter.getInstance(); 140 break; 141 case "com.sun.javafx.css.converters.EffectConverter" : 142 styleConverter = com.sun.javafx.css.converters.EffectConverter.getInstance(); 143 break; 144 case "com.sun.javafx.css.converters.EffectConverter$DropShadowConverter" : 145 styleConverter = com.sun.javafx.css.converters.EffectConverter.DropShadowConverter.getInstance(); 146 break; 147 case "com.sun.javafx.css.converters.EffectConverter$InnerShadowConverter" : 148 styleConverter = com.sun.javafx.css.converters.EffectConverter.InnerShadowConverter.getInstance(); 149 break; 150 case "com.sun.javafx.css.converters.FontConverter" : 151 styleConverter = com.sun.javafx.css.converters.FontConverter.getInstance(); 152 break; 153 case "com.sun.javafx.css.converters.FontConverter$FontStyleConverter" : 154 case "com.sun.javafx.css.converters.FontConverter$StyleConverter" : 155 styleConverter = com.sun.javafx.css.converters.FontConverter.FontStyleConverter.getInstance(); 156 break; 157 case "com.sun.javafx.css.converters.FontConverter$FontWeightConverter" : 158 case "com.sun.javafx.css.converters.FontConverter$WeightConverter" : 159 styleConverter = com.sun.javafx.css.converters.FontConverter.FontWeightConverter.getInstance(); 160 break; 161 case "com.sun.javafx.css.converters.FontConverter$FontSizeConverter" : 162 case "com.sun.javafx.css.converters.FontConverter$SizeConverter" : 163 styleConverter = com.sun.javafx.css.converters.FontConverter.FontSizeConverter.getInstance(); 164 break; 165 166 case "com.sun.javafx.css.converters.InsetsConverter" : 167 styleConverter = com.sun.javafx.css.converters.InsetsConverter.getInstance(); 168 break; 169 case "com.sun.javafx.css.converters.InsetsConverter$SequenceConverter" : 170 styleConverter = com.sun.javafx.css.converters.InsetsConverter.SequenceConverter.getInstance(); 171 break; 172 173 case "com.sun.javafx.css.converters.PaintConverter" : 174 styleConverter = com.sun.javafx.css.converters.PaintConverter.getInstance(); 175 break; 176 case "com.sun.javafx.css.converters.PaintConverter$SequenceConverter" : 177 styleConverter = com.sun.javafx.css.converters.PaintConverter.SequenceConverter.getInstance(); 178 break; 179 case "com.sun.javafx.css.converters.PaintConverter$LinearGradientConverter" : 180 styleConverter = com.sun.javafx.css.converters.PaintConverter.LinearGradientConverter.getInstance(); 181 break; 182 case "com.sun.javafx.css.converters.PaintConverter$RadialGradientConverter" : 183 styleConverter = com.sun.javafx.css.converters.PaintConverter.RadialGradientConverter.getInstance(); 184 break; 185 186 case "com.sun.javafx.css.converters.SizeConverter" : 187 styleConverter = com.sun.javafx.css.converters.SizeConverter.getInstance(); 188 break; 189 case "com.sun.javafx.css.converters.SizeConverter$SequenceConverter" : 190 styleConverter = com.sun.javafx.css.converters.SizeConverter.SequenceConverter.getInstance(); 191 break; 192 193 case "com.sun.javafx.css.converters.StringConverter" : 194 styleConverter = com.sun.javafx.css.converters.StringConverter.getInstance(); 195 break; 196 case "com.sun.javafx.css.converters.StringConverter$SequenceConverter" : 197 styleConverter = com.sun.javafx.css.converters.StringConverter.SequenceConverter.getInstance(); 198 break; 199 case "com.sun.javafx.css.converters.URLConverter" : 200 styleConverter = com.sun.javafx.css.converters.URLConverter.getInstance(); 201 break; 202 case "com.sun.javafx.css.converters.URLConverter$SequenceConverter" : 203 styleConverter = com.sun.javafx.css.converters.URLConverter.SequenceConverter.getInstance(); 204 break; 205 206 // Region stuff - including 2.x class names 207 case "com.sun.javafx.scene.layout.region.BackgroundPositionConverter" : 208 case "com.sun.javafx.scene.layout.region.BackgroundImage$BackgroundPositionConverter" : 209 styleConverter = com.sun.javafx.scene.layout.region.BackgroundPositionConverter.getInstance(); 210 break; 211 case "com.sun.javafx.scene.layout.region.BackgroundSizeConverter" : 212 case "com.sun.javafx.scene.layout.region.BackgroundImage$BackgroundSizeConverter" : 213 styleConverter = com.sun.javafx.scene.layout.region.BackgroundSizeConverter.getInstance(); 214 break; 215 case "com.sun.javafx.scene.layout.region.BorderImageSliceConverter" : 216 case "com.sun.javafx.scene.layout.region.BorderImage$SliceConverter" : 217 styleConverter = com.sun.javafx.scene.layout.region.BorderImageSliceConverter.getInstance(); 218 break; 219 case "com.sun.javafx.scene.layout.region.BorderImageWidthConverter" : 220 styleConverter = com.sun.javafx.scene.layout.region.BorderImageWidthConverter.getInstance(); 221 break; 222 case "com.sun.javafx.scene.layout.region.BorderImageWidthsSequenceConverter" : 223 styleConverter = com.sun.javafx.scene.layout.region.BorderImageWidthsSequenceConverter.getInstance(); 224 break; 225 case "com.sun.javafx.scene.layout.region.BorderStrokeStyleSequenceConverter" : 226 case "com.sun.javafx.scene.layout.region.StrokeBorder$BorderStyleSequenceConverter" : 227 styleConverter = com.sun.javafx.scene.layout.region.BorderStrokeStyleSequenceConverter.getInstance(); 228 break; 229 case "com.sun.javafx.scene.layout.region.BorderStyleConverter" : 230 case "com.sun.javafx.scene.layout.region.StrokeBorder$BorderStyleConverter" : 231 styleConverter = com.sun.javafx.scene.layout.region.BorderStyleConverter.getInstance(); 232 break; 233 case "com.sun.javafx.scene.layout.region.LayeredBackgroundPositionConverter" : 234 case "com.sun.javafx.scene.layout.region.BackgroundImage$LayeredBackgroundPositionConverter" : 235 styleConverter = com.sun.javafx.scene.layout.region.LayeredBackgroundPositionConverter.getInstance(); 236 break; 237 case "com.sun.javafx.scene.layout.region.LayeredBackgroundSizeConverter" : 238 case "com.sun.javafx.scene.layout.region.BackgroundImage$LayeredBackgroundSizeConverter" : 239 styleConverter = com.sun.javafx.scene.layout.region.LayeredBackgroundSizeConverter.getInstance(); 240 break; 241 case "com.sun.javafx.scene.layout.region.LayeredBorderPaintConverter" : 242 case "com.sun.javafx.scene.layout.region.StrokeBorder$LayeredBorderPaintConverter" : 243 styleConverter = com.sun.javafx.scene.layout.region.LayeredBorderPaintConverter.getInstance(); 244 break; 245 case "com.sun.javafx.scene.layout.region.LayeredBorderStyleConverter" : 246 case "com.sun.javafx.scene.layout.region.StrokeBorder$LayeredBorderStyleConverter" : 247 styleConverter = com.sun.javafx.scene.layout.region.LayeredBorderStyleConverter.getInstance(); 248 break; 249 case "com.sun.javafx.scene.layout.region.RepeatStructConverter" : 250 case "com.sun.javafx.scene.layout.region.BackgroundImage$BackgroundRepeatConverter" : 251 case "com.sun.javafx.scene.layout.region.BorderImage$RepeatConverter" : 252 styleConverter = com.sun.javafx.scene.layout.region.RepeatStructConverter.getInstance(); 253 break; 254 case "com.sun.javafx.scene.layout.region.SliceSequenceConverter" : 255 case "com.sun.javafx.scene.layout.region.BorderImage$SliceSequenceConverter" : 256 styleConverter = com.sun.javafx.scene.layout.region.SliceSequenceConverter.getInstance(); 257 break; 258 case "com.sun.javafx.scene.layout.region.StrokeBorderPaintConverter" : 259 case "com.sun.javafx.scene.layout.region.StrokeBorder$BorderPaintConverter" : 260 styleConverter = com.sun.javafx.scene.layout.region.StrokeBorderPaintConverter.getInstance(); 261 break; 262 case "com.sun.javafx.scene.layout.region.Margins$Converter" : 263 styleConverter = com.sun.javafx.scene.layout.region.Margins.Converter.getInstance(); 264 break; 265 case "com.sun.javafx.scene.layout.region.Margins$SequenceConverter" : 266 styleConverter = com.sun.javafx.scene.layout.region.Margins.SequenceConverter.getInstance(); 267 break; 268 case "javafx.scene.layout.CornerRadiiConverter" : // Fix for RT-39665 269 case "com.sun.javafx.scene.layout.region.CornerRadiiConverter" : 270 styleConverter = CornerRadiiConverter.getInstance(); 271 break; 272 273 // parser stuff 274 case "com.sun.javafx.css.parser.DeriveColorConverter" : 275 styleConverter = com.sun.javafx.css.parser.DeriveColorConverter.getInstance(); 276 break; 277 case "com.sun.javafx.css.parser.DeriveSizeConverter" : 278 styleConverter = com.sun.javafx.css.parser.DeriveSizeConverter.getInstance(); 279 break; 280 case "com.sun.javafx.css.parser.LadderConverter" : 281 styleConverter = com.sun.javafx.css.parser.LadderConverter.getInstance(); 282 break; 283 case "com.sun.javafx.css.parser.StopConverter" : 284 styleConverter = com.sun.javafx.css.parser.StopConverter.getInstance(); 285 break; 286 287 default : 288 final PlatformLogger logger = Logging.getCSSLogger(); 289 if (logger.isLoggable(Level.SEVERE)) { 290 logger.severe("StyleConverterImpl : converter Class is null for : "+converterClass); 291 } 292 break; 293 } 294 295 return styleConverter; 296 } 297 }