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;
}