001/**
002 * MutableAccumulator.java
003 * 
004 * Copyright (c) 2004-2012, Nicole C. Tedesco. All rights reserved.
005 * 
006 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
007 * use this file except in compliance with the License. You may obtain a copy of
008 * the License at:
009 * 
010 * http://www.apache.org/licenses/LICENSE-2.0
011 * 
012 * Unless required by applicable law or agreed to in writing, software
013 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
014 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
015 * License for the specific language governing permissions and limitations under
016 * the License.
017 */
018
019package net.sf.jaccumulator;
020
021import java.util.List;
022
023import net.sf.jaccumulator.primitives.Primitive;
024import net.sf.jupperware.association.AssociativeList;
025
026/**
027 * An <b>Accumulator</b> is a three-way association between a {@link Primitive}
028 * <b>target</b>, a Javascript-like {@link AssociativeList associative} list of
029 * <b>member</b> relationships, and a <b>function</b> defined by the subclass of
030 * Accumulator. The scalar and textual values of the Primitive target are
031 * offered by the Accumulator's own Primitive interface, while the structural
032 * properties of the relationship container are offered through through the
033 * structural queries of the same Primitive interface. For instance, both the
034 * Accumulator's {@link #isEmpty()} and {@link #size()} functions will reflect
035 * the current member count, not the size of the associated Primitive target.
036 * Similarly, the {@link #clear()} and {@link #clearContents()} calls will empty
037 * the relationship collection. To access the structure of the target Primitive,
038 * the use {@link #getTarget()} first. Moreover, {@link #getDomain()} will
039 * reflect the domain of the Accumulator, which will usually be
040 * {@link Domain#ALGEBRAIC ALGEBRAIC}.<br/>
041 * <br/>
042 * Accumulators maintain relationships to other Accumulators, or <i>members</i>
043 * using a Javascript-like {@link AssociativeList associative} list. They keys
044 * in this mapped {@link List}, although they are themselves Accumulators, are
045 * usually implemented by text, and are usually interpreted as attribute names.
046 * The values in this list are, of course, the Accumulator values of those
047 * attributes. Since both keys and values are other Accumulators, it is possible
048 * to build rich, hierarchical structures.<br/>
049 * <br/>
050 * The Accumulator's function can be called through an "apply" protocol which
051 * uses another Accumulator as a parameter and result stack. <h3>Minimizing
052 * Implicit Loops</h3> An important design principle when implementing
053 * {@code apply} or {@link AccumulatorReplicator#copy() copy} functions is to
054 * avoid implicit loops. Instead, function implementors should try to implement
055 * atomic, or near-atomic actions, then leave looping control to the caller. To
056 * support this, the {@code apply} function must return an applicable
057 * {@link ControlIntention}, so that the caller can be appropriately directed
058 * towards their next recommended course of action. The presence of the
059 * Accumulator members collection increases the risk of long implicit looping
060 * outside of the caller's control, which the state machine control strategy is
061 * intended to help avoid.
062 * 
063 * @param <ACCUMULATOR>
064 *        this {@link Accumulator} type
065 * @since JAccumulator 4.0
066 * @author Nicole Tedesco (<a
067 *         href="mailto:nicole@tedesco.name">nicole@tedesco.name</a>)
068 */
069public interface Accumulator<ACCUMULATOR extends Accumulator<ACCUMULATOR>>
070    extends
071        SealedAccumulator<ACCUMULATOR>,
072        MutableAccumulator<ACCUMULATOR>,
073        Primitive<ACCUMULATOR>,
074        Iterable<Accumulator<?>>
075{
076    /**
077     * Apply this Accumulator's association function to the specified
078     * Accumulator, using it as a parameter and result stack
079     * 
080     * @param aStack
081     *        a parameter and result stack
082     * @return the next suggested {@link ControlIntention action} to be taken by
083     *         the caller
084     */
085    public ControlIntention apply( final Accumulator<?> aStack );
086}