blob: ccd12d2d767cf9d2d207f664f86781db2e0e1532 [file] [log] [blame]
/**
* 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.common.util.ModCountCopyOnWriteArrayList;
import org.apache.cxf.interceptor.Interceptor;
import org.apache.cxf.message.Message;
/**
* The PhaseChainCache provides default interceptor chains for SOAP requests
* and responses, both from the client and web service side. The list of
* phases supplied in the get() methods of this class are defined by default
* within org.apache.cxf.phase.PhaseManagerImpl. For an example of this class
* in use, check the sourcecode of org.apache.cxf.endpoint.ClientImpl.
*/
public final class PhaseChainCache {
AtomicReference<ChainHolder> lastData = new AtomicReference<>();
public PhaseInterceptorChain get(SortedSet<Phase> phaseList,
List<Interceptor<? extends Message>> p1) {
return getChain(lastData, phaseList, p1);
}
public PhaseInterceptorChain get(SortedSet<Phase> phaseList,
List<Interceptor<? extends Message>> p1,
List<Interceptor<? extends Message>> p2) {
return getChain(lastData, phaseList, p1, p2);
}
public PhaseInterceptorChain get(SortedSet<Phase> phaseList,
List<Interceptor<? extends Message>> p1,
List<Interceptor<? extends Message>> p2,
List<Interceptor<? extends Message>> p3) {
return getChain(lastData, phaseList, p1, p2, p3);
}
public PhaseInterceptorChain get(SortedSet<Phase> phaseList,
List<Interceptor<? extends Message>> p1,
List<Interceptor<? extends Message>> p2,
List<Interceptor<? extends Message>> p3,
List<Interceptor<? extends Message>> p4) {
return getChain(lastData, phaseList, p1, p2, p3, p4);
}
public PhaseInterceptorChain get(SortedSet<Phase> phaseList,
List<Interceptor<? extends Message>> p1,
List<Interceptor<? extends Message>> p2,
List<Interceptor<? extends Message>> p3,
List<Interceptor<? extends Message>> p4,
List<Interceptor<? extends Message>> p5) {
return getChain(lastData, phaseList, p1, p2, p3, p4, p5);
}
@SafeVarargs
static PhaseInterceptorChain getChain(AtomicReference<ChainHolder> lastData,
SortedSet<Phase> phaseList,
List<Interceptor<? extends Message>> ... providers) {
ChainHolder last = lastData.get();
if (last == null
|| !last.matches(providers)) {
PhaseInterceptorChain chain = new PhaseInterceptorChain(phaseList);
List<ModCountCopyOnWriteArrayList<Interceptor<? extends Message>>> copy
= new ArrayList<>(providers.length);
for (List<Interceptor<? extends Message>> p : providers) {
copy.add(new ModCountCopyOnWriteArrayList<>(p));
chain.add(p);
}
last = new ChainHolder(chain, copy);
lastData.set(last);
}
return last.chain.cloneChain();
}
private static class ChainHolder {
List<ModCountCopyOnWriteArrayList<Interceptor<? extends Message>>> lists;
PhaseInterceptorChain chain;
ChainHolder(PhaseInterceptorChain c,
List<ModCountCopyOnWriteArrayList<Interceptor<? extends Message>>> l) {
lists = l;
chain = c;
}
@SafeVarargs
final boolean matches(List<Interceptor<? extends Message>> ... providers) {
if (lists.size() == providers.length) {
for (int x = 0; x < providers.length; x++) {
if (lists.get(x).size() != providers[x].size()) {
return false;
}
if (providers[x].getClass() == ModCountCopyOnWriteArrayList.class) {
if (((ModCountCopyOnWriteArrayList<?>)providers[x]).getModCount()
!= lists.get(x).getModCount()) {
return false;
}
} else {
ListIterator<Interceptor<? extends Message>> i1 = lists.get(x).listIterator();
ListIterator<Interceptor<? extends Message>> i2 = providers[x].listIterator();
while (i1.hasNext()) {
if (i1.next() != i2.next()) {
return false;
}
}
}
}
return true;
}
return false;
}
}
}