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