private void _resolveStyleWork()

in trinidad-impl/src/main/java/org/apache/myfaces/trinidadinternal/style/xml/parse/StyleSheetDocument.java [803:1000]


  private void _resolveStyleWork(
    StyleContext           context,
    String                 id,
    boolean                forIconNode,
    StyleSheetList         styleSheets,
    Map<String, StyleNode> resolvedStyles,
    Map<String, StyleNode> resolvedNamedStyles,
    Deque<String>          includesStack,
    Deque<String>          namedIncludesStack,
    StyleEntry             entry,
    List<StyleNode>        nodeList)
  {
    if (nodeList != null)
    {
      for (StyleNode node : nodeList)
      {
        // We've got a match!  We need to do the following:
        // 0. Check to see whether we need to reset our properties.
        // 1. Resolve any included styles, and shove those properties
        //    into our StyleEntry.
        // 2. Resolve any included properties, and shove those properties
        //    into our StyleEntry.
        // 3. Remove all properties that were inhibited.
        // 4. Shove all properties from the matching StyleNode into our
        //    StyleEntry, overwriting included values
        // 5. Shove all skin properties from the matching StyleNode into our
        //     StyleEntry, overwriting included values
        // -= Simon Lessard =-
        // FIXME: That sequence looks buggy. If more than 1 matching node 
        //        is found, then the included properties of the second will
        //        have priority over the properties found at step 5 on the
        //        first node, which is most likely incorrect.
        //
        //        A possible fix would be to put entries from the 5 steps 
        //        into 5 different lists then resolve all priorities at the 
        //        end.
        
        // 0. Reset properties?
        if (node.__getResetProperties() || node.isInhibitingAll())
          entry.resetProperties();
    
        // 1. Resolve included styles
        Iterable<IncludeStyleNode> includedStyles = node.getIncludedStyles();
        for (IncludeStyleNode includeStyle : includedStyles)
        {
          String includeID = null;
          boolean includeIsNamed = false;

          if (includeStyle.getName() != null)
          {
            includeID = includeStyle.getName();
            includeIsNamed = true;
          }
          else
          {
            includeID = includeStyle.getSelector();
          }
        
          // for include styles we do not support selectors and properties within client rules
          // this is because, we cannot determine which selector or property should be applied,
          // as the client rules are resolved on the browser.
          // so we look for a selector or property without any client rules.
          // thus pass null for cacheId and clientRule
          StyleNode resolvedNode = _resolveStyleNode(context, forIconNode,
                                                 styleSheets,
                                                 resolvedStyles,
                                                 resolvedNamedStyles,
                                                 includesStack,
                                                 namedIncludesStack,
                                                 includeID,
                                                 includeIsNamed,
                                                 null,
                                                 null);

          if (resolvedNode != null)
            _addIncludedProperties(entry, resolvedNode);
          else 
          {
            // Fortunately this is an uncommon usecase
            // af|foo::some-icon {content: url(); width:16px; height:16px} 
            // // In SkinStyleSheetParserUtils, we are not sure if this is an icon or style 
            // // since there is no explicit 'content' attr. So we create both an Icon and a Style.
            // af|bar::some-icon {-tr-rule-ref: selector("af|foo");} 
            if (_LOG.isFinest() && !forIconNode && StyleUtils.isIcon(includeID) && 
                StyleUtils.isIcon(id))
            {
                _LOG.finest(id + " is being written to the CSS file " +
                  "even though it is likely a Skin Icon Object, not a style.");
  

            }
          }
        }
    
    
        // 2. Resolve included properties
        // color: -tr-property-ref(".AFDefaultFont:alias","background-color");
        Iterable<IncludePropertyNode> includedProperties = node.getIncludedProperties();
        for (IncludePropertyNode includeProperty : includedProperties)
        {
          StyleNode resolvedNode = 
            _resolveIncludedProperties(context, forIconNode, styleSheets, resolvedStyles, 
                                       resolvedNamedStyles, includesStack, namedIncludesStack, 
                                       includeProperty);
          if (resolvedNode != null)
          {
            _addIncludedProperty(entry,
                                 resolvedNode,
                                 includeProperty.getPropertyName(),
                                 includeProperty.getLocalPropertyName());
          }
        }
        
        // 2'. Resolve included properties in a composite property value.
        // e.g., border: 1px solid -tr-property-ref(".AFDarkColor:alias",color);
        // e.g., background: -ms-linear-gradient(top, -tr-property-ref(".AFRed:alias", "color") 0%, -tr-property-ref(".AFGreen:alias","color") 100%);
        Iterable<EmbeddedIncludePropertyNode> embeddedIncludeProperties = 
          node.getEmbeddedIncludeProperties();
        for (EmbeddedIncludePropertyNode embeddedInclude : embeddedIncludeProperties)
        {
          // get each IncludePropertyNode, and resolve it.        
          Map<String, IncludePropertyNode> ipNodes = embeddedInclude.getIncludedProperties();
          Map<String, String> resolvedValues = new HashMap<String, String>();
          
          Iterator<Map.Entry<String,IncludePropertyNode>> entryIter = ipNodes.entrySet().iterator();
          
          while (entryIter.hasNext())
          {
            Map.Entry<String,IncludePropertyNode> currEntry = entryIter.next();
            String placeHolder = currEntry.getKey();
            IncludePropertyNode includeProperty = currEntry.getValue();
            
            StyleNode resolvedNode = _resolveIncludedProperties(context, 
                                                                forIconNode, 
                                                                styleSheets, 
                                                                resolvedStyles,
                                                                resolvedNamedStyles, 
                                                                includesStack, 
                                                                namedIncludesStack,
                                                                includeProperty);
              
            if (resolvedNode != null)
            {
              List<PropertyNode> pNodes = _getIncludedPropertyNodes(
                                            resolvedNode,
                                            includeProperty.getPropertyName(),
                                            includeProperty.getLocalPropertyName());
              // stores all the resolved 'values'. we will concat these values when we
              // create the PropertyNode because these are composite values, like "1px solid red"
              if (pNodes != null && !pNodes.isEmpty())
                resolvedValues.put(placeHolder, pNodes.get(0).getValue());
            }
          }
          
          // here we are. We have processed one EmbeddedIncludePropertyNode's includePropertyNodes.
          // now we need to add to the entry: 
          if (!resolvedValues.isEmpty() || embeddedInclude.getPropertyValues().hasNext())
          {
            String compositeValue = _createCompositeValue(embeddedInclude, resolvedValues);
            String localName = embeddedInclude.getLocalPropertyName();
            PropertyNode propertyNode = new PropertyNode(localName,
                                                         compositeValue);
            
            if (!(localName.startsWith(_TR_PROPERTY_PREFIX)))
              entry.addProperty(propertyNode);
            else
              entry.addSkinProperty(propertyNode);
          }

        }
    
        // 3. Check inhibited properties
        Iterable<String> inhibitedProperties = node.getInhibitedProperties();
        for (String inhibitedPropertyName : inhibitedProperties)
        {
          entry.removeProperty(inhibitedPropertyName);
          entry.removeSkinProperty(inhibitedPropertyName);
        }
        
    
        // 4. Add non-included properties
        Iterable<PropertyNode> properties = node.getProperties();
        for (PropertyNode propertyNode : properties)
        {
          entry.addProperty(propertyNode);
          
        }
        
        // 5. Add non-included skin property node properties
        Iterable<PropertyNode> skinProperties = node.getSkinProperties();
        for (PropertyNode skinPropNode : skinProperties)
        {
          entry.addSkinProperty(skinPropNode);
        }

      }
    }
  }