Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * JBoss, Home of Professional Open Source
   * Copyright 2010, Red Hat, Inc. and/or its affiliates, and individual
   * contributors by the @authors tag. See the copyright.txt in the
   * distribution for a full listing of individual contributors.
   *
   * Licensed under the Apache License, Version 2.0 (the "License");
   * you may not use this file except in compliance with the License.
   * You may obtain a copy of the License at
  * http://www.apache.org/licenses/LICENSE-2.0
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 package org.jboss.weld.bean.proxy;
 
 
A class that holds the interception (and decoration) contexts which are currently in progress.

An interception context is a set of CombinedInterceptorAndDecoratorStackMethodHandler references for which interception is currently suppressed (so that self-invocation is not possible). Such references are added as soon as a CombinedMethodHandler is executed in an interception context that does not hold it.

Classes may create new interception contexts as necessary (e.g. allowing client proxies to create new interception contexts in order to make circular references interceptable multiple times).

Author(s):
Marius Bogoevici
 
     private static ThreadLocal<StackinterceptionContexts = new ThreadLocal<Stack>();
 
     public static class Stack implements RequestScopedItem {
         private boolean removeWhenEmpty;
         private final ThreadLocal<StackinterceptionContexts;
         private boolean valid;
 
         private Stack(ThreadLocal<StackinterceptionContexts) {
             this. = interceptionContexts;
             this. = new ArrayDeque<CombinedInterceptorAndDecoratorStackMethodHandler>();
             /*
              * Setting / removing of a thread-local is much more expensive compared to get. Therefore,
              * if RequestScopedCache is active we register the thread-local for removal at the end of the
              * request. This yields possitive results only if the number of intercepted invocations is large.
              * If it is not, the performance characteristics are similar to explicitly removing the thread-local
              * once the stack gets empty.
              */
             this. = !RequestScopedCache.addItemIfActive(this);
             this. = true;
         }

        
Pushes the given context to the stack if the given context is not on top of the stack already. If push happens, the caller is responsible for calling InterceptionDecorationContext.endInterceptorContext() after the invocation finishes.

Parameters:
context the given context
Returns:
true if the given context was pushed to the top of the stack, false if the given context was on top already
 
         public boolean startIfNotOnTop(CombinedInterceptorAndDecoratorStackMethodHandler context) {
             checkState();
             if (.isEmpty() || peek() != context) {
                 push(context);
                 return true;
             }
             return false;
         }
 
         public void end() {
             pop();
         }
 
         private void push(CombinedInterceptorAndDecoratorStackMethodHandler item) {
             checkState();
             .addFirst(item);
         }
 
             checkState();
             return .peekFirst();
         }
 
             checkState();
             removeIfEmpty();
             return top;
         }
 
         private void checkState() {
            if (!) {
                throw new IllegalStateException("This InterceptionDecorationContext is no longer valid.");
            }
        }
        @Override
        public void invalidate() {
            /*
             * This cached item is being invalidated.
             * It does not necessarily mean that the request is being destroyed - it may just be the case that it is being flushed in the middle
             * of a request (e.g. for AlterableContext.destroy()).
             * Therefore, we cannot remove IDC now but we just set removeWhenEmpty flag and let it remove itself once the stack gets empty.
             */
             = true;
            removeIfEmpty();
        }
        private void removeIfEmpty() {
            if ( && .isEmpty()) {
                .remove();
                 = false;
            }
        }
        public int size() {
            return .size();
        }
        @Override
        public String toString() {
            return "Stack [valid=" +  + ", cached=" + ! + ", elements=" +  + "]";
        }
    }
    private InterceptionDecorationContext() {
    }

    
Peeks the current top of the stack.

Returns:
the current top of the stack
Throws:
java.util.EmptyStackException
        return peek(.get());
    }

    
Peeks the current top of the stack or returns null if the stack is empty

Returns:
the current top of the stack or returns null if the stack is empty
        Stack stack = .get();
        if (stack == null) {
            return null;
        }
        return stack.peek();
    }

    
Indicates whether the stack is empty.
    public static boolean empty() {
        return empty(.get());
    }
    public static void endInterceptorContext() {
        pop(.get());
    }

    
This is called by client proxies. Calling a method on a client proxy means that we left the interception context of the calling bean. Therefore, client proxies call this method to start a new interception context of the called (possibly intercepted) bean. If however there is not interception context at the time the proxy is called (meaning the caller is not intercepted), there is no need to create new interception context. This is an optimization as the first startInterceptorContext call is expensive. If this method returns a non-null value, the caller of this method is required to call InterceptionDecorationContext.Stack.end() on the returned value.
    public static Stack startIfNotEmpty() {
        Stack stack = .get();
        if (empty(stack)) {
            return null;
        }
        return stack;
    }

    
Pushes the given context to the stack if the given context is not on top of the stack already. If this method return a non-null value, the caller is responsible for calling endInterceptorContext() after the invocation finishes.

Parameters:
context the given context
Returns:
true if the given context was pushed to the top of the stack, false if the given context was on top already
        Stack stack = getStack();
        if (stack.startIfNotOnTop(context)) {
            return stack;
        }
        return null;
    }

    
Gets the current Stack. If the stack is not set, a new empty instance is created and set.

Returns:
    public static Stack getStack() {
        Stack stack = .get();
        if (stack == null) {
            stack = new Stack();
            .set(stack);
        }
        return stack;
    }
        if (stack == null) {
            throw new EmptyStackException();
        } else {
            return stack.pop();
        }
    }
        if (stack == null) {
            throw new EmptyStackException();
        } else {
            return stack.peek();
        }
    }
    private static boolean empty(Stack stack) {
        if (stack == null) {
            return true;
        } else {
            return stack.elements.isEmpty();
        }
    }
New to GrepCode? Check out our FAQ X