001/**
002 * AccumulatorReplicator.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 net.sf.jaccumulator.primitives.Primitive;
022import net.sf.jaccumulator.primitives.PrimitiveReplicator;
023import net.sf.jaccumulator.primitives.SealedPrimitive;
024import net.sf.jupperware.association.AssociativeList;
025
026/**
027 * A {@link Replicator replicator} for {@link Accumulator Accumulators}
028 * 
029 * @param <ACCUMULATOR>
030 *        the factory product
031 * @since JAccumulator 4.0
032 * @author Nicole Tedesco (<a
033 *         href="mailto:Nicole@NicoleTedesco.com">Nicole@NicoleTedesco.com</a>)
034 */
035public interface AccumulatorReplicator<ACCUMULATOR extends AccumulatorReplicator<ACCUMULATOR>>
036    extends
037        PrimitiveReplicator<ACCUMULATOR>
038{
039    /**
040     * Minimize implicit loops and produce a <i>shallow</i> copy of this
041     * Accumulator. The new copy will possess its own
042     * {@link Accumulator#members() member} collection management system but
043     * will share each member instance.
044     * 
045     * @return a <i>shallow</i> copy of this Accumulator
046     */
047    @Override
048    public ACCUMULATOR copy();
049
050    /**
051     * Using this Accumulator as a factory, and where possible, produce a new
052     * Accumulator of the same type but directly <i>sharing</i> the
053     * {@link SealedAccumulator#getTarget() target} {@link Primitive} and its
054     * {@link Accumulator#members() relationship} collection. Where direct
055     * sharing is not possible, shallow copies will be performed instead.
056     * 
057     * @param anAccumulator
058     *        an Accumulator to share with
059     * @return a copy of this Accumulator that directly <i>shares</i> the
060     *         {@link SealedAccumulator#getTarget() target} {@link Primitive}
061     *         and and its {@link Accumulator#members() relationship} collection
062     */
063    public ACCUMULATOR copySharing( final Accumulator<?> anAccumulator );
064
065    /**
066     * Using this Accumulator as a factory, and where possible, produce a new
067     * Accumulator of the same type but directly <i>share</i> the specified
068     * relationship collection. Where direct sharing is not possible, shallow
069     * copies will be performed instead.
070     * 
071     * @param members
072     *        the relationship collection to share
073     * @return a copy of this Accumulator that directly <i>shares</i> the
074     *         specified relationship collection
075     */
076    public ACCUMULATOR copySharing(
077        final AssociativeList<Accumulator<?>,Accumulator<?>> members );
078
079    /**
080     * Using this Accumulator as a factory, and where possible, produce a new
081     * Accumulator of the same type but directly <i>share</i> the specified
082     * {@link Primitive} target. Where direct sharing is not possible, shallow
083     * copies will be performed instead.
084     * 
085     * @param members
086     *        the Primitive to share
087     * @return a copy of this Accumulator that directly <i>shares</i> the
088     *         specified Primitive target
089     */
090    public ACCUMULATOR copySharing( final Primitive<?> aTarget );
091
092    /**
093     * Using this Accumulator as a factory, and where possible, produce a new
094     * Accumulator of the same type but directly <i>share</i> the specified
095     * {@link Primitive} target and relationship collection. Where direct
096     * sharing is not possible, shallow copies will be performed instead.
097     * 
098     * @param aTarget
099     *        the Primitive to share
100     * @param members
101     *        the relationship collection to share
102     * @return a copy of this Accumulator that directly <i>shares</i> the
103     *         specified Primitive target and relationship collection
104     */
105    public ACCUMULATOR copySharing(
106        final Primitive<?> aTarget,
107        final AssociativeList<Accumulator<?>,Accumulator<?>> members );
108
109    /**
110     * Using this Accumulator as a factory, produce a new Accumulator of the
111     * same type but initialized with the {@link SealedAccumulator#getTarget()
112     * target} {@link Primitive} and a shallow copy of the
113     * {@link Accumulator#members() members} of the specified Accumulator
114     * 
115     * @param anAccumulator
116     *        an Accumulator to copy from
117     * @return a copy of this Accumulator initialized using the
118     *         {@link SealedAccumulator#getTarget() target} {@link Primitive}
119     *         and a shallow copy of the {@link Accumulator#members() members}
120     *         of the specified Accumulator
121     */
122    public ACCUMULATOR copyUsingAccumulator(
123        final SealedAccumulator<?> anAccumulator );
124
125    /**
126     * Using this Accumulator as a factory, produce a new Accumulator of the
127     * same type, and with a shallow copy of its {@link Accumulator#members()
128     * members}, but initialize the {@link Primitive}
129     * {@link SealedAccumulator#getTarget() target} of the new instance with the
130     * specified value
131     * 
132     * @param aValue
133     *        a new value
134     * @return a new Accumulator of this type, a shallow copy of its current
135     *         {@link Accumulator#members() members}, but a {@link Primitive}
136     *         {@link SealedAccumulator#getTarget() target} initialized using
137     *         the specified value
138     */
139    @Override
140    public ACCUMULATOR copyUsingPrimitive( final SealedPrimitive<?> aValue );
141
142    /**
143     * If this object is already {@link Accumulator Accumulator} then simply
144     * call its {@link #copy()} function, otherwise convert it to a new
145     * Accumulator instance
146     * 
147     * @return a new Accumulator
148     */
149    public Accumulator<?> toAccumulator();
150}