private void insertInterceptor()

in core/src/main/java/org/apache/cxf/phase/PhaseInterceptorChain.java [562:692]


    private void insertInterceptor(int phase, PhaseInterceptor<? extends Message> interc, boolean force) {
        InterceptorHolder ih = new InterceptorHolder(interc, phase);
        if (heads[phase] == null) {
            // no interceptors yet in this phase
            heads[phase] = ih;
            tails[phase] = ih;
            hasAfters[phase] = !interc.getAfter().isEmpty();

            int idx = phase - 1;
            while (idx >= 0) {
                if (tails[idx] != null) {
                    break;
                }
                --idx;
            }
            if (idx >= 0) {
                //found something before us, in an earlier phase
                ih.prev = tails[idx];
                ih.next = tails[idx].next;
                if (ih.next != null) {
                    ih.next.prev = ih;
                }
                tails[idx].next = ih;
            } else {
                //did not find something before us, try after
                idx = phase + 1;
                while (idx < heads.length) {
                    if (heads[idx] != null) {
                        break;
                    }
                    ++idx;
                }

                if (idx != heads.length) {
                    //found something after us
                    ih.next = heads[idx];
                    heads[idx].prev = ih;
                }
            }
        } else { // this phase already has interceptors attached

            // list of interceptors that the new interceptor should precede
            Set<String> beforeList = interc.getBefore();

            // list of interceptors that the new interceptor should be after
            Set<String> afterList = interc.getAfter();

            // firstBefore will hold the first interceptor of a given phase
            // that the interceptor to be added must precede
            InterceptorHolder firstBefore = null;

            // lastAfter will hold the last interceptor of a given phase
            // that the interceptor to be added must come after
            InterceptorHolder lastAfter = null;

            String id = interc.getId();
            if (hasAfters[phase] || !beforeList.isEmpty()) {

                InterceptorHolder ih2 = heads[phase];
                while (ih2 != tails[phase].next) {
                    PhaseInterceptor<? extends Message> cmp = ih2.interceptor;
                    String cmpId = cmp.getId();
                    if (cmpId != null && firstBefore == null
                        && (beforeList.contains(cmpId)
                            || cmp.getAfter().contains(id))) {
                        firstBefore = ih2;
                    }
                    if (cmp.getBefore().contains(id)
                        || (cmpId != null && afterList.contains(cmpId))) {
                        lastAfter = ih2;
                    }
                    if (!force && cmpId.equals(id)) {
                        // interceptor is already in chain
                        return;
                    }
                    ih2 = ih2.next;
                }
                if (lastAfter == null && beforeList.contains("*")) {
                    firstBefore = heads[phase];
                }
                
            } else if (!force) {
                // skip interceptor if already in chain
                InterceptorHolder ih2 = heads[phase];
                while (ih2 != tails[phase].next) {
                    if (ih2.interceptor.getId().equals(id)) {
                        return;
                    }
                    ih2 = ih2.next;
                }

            }
            hasAfters[phase] |= !afterList.isEmpty();

            if (firstBefore == null
                && lastAfter == null
                && !beforeList.isEmpty()
                && afterList.isEmpty()) {
                //if this interceptor has stuff it MUST be before,
                //but nothing it must be after, just
                //stick it at the beginning
                firstBefore = heads[phase];
            }

            if (firstBefore == null) {
                //just add new interceptor at the end
                ih.prev = tails[phase];
                ih.next = tails[phase].next;
                tails[phase].next = ih;

                if (ih.next != null) {
                    ih.next.prev = ih;
                }
                tails[phase] = ih;
            } else {
                ih.prev = firstBefore.prev;
                if (ih.prev != null) {
                    ih.prev.next = ih;
                }
                ih.next = firstBefore;
                firstBefore.prev = ih;

                if (heads[phase] == firstBefore) {
                    heads[phase] = ih;
                }
            }
        }
        if (iterator != null) {
            outputChainToLog(true);
        }
    }