changeset 1392:121a87ea1d97

RT-22076: backout patch for RT-22076 until after integration
author David Grieve<david.grieve@oracle.com>
date Mon, 02 Jul 2012 14:15:51 -0400
parents ad5af91935ff
children 80668368c867
files javafx-ui-common/src/com/sun/javafx/css/CompoundSelector.java javafx-ui-common/src/com/sun/javafx/css/Rule.java javafx-ui-common/src/com/sun/javafx/css/Selector.java javafx-ui-common/src/com/sun/javafx/css/SimpleSelector.java javafx-ui-common/src/com/sun/javafx/css/StyleManager.java javafx-ui-common/src/javafx/scene/Node.java javafx-ui-common/test/unit/com/sun/javafx/css/RuleTest.java
diffstat 7 files changed, 56 insertions(+), 161 deletions(-) [+]
line wrap: on
line diff
--- a/javafx-ui-common/src/com/sun/javafx/css/CompoundSelector.java	Fri Jun 29 13:18:52 2012 -0400
+++ b/javafx-ui-common/src/com/sun/javafx/css/CompoundSelector.java	Mon Jul 02 14:15:51 2012 -0400
@@ -211,7 +211,7 @@
     }
 
     @Override
-    boolean mightApply(final String className, final String id, final long[] styleClasses) {
+    boolean mightApply(final String className, final String id, final List<String> styleClasses) {
         return selectors.get(selectors.size()-1).mightApply(className, id, styleClasses);
     }
 
--- a/javafx-ui-common/src/com/sun/javafx/css/Rule.java	Fri Jun 29 13:18:52 2012 -0400
+++ b/javafx-ui-common/src/com/sun/javafx/css/Rule.java	Mon Jul 02 14:15:51 2012 -0400
@@ -122,7 +122,7 @@
         return matches;
     }
 
