/** * Checks whether the inheritance hierarchy is correct. An incorrect hierarchy is for example a * loop definition, in which a parent-style extends a child-style: * * <pre> * myStyle extends parent { * font-face: monospace; * } * parent extends grandparent { * font-size: large; * font-face: system; * } * grandparent extends myStyle { * background-color: white; * } * </pre> * * @param style the style whose inheritance hierarchy should be checked. * @throws BuildException when a circle definition is found. */ private void checkInheritanceHierarchy(Style style) { HashMap<String, Boolean> parentNames = new HashMap<String, Boolean>(5); // System.out.println("checking inheritance of style " + style.getSelector()); String originalSelector = style.getSelector(); String parentName = style.getParentName(); while (parentName != null) { // System.out.println( style.getSelector() + " extends " + parentName ); String currentSelector = style.getSelector(); parentName = parentName.toLowerCase(); if (parentNames.get(parentName) == null) { // okay, this ancestor is not known yet. parentNames.put(parentName, Boolean.TRUE); } else { throw new BuildException( "Invalid CSS code: Loop in inheritance found: The style [" + originalSelector + "] extends the child-style [" + parentName + "]. Please check your extends operator."); } style = getStyle(parentName); if (style == null) { throw new BuildException( "Invalid CSS code: The style [" + currentSelector + "] extends the non-existing style [" + parentName + "]. Please define the style [" + parentName + "] or remove the extends operator."); } parentName = style.getParentName(); } }
private void inheritDo(Style style, HashSet<String> set) { String parentName = style.getParentName(); String currentName = style.getSelector(); if (parentName == null) { // System.out.println("style [" + currentName + "] no parent."); return; // No parent. } else if (set.contains(currentName)) { // System.out.println("style [" + currentName + "] has been set."); return; // Has been set } else { checkInheritanceHierarchy(style); Style parent = getStyle(parentName); // System.out.println("inheriting style [" + currentName + "] from style [" + parentName + // "]."); if (parent == null) { throw new BuildException( "Invalid CSS code: the style [" + currentName + "] extends the non-existing style [" + parentName + "]."); } inheritDo(parent, set); style.setParent(parent); set.add(currentName); } }
/** * Sets the parents of the styles. This method is automatically called when the sourcecode will be * retrieved. * * @throws BuildException when invalid inheritances are found. * @see #isInherited() * @see #getSourceCode() */ public void oldInherit() { // create default-style when not explicitly defined: if (this.stylesByName.get("default") == null) { addCssBlock(DEFAULT_STYLE); } Style[] allStyles = getAllStyles(); for (int i = 0; i < allStyles.length; i++) { Style style = allStyles[i]; // System.out.println("inheriting style [" + style.getSelector() + "]."); checkInheritanceHierarchy(style); String parentName = style.getParentName(); if (parentName != null) { Style parent = getStyle(parentName); if (parent == null) { throw new BuildException( "Invalid CSS code: the style [" + style.getSelector() + "] extends the non-existing style [" + parentName + "]."); } style.setParent(parent); } } this.isInitialised = true; }