All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.smooks.cartridges.calc.Counter Maven / Gradle / Ivy

There is a newer version: 2.0.1
Show newest version
/*-
 * ========================LICENSE_START=================================
 * smooks-calc-cartridge
 * %%
 * Copyright (C) 2020 Smooks
 * %%
 * Licensed under the terms of the Apache License Version 2.0, or
 * the GNU Lesser General Public License version 3.0 or later.
 * 
 * SPDX-License-Identifier: Apache-2.0 OR LGPL-3.0-or-later
 * 
 * ======================================================================
 * 
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 * 
 *     http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 * 
 * ======================================================================
 * 
 * This program 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 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.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 * =========================LICENSE_END==================================
 */
package org.smooks.cartridges.calc;

import org.smooks.api.ApplicationContext;
import org.smooks.api.ExecutionContext;
import org.smooks.api.SmooksException;
import org.smooks.api.bean.context.BeanContext;
import org.smooks.api.bean.repository.BeanId;
import org.smooks.api.delivery.fragment.Fragment;
import org.smooks.api.delivery.ordering.Producer;
import org.smooks.api.expression.ExpressionEvaluator;
import org.smooks.api.resource.visitor.VisitAfterIf;
import org.smooks.api.resource.visitor.VisitBeforeIf;
import org.smooks.api.resource.visitor.dom.DOMVisitAfter;
import org.smooks.api.resource.visitor.dom.DOMVisitBefore;
import org.smooks.api.resource.visitor.sax.ng.AfterVisitor;
import org.smooks.api.resource.visitor.sax.ng.BeforeVisitor;
import org.smooks.engine.delivery.fragment.NodeFragment;
import org.w3c.dom.Element;

import jakarta.annotation.PostConstruct;
import javax.inject.Inject;
import javax.inject.Named;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * The counter can increment or decrement a value.
 * 

* This counter has extended xml schema configuration. Take a look at the * schema {@link https://www.smooks.org/xsd/smooks/calc-2.0.xsd} for more * information. *

* Example basic configuration: *

 * <resource-config selector="orderItems">
 *    <resource>org.smooks.calc.Counter</resource>
 *    <param name="beanId">count</param>
 * </resource-config>
 * 

* Optional parameters: * <param name="start">1</param> * <param name="amount">2</param> * <param name="amountExpression">incrementAmount</param> * <param name="startExpression">startValue</param> * <param name="resetCondition">count == 10</param> * <param name="direction">DECREMENT</param> * <param name="executeAfter>false</param> *

* Description of configuration properties: * *
    *
  • beanId: The beanId in which the counter value is stored. The value is always stored as a Long type.
  • *
  • start: The counter start value.
  • *
  • startExpression: The result of this expression is the counter start value. * This expression is executed at the first count and every time the counter * is reset. The expression must result in an integer or a long. * If the startIndex attribute of the counter is set then this expression never gets * executed.
  • *
  • amount: The amount that the counter increments or decrements the counter value.
  • *
  • amountExpression: The result of this expression is the amount the counter increments or decrements. * This expression is executed every time the counter counts. * The expression must result in an integer. * If the amount attribute of the counter is set then this expression never gets * executed.
  • *
  • resetCondition: When the expression is set and results in a true value then the counter is reset to * the start index. The expression must result in a boolean.
  • *
  • direction: The direction that the counter counts. Can be INCREMENT (default) or DECREMENT.
  • *
  • executeAfter: If the counter is executed after the element else it will execute before the element. * Default is 'false'.
  • * * @author [email protected] * @since 1.1 */ @VisitBeforeIf(condition = "!executeAfter") @VisitAfterIf(condition = "executeAfter") public class Counter implements BeforeVisitor, AfterVisitor, DOMVisitBefore, DOMVisitAfter, Producer { public static final Long DEFAULT_START_INDEX = 0L; public static final int DEFAULT_AMOUNT = 1; @Inject @Named("beanId") private String beanIdName; @Inject private Optional start; @Inject private Optional amount; @Inject private Optional amountExpression; @Inject private Optional startExpression; @Inject private Optional resetCondition; @Inject private CountDirection direction = CountDirection.INCREMENT; @Inject private Boolean executeAfter = false; private BeanId beanId; @Inject private ApplicationContext appContext; @PostConstruct public void initialize() { beanId = appContext.getBeanIdStore().register(beanIdName); } @Override public void visitBefore(Element element, ExecutionContext executionContext) throws SmooksException { count(executionContext, new NodeFragment(element)); } @Override public void visitAfter(Element element, ExecutionContext executionContext) throws SmooksException { count(executionContext, new NodeFragment(element)); } public void count(ExecutionContext executionContext, Fragment source) { BeanContext beanContext = executionContext.getBeanContext(); Long value = (Long) beanContext.getBean(beanId); if (value == null || (resetCondition.isPresent() && resetCondition.get().eval(beanContext.getBeanMap()))) { value = getStart(beanContext); } else { int amount = getAmount(beanContext); if (direction == CountDirection.INCREMENT) { value = value + amount; } else { value = value - amount; } } beanContext.addBean(beanId, value, source); } private Long getStart(BeanContext beanContext) { if (!start.isPresent() && !startExpression.isPresent()) { return DEFAULT_START_INDEX; } else if (start.isPresent()) { return start.get(); } else { Object result = startExpression.get().getValue(beanContext.getBeanMap()); if (!(result instanceof Long || result instanceof Integer)) { throw new SmooksException("The start expression must result in a Integer or a Long"); } return new Long(result.toString()); } } public Boolean getExecuteAfter() { return executeAfter; } private int getAmount(BeanContext beanContext) { if (!amount.isPresent() && !amountExpression.isPresent()) { return DEFAULT_AMOUNT; } else if (amount.isPresent()) { return amount.get(); } else { Object result = amountExpression.get().getValue(beanContext.getBeanMap()); if (!(result instanceof Integer)) { throw new SmooksException("The amount expression must result in a Integer"); } return (Integer) result; } } public Set getProducts() { return Stream.of(beanIdName).collect(Collectors.toSet()); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy