Package eu.bges

Source Code of eu.bges.CssUtil

/*
* Copyright 2014 Matthias Braun
*
* This library is free software: you can redistribute it and/or modify it under
* the terms of the GNU Lesser General Public License as published by the Free
* Software Foundation, either version 3 of the License, or (at your option) any
* later version.
*
* This library is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
* FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library. If not, see <http://www.gnu.org/licenses/>.
*/

package eu.bges;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.css.sac.InputSource;
import org.w3c.dom.css.CSSRule;
import org.w3c.dom.css.CSSRuleList;
import org.w3c.dom.css.CSSStyleDeclaration;
import org.w3c.dom.css.CSSStyleRule;
import org.w3c.dom.css.CSSStyleSheet;
import org.w3c.dom.css.CSSValue;

import com.google.common.base.Optional;
import com.steadystate.css.dom.CSSStyleSheetImpl;
import com.steadystate.css.parser.CSSOMParser;

/**
* Provides constants and functions for dealing with Cascading Style Sheets.
*
* @author Matthias Braun
* @see <a href="http://cssparser.sourceforge.net/apidocs/index.html">CSS
*      parser</a>
*
*
*/
public final class CssUtil {
    /**
     * Selectors and their attributes found in a typical CSS file.
     */
    public static final String FONT_SIZE = "font-size",
            FONT_FAMILY = "font-family", STROKE = "stroke",
            STROKE_OPACITY = "stroke-opacity", STROKE_WIDTH = "stroke-width",
            FILL_OPACITY = "fill-opacity", FILL = "fill",
            BACKGROUND_COLOR = "background-color", WIDTH = "width",
            HEIGHT = "height", BODY = "body";
    private static final Logger LOG = LoggerFactory.getLogger(CssUtil.class);

    /** This is a utility class not meant to be instantiated by others. */
    private CssUtil() {
    }

    /**
     * Get the value of a property from a CSS file.
     *
     * @param cssFile
     *            The Cascading Style Sheet file.
     * @param selector
     *            The selector to which the property belongs.
     * @param property
     *            The property whose value we want to know.
     * @return The property's value wrapped in an {@code Optional} in case the
     *         property doesn't exist or the CSS file could not be read.
     */
    public static Optional<String> getValue(final File cssFile,
            final String selector, final String property) {
        String value = null;
        final List<CSSStyleRule> rules = getRules(getStyleSheet(cssFile));
        final Optional<CSSStyleDeclaration> styleMaybe = getStyle(rules,
                selector);
        if (styleMaybe.isPresent()) {
            final CSSStyleDeclaration style = styleMaybe.get();
            final CSSValue val = style.getPropertyCSSValue(property);
            if (val == null) {
                // The property might be a CSS shorthand property
                final String strVal = style.getPropertyValue(property);
                if (!strVal.isEmpty()) {
                    value = strVal;
                }
            } else {
                value = val.getCssText();
            }
        }
        return Optional.fromNullable(value);
    }

    /**
     * Set a new value of property in a CSS file.
     * <p>
     * This either overwrites the value of an existing property or it creates a
     * new property with the specified value.
     *
     * @param cssFile
     *            The CSS file we want to change.
     * @param selector
     *            The selector to which the property belongs.
     * @param property
     *            The property whose value we want to change.
     * @param newValue
     *            This is the value the property has after we changed it.
     * @return Whether the setting of the value was successful.
     */
    public static boolean setValue(final File cssFile, final String selector,
            final String property, final String newValue) {
        return setValue(cssFile, selector, property, newValue, "");

    }

    /**
     * Set a new value for a property in a CSS file.
     * <p>
     * This either overwrites the value of an existing property or it creates a
     * new property with the specified value.
     *
     * @param cssFile
     *            The CSS file we want to change.
     * @param selector
     *            The selector to which the property belongs.
     * @param property
     *            The property whose value we want to change.
     * @param newValue
     *            This is the value the property has after we changed it.
     * @param priority
     *            The new priority the property should get (e.g., 'important').
     *            The empty string means that the priority isn't set.
     * @return Whether the setting of the value was successful.
     */
    public static boolean setValue(final File cssFile, final String selector,
            final String property, final String newValue, final String priority) {
        boolean success = false;
        final CSSStyleSheet styleSheet = getStyleSheet(cssFile);
        final List<CSSStyleRule> rules = getRules(styleSheet);
        final Optional<CSSStyleDeclaration> styleMaybe = getStyle(rules,
                selector);
        if (styleMaybe.isPresent()) {
            final CSSStyleDeclaration style = styleMaybe.get();
            style.setProperty(property, newValue, priority);
            success = IOUtil.write(styleSheet.toString(), cssFile);
        }
        return success;
    }

    /**
     * Get all valid {@code CSSStyleRule}s from a {@code CSSStyleSheet}.
     * <p>
     * If a rule is not valid CSS the parser will continue with the next rule.
     *
     * @param styleSheet
     *            The {@code CSSStyleSheet} containing the rules.
     * @return The CSS rules.
     */
    private static List<CSSStyleRule> getRules(final CSSStyleSheet styleSheet) {
        final List<CSSStyleRule> rules = new ArrayList<>();
        final CSSRuleList ruleList = styleSheet.getCssRules();
        for (int i = 0; i < ruleList.getLength(); i++) {
            final CSSRule rule = ruleList.item(i);
            if (rule instanceof CSSStyleRule) {
                final CSSStyleRule styleRule = (CSSStyleRule) rule;
                rules.add(styleRule);
            }
        }
        return rules;

    }

    /**
     * Find the {@code CSSStyleDeclaration} belonging to a selector among a list
     * of {@code CSSStyleRule}s.
     *
     * @param rules
     *            The {@code CSSStyleRule}s that may contain the selector we are
     *            looking for.
     * @param selector
     *            The selector that defines in what rule we are interested.
     * @return The style declaration of the rule wrapped in an {@code Optional}
     *         in case the rule wasn't found.
     */
    private static Optional<CSSStyleDeclaration> getStyle(
            final List<CSSStyleRule> rules, final String selector) {
        CSSStyleDeclaration styleDeclaration = null;
        for (final CSSStyleRule rule : rules) {
            final String currSelector = rule.getSelectorText();
            if (currSelector.equals(selector)) {
                styleDeclaration = rule.getStyle();
                break;
            }
        }
        return Optional.fromNullable(styleDeclaration);
    }

    /**
     * Turn a {@code File} into an {@code CSSStyleSheet}.
     *
     * @param cssFile
     *            The file containing the Cascading Style Sheet.
     * @return The parsed {@code CSSStyleSheet} or an initialized but empty
     *         {@code CSSStyleSheetImpl} if the parsing was unsuccessful.
     */
    private static CSSStyleSheet getStyleSheet(final File cssFile) {

        CSSStyleSheet sheet = null;
        final InputSource source = new InputSource(cssFile.toURI().toString());
        try {
            sheet = new CSSOMParser().parseStyleSheet(source, null, null);
        } catch (final IOException e) {
            LOG.error("IOException while reading {}", cssFile, e);
        }
        if (sheet == null) {
            sheet = new CSSStyleSheetImpl();
        }
        return sheet;
    }
}
TOP

Related Classes of eu.bges.CssUtil

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.