/*! * This program is free software; you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License, version 2.1 as published by the Free Software * Foundation. * * You should have received a copy of the GNU Lesser General Public License along with this * program; if not, you can obtain a copy at http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html * or from the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. * * This program 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. * * Copyright (c) 2002-2013 Pentaho Corporation.. All rights reserved. */ package org.pentaho.reporting.libraries.css.model; import org.pentaho.reporting.libraries.css.parser.StyleSheetParserUtil; import org.pentaho.reporting.libraries.css.values.CSSValue; import org.pentaho.reporting.libraries.resourceloader.ResourceKey; import org.pentaho.reporting.libraries.resourceloader.ResourceManager; import java.util.Arrays; /** * This class is a merger between the CSSStyleDeclaration and the other stylerule classes holding property name pairs. * Actually, this is what once was called a stylesheet in JFreeReport. * <p/> * StyleProperties are key as Strings and have CSSValues as mapped values.. * * @author Thomas Morgner */ public abstract class CSSDeclarationRule extends StyleRule { private CSSValue[] styleValues; private boolean[] importantValues; private StyleSheetParserUtil styleSheetParserUtil; protected CSSDeclarationRule( final StyleSheet parentStyle, final StyleRule parentRule ) { super( parentStyle, parentRule ); } public boolean isImportant( StyleKey propertyName ) { if ( propertyName == null ) { throw new NullPointerException(); } if ( importantValues == null ) { return false; } return importantValues[ propertyName.index ]; } protected void setImportant( StyleKey propertyName, final boolean important ) { if ( propertyName == null ) { throw new NullPointerException(); } if ( importantValues == null ) { final StyleKeyRegistry styleKeyRegistry = getStyleKeyRegistry(); importantValues = new boolean[ styleKeyRegistry.getKeyCount() ]; } importantValues[ propertyName.index ] = important; } public CSSValue getPropertyCSSValue( StyleKey propertyName ) { if ( propertyName == null ) { throw new NullPointerException(); } if ( styleValues == null ) { return null; } return styleValues[ propertyName.index ]; } /** * Parses the given value for the stylekey. As stylekeys are only defined for atomic style declarations, this method * will only affect a single name-value pair. * * @param styleKey * @param value */ public void setPropertyValueAsString( final StyleKey styleKey, final String value ) { final StyleSheet parentStyle = getParentStyle(); final ResourceKey source; if ( parentStyle == null ) { source = null; } else { source = parentStyle.getSource(); } if ( styleSheetParserUtil == null ) { styleSheetParserUtil = new StyleSheetParserUtil(); } final StyleSheet parent = getParentStyle(); final CSSStyleRule cssValues; if ( parent != null ) { cssValues = styleSheetParserUtil.parseStyles ( parent.getNamespaces(), styleKey.getName(), value, source, parent.getResourceManager(), StyleKeyRegistry.getRegistry() ); } else { final ResourceManager resourceManager = new ResourceManager(); resourceManager.registerDefaults(); cssValues = styleSheetParserUtil.parseStyles ( null, styleKey.getName(), value, source, resourceManager, StyleKeyRegistry.getRegistry() ); } if ( cssValues != null ) { if ( cssValues.isEmpty() ) { return; } final boolean[] importantFlags = cssValues.getImportantValues(); final CSSValue[] values = cssValues.getStyleValues(); final StyleKey[] keys = cssValues.getPropertyKeysAsArray(); for ( int i = 0; i < values.length; i++ ) { final CSSValue cssValue = values[ i ]; if ( cssValue != null ) { setPropertyValue( keys[ i ], cssValue, importantFlags[ i ] ); } } } } public void setPropertyValue( StyleKey propertyName, CSSValue value ) { setPropertyValue( propertyName, value, false ); } public void setPropertyValue( StyleKey propertyName, CSSValue value, boolean important ) { if ( styleValues == null ) { final StyleKeyRegistry styleKeyRegistry = getStyleKeyRegistry(); styleValues = new CSSValue[ styleKeyRegistry.getKeyCount() ]; } styleValues[ propertyName.index ] = value; setImportant( propertyName, important ); } public void removeProperty( StyleKey name ) { if ( styleValues == null ) { return; } setPropertyValue( name, null ); } public void clear() { if ( styleValues != null ) { Arrays.fill( styleValues, null ); } if ( importantValues != null ) { Arrays.fill( importantValues, false ); } } public StyleKey[] getPropertyKeysAsArray() { return getStyleKeyRegistry().getKeys(); } public CSSValue[] getStyleValues() { if ( styleValues == null ) { final StyleKeyRegistry styleKeyRegistry = getStyleKeyRegistry(); styleValues = new CSSValue[ styleKeyRegistry.getKeyCount() ]; } return (CSSValue[]) styleValues.clone(); } public boolean[] getImportantValues() { if ( importantValues == null ) { importantValues = new boolean[ getStyleKeyRegistry().getKeyCount() ]; } return (boolean[]) importantValues.clone(); } public Object clone() throws CloneNotSupportedException { final CSSDeclarationRule rule = (CSSDeclarationRule) super.clone(); if ( importantValues != null ) { rule.importantValues = (boolean[]) importantValues.clone(); } if ( styleValues != null ) { rule.styleValues = (CSSValue[]) styleValues.clone(); } return rule; } public boolean isEmpty() { return importantValues == null && styleValues == null; } }