Package org.pentaho.reporting.libraries.css.resolver.impl

Source Code of org.pentaho.reporting.libraries.css.resolver.impl.AbstractStyleResolver

/*!
* 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.resolver.impl;

import java.util.HashMap;
import java.util.Iterator;

import org.pentaho.reporting.libraries.base.config.Configuration;
import org.pentaho.reporting.libraries.base.util.ObjectUtilities;
import org.pentaho.reporting.libraries.css.LibCssBoot;
import org.pentaho.reporting.libraries.css.dom.DefaultLayoutStyle;
import org.pentaho.reporting.libraries.css.dom.DocumentContext;
import org.pentaho.reporting.libraries.css.dom.LayoutElement;
import org.pentaho.reporting.libraries.css.dom.LayoutStyle;
import org.pentaho.reporting.libraries.css.keys.content.ContentStyleKeys;
import org.pentaho.reporting.libraries.css.model.CSSDeclarationRule;
import org.pentaho.reporting.libraries.css.model.StyleKey;
import org.pentaho.reporting.libraries.css.model.StyleKeyRegistry;
import org.pentaho.reporting.libraries.css.model.StyleRule;
import org.pentaho.reporting.libraries.css.model.StyleSheet;
import org.pentaho.reporting.libraries.css.namespace.NamespaceCollection;
import org.pentaho.reporting.libraries.css.resolver.FunctionEvaluationException;
import org.pentaho.reporting.libraries.css.resolver.StyleResolver;
import org.pentaho.reporting.libraries.css.resolver.function.StyleValueFunction;
import org.pentaho.reporting.libraries.css.values.CSSFunctionValue;
import org.pentaho.reporting.libraries.css.values.CSSValue;
import org.pentaho.reporting.libraries.css.values.CSSValueList;
import org.pentaho.reporting.libraries.css.values.CSSValuePair;
import org.pentaho.reporting.libraries.resourceloader.Resource;
import org.pentaho.reporting.libraries.resourceloader.ResourceManager;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.logging.Log;

public abstract class AbstractStyleResolver implements StyleResolver
{
  private static final String INITIAL_CSS_PREFIX = "org.pentaho.reporting.libraries.css.styles.initial";
  private static final String CSS_VALUE_FUNCTIONS_PREFIX = "org.pentaho.reporting.libraries.css.styles.value-functions.";
  private static final Log logger = LogFactory.getLog(AbstractStyleResolver.class);
  private LayoutStyle initialStyle;
  private DocumentContext documentContext;
  private NamespaceCollection namespaces;
  private StyleKey[] keys;
  private HashMap functions;

  protected AbstractStyleResolver()
  {
    functions = new HashMap();
  }

  public void initialize(final DocumentContext documentContext)
  {
    this.documentContext = documentContext;
    this.namespaces = documentContext.getNamespaces();
    initializeFunctions();
  }

  private void initializeFunctions()
  {
    final Configuration config = LibCssBoot.getInstance().getGlobalConfig();
    Iterator it = config.findPropertyKeys(CSS_VALUE_FUNCTIONS_PREFIX);
    while (it.hasNext())
    {
      final String key = (String) it.next();
      final String value = config.getConfigProperty(key);
      final String name = key.substring(CSS_VALUE_FUNCTIONS_PREFIX.length()).toLowerCase();
      final Object o =
          ObjectUtilities.loadAndInstantiate(value, AbstractStyleResolver.class, StyleValueFunction.class);
      if (o != null)
      {
        functions.put(name, o);
      }
    }
  }

  protected void loadInitialStyle(DocumentContext context)
  {
    this.initialStyle = new DefaultLayoutStyle();
    try
    {
      final ResourceManager manager = documentContext.getResourceManager();

      // Get the configuration file properties for the initial css load
      final Configuration config = LibCssBoot.getInstance().getGlobalConfig();
      Iterator it = config.findPropertyKeys(INITIAL_CSS_PREFIX);
      while (it.hasNext())
      {
        // Get the next initial set of styles to add to the global list of initial styles
        final String key = (String) it.next();
        final String value = config.getConfigProperty(key);

        // Load the style information
        final Resource resource = manager.createDirectly(value, StyleSheet.class);
        final StyleSheet initialStyleSheet = (StyleSheet) resource.getResource();

        // Add to the master list
        final int rc = initialStyleSheet.getRuleCount();
        for (int i = 0; i < rc; i++)
        {
          final StyleRule rule = initialStyleSheet.getRule(i);
          if (rule instanceof CSSDeclarationRule)
          {
            final CSSDeclarationRule drule = (CSSDeclarationRule) rule;
            copyStyleInformation(initialStyle, drule, null);
          }
        }
      }
    }
    catch (Exception e)
    {
      logger.error("Initial-StyleSheet could not be parsed. This is a FATAL error.", e);
      throw new IllegalStateException("Initial-StyleSheet could not be parsed. This is a FATAL error.");
    }
  }

  protected void copyStyleInformation
      (final LayoutStyle target, final CSSDeclarationRule rule, final LayoutElement element)
  {
    try
    {
      final StyleRule parentRule = rule.getParentRule();
      if (parentRule instanceof CSSDeclarationRule)
      {
        copyStyleInformation(target, (CSSDeclarationRule) parentRule, element);
      }

      if (element == null)
      {
        final StyleKey[] propertyKeys = rule.getPropertyKeysAsArray();
        for (int i = 0; i < propertyKeys.length; i++)
        {
          final StyleKey key = propertyKeys[i];
          final CSSValue propertyCSSValue = rule.getPropertyCSSValue(key);
          if (propertyCSSValue != null)
          {
            target.setValue(key, propertyCSSValue);
          }
        }
        return;
      }

      final StyleKey[] propertyKeys = rule.getPropertyKeysAsArray();
      final CSSValue[] values = rule.getStyleValues();
      for (int i = 0; i < values.length; i++)
      {
        final StyleKey key = propertyKeys[i];
        final CSSValue value = rule.getPropertyCSSValue(key);
        if (ContentStyleKeys.CONTENT.equals(key) ||
            ContentStyleKeys.STRING_DEFINE.equals(key) ||
            ContentStyleKeys.STRING_SET.equals(key))
        {
          // dont resolve that one ..
          values[i] = value;
        }
        else
        {
          values[i] = resolveValue(value, element);
        }
      }

      for (int i = 0; i < values.length; i++)
      {
        final StyleKey key = propertyKeys[i];

        final CSSValue value = values[i];
        if (value != null)
        {
          target.setValue(key, value);
        }
      }
    }
    catch (FunctionEvaluationException e)
    {
      // something went terribly wrong
//      Log.debug("Skipping rule, as resolving failed.");
    }

  }

  protected CSSValue resolveValue(final CSSValue value, final LayoutElement element)
      throws FunctionEvaluationException

  {
    if (element == null)
    {
      return value;
    }
    if (value == null)
    {
      return null;
    }
    if (containsResolveableFunction(value) == false)
    {
      return value;
    }

    if (value instanceof CSSFunctionValue)
    {
      // thats plain and simple - resolve it directly.
      final CSSFunctionValue functionValue = (CSSFunctionValue) value;
      final String name = functionValue.getFunctionName().toLowerCase();
      final StyleValueFunction o = (StyleValueFunction) functions.get(name);
      if (o == null)
      {
        throw new FunctionEvaluationException("No such function registered: " + name);
      }
      return o.evaluate(documentContext, element, (CSSFunctionValue) value);
    }
    else if (value instanceof CSSValueList)
    {
      final CSSValueList list = (CSSValueList) value;
      final int length = list.getLength();
      final CSSValue[] retValus = new CSSValue[length];
      for (int i = 0; i < length; i++)
      {
        final CSSValue item = list.getItem(i);
        retValus[i] = resolveValue(item, element);
      }
      return new CSSValueList(retValus);
    }
    else if (value instanceof CSSValuePair)
    {
      final CSSValuePair pair = (CSSValuePair) value;
      return new CSSValuePair
          (resolveValue(pair.getFirstValue(), element),
              resolveValue(pair.getSecondValue(), element));
    }
    else
    {
      return value;
    }
  }

  protected boolean containsResolveableFunction(final CSSValue value)
  {
    if (value == null)
    {
      return false;
    }
    if (value instanceof CSSFunctionValue)
    {
      return true;
    }

    if (value instanceof CSSValueList)
    {
      final CSSValueList list = (CSSValueList) value;
      final int length = list.getLength();
      for (int i = 0; i < length; i++)
      {
        final CSSValue item = list.getItem(i);
        if (containsResolveableFunction(item))
        {
          return true;
        }
      }
      return false;
    }

    if (value instanceof CSSValuePair)
    {
      final CSSValuePair pair = (CSSValuePair) value;
      if (containsResolveableFunction(pair.getFirstValue()))
      {
        return true;
      }
      if (containsResolveableFunction(pair.getSecondValue()))
      {
        return true;
      }
      return false;
    }
    return false;
  }

  public LayoutStyle getInitialStyle()
  {
    return initialStyle;
  }

  protected DocumentContext getDocumentContext()
  {
    return documentContext;
  }

  protected StyleKey[] getKeys()
  {
    if (keys == null)
    {
      keys = StyleKeyRegistry.getRegistry().getKeys();
    }
    return keys;
  }

  protected NamespaceCollection getNamespaces()
  {
    return namespaces;
  }

  protected abstract void resolveOutOfContext(LayoutElement element);

}
TOP

Related Classes of org.pentaho.reporting.libraries.css.resolver.impl.AbstractStyleResolver

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.