/**
   * Creates a new instance of the element. Override this method to return a concrete subclass of
   * the element.
   *
   * @return the newly generated instance of the element.
   */
  public Element createElement() {
    final Element element = new Element();
    applyElementName(element);
    applyStyle(element.getStyle());

    element.setElementType(new LineSparklineType());
    if (getContent() != null) {
      element.setAttribute(AttributeNames.Core.NAMESPACE, AttributeNames.Core.VALUE, getContent());
    }
    if (getFieldname() != null) {
      element.setAttribute(
          AttributeNames.Core.NAMESPACE, AttributeNames.Core.FIELD, getFieldname());
    }
    if (getFormula() != null) {
      final FormulaExpression formulaExpression = new FormulaExpression();
      formulaExpression.setFormula(getFormula());
      element.setAttributeExpression(
          AttributeNames.Core.NAMESPACE, AttributeNames.Core.VALUE, formulaExpression);
    }
    if (spacing != null) {
      element.setAttribute(
          SparklineAttributeNames.NAMESPACE, SparklineAttributeNames.SPACING, spacing);
    }
    return element;
  }
  public void testErrorHandlingBad() throws Exception {
    final URL url = getClass().getResource("Prd-3985.prpt");
    final ResourceManager mgr = new ResourceManager();
    final MasterReport report =
        (MasterReport) mgr.createDirectly(url, MasterReport.class).getResource();
    report
        .getReportConfiguration()
        .setConfigProperty(
            "org.pentaho.reporting.engine.classic.core.FailOnAttributeExpressionErrors", "true");

    final FormulaExpression function = new FormulaExpression();
    function.setName("Test");
    function.setFormula("=MULTIVALUEQUERY(\"Bad\")");

    report
        .getReportHeader()
        .setAttributeExpression(AttributeNames.Core.NAMESPACE, AttributeNames.Core.NAME, function);

    try {
      DebugReportRunner.createPDF(report);
      Assert.fail();
    } catch (Exception e) {
      // ignored
    }
  }
 /**
  * Return a completly separated copy of this function. The copy does no longer share any
  * changeable objects with the original function.
  *
  * @return a copy of this function.
  */
 public Expression getInstance() {
   final IndexDataGeneratorFunction instance = (IndexDataGeneratorFunction) super.getInstance();
   instance.model = new TypedTableModel();
   instance.pageFunction = (PageFunction) pageFunction.getInstance();
   instance.dataFormula = (FormulaExpression) dataFormula.getInstance();
   instance.dataStorage = new TreeMap<String, IndexDataHolder>();
   instance.initialized = false;
   return instance;
 }
  /**
   * Creates the text field element.
   *
   * @return the generated text field element
   * @see org.pentaho.reporting.engine.classic.core.elementfactory.ElementFactory#createElement()
   */
  public Element createElement() {
    final Element element = new Element();
    applyElementName(element);
    applyStyle(element.getStyle());
    element.setElementType(new TextFieldType());
    if (getFieldname() != null) {
      element.setAttribute(
          AttributeNames.Core.NAMESPACE, AttributeNames.Core.FIELD, getFieldname());
    }
    if (getFormula() != null) {
      final FormulaExpression formulaExpression = new FormulaExpression();
      formulaExpression.setFormula(getFormula());
      element.setAttributeExpression(
          AttributeNames.Core.NAMESPACE, AttributeNames.Core.VALUE, formulaExpression);
    }

    element.setAttribute(
        AttributeNames.Core.NAMESPACE, AttributeNames.Core.NULL_VALUE, getNullString());
    return element;
  }
  /**
   * Returns the object for this element or null, if this element does not create an object.
   *
   * @return the object.
   * @throws SAXException if an parser error occured.
   */
  public Expression getFormula() throws SAXException {
    if (propertyReadHandler == null) {
      return null;
    }

    String s = propertyReadHandler.getResult();
    if (StringUtils.isEmpty(s, true) == false) {
      final FormulaExpression formulaExpression = new FormulaExpression();
      if (s.startsWith("report:")) {
        s = "=" + s.substring("report:".length()).trim();
      } else {
        s = s.trim();
      }
      if (s.endsWith(";")) {
        s = s.substring(0, s.length() - 1);
      }
      formulaExpression.setFormula(s);
      return formulaExpression;
    }
    return null;
  }
 private Object computeDataValue(final ReportEvent event) {
   final DataRow dataRow = extractDataRow(event);
   if (StringUtils.isEmpty(dataField) == false) {
     return dataRow.get(dataField);
   }
   try {
     this.dataFormula.setRuntime(new WrapperExpressionRuntime(dataRow, getRuntime()));
     return dataFormula.getValue();
   } finally {
     this.dataFormula.setRuntime(null);
   }
 }
  public static void writeExpressionCore(
      final WriteableDocumentBundle bundle,
      final BundleWriterState state,
      final Expression expression,
      final XmlWriter writer,
      final String namespaceUri,
      final String expressionTag,
      final AttributeList expressionAttrList)
      throws IOException, BundleWriterException {
    if (bundle == null) {
      throw new NullPointerException();
    }
    if (state == null) {
      throw new NullPointerException();
    }
    if (expression == null) {
      throw new NullPointerException();
    }
    if (writer == null) {
      throw new NullPointerException();
    }
    if (namespaceUri == null) {
      throw new NullPointerException();
    }
    if (expressionTag == null) {
      throw new NullPointerException();
    }
    if (expressionAttrList == null) {
      throw new NullPointerException();
    }

    if (expression instanceof FormulaExpression) {
      final FormulaExpression fe = (FormulaExpression) expression;
      if (StringUtils.isEmpty(fe.getFormula())) {
        return;
      }
      expressionAttrList.setAttribute(namespaceUri, "formula", fe.getFormula()); // NON-NLS
      writer.writeTag(namespaceUri, expressionTag, expressionAttrList, XmlWriterSupport.CLOSE);
      return;
    }

    if (expression instanceof FormulaFunction) {
      final FormulaFunction fe = (FormulaFunction) expression;
      if (StringUtils.isEmpty(fe.getFormula())) {
        return;
      }
      expressionAttrList.setAttribute(namespaceUri, "formula", fe.getFormula()); // NON-NLS
      expressionAttrList.setAttribute(namespaceUri, "initial", fe.getInitial()); // NON-NLS
      writer.writeTag(namespaceUri, expressionTag, expressionAttrList, XmlWriterSupport.CLOSE);
      return;
    }

    try {

      final String expressionId = expression.getClass().getName();
      expressionAttrList.setAttribute(namespaceUri, "class", expressionId);

      final ExpressionMetaData emd;
      if (ExpressionRegistry.getInstance().isExpressionRegistered(expressionId)) {
        emd = ExpressionRegistry.getInstance().getExpressionMetaData(expressionId);
      } else {
        emd = null;
      }

      if (emd != null) {
        final BeanUtility bu = new BeanUtility(expression);
        final ExpressionPropertyMetaData[] expressionProperties = emd.getPropertyDescriptions();
        boolean propertiesOpen = false;
        for (int i = 0; i < expressionProperties.length; i++) {
          final ExpressionPropertyMetaData metaData = expressionProperties[i];
          final String propertyName = metaData.getName();
          if (isFilteredProperty(propertyName)) {
            continue;
          }
          if (metaData.isComputed()) {
            continue;
          }
          if (propertiesOpen == false) {
            writer.writeTag(namespaceUri, expressionTag, expressionAttrList, XmlWriterSupport.OPEN);
            writer.writeTag(namespaceUri, "properties", XmlWriterSupport.OPEN); // NON-NLS
            propertiesOpen = true;
          }

          copyStaticResources(bundle, state, expression, bu, expressionProperties);
          writeExpressionParameter(
              bundle, state, writer, expression, bu, propertyName, namespaceUri);
        }

        if (propertiesOpen) {
          writer.writeCloseTag();
          writer.writeCloseTag();
        } else {
          writer.writeTag(namespaceUri, expressionTag, expressionAttrList, XmlWriterSupport.CLOSE);
        }
      } else {
        // the classic way, in case the expression does not provide any meta-data. This is
        // in the code for legacy reasons, as there are many expression implementations out there
        // that do not yet provide meta-data descriptions ..

        final BeanUtility beanUtility = new BeanUtility(expression);
        final String[] propertyNames = beanUtility.getProperties();

        for (int i = 0; i < propertyNames.length; i++) {
          final String key = propertyNames[i];
          // filter some of the standard properties. These are system-properties
          // and are set elsewhere
          if (isFilteredProperty(key)) {
            continue;
          }

          writeExpressionParameter(
              bundle, state, writer, expression, beanUtility, key, namespaceUri);
        }
      }
    } catch (IOException ioe) {
      throw ioe;
    } catch (Exception e) {
      throw new BundleWriterException("Unable to extract or write properties.", e);
    }
  }
 /**
  * Clones the expression. The expression should be reinitialized after the cloning.
  *
  * <p>Expressions maintain no state, cloning is done at the beginning of the report processing to
  * disconnect the expression from any other object space.
  *
  * @return a clone of this expression.
  * @throws CloneNotSupportedException this should never happen.
  */
 public Object clone() throws CloneNotSupportedException {
   final IndexDataGeneratorFunction o = (IndexDataGeneratorFunction) super.clone();
   o.dataFormula = (FormulaExpression) dataFormula.clone();
   o.pageFunction = (PageFunction) pageFunction.clone();
   return o;
 }
 public String getDataFormula() {
   return dataFormula.getFormula();
 }