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}