You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cxf.apache.org by dk...@apache.org on 2007/06/12 20:22:30 UTC

svn commit: r546581 - in /incubator/cxf/trunk: api/src/main/java/org/apache/cxf/phase/ rt/core/src/main/java/org/apache/cxf/interceptor/ rt/core/src/main/java/org/apache/cxf/transport/ rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/htt...

Author: dkulp
Date: Tue Jun 12 11:22:29 2007
New Revision: 546581

URL: http://svn.apache.org/viewvc?view=rev&rev=546581
Log:
[CXF-723, CXF-725, CXF-724] Fixes
* Change PhaseInterceptorChain internals to be more clone friendly
* Update server side to clone a pre-setup chain when possible.   (still testing the performance impact of this)


Added:
    incubator/cxf/trunk/api/src/main/java/org/apache/cxf/phase/PhaseChainCache.java   (with props)
Modified:
    incubator/cxf/trunk/api/src/main/java/org/apache/cxf/phase/PhaseInterceptorChain.java
    incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/OutgoingChainInterceptor.java
    incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/transport/ChainInitiationObserver.java
    incubator/cxf/trunk/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/https_jetty/CXFJettySslSocketConnector.java
    incubator/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
    incubator/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptor.java
    incubator/cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/WSS4JInOutTest.java

Added: incubator/cxf/trunk/api/src/main/java/org/apache/cxf/phase/PhaseChainCache.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/api/src/main/java/org/apache/cxf/phase/PhaseChainCache.java?view=auto&rev=546581
==============================================================================
--- incubator/cxf/trunk/api/src/main/java/org/apache/cxf/phase/PhaseChainCache.java (added)
+++ incubator/cxf/trunk/api/src/main/java/org/apache/cxf/phase/PhaseChainCache.java Tue Jun 12 11:22:29 2007
@@ -0,0 +1,122 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you 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.apache.cxf.phase;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.ListIterator;
+import java.util.SortedSet;
+import java.util.concurrent.atomic.AtomicReference;
+
+import org.apache.cxf.interceptor.Interceptor;
+
+
+public final class PhaseChainCache {
+    AtomicReference<ChainHolder> lastData = new AtomicReference<ChainHolder>();
+    
+    
+    @SuppressWarnings("unchecked")
+    public PhaseInterceptorChain get(SortedSet<Phase> phaseList,
+                                     List<Interceptor> p1) {
+        return getChain(phaseList, p1);
+    }
+
+    @SuppressWarnings("unchecked")
+    public PhaseInterceptorChain get(SortedSet<Phase> phaseList,
+                                     List<Interceptor> p1,
+                                     List<Interceptor> p2) {
+        return getChain(phaseList, p1, p2);
+    }
+    @SuppressWarnings("unchecked")
+    public PhaseInterceptorChain get(SortedSet<Phase> phaseList,
+                                     List<Interceptor> p1,
+                                     List<Interceptor> p2,
+                                     List<Interceptor> p3) {
+        return getChain(phaseList, p1, p2, p3);
+    }
+    @SuppressWarnings("unchecked")
+    public PhaseInterceptorChain get(SortedSet<Phase> phaseList,
+                                     List<Interceptor> p1,
+                                     List<Interceptor> p2,
+                                     List<Interceptor> p3,
+                                     List<Interceptor> p4) {
+        return getChain(phaseList, p1, p2, p3, p4);
+    }
+    @SuppressWarnings("unchecked")
+    public PhaseInterceptorChain get(SortedSet<Phase> phaseList,
+                                     List<Interceptor> p1,
+                                     List<Interceptor> p2,
+                                     List<Interceptor> p3,
+                                     List<Interceptor> p4,
+                                     List<Interceptor> p5) {
+        return getChain(phaseList, p1, p2, p3, p4, p5);
+    }
+    
+    private PhaseInterceptorChain getChain(SortedSet<Phase> phaseList, List<Interceptor> ... providers) {
+        ChainHolder last = lastData.get();
+        
+        if (last == null 
+            || !last.matches(providers)) {
+        
+            PhaseInterceptorChain chain = new PhaseInterceptorChain(phaseList);
+            List<List<Interceptor>> copy = new ArrayList<List<Interceptor>>(providers.length);
+            for (List<Interceptor> p : providers) {
+                copy.add(new ArrayList<Interceptor>(p));
+                chain.add(p);
+            }
+            last = new ChainHolder(chain, copy);
+            lastData.set(last);
+        }
+        
+        
+        return last.chain.cloneChain();
+    }
+    
+    private static class ChainHolder {
+        List<List<Interceptor>> lists;
+        PhaseInterceptorChain chain;
+        
+        ChainHolder(PhaseInterceptorChain c, List<List<Interceptor>> l) {
+            lists = l;
+            chain = c;
+        }
+        
+        boolean matches(List<Interceptor> ... providers) {
+            if (lists.size() == providers.length) {
+                for (int x = 0; x < providers.length; x++) {
+                    if (lists.get(x).size() != providers[x].size()) {
+                        return false;
+                    }
+                    
+                    ListIterator<Interceptor> i1 = lists.get(x).listIterator();
+                    ListIterator<Interceptor> i2 = providers[x].listIterator();
+                    
+                    while (i1.hasNext()) {
+                        if (i1.next() != i2.next()) {
+                            return false;
+                        }
+                    }
+                }
+                return true;
+            }
+            return false;
+        }
+    }
+}