-    public boolean mightApply(String className, String id, long[] styleClasses) {
+    public boolean mightApply(String className, String id, List<String> styleClasses) {
         for (int i = 0; i < selectors.size(); i++) {
             Selector sel = selectors.get(i);
             if (sel.mightApply(className, id, styleClasses)) return true;
--- a/javafx-ui-common/src/com/sun/javafx/css/Selector.java	Fri Jun 29 13:18:52 2012 -0400
+++ b/javafx-ui-common/src/com/sun/javafx/css/Selector.java	Mon Jul 02 14:15:51 2012 -0400
@@ -81,8 +81,7 @@
     abstract Match matches(Scene scene);
     // same as the matches method expect return true/false rather than a match
     public abstract boolean applies(Node node);
-    abstract boolean mightApply(String className, String id, long[] styleClasses);
-    
+    abstract boolean mightApply(String className, String id, List<String> styleClasses);
     /**
      * Determines whether the current state of the node and its parents
      * matches the pseudoclasses defined (if any) for this selector.
--- a/javafx-ui-common/src/com/sun/javafx/css/SimpleSelector.java	Fri Jun 29 13:18:52 2012 -0400
+++ b/javafx-ui-common/src/com/sun/javafx/css/SimpleSelector.java	Mon Jul 02 14:15:51 2012 -0400
@@ -59,105 +59,6 @@
 final public class SimpleSelector extends Selector {
     static final private Object MAX_CLASS_DEPTH = 255;
     
-    //
-    // The Long value is a bit mask. The upper 4 bits of the mask are used to
-    // hold the index of the mask within the long[] and the remaining bits are
-    // used to hold the mask value. If, for example, "foo" is the 96th entry in
-    // styleClassMask, the upper 4 bits will be 0x01 (foo will be at mask[1]) 
-    // and the remaining bits will have the 36th bit set. 
-    //
-    // When creating the long[] bit set, you get the value from styleClassMask,
-    // mask and shift the upper 4 bits to get the index of the style class in 
-    // the long[], then or the value from styleClassMask with the mask[index]. 
-    // In our example, "foo" will always be at mask[1]
-    //
-    private static final Map<String,Long> styleClassMask = new HashMap<String,Long>();
-    
-    
-    // 4 is arbitrary but allows for 960 style classes. Well, actually 
-    // less since the first bit of each mask[index>0] is wasted since
-    // 61 % 60 is 1, even though the 61st entry is the zeroth value in mask[1]. 
-    // So, 945 style classes.
-    private static final int VALUE_BITS = Long.SIZE-4;
-    
-    // 0x0fffffffffffffff
-    private static final long VALUE_MASK = ~(0xfL << VALUE_BITS);
-        
-    /** 
-     * Convert styleClass string to a bit mask
-     * @param styleClass
-     * @return The upper 4 bits is an index into the long[] mask representation 
-     * of styleClasses. The remaining bits are the bit mask for this styleClass
-     * within the mask[index]
-     */
-    public static long getStyleClassMask(String styleClass) {
-        Long mask = styleClassMask.get(styleClass);
-        if (mask == null) {
-            final int size = styleClassMask.size();
-            final long element = size / VALUE_BITS; // use top bits for element
-            final int exp = size % VALUE_BITS; // remaining bits for value
-            mask = Long.valueOf(
-                (element << VALUE_BITS) | (1L << exp) // same as Math.pow(2,exp)
-            ); 
-            styleClassMask.put(styleClass, mask);
-        }
-        return mask.longValue();
-    }
-
-    /**
-     * Convert a list of style class strings to an array of bit masks.
-     * @param styleClasses
-     * @return The upper 4 bits of each element is an index into the long[] mask
-     * representation of styleClasses. The remaining bits of each element are 
-     * the bit mask for this styleClass within the mask[index]
-     */
-    public static long[] getStyleClassMasks(List<String> styleClasses) {
-        
-        long[] mask = new long[0]; // return zero length if styleClasses is null
-        
-        final int max = styleClasses != null ? styleClasses.size() : -1;
-        for (int n=0; n<max; n++) {
-            final String styleClass = styleClasses.get(n);
-            final long m = getStyleClassMask(styleClass);
-            final long element = (m & ~VALUE_MASK);
-            final int  index = (int)(element >> VALUE_BITS);
-            // need to grow?
-            if (index >= mask.length) {
-                final long[] temp = new long[index+1];
-                System.arraycopy(mask, 0, temp, 0, mask.length);
-                mask = temp;
-            }
-            mask[index] = mask[index] | m;
-        }
-        return mask;
-    }
-
-    public static List<String> getStyleClassStrings(long[] mask) {
-        
-        if (mask == null || mask.length == 0) return Collections.EMPTY_LIST;
-
-        final Map<Long,String> stringMap = new HashMap<Long,String>();
-        for (Map.Entry<String,Long> entry : styleClassMask.entrySet()) {
-            stringMap.put(entry.getValue(), entry.getKey());
-        }
-        final List<String> strings = new ArrayList<String>();
-        for(int index=0; index<mask.length; index++) {
-            final long m = mask[index];
-            final long element = (m & ~VALUE_MASK);
-            for (int exp=0; exp < VALUE_BITS; exp++) {
-                final long key = element | ((1L << exp) & m);
-                if (key != 0) {
-                    final String value = stringMap.get(key);
-                    if (value != null) strings.add(value);
-                }
-            }
-        }
-        // even though the list returned could be modified without causing 
-        // harm, returning an unmodifiableList is consistent with 
-        // SimpleSelector.getStyleClasses()         
-        return Collections.unmodifiableList(strings);
-    }    
-    
     /**
      * If specified in the CSS file, the name of the java class to which
      * this selector is applied. For example, if the CSS file had:
@@ -174,16 +75,15 @@
         return name;
     }
     
+    final private List<String> styleClasses;
+    
     /**
      * @return Immutable List&lt;String&gt; of style-classes of the selector
      */
     public List<String> getStyleClasses() {
-        return getStyleClassStrings(styleClassMasks);
+        return styleClasses;
     }
 
-    /** styleClasses converted to a set of bit masks */
-    final private long[] styleClassMasks;
-    
     final private List<String> pseudoclasses;
     /**
      * @return Immutable List&lt;String&gt; of pseudo-classes of the selector
@@ -222,11 +122,11 @@
         // then match needs to check name
         this.matchOnName = (name != null && !("".equals(name)) && !("*".equals(name)));
 
-        this.styleClassMasks = 
-                (styleClasses != null && styleClasses.isEmpty() == false)
-                ? getStyleClassMasks(styleClasses)
-                : new long[0];
-        this.matchOnStyleClass = (this.styleClassMasks.length > 0);
+        this.styleClasses = 
+                (styleClasses != null) 
+                ? Collections.unmodifiableList(styleClasses)  
+                : Collections.EMPTY_LIST;
+        this.matchOnStyleClass = (this.styleClasses.size() > 0);
 
         this.pseudoclasses = 
                 (pseudoclasses != null) 
@@ -252,7 +152,7 @@
     Match matches(final Node node) {
         if (applies(node)) {
             final int idCount = (matchOnId) ? 1 : 0;
-            return new Match(this, pseudoclasses, idCount, styleClassMasks.length);
+            return new Match(this, pseudoclasses, idCount, styleClasses.size());
         }
         return null;
     }
@@ -276,7 +176,7 @@
     }
 
     @Override 
-    public boolean applies(Node node) {
+    public boolean applies(final Node node) {
         // if the selector has an id,
         // then bail if it doesn't match the node's id
         // (do this first since it is potentially the cheapest check)
@@ -295,14 +195,14 @@
         }
 
         if (matchOnStyleClass) {
-            boolean styleClassMatch = matchStyleClasses(node.impl_cssGetStyleClassBits());
+            boolean styleClassMatch = matchStyleClasses(node.getStyleClass());
             if (!styleClassMatch) return false;
         }
         return true;
     }
 
     @Override
-    boolean mightApply(final String className, final String id, final long[] styleClasses) {
+    boolean mightApply(final String className, final String id, final List<String> styleClasses) {
         if (matchOnName && nameMatchesAtEnd(className)) return true;
         if (matchOnId   && this.id.equals(id)) return true;
         if (matchOnStyleClass) return matchStyleClasses(styleClasses);
@@ -346,8 +246,8 @@
     //
     // This rule matches when class="pastoral blue aqua marine" but does not
     // match for class="pastoral blue".
-    private boolean matchStyleClasses(long[] nodeStyleClasses) {
-        return isSubsetOf(styleClassMasks, nodeStyleClasses);
+    private boolean matchStyleClasses(final List<String> nodeStyleClasses) {
+        return isSubsetOf(styleClasses, nodeStyleClasses);
     }
 
     /**
@@ -360,20 +260,36 @@
       * return true if seq1 is a subset of seq2. That is, all the strings
       * in seq1 are contained in seq2
       */
-    boolean isSubsetOf(long[] seq1, long[] seq2) {
-        
+    boolean isSubsetOf(final List<String> seq1, final List<String> seq2) {
         // if one or the other is null, then they are a subset if both are null
         if (seq1 == null || seq2 == null) return seq1 == null && seq2 == null;
         
         // they are a subset if both are empty
-        if (seq1.length == 0 && seq2.length == 0) return true;
+        if (seq1.isEmpty() && seq2.isEmpty()) return true;
 
         // [foo bar] cannot be a subset of [foo]
-        if (seq1.length > seq2.length) return false;
+        if (seq1.size() > seq2.size()) return false;
+
+        // is [foo] a subset of [foo bar bang]?
+        // Just need to find the first string in seq2 that equals seq1[0]
+        if (seq1.size() == 1) {
+            final String otherString = seq1.get(0);
+            if (otherString == null) return false;
+
+            for (int n=0, max=seq2.size(); n<max; n++) {
+                String item = seq2.get(n);
+                if (item == null) continue;
+                if (item.equals(otherString)) return true;
+            }
+            return false;
+        }
 
         // is [foo bar] a subset of [foo bar bang]?
-        for (int n=0, max=seq1.length; n<max; n++) {
-            if ((seq1[n] & seq2[n]) != seq1[n]) return false;
+        // Check if each string in seq1 is in seq2
+        strSet.clear();
+        for (int n=0, max=seq2.size(); n<max; n++) strSet.add(seq2.get(n));
+        for (int n=0, max=seq1.size(); n<max; n++) {
+            if (! strSet.contains(seq1.get(n))) return false;
         }
         return true;
 
@@ -397,7 +313,7 @@
         if ((this.id == null) ? (other.id != null) : !this.id.equals(other.id)) {
             return false;
         }
-        if (this.styleClassMasks != other.styleClassMasks && (this.styleClassMasks == null || !Arrays.equals(this.styleClassMasks, other.styleClassMasks))) {
+        if (this.styleClasses != other.styleClasses && (this.styleClasses == null || !this.styleClasses.equals(other.styleClasses))) {
             return false;
         }
         return true;
@@ -409,7 +325,7 @@
     @Override public int hashCode() {
         if (hash == -1) {
             hash = name.hashCode();
-            hash = 31 * (hash + (styleClassMasks != null ? Arrays.hashCode(styleClassMasks) : 37));
+            hash = 31 * (hash + styleClasses.hashCode());
             hash = 31 * (hash + (id != null ? id.hashCode() : 1229));
             hash = 31 * (int)(pclassMask ^ (pclassMask >>> 32));
         }
@@ -421,12 +337,9 @@
         StringBuilder sbuf = new StringBuilder();
         if (name != null && name.isEmpty() == false) sbuf.append(name);
         else sbuf.append("*");
-        if (styleClassMasks != null && styleClassMasks.length > 0) {
-            List<String> strings = getStyleClassStrings(styleClassMasks);
-            for(String styleClass : strings) {
-                sbuf.append('.');
-                sbuf.append(styleClass);
-            }
+        for (int n=0; n<styleClasses.size(); n++) {
+            sbuf.append('.');
+            sbuf.append(styleClasses.get(n));
         }
         if (id != null && id.isEmpty() == false) {
             sbuf.append('#');
@@ -444,7 +357,6 @@
     {
         super.writeBinary(os, stringStore);
         os.writeShort(stringStore.addString(name));
-        final List<String> styleClasses = getStyleClasses();
         os.writeShort(styleClasses.size());
         for (String sc  : styleClasses) os.writeShort(stringStore.addString(sc));
         os.writeShort(stringStore.addString(id));
--- a/javafx-ui-common/src/com/sun/javafx/css/StyleManager.java	Fri Jun 29 13:18:52 2012 -0400
+++ b/javafx-ui-common/src/com/sun/javafx/css/StyleManager.java	Mon Jul 02 14:15:51 2012 -0400
@@ -887,10 +887,7 @@
                 if (value != null) strings.add(value);
             }
         }
-        // even though the list returned could be modified without causing 
-        // harm, returning an unmodifiableList is consistent with 
-        // SimpleSelector.getStyleClasses()
-        return Collections.unmodifiableList(strings);
+        return strings;
     }
 
     /*
@@ -1151,7 +1148,7 @@
             // of the node and lookup the associated Cache in the cacheMap
             final String className = node.getClass().getName();
             final String id = node.getId();
-            final long[] styleClass = node.impl_cssGetStyleClassBits();
+            final List<String> styleClass = node.getStyleClass();
             
             final int[] indicesOfParentsWithStylesheets =  
                 getIndicesOfParentsWithStylesheets(
@@ -1331,7 +1328,12 @@
                 final Key newKey = new Key();
                 newKey.className = className;
                 newKey.id = id;
-                newKey.styleClass = styleClass;
+                // Copy the list.
+                // If the contents of the Node's styleClass changes,
+                // the cacheMap lookup should miss.
+                final int nElements = styleClass.size();
+                newKey.styleClass = new ArrayList<String>(nElements);
+                for(int n=0; n<nElements; n++) newKey.styleClass.add(styleClass.get(n));
                 newKey.indices = hasParentStylesheets ? indicesOfParentsWithStylesheets : null;
                 
                 cache = new Cache(this, rules, pseudoclassStateMask, impactsChildren);
@@ -1546,7 +1548,7 @@
         // necessary.
         String className;
         String id;
-        long[] styleClass;
+        List<String> styleClass;
         
         // this will be initialized if a Parent has a stylesheet and will 
         // hold the indices of those Parents with stylesheets (the Parent's
@@ -1574,7 +1576,7 @@
                         || (id != null && id.equals(other.id))
                        )
                     && (   (styleClass == null && other.styleClass == null)
-                        || (styleClass != null && Arrays.equals(styleClass, other.styleClass))
+                        || (styleClass != null && styleClass.containsAll(other.styleClass))
                        );
                 
                 if (eq && indices != null) {
@@ -1601,7 +1603,7 @@
         public int hashCode() {
             int hash = className.hashCode();
             hash = 31 * (hash + ((id == null || id.isEmpty()) ? 1231 : id.hashCode()));
-            hash = 31 * (hash + ((styleClass == null) ? 1237 : Arrays.hashCode(styleClass)));
+            hash = 31 * (hash + ((styleClass == null || styleClass.isEmpty()) ? 1237 : styleClass.hashCode()));
             if (indices != null) hash = 31 * (hash + Arrays.hashCode(indices));
             return hash;
         }
--- a/javafx-ui-common/src/javafx/scene/Node.java	Fri Jun 29 13:18:52 2012 -0400
+++ b/javafx-ui-common/src/javafx/scene/Node.java	Mon Jul 02 14:15:51 2012 -0400
@@ -793,9 +793,6 @@
     private ObservableList<String> styleClass = new TrackableObservableList<String>() {
         @Override
         protected void onChanged(Change<String> c) {
-            // setting styleClassBits to null will cause the bits to get
-            // recalculated on the next call to impl_cssGetStyleClassBits
-            styleClassBits = null;
             impl_reapplyCSS();
         }
 
@@ -818,20 +815,6 @@
         }
     };
     
-    private long[] styleClassBits = new long[0];
-    /**
-     * @treatAsPrivate implementation detail
-     * @deprecated This is an internal API that is not intended for use and will be removed in the next version
-     */
-    @Deprecated
-    public final long[] impl_cssGetStyleClassBits() {
-        if (styleClassBits == null) {
-            styleClassBits = com.sun.javafx.css.SimpleSelector.getStyleClassMasks(styleClass);
-        }
-        // return a copy so caller can't alter styleClassBits itself.
-        return Arrays.copyOf(styleClassBits, styleClassBits.length);
-    }
-    
     public final ObservableList<String> getStyleClass() { 
         return styleClass; 
     }
--- a/javafx-ui-common/test/unit/com/sun/javafx/css/RuleTest.java	Fri Jun 29 13:18:52 2012 -0400
+++ b/javafx-ui-common/test/unit/com/sun/javafx/css/RuleTest.java	Mon Jul 02 14:15:51 2012 -0400
@@ -151,10 +151,9 @@
         String className = "";
         String id = "";
         List<String> styleClasses = null;
-        long[] styleClassBits = null;
         Rule instance = null;
         boolean expResult = false;
-        boolean result = instance.mightApply(className, id, styleClassBits);
+        boolean result = instance.mightApply(className, id, styleClasses);
         assertEquals(expResult, result);
         fail("The test case is a prototype.");
     }