FileDocCategorySizeDatePackage
FilteringInvocationProcessor.javaAPI DocExample12450Tue May 29 16:56:38 BST 2007com.sun.xml.ws.policy.jaxws.xmlstreamwriter.documentfilter

FilteringInvocationProcessor

public final class FilteringInvocationProcessor extends Object implements com.sun.xml.ws.policy.jaxws.xmlstreamwriter.InvocationProcessor
author
Marek Potociar (marek.potociar at sun.com)

Fields Summary
private static final com.sun.xml.ws.policy.privateutil.PolicyLogger
LOGGER
private static final XMLOutputFactory
XML_OUTPUT_FACTORY
private final XMLStreamWriter
originalWriter
private final XMLStreamWriter
mirrorWriter
private final LinkedList
invocationBuffers
private final StateMachineContext[]
stateMachineContexts
private final List
startBufferingCandidates
private final List
stopBufferingCandidates
private final List
startFilteringCandidates
private int
filteringCount
private boolean
doFiltering
Constructors Summary
public FilteringInvocationProcessor(XMLStreamWriter writer, FilteringStateMachine stateMachines)
Creates a new instance of FilteringInvocationProcessor

        this.originalWriter = writer;
        this.stateMachineContexts = new StateMachineContext[stateMachines.length];
        for (int i = 0; i < stateMachines.length; i++) {
            this.stateMachineContexts[i] = new StateMachineContext(stateMachines[i]);
        }
        
        this.mirrorWriter = XML_OUTPUT_FACTORY.createXMLStreamWriter(new StringWriter());
        this.invocationBuffers = new LinkedList<InvocationBuffer>();
        this.startBufferingCandidates = new LinkedList<StateMachineContext>();
        this.stopBufferingCandidates = new LinkedList<StateMachineContext>();
        this.startFilteringCandidates = new LinkedList<StateMachineContext>();
    
Methods Summary
private voidexecuteCommands(javax.xml.stream.XMLStreamWriter writer, com.sun.xml.ws.policy.jaxws.xmlstreamwriter.documentfilter.FilteringInvocationProcessor$InvocationBuffer invocationBuffer)

        final Queue<Invocation> invocationQueue = invocationBuffer.getQueue();
        while (!invocationQueue.isEmpty()) {
            final Invocation command = invocationQueue.poll();
            try {
                command.execute(writer);
            } catch (InvocationTargetException e) {
                throw LOGGER.logSevereException(new InvocationProcessingException(command, e));
            }
        }
    
public java.lang.Objectprocess(com.sun.xml.ws.policy.jaxws.xmlstreamwriter.Invocation invocation)

        LOGGER.entering(invocation);
        try {
            this.startBufferingCandidates.clear();
            this.stopBufferingCandidates.clear();
            this.startFilteringCandidates.clear();
            for (StateMachineContext context : this.stateMachineContexts) {
                final InvocationProcessingState state = context.getStateMachine().getState(invocation, mirrorWriter);
                
                switch (state) {
                    case START_BUFFERING:
                    case RESTART_BUFFERING:
                        this.startBufferingCandidates.add(context);
                        if (state == START_BUFFERING) {
                            break;
                        }
                    case STOP_BUFFERING:
                        if (context.getBuffer() != null) {
                            this.stopBufferingCandidates.add(context);
                        }
                        break;
                    case START_FILTERING:
                        if (context.getBuffer() != null) {
                            this.startFilteringCandidates.add(context);
                        }
                        filteringCount++;
                        break;
                    case STOP_FILTERING:
                        filteringCount--;
                        break;
                    default:
                        break;
                }
            }
            
            // filtered buffers
            int firstFilteredBufferIndex = invocationBuffers.size();
            for (StateMachineContext context : startFilteringCandidates) {
                final InvocationBuffer buffer = context.getBuffer();
                context.setBuffer(null);
                int currentBufferIndex;
                if ((currentBufferIndex = invocationBuffers.indexOf(buffer)) < firstFilteredBufferIndex) {
                    firstFilteredBufferIndex = currentBufferIndex;
                }
            }
            while (invocationBuffers.size() > firstFilteredBufferIndex) {
                final InvocationBuffer filteredBuffer = invocationBuffers.removeLast();
                filteredBuffer.clear();
            }
            
            // stopped buffers
            for (StateMachineContext context : stopBufferingCandidates) {
                final InvocationBuffer buffer = context.getBuffer();
                context.setBuffer(null);
                if (buffer == null) {
                    continue;
                }
                
                final int newRefCount = buffer.removeReference();
                if (newRefCount == 0) {
                    int bufferIndex;
                    if ((bufferIndex = invocationBuffers.indexOf(buffer)) != -1) {
                        invocationBuffers.remove(bufferIndex);
                        if (bufferIndex == 0) {
                            executeCommands(originalWriter, buffer);
                        } else {
                            invocationBuffers.get(bufferIndex - 1).getQueue().addAll(buffer.getQueue());
                        }
                    }
                }
            }
            
            //started buffers (must be placed after stopped buffers so that restart buffering works properly)
            if (filteringCount == 0 && startBufferingCandidates.size() > 0) {
                final InvocationBuffer buffer = new InvocationBuffer(startBufferingCandidates.size());
                invocationBuffers.addLast(buffer);
                for (StateMachineContext context : startBufferingCandidates) {
                    context.setBuffer(buffer);
                }
            }
            
            // start filtering if it is not active and should be
            if (!doFiltering) {
                doFiltering = filteringCount > 0;
            }
            
            // choose invocation target and execute invocation
            XMLStreamWriter invocationTarget;
            if (doFiltering) {
                doFiltering = filteringCount > 0; // stop filtering for the next call if there are no more filtering requests active
                invocationTarget = mirrorWriter;
            } else {
                if (invocationBuffers.isEmpty()) {
                    invocation.execute(mirrorWriter);
                    invocationTarget = originalWriter;
                } else {
                    invocationBuffers.getLast().getQueue().offer(invocation);
                    invocationTarget = mirrorWriter;
                }
            }
            
            return invocation.execute(invocationTarget);
        } catch (IllegalArgumentException e) {
            throw LOGGER.logSevereException(new InvocationProcessingException(invocation, e));
        } catch (InvocationTargetException e) {
            throw LOGGER.logSevereException(new InvocationProcessingException(invocation, e.getCause()));
        } catch (IllegalAccessException e) {
            throw LOGGER.logSevereException(new InvocationProcessingException(invocation, e));
        } finally {
            LOGGER.exiting();
        }