Package javaflow.network.impl

Source Code of javaflow.network.impl.PacketImpl$PacketChainIterator

package javaflow.network.impl;

import java.util.*;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicLong;
import javaflow.components.api.NewPacket;
import javaflow.components.api.OutputPort;
import javaflow.components.api.Packet;

class PacketImpl implements Packet, NewPacket {

    private static final AtomicLong packetIdCounter = new AtomicLong();
    //private final PacketListener listener;
    private final long packetId;
    private final Object content;
    private Map<String, Object> metadata;
    private PacketType type = PacketType.NORMAL;
    AtomicBoolean dropped = new AtomicBoolean(false);
    private final OutputPortImpl creatorPort;
    private List<PacketImpl> chained;
    private PacketImpl attachedTo;
    private int packetSize = 1;
    private AbstractRunnableComponent owner = null;
    Set<PacketChainIterator> iterators = Collections.newSetFromMap(new WeakHashMap<PacketChainIterator, Boolean>());

    public PacketImpl(Object content, OutputPortImpl creatorPort) {
        this.content = content;
        this.creatorPort = creatorPort;
        //this.listener = listener;
        this.packetId = packetIdCounter.incrementAndGet();
        if (creatorPort != null) {
            this.owner = creatorPort.owner();
        }
    }

    @Override
    public long getId() {
        return packetId;
    }

    @Override
    public Object getContent() {
        return content;
    }

    @Override
    public void drop() {
        if (!dropped.compareAndSet(false, true)) {
            throw new Error("Already dropped!");
        }
        detach();
        dropRecursively();
    }

    private void dropRecursively() {
        owner.packetDroppedByComponent(this);
        if (chained != null) {
            for (PacketImpl p : chained) {
                p.dropRecursively();
            }
        }
        owner = null;
    }

    @Override
    public Object getContentAndDrop() {
        Object o = getContent();
        drop();
        return o;
    }

    @Override
    public Object getMetadata(String key) {
        if (metadata == null) {
            return null;
        }
        return metadata.get(key);
    }

    @Override
    public PacketImpl setMetadata(String key, Object value) {
        createMetadataIfNecessary();
        metadata.put(key, value);
        return this;
    }
       
    @Override
    public Packet removeMetadata(String key) {
        metadata.remove(key);
        return this;
    }

    @Override
    public Collection<String> getMetadataKeys() {
        if (metadata == null) {
            return Collections.emptyList();
        }
        return metadata.keySet();
    }

    @Override
    public PacketType getType() {
        return type;
    }

    @Override
    public boolean isStartPacket() {
        return PacketType.START.equals(type);
    }

    @Override
    public boolean isEndPacket() {
        return PacketType.END.equals(type);
    }

    @Override
    public String toString() {
        StringBuilder builder = new StringBuilder();
        builder.append("Packet #" + packetId());
        if (isStartPacket()) {
            builder.append(" START ");
        }
        if (isEndPacket()) {
            builder.append(" END ");
        }
        builder.append(" [");
        if (null != getContent()) {
            builder.append(getContent().toString());
        } else {
            builder.append(" no content ");
        }
        builder.append("]");
        return builder.toString();
    }

    boolean isDropped() {
        return dropped.get();
    }

    @Override
    public PacketImpl copyMetadataFrom(Packet packet) {
        final Map<String, Object> otherMetaData = ((PacketImpl) packet).metadata;
        if (otherMetaData != null) {
            createMetadataIfNecessary();
            metadata.putAll(otherMetaData);
        }
        return this;
    }

    private void createMetadataIfNecessary() {
        if (metadata == null) {
            metadata = new HashMap<>();
        }
    }

    @Override
    public void sendTo(OutputPort out) {
        out.send(this);
    }

    @Override
    public PacketImpl beStart() {
        type = PacketType.START;
        return this;
    }

    @Override
    public PacketImpl beEnd() {
        type = PacketType.END;
        return this;
    }

    @Override
    public void send() {
        creatorPort.send(this);
    }

    @Override
    public PacketImpl attach(Packet packet) {
        PacketImpl p = (PacketImpl) packet;
        if (null == chained) {
            chained = new ArrayList<>();
        }
        packet.detach();
        chained.add(p);
        p.attachedTo = this;
        p.attachedTo.alterSize(packetSize);

        for(PacketChainIterator iterator : iterators){
            iterator.indexAdded(chained.size()-1);
        }
        return this;
    }

    @Override
    public boolean isTree() {
        return chained != null && chained.size() > 0;
    }

    @Override
    public PacketImpl getSubchain(Object chainName) {
        if (chained == null){
            return null;
        }
        for (PacketImpl p : chained) {
            if (chainName.equals(p.getContent())) {
                return p;
            }
        }
        return null;
    }

    @Override
    public PacketImpl detach() {
        if (attachedTo != null) {
            int index = attachedTo.chained.indexOf(this);
            attachedTo.chained.remove(index);
            attachedTo.alterSize(-packetSize);
            for(PacketChainIterator iterator : attachedTo.iterators){
                iterator.indexRemoved(index);
            }
            attachedTo = null;
        }
        return this;
    }

    @Override
    public Packet attachedTo() {
        return attachedTo;
    }

    @Override
    public Iterator<Packet> iterator() {
        PacketChainIterator iterator = new PacketChainIterator();
        iterators.add(iterator);
        return iterator;
    }

    private void alterSize(int subsize) {
        int oldSize = packetSize;
        this.packetSize += subsize;
        if (attachedTo != null) {
            attachedTo.alterSize(packetSize - oldSize);
        }
    }

    /**
     * Size of the whole tree including this packet.
     *
     * @return
     */
    protected int totalTreeSize() {
        return packetSize;
    }

    @Override
    public boolean isNormalPacket() {
        return PacketType.NORMAL.equals(type);
    }

    public long packetId() {
        return packetId;
    }

    void arrivedAtComponent(AbstractRunnableComponent component) {
        this.owner = component;
        component.packetArrived(this);
        if (chained != null) {
            for (PacketImpl p : chained) {
                p.arrivedAtComponent(component);
            }
        }
    }

    void owner(AbstractRunnableComponent owner) {
        this.owner = owner;
    }

    int ownerId() {
        return owner.componentId();
    }

    void leftComponentTowards(InputPortImpl inputPort) {
        owner.packetLeftComponent(this,inputPort.owner());
        owner = null;
        if (chained != null) {
            for (PacketImpl p : chained) {
                p.leftComponentTowards(inputPort);
            }
        }
    }

    @Override
    public int chainSize() {
        if (chained != null) {
            return chained.size();
        }
        return 0;
    }

    private class PacketChainIterator implements Iterator<Packet> {
        int nextIndex = 0;
        boolean started = false;

        @Override
        public boolean hasNext() {
            return chained != null && nextIndex < chained.size();
        }


        @Override
        public Packet next() {
            started = true;
            Packet packet = chained.get(nextIndex);
            nextIndex++;
            return packet;
        }

        @Override
        public void remove() {
            if (!started){
                throw new IllegalStateException("You must call next before removing anything!");
            }
            chained.get(nextIndex).detach();
        }

        public void indexRemoved(int i) {
            if (i<= nextIndex){
                nextIndex--;
            }
            if (nextIndex <0){
                nextIndex = 0;
            }

        }

        public void indexAdded(int i) {
            if (i< nextIndex){
                nextIndex++;
            }
        }
    }
}
TOP

Related Classes of javaflow.network.impl.PacketImpl$PacketChainIterator

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.