1 /* 2 * Copyright (c) 2011, 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 javafx.css.converter; 27 28 import com.sun.javafx.util.Logging; 29 import javafx.css.ParsedValue; 30 import javafx.css.StyleConverter; 31 import javafx.scene.text.Font; 32 import sun.util.logging.PlatformLogger; 33 import sun.util.logging.PlatformLogger.Level; 34 35 import java.io.DataInputStream; 36 import java.io.DataOutputStream; 37 import java.io.IOException; 38 import java.util.HashMap; 39 import java.util.Locale; 40 import java.util.Map; 41 42 /** 43 * @since 9 44 */ 45 public final class EnumConverter<E extends Enum<E>> extends StyleConverter<String, E> { 46 47 // package for unit testing 48 final Class<E> enumClass; 49 50 public EnumConverter(Class<E> enumClass) { 51 this.enumClass = enumClass; 52 } 53 54 @Override 55 public E convert(ParsedValue<String, E> value, Font not_used) { 56 if (enumClass == null) { 57 return null; 58 } 59 String string = value.getValue(); 60 final int dotPos = string.lastIndexOf('.'); 61 if (dotPos > -1) { 62 string = string.substring(dotPos + 1); 63 } 64 try { 65 string = string.replace('-', '_'); 66 return Enum.valueOf(enumClass, string.toUpperCase(Locale.ROOT)); 67 } catch (IllegalArgumentException e) { 68 // may throw another IllegalArgumentException 69 return Enum.valueOf(enumClass, string); 70 } 71 } 72 73 @Override 74 public void writeBinary(DataOutputStream os, StringStore sstore) throws IOException { 75 super.writeBinary(os,sstore); 76 String ename = enumClass.getName(); 77 int index = sstore.addString(ename); 78 os.writeShort(index); 79 } 80 81 82 public static StyleConverter<?,?> readBinary(DataInputStream is, String[] strings) 83 throws IOException { 84 85 short index = is.readShort(); 86 String ename = 0 <= index && index <= strings.length ? strings[index] : null; 87 88 if (ename == null || ename.isEmpty()) return null; 89 90 if (converters == null || converters.containsKey(ename) == false) { 91 StyleConverter<?,?> converter = getInstance(ename); 92 93 if (converter == null) { 94 final PlatformLogger logger = Logging.getCSSLogger(); 95 if (logger.isLoggable(Level.SEVERE)) { 96 logger.severe("could not deserialize EnumConverter for " + ename); 97 } 98 } 99 100 if (converters == null) converters = new HashMap<String,StyleConverter<?,?>>(); 101 converters.put(ename, converter); 102 return converter; 103 } 104 return converters.get(ename); 105 } 106 107 private static Map<String,StyleConverter<?,?>> converters; 108 109 // package for unit testing 110 static public StyleConverter<?,?> getInstance(final String ename) { 111 112 StyleConverter<?,?> converter = null; 113 114 switch (ename) { 115 case "com.sun.javafx.cursor.CursorType" : 116 converter = new EnumConverter<com.sun.javafx.cursor.CursorType>(com.sun.javafx.cursor.CursorType.class); 117 break; 118 case "javafx.scene.layout.BackgroundRepeat" : 119 case "com.sun.javafx.scene.layout.region.Repeat" : 120 converter = new EnumConverter<javafx.scene.layout.BackgroundRepeat>(javafx.scene.layout.BackgroundRepeat.class); 121 break; 122 case "javafx.geometry.HPos" : 123 converter = new EnumConverter<javafx.geometry.HPos>(javafx.geometry.HPos.class); 124 break; 125 case "javafx.geometry.Orientation" : 126 converter = new EnumConverter<javafx.geometry.Orientation>(javafx.geometry.Orientation.class); 127 break; 128 case "javafx.geometry.Pos" : 129 converter = new EnumConverter<javafx.geometry.Pos>(javafx.geometry.Pos.class); 130 break; 131 case "javafx.geometry.Side" : 132 converter = new EnumConverter<javafx.geometry.Side>(javafx.geometry.Side.class); 133 break; 134 case "javafx.geometry.VPos" : 135 converter = new EnumConverter<javafx.geometry.VPos>(javafx.geometry.VPos.class); 136 break; 137 case "javafx.scene.effect.BlendMode" : 138 converter = new EnumConverter<javafx.scene.effect.BlendMode>(javafx.scene.effect.BlendMode.class); 139 break; 140 case "javafx.scene.effect.BlurType" : 141 converter = new EnumConverter<javafx.scene.effect.BlurType>(javafx.scene.effect.BlurType.class); 142 break; 143 case "javafx.scene.paint.CycleMethod" : 144 converter = new EnumConverter<javafx.scene.paint.CycleMethod>(javafx.scene.paint.CycleMethod.class); 145 break; 146 case "javafx.scene.shape.ArcType" : 147 converter = new EnumConverter<javafx.scene.shape.ArcType>(javafx.scene.shape.ArcType.class); 148 break; 149 case "javafx.scene.shape.StrokeLineCap" : 150 converter = new EnumConverter<javafx.scene.shape.StrokeLineCap>(javafx.scene.shape.StrokeLineCap.class); 151 break; 152 case "javafx.scene.shape.StrokeLineJoin" : 153 converter = new EnumConverter<javafx.scene.shape.StrokeLineJoin>(javafx.scene.shape.StrokeLineJoin.class); 154 break; 155 case "javafx.scene.shape.StrokeType" : 156 converter = new EnumConverter<javafx.scene.shape.StrokeType>(javafx.scene.shape.StrokeType.class); 157 break; 158 case "javafx.scene.text.FontPosture" : 159 converter = new EnumConverter<javafx.scene.text.FontPosture>(javafx.scene.text.FontPosture.class); 160 break; 161 case "javafx.scene.text.FontSmoothingType" : 162 converter = new EnumConverter<javafx.scene.text.FontSmoothingType>(javafx.scene.text.FontSmoothingType.class); 163 break; 164 case "javafx.scene.text.FontWeight" : 165 converter = new EnumConverter<javafx.scene.text.FontWeight>(javafx.scene.text.FontWeight.class); 166 break; 167 case "javafx.scene.text.TextAlignment" : 168 converter = new EnumConverter<javafx.scene.text.TextAlignment>(javafx.scene.text.TextAlignment.class); 169 break; 170 171 default : 172 // 173 // Enum types that are not in the javafx-ui-common source tree. 174 // 175 // Because the parser doesn't explicitly know about these enums 176 // outside of the javafx-ui-common package, I don't expect these 177 // EnumConverters to have been persisted. For example, the 178 // -fx-text-overrun and -fx-content-display properties, will yield 179 // a ParsedValue<String,String> with a null converter. 180 // 181 // If assertions are disabled, then null is returned. The StyleHelper 182 // code will use the StyleableProperty's converter in this case. 183 // 184 assert false : "EnumConverter<"+ ename + "> not expected"; 185 186 final PlatformLogger logger = Logging.getCSSLogger(); 187 if (logger.isLoggable(Level.SEVERE)) { 188 logger.severe("EnumConverter : converter Class is null for : "+ename); 189 } 190 break; 191 } 192 193 return converter; 194 } 195 196 197 @Override 198 public boolean equals(Object other) { 199 if (other == this) return true; 200 if (other == null || !(other instanceof EnumConverter)) return false; 201 return (enumClass.equals(((EnumConverter)other).enumClass)); 202 } 203 204 @Override 205 public int hashCode() { 206 return enumClass.hashCode(); 207 } 208 209 @Override 210 public String toString() { 211 return "EnumConveter[" + enumClass.getName() + "]"; 212 } 213 }