private StyleNode _resolveStyleNode()

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


  private StyleNode _resolveStyleNode(
    StyleContext           context,
    boolean                forIconNode,
    StyleSheetList         styleSheets,
    Map<String, StyleNode> resolvedStyles,
    Map<String, StyleNode> resolvedNamedStyles,
    Deque<String>          includesStack,
    Deque<String>          namedIncludesStack,
    String                 id,
    boolean                isNamed,
    String                 cacheId,
    String                 clientRule
    )
  {
    assert (styleSheets != null);
    assert (resolvedStyles != null);
    assert (resolvedNamedStyles != null);
    assert (id != null);

    // First, let's check to see if we've already got a StyleNode for this id
    StyleNode style = null;
    String selector = null;
    String name = null;

    if (cacheId == null) cacheId = id;

    if (isNamed)
    {
      style = resolvedNamedStyles.get(cacheId);
      name = id;
    }
    else
    {
      style = resolvedStyles.get(cacheId);
      selector = id;
    }

    // If we've already got a style, return it and we're done!
    if (style != null)
    {
      // FIXME: AdamWiner - _ERROR_STYLE_NODE is in fact never used!
      
      // We use _ERROR_STYLE_NODE for internal error tracking, but we
      // never return it - return null instead.
      if (style == _ERROR_STYLE_NODE)
        return null;

      return style;
    }

    // Next, make sure we don't have a circular dependency
    if ((isNamed && _stackContains(namedIncludesStack, cacheId)) ||
        (!isNamed && _stackContains(includesStack, cacheId)))
    {
      if (_LOG.isWarning())
        _LOG.warning(_CIRCULAR_INCLUDE_ERROR + id);
      return null;
    }

    // Create the StyleEntry that we're going to use to store properties
    // as we are resolving this style
    StyleEntry entry = new StyleEntry(selector, name, clientRule);

    // Push this style onto the appropriate include stack
    if (isNamed)
    {
      if (namedIncludesStack == null)
        namedIncludesStack = new ArrayDeque<String>();

      namedIncludesStack.push(cacheId);
    }
    else
    {
      if (includesStack == null)
        includesStack = new ArrayDeque<String>();

      includesStack.push(cacheId);
    }

    // styleSheets.styleNodes(id, isNamed) returns a List of StyleNodes that match the StyleContext
    // and have the same selector name. For example, if the css files contains 
    // .someStyle {color: red} .someStyle {font-size: 11px}
    // you will get two StyleNodes, and the properties will get merged together.
    List<StyleNode> nodeList = styleSheets.styleNodes(cacheId, isNamed);
    
    // get the StyleNodes from each iconNodeList and add it to the StyleNode list
    if (forIconNode)
    {
      List<IconNode> iconNodeList = styleSheets.iconNodes(cacheId);

      // protect against null - 
      // iconNodeList could be null if in SkinStyleSheetParserUtils 
      // we thought a selector was an icon because it ended in -icon and we created an IconNode.
      // But we also saw that it had no 'content', so we created a StyleNode.
      // Really this is a mis-named style selector (should have ended with -icon-style),
      // and this resolving work is wasted cycles.
      if (iconNodeList != null)
      {
        for (IconNode iconNode: iconNodeList)
        {
          StyleNode sNode = iconNode.getStyleNode();

          if (sNode != null)
          {
            if (nodeList == null)
              nodeList = new ArrayList<StyleNode>(iconNodeList.size());
            nodeList.add(sNode);
          }
        }
      }        
    }
    _resolveStyleWork(context, id, forIconNode, styleSheets, resolvedStyles, resolvedNamedStyles,  
                      includesStack, namedIncludesStack, entry, nodeList);
    
    // Pop the include stack
    if (isNamed)
    {
      namedIncludesStack.pop();
    }
    else
    {
      includesStack.pop();
    }

    // Set<String> blackList = _DESTYLED_SUPPRESSED_PROPERTIES;
    //Set<String> blackList = _IE_SUPPRESSED_PROPERTIES;
    Set<String> blackList = null;
      
    StyleNode resolvedNode = entry.toStyleNode(blackList);

    // If we got a node, add it in to our list
    if (resolvedNode != null)
    {
      // cache already resolved styles so we don't
      // resolve them again. This saves (a lot of) time.
      // TODO: AdamWiner: entry.toStyleNode() will return
      // null if it's an empty style.  But that means
      // that this cache doesn't get used, so we end
      // up hammering on these.  This doesn't appear
      // to be a performance issue at this time.
      String namedStyle = resolvedNode.getName();
      if (namedStyle != null)
      {
        resolvedNamedStyles.put(resolvedNode.getId(), resolvedNode);
      }
      else 
      {
        String selectorStyle = resolvedNode.getSelector();
        if (selectorStyle != null)
        {
          resolvedStyles.put(resolvedNode.getId(), resolvedNode);
        }
      }
    }
    
    // Convert the StyleEntry to a StyleNode and return it
    return resolvedNode;
  }