Propchange: incubator/cxf/trunk/api/src/main/java/org/apache/cxf/phase/PhaseChainCache.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/cxf/trunk/api/src/main/java/org/apache/cxf/phase/PhaseChainCache.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Modified: incubator/cxf/trunk/api/src/main/java/org/apache/cxf/phase/PhaseInterceptorChain.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/api/src/main/java/org/apache/cxf/phase/PhaseInterceptorChain.java?view=diff&rev=546581&r1=546580&r2=546581
==============================================================================
--- incubator/cxf/trunk/api/src/main/java/org/apache/cxf/phase/PhaseInterceptorChain.java (original)
+++ incubator/cxf/trunk/api/src/main/java/org/apache/cxf/phase/PhaseInterceptorChain.java Tue Jun 12 11:22:29 2007
@@ -54,8 +54,13 @@
     private static final Logger LOG = Logger.getLogger(PhaseInterceptorChain.class.getName());
 
     
-    private final Map<String, PhaseHolder> nameMap = new HashMap<String, PhaseHolder>();
-    private final PhaseHolder firstPhase;
+    private final Map<String, Integer> nameMap;
+    private final Phase phases[];
+
+    private InterceptorHolder heads[];
+    private InterceptorHolder tails[];
+    private boolean hasAfters[];
+
     
     private State state;
     private Message pausedMessage;
@@ -66,29 +71,68 @@
     // on nested calling of doIntercept(), which will throw same fault multi-times
     private boolean faultOccured;
     
+    
+    private PhaseInterceptorChain(PhaseInterceptorChain src) {
+        //only used for clone
+        state = State.EXECUTING;
+        
+        //immutable, just repoint
+        nameMap = src.nameMap;
+        phases = src.phases;
+        
+        int length = phases.length;
+        hasAfters = new boolean[length];
+        System.arraycopy(src.hasAfters, 0, hasAfters, 0, length);
+        
+        heads = new InterceptorHolder[length];
+        tails = new InterceptorHolder[length];
+        
+        InterceptorHolder last = null;
+        for (int x = 0; x < length; x++) {
+            InterceptorHolder ih = src.heads[x];
+            while (ih != null
+                && ih.phaseIdx == x) {
+                InterceptorHolder ih2 = new InterceptorHolder(ih);
+                ih2.prev = last;
+                if (last != null) {
+                    last.next = ih2;
+                }
+                if (heads[x] == null) {
+                    heads[x] = ih2;
+                }
+                tails[x] = ih2;
+                last = ih2;
+                ih = ih.next;
+            }
+        }
+    }
+    
     public PhaseInterceptorChain(SortedSet<Phase> ps) {
         state = State.EXECUTING;
-
-        PhaseHolder last = null;
-        PhaseHolder first = null;
+        
+        int numPhases = ps.size();
+        phases = new Phase[numPhases];
+        nameMap = new HashMap<String, Integer>();
+
+        heads = new InterceptorHolder[numPhases];
+        tails = new InterceptorHolder[numPhases];
+        hasAfters = new boolean[numPhases];
+        
+        int idx = 0;
         for (Phase phase : ps) {
-            PhaseHolder ph = new PhaseHolder(phase);
-            if (first == null) {
-                first = ph;
-            }
-            if (last != null) {
-                last.next = ph;
-            }
-            ph.prev = last;
-            last = ph;
-            nameMap.put(phase.getName(), ph);
+            phases[idx] = phase; 
+            nameMap.put(phase.getName(), idx);
+            ++idx;
         }
-        firstPhase = first;
+    }
+    
+    public PhaseInterceptorChain cloneChain() {
+        return new PhaseInterceptorChain(this);
     }
     
     private void updateIterator() {
         if (iterator == null) {
-            iterator = new PhaseInterceptorIterator(firstPhase);
+            iterator = new PhaseInterceptorIterator(heads);
             outputChainToLog(false);
             //System.out.println(toString());
         }
@@ -121,7 +165,7 @@
 
         String phaseName = pi.getPhase();
         
-        PhaseHolder phase = nameMap.get(phaseName);
+        Integer phase = nameMap.get(phaseName);
         if (phase == null) {
             LOG.fine("Phase " + phaseName + " does not exist. Skipping handler "
                       + i.getClass().getName());
@@ -253,7 +297,7 @@
     }
 
     public void remove(Interceptor i) {
-        PhaseInterceptorIterator it = new PhaseInterceptorIterator(firstPhase);
+        PhaseInterceptorIterator it = new PhaseInterceptorIterator(heads);
         while (it.hasNext()) {
             InterceptorHolder holder = it.nextInterceptorHolder();
             if (holder.interceptor == i) {
@@ -271,7 +315,7 @@
         return getIterator();
     }
     public ListIterator<Interceptor<? extends Message>> getIterator() {
-        return new PhaseInterceptorIterator(firstPhase);
+        return new PhaseInterceptorIterator(heads);
     }
 
     private void remove(InterceptorHolder i) {
@@ -281,139 +325,139 @@
         if (i.next != null) {
             i.next.prev = i.prev;
         }
-        PhaseHolder ph = i.phase;
-        if (ph.head == i) {
+        int ph = i.phaseIdx;
+        if (heads[ph] == i) {
             if (i.next != null
-                && i.next.phase == ph) {
-                ph.head = i.next;
+                && i.next.phaseIdx == ph) {
+                heads[ph] = i.next;
             } else {
-                ph.head = null;
-                ph.tail = null;
+                heads[ph] = null;
+                tails[ph] = null;
             }
         }
-        if (ph.tail == i) {
+        if (tails[ph] == i) {
             if (i.prev != null
-                && i.prev.phase == ph) {
-                ph.tail = i.prev;
+                && i.prev.phaseIdx == ph) {
+                tails[ph] = i.prev;
             } else {
-                ph.head = null;
-                ph.tail = null;
+                heads[ph] = null;
+                tails[ph] = null;
             }
         }
     }
-    private void insertInterceptor(PhaseHolder phase, PhaseInterceptor interc, boolean force) {
+    
+    private void insertInterceptor(int phase, PhaseInterceptor interc, boolean force) {
         InterceptorHolder ih = new InterceptorHolder(interc, phase);
-        if (phase.head == null) {
-            phase.head = ih;
-            phase.tail = ih;
+        if (heads[phase] == null) {
+            heads[phase] = ih;
+            tails[phase] = ih;
             
-            PhaseHolder prev = phase.prev;
-            while (prev != null 
-                && prev.tail == null) {
-                prev = prev.prev;
+            int idx = phase - 1;
+            while (idx >= 0) {
+                if (tails[idx] != null) {
+                    break;
+                }
+                --idx;
             }
-            if (prev != null) {
+            if (idx >= 0) {
                 //found something before us
-                ih.prev = prev.tail;
-                ih.next = prev.tail.next;
+                ih.prev = tails[idx];
+                ih.next = tails[idx].next;
                 if (ih.next != null) {
                     ih.next.prev = ih;
                 }
-                prev.tail.next = ih;
+                tails[idx].next = ih;
             } else {
                 //did not find something before us, try after
-                prev = phase.next;
-                while (prev != null 
-                    && prev.head == null) {
-                    prev = prev.next;
+                idx = phase + 1;
+                while (idx < heads.length) {
+                    if (heads[idx] != null) {
+                        break;
+                    }
+                    ++idx;
                 }
-                if (prev != null) {
+                
+                if (idx != heads.length) {
                     //found something after us
-                    ih.next = prev.head;
-                    prev.head.prev = ih;
+                    ih.next = heads[idx];
+                    heads[idx].prev = ih;
                 }
             }
-            phase.hasAfters = !interc.getAfter().isEmpty();
-            if (iterator != null) {
-                outputChainToLog(true);
-            }
-            return;
-        }
+            hasAfters[phase] = !interc.getAfter().isEmpty();
+        } else {
         
-        Set beforeList = interc.getBefore();
-        Set afterList = interc.getAfter();
-        InterceptorHolder before = null;
-        InterceptorHolder after = null;
-        
-        String id = interc.getId();
-        if (phase.hasAfters
-            || !beforeList.isEmpty()) {
-        
-            InterceptorHolder ih2 = phase.head;
-            while (ih2 != phase.tail.next) {
-                PhaseInterceptor cmp = ih2.interceptor;
-                String cmpId = cmp.getId();
-                if (cmpId != null
-                    && before == null
-                    && (beforeList.contains(cmpId)
-                        || cmp.getAfter().contains(id))) {
-                    //first one we need to be before
-                    before = ih2;
-                } 
-                if (cmpId != null 
-                    && afterList.contains(cmpId)) {
-                    after = ih2;
-                }
-                if (!force
-                    && cmpId.equals(id)) {
-                    return;
-                }
-                ih2 = ih2.next;
-            }
-            if (after == null
-                && beforeList.contains("*")) {
-                before = phase.head;
-            }
-            //System.out.print("Didn't skip: " + phase.toString());
-            //System.out.println("             " + interc.getId());
-        } else if (!force) {
-            InterceptorHolder ih2 = phase.head;
-            while (ih2 != phase.tail.next) {
-                PhaseInterceptor cmp = ih2.interceptor;
-                String cmpId = cmp.getId();
-                if (!force
-                    && cmpId.equals(id)) {
-                    return;
-                }
-                ih2 = ih2.next;
-            }
+            Set beforeList = interc.getBefore();
+            Set afterList = interc.getAfter();
+            InterceptorHolder before = null;
+            InterceptorHolder after = null;
             
-            //System.out.print("Skipped: " + phase.toString());
-            //System.out.println("         " + interc.getId());
-        }
-        phase.hasAfters |= afterList.isEmpty();
-        
-        if (before == null) {
-            //just add at the end
-            ih.prev = phase.tail;
-            if (phase.tail != null) {
-                ih.next = phase.tail.next;
-                phase.tail.next = ih;
-            }
-            if (ih.next != null) {
-                ih.next.prev = ih;
-            }
-            phase.tail = ih;
-        } else {
-            ih.prev = before.prev;
-            if (ih.prev != null) {
-                ih.prev.next = ih;
+            String id = interc.getId();
+            if (hasAfters[phase]
+                || !beforeList.isEmpty()) {
+            
+                InterceptorHolder ih2 = heads[phase];
+                while (ih2 != tails[phase].next) {
+                    PhaseInterceptor cmp = ih2.interceptor;
+                    String cmpId = cmp.getId();
+                    if (cmpId != null
+                        && before == null
+                        && (beforeList.contains(cmpId)
+                            || cmp.getAfter().contains(id))) {
+                        //first one we need to be before
+                        before = ih2;
+                    } 
+                    if (cmpId != null 
+                        && afterList.contains(cmpId)) {
+                        after = ih2;
+                    }
+                    if (!force
+                        && cmpId.equals(id)) {
+                        return;
+                    }
+                    ih2 = ih2.next;
+                }
+                if (after == null
+                    && beforeList.contains("*")) {
+                    before = heads[phase];
+                }
+                //System.out.print("Didn't skip: " + phase.toString());
+                //System.out.println("             " + interc.getId());
+            } else if (!force) {
+                InterceptorHolder ih2 = heads[phase];
+                while (ih2 != tails[phase].next) {
+                    if (ih2.interceptor.getId().equals(id)) {
+                        return;
+                    }
+                    ih2 = ih2.next;
+                }
+                
+                //System.out.print("Skipped: " + phase.toString());
+                //System.out.println("         " + interc.getId());
             }
-            ih.next = before;
-            before.prev = ih;
+            hasAfters[phase] |= !afterList.isEmpty();
             
-            if (phase.head == before) {
-                phase.head = ih;
+            if (before == null) {
+                //just add at the end
+                ih.prev = tails[phase];
+                if (tails[phase] != null) {
+                    ih.next = tails[phase].next;
+                    tails[phase].next = ih;
+                }
+                if (ih.next != null) {
+                    ih.next.prev = ih;
+                }
+                tails[phase] = ih;
+            } else {
+                ih.prev = before.prev;
+                if (ih.prev != null) {
+                    ih.prev.next = ih;
+                }
+                ih.next = before;
+                before.prev = ih;
+                
+                if (heads[phase] == before) {
+                    heads[phase] = ih;
+                }
             }
         }
         if (iterator != null) {
@@ -432,22 +476,21 @@
             .append(message)
             .append(". Current flow:\n");
         
-        PhaseHolder ph = firstPhase;
-        while (ph != null) {
-            if (ph.head != null) {
+        for (int x = 0; x < phases.length; x++) {
+            if (heads[x] != null) {
                 chain.append("  ");
-                printPhase(ph, chain);
-            }
-            ph = ph.next;
+                printPhase(x, chain);
+            }            
         }
         return chain.toString();
     }
-    private static void printPhase(PhaseHolder ph, StringBuilder chain) {
-        chain.append(ph.phase.getName())
+    private void printPhase(int ph, StringBuilder chain) {
+        
+        chain.append(phases[ph].getName())
             .append(" [");
-        InterceptorHolder i = ph.head;
+        InterceptorHolder i = heads[ph];
         boolean first = true;
-        while (i != ph.tail.next) {
+        while (i != tails[ph].next) {
             if (first) {
                 first = false;
             } else {
@@ -478,12 +521,12 @@
     }
     
     static final class PhaseInterceptorIterator implements ListIterator<Interceptor<? extends Message>> {
-        PhaseHolder firstPhase;
+        InterceptorHolder heads[];
         InterceptorHolder prev;
         InterceptorHolder first;
         
-        public PhaseInterceptorIterator(PhaseHolder f) {
-            firstPhase = f;
+        public PhaseInterceptorIterator(InterceptorHolder h[]) {
+            heads = h;
             first = findFirst();
         }
         
@@ -493,12 +536,10 @@
         }
         
         private InterceptorHolder findFirst() {
-            PhaseHolder ph = firstPhase;
-            while (ph != null && ph.head == null) {
-                ph = ph.next;
-            }
-            if (ph != null) {
-                return ph.head;
+            for (int x = 0; x < heads.length; x++) {
+                if (heads[x] != null) {
+                    return heads[x];
+                }
             }
             return null;
         }
@@ -571,42 +612,20 @@
         }
     }
 
-
-
-    
     
     static final class InterceptorHolder {
         PhaseInterceptor interceptor;
         InterceptorHolder next;
         InterceptorHolder prev;
-        PhaseHolder phase;
+        int phaseIdx;
         
-        InterceptorHolder(PhaseInterceptor i, PhaseHolder p) {
+        InterceptorHolder(PhaseInterceptor i, int p) {
             interceptor = i;
-            phase = p;
-        }
-    }
-    
-    static final class PhaseHolder implements Comparable {
-        Phase phase;
-        PhaseHolder next;
-        PhaseHolder prev;
-        
-        InterceptorHolder head;
-        InterceptorHolder tail;
-        boolean hasAfters;
-        
-        PhaseHolder(Phase p) {
-            phase = p;
-        }
-
-        public int compareTo(Object o) {
-            return phase.compareTo(((PhaseHolder)o).phase);
+            phaseIdx = p;
         }
-        public String toString() {
-            StringBuilder builder = new StringBuilder();
-            printPhase(this, builder);
-            return builder.toString();
+        InterceptorHolder(InterceptorHolder p) {
+            interceptor = p.interceptor;
+            phaseIdx = p.phaseIdx;
         }
     }
 

Modified: incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/OutgoingChainInterceptor.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/OutgoingChainInterceptor.java?view=diff&rev=546581&r1=546580&r2=546581
==============================================================================
--- incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/OutgoingChainInterceptor.java (original)
+++ incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/interceptor/OutgoingChainInterceptor.java Tue Jun 12 11:22:29 2007
@@ -33,6 +33,7 @@
 import org.apache.cxf.message.Message;
 import org.apache.cxf.phase.AbstractPhaseInterceptor;
 import org.apache.cxf.phase.Phase;
+import org.apache.cxf.phase.PhaseChainCache;
 import org.apache.cxf.phase.PhaseInterceptorChain;
 import org.apache.cxf.phase.PhaseManager;
 import org.apache.cxf.service.model.BindingMessageInfo;
@@ -43,6 +44,9 @@
 
 public class OutgoingChainInterceptor extends AbstractPhaseInterceptor<Message> {
     private static final Logger LOG = Logger.getLogger(OutgoingChainInterceptor.class.getName());
+    
+    private PhaseChainCache chainCache = new PhaseChainCache();
+    
     public OutgoingChainInterceptor() {
         super(Phase.POST_INVOKE);
     }
@@ -63,7 +67,7 @@
             
             InterceptorChain outChain = out.getInterceptorChain();
             if (outChain == null) {
-                outChain = getOutInterceptorChain(ex);
+                outChain = getChain(ex);
                 out.setInterceptorChain(outChain);
             }
             outChain.doIntercept(out);
@@ -121,5 +125,45 @@
         chain.setFaultObserver(ep.getOutFaultObserver());
         return chain;
     }
+
+    private PhaseInterceptorChain getChain(Exchange ex) {
+        Bus bus = ex.get(Bus.class);
+        Binding binding = ex.get(Binding.class);
+        
+        Endpoint ep = ex.get(Endpoint.class);
+        
+        List<Interceptor> i1 = ep.getOutInterceptors();
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("Interceptors contributed by endpoint: " + i1);
+        }
+        List<Interceptor> i2 = ep.getService().getOutInterceptors();
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("Interceptors contributed by service: " + i2);
+        }
+        List<Interceptor> i3 = bus.getOutInterceptors();
+        if (LOG.isLoggable(Level.FINE)) {
+            LOG.fine("Interceptors contributed by bus: " + i3);
+        }
+        List<Interceptor> i4 = null;
+        PhaseInterceptorChain chain;
+        if (binding != null) {
+            i4 = binding.getOutInterceptors();
+            if (LOG.isLoggable(Level.FINE)) {
+                LOG.fine("Interceptors contributed by binding: " + i4);
+            }
+        }
+        if (i4 != null) {
+            chain = chainCache.get(bus.getExtension(PhaseManager.class).getOutPhases(),
+                                   i1, i2, i3, i4);
+        } else {
+            chain = chainCache.get(bus.getExtension(PhaseManager.class).getOutPhases(),
+                                   i1, i2, i3);
+        }
+        
+        chain.setFaultObserver(ep.getOutFaultObserver());
+        return chain;
+    }
+    
+    
 }
 

Modified: incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/transport/ChainInitiationObserver.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/transport/ChainInitiationObserver.java?view=diff&rev=546581&r1=546580&r2=546581
==============================================================================
--- incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/transport/ChainInitiationObserver.java (original)
+++ incubator/cxf/trunk/rt/core/src/main/java/org/apache/cxf/transport/ChainInitiationObserver.java Tue Jun 12 11:22:29 2007
@@ -19,12 +19,14 @@
 
 package org.apache.cxf.transport;
 
+
 import org.apache.cxf.Bus;
 import org.apache.cxf.binding.Binding;
 import org.apache.cxf.endpoint.Endpoint;
 import org.apache.cxf.message.Exchange;
 import org.apache.cxf.message.ExchangeImpl;
 import org.apache.cxf.message.Message;
+import org.apache.cxf.phase.PhaseChainCache;
 import org.apache.cxf.phase.PhaseInterceptorChain;
 import org.apache.cxf.phase.PhaseManager;
 import org.apache.cxf.service.Service;
@@ -32,6 +34,8 @@
 public class ChainInitiationObserver implements MessageObserver {
     protected Endpoint endpoint;
     protected Bus bus;
+    
+    private PhaseChainCache chainCache = new PhaseChainCache();
 
     public ChainInitiationObserver(Endpoint endpoint, Bus bus) {
         super();
@@ -47,27 +51,22 @@
             exchange.setInMessage(message);
         }
         setExchangeProperties(exchange, message);
-        
+
         // setup chain
-        PhaseInterceptorChain chain = createChain();
+        PhaseInterceptorChain chain = chainCache.get(bus.getExtension(PhaseManager.class).getInPhases(),
+                                                     bus.getInInterceptors(),
+                                                     endpoint.getInInterceptors(),
+                                                     getBinding().getInInterceptors(),
+                                                     endpoint.getService().getInInterceptors());
+        
         
         message.setInterceptorChain(chain);
         
-        chain.add(bus.getInInterceptors());
-        chain.add(endpoint.getInInterceptors());
-        chain.add(getBinding().getInInterceptors());
-        chain.add(endpoint.getService().getInInterceptors());
-
         chain.setFaultObserver(endpoint.getOutFaultObserver());
        
         chain.doIntercept(message);        
     }
 
-    protected PhaseInterceptorChain createChain() {
-        PhaseInterceptorChain chain = new PhaseInterceptorChain(bus.getExtension(PhaseManager.class)
-            .getInPhases());
-        return chain;
-    }
 
     protected Binding getBinding() {
         return endpoint.getBinding();

Modified: incubator/cxf/trunk/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/https_jetty/CXFJettySslSocketConnector.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/https_jetty/CXFJettySslSocketConnector.java?view=diff&rev=546581&r1=546580&r2=546581
==============================================================================
--- incubator/cxf/trunk/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/https_jetty/CXFJettySslSocketConnector.java (original)
+++ incubator/cxf/trunk/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/https_jetty/CXFJettySslSocketConnector.java Tue Jun 12 11:22:29 2007
@@ -89,11 +89,13 @@
      * configures an HTTP Destination.
      */
     protected void setClientAuthentication(ClientAuthentication clientAuth) {
-        if (clientAuth.isSetWant()) {
-            setWantClientAuth(clientAuth.isWant());
-        }
-        if (clientAuth.isSetRequired()) {
-            setNeedClientAuth(clientAuth.isRequired());
+        if (clientAuth != null) {
+            if (clientAuth.isSetWant()) {
+                setWantClientAuth(clientAuth.isWant());
+            }
+            if (clientAuth.isSetRequired()) {
+                setNeedClientAuth(clientAuth.isRequired());
+            }
         }
     }
     

Modified: incubator/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java?view=diff&rev=546581&r1=546580&r2=546581
==============================================================================
--- incubator/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java (original)
+++ incubator/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JInInterceptor.java Tue Jun 12 11:22:29 2007
@@ -90,7 +90,6 @@
         long t1 = 0;
         long t2 = 0;
         long t3 = 0;
-        long t4 = 0;
 
         if (doTimeLog) {
             t0 = System.currentTimeMillis();
@@ -212,10 +211,11 @@
             doResults(msg, actor, doc, wsResult);
 
             if (doTimeLog) {
-                t4 = System.currentTimeMillis();
-                TIME_LOG.fine("Receive request: total= " + (t4 - t0) + " request preparation= " + (t1 - t0)
-                              + " request processing= " + (t2 - t1) + " request to CXF= " + (t3 - t2)
-                              + " header, cert verify, timestamp= " + (t4 - t3) + "\n");
+                t3 = System.currentTimeMillis();
+                TIME_LOG.fine("Receive request: total= " + (t3 - t0) 
+                        + " request preparation= " + (t1 - t0)
+                        + " request processing= " + (t2 - t1) 
+                        + " header, cert verify, timestamp= " + (t3 - t2) + "\n");
             }
 
             if (doDebug) {

Modified: incubator/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptor.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptor.java?view=diff&rev=546581&r1=546580&r2=546581
==============================================================================
--- incubator/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptor.java (original)
+++ incubator/cxf/trunk/rt/ws/security/src/main/java/org/apache/cxf/ws/security/wss4j/WSS4JOutInterceptor.java Tue Jun 12 11:22:29 2007
@@ -65,7 +65,6 @@
         long t0 = 0;
         long t1 = 0;
         long t2 = 0;
-        long t3 = 0;
 
         if (doTimeDebug) {
             t0 = System.currentTimeMillis();
@@ -169,14 +168,10 @@
 
             if (doTimeDebug) {
                 t2 = System.currentTimeMillis();
-            }
-
-            if (doTimeDebug) {
-                t3 = System.currentTimeMillis();
-                TIME_LOG.fine("Send request: total= " + (t3 - t0)
+                TIME_LOG.fine("Send request: total= " + (t2 - t0)
                         + " request preparation= " + (t1 - t0)
                         + " request processing= " + (t2 - t1)
-                        + " request to CXF= " + (t3 - t2) + "\n");
+                        + "\n");
             }
 
             if (doDebug) {

Modified: incubator/cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/WSS4JInOutTest.java
URL: http://svn.apache.org/viewvc/incubator/cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/WSS4JInOutTest.java?view=diff&rev=546581&r1=546580&r2=546581
==============================================================================
--- incubator/cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/WSS4JInOutTest.java (original)
+++ incubator/cxf/trunk/rt/ws/security/src/test/java/org/apache/cxf/ws/security/wss4j/WSS4JInOutTest.java Tue Jun 12 11:22:29 2007
@@ -21,6 +21,10 @@
 import java.io.ByteArrayInputStream;
 import java.io.ByteArrayOutputStream;
 import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.SortedSet;
+import java.util.TreeSet;
 
 import javax.xml.parsers.DocumentBuilder;
 import javax.xml.parsers.DocumentBuilderFactory;
@@ -34,10 +38,15 @@
 import org.w3c.dom.Document;
 
 import org.apache.cxf.binding.soap.SoapMessage;
+import org.apache.cxf.binding.soap.interceptor.MustUnderstandInterceptor;
+import org.apache.cxf.binding.soap.saaj.SAAJInInterceptor;
 import org.apache.cxf.helpers.DOMUtils.NullResolver;
+import org.apache.cxf.interceptor.Interceptor;
 import org.apache.cxf.message.Exchange;
 import org.apache.cxf.message.ExchangeImpl;
 import org.apache.cxf.message.MessageImpl;
+import org.apache.cxf.phase.Phase;
+import org.apache.cxf.phase.PhaseInterceptorChain;
 import org.apache.cxf.staxutils.StaxUtils;
 import org.apache.ws.security.WSSecurityEngineResult;
 import org.apache.ws.security.handler.WSHandlerConstants;
@@ -52,6 +61,22 @@
     public WSS4JInOutTest() {
     }
 
+    @Test
+    public void testOrder() throws Exception {
+        //make sure the interceptors get ordered correctly
+        SortedSet<Phase> phases = new TreeSet<Phase>();
+        phases.add(new Phase(Phase.PRE_PROTOCOL, 1));
+        
+        List<Interceptor> lst = new ArrayList<Interceptor>();
+        lst.add(new MustUnderstandInterceptor());
+        lst.add(new WSS4JInInterceptor());
+        lst.add(new SAAJInInterceptor());
+        PhaseInterceptorChain chain = new PhaseInterceptorChain(phases);
+        chain.add(lst);
+        String output = chain.toString();
+        assertTrue(output.contains("MustUnderstandInterceptor, SAAJInInterceptor, WSS4JInInterceptor"));
+    }
+    
     @Test
     public void testSignature() throws Exception {
         Document doc = readDocument("wsse-request-clean.xml");