001 /** 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017 package org.apache.xbean.naming.context; 018 019 import java.util.concurrent.atomic.AtomicReference; 020 021 import javax.naming.Context; 022 import javax.naming.Name; 023 import javax.naming.NamingException; 024 import javax.naming.NamingEnumeration; 025 import javax.naming.Binding; 026 import javax.naming.OperationNotSupportedException; 027 import java.util.Collections; 028 import java.util.Iterator; 029 import java.util.LinkedHashSet; 030 import java.util.Set; 031 import java.util.Map; 032 import java.util.HashMap; 033 034 /** 035 * @version $Rev$ $Date$ 036 */ 037 public class ContextFederation { 038 private final Context actualContext; 039 private final AtomicReference federatedContextRef = new AtomicReference(Collections.EMPTY_SET); 040 public static final int MAX_WRITE_ATTEMPTS = 10; 041 042 public ContextFederation(Context actualContext) { 043 this.actualContext = actualContext; 044 } 045 046 public void addContext(Context context) { 047 Set federatedContext; 048 Set newFederatedContext; 049 for (int i = 0; i < MAX_WRITE_ATTEMPTS; i++) { 050 federatedContext = getFederatedContexts(); 051 052 newFederatedContext = new LinkedHashSet(federatedContext); 053 newFederatedContext.add(context); 054 newFederatedContext = Collections.unmodifiableSet(newFederatedContext); 055 if (federatedContextRef.compareAndSet(federatedContext, newFederatedContext)) { 056 return; 057 } 058 } 059 throw new RuntimeException("Unable to update federatedContextRef within " + MAX_WRITE_ATTEMPTS + " attempts"); 060 } 061 062 public Set getFederatedContexts() { 063 return (Set) federatedContextRef.get(); 064 } 065 066 public Object getFederatedBinding(String name) throws NamingException { 067 for (Iterator iterator = getFederatedContexts().iterator(); iterator.hasNext();) { 068 Context context = (Context) iterator.next(); 069 070 try { 071 Object value = context.lookup(name); 072 if (value != null) { 073 return value; 074 } 075 } catch (NamingException e) { 076 // ignore 077 } 078 } 079 return null; 080 } 081 082 public Map getFederatedBindings() throws NamingException { 083 Map bindings = new HashMap(); 084 for (Iterator iterator = getFederatedContexts().iterator(); iterator.hasNext();) { 085 Context context = (Context) iterator.next(); 086 087 // list federated context 088 NamingEnumeration namingEnumeration = context.listBindings(""); 089 090 // add to bindings 091 while (namingEnumeration.hasMoreElements()) { 092 Binding binding = (Binding) namingEnumeration.nextElement(); 093 String name = binding.getName(); 094 095 // don't overwrite existing bindings 096 if (!bindings.containsKey(name)) { 097 bindings.put(name, binding.getObject()); 098 } 099 } 100 } 101 return bindings; 102 } 103 104 protected boolean addBinding(String name, Object value, boolean rebind) throws NamingException { 105 for (Iterator iterator = getFederatedContexts().iterator(); iterator.hasNext();) { 106 Context context = (Context) iterator.next(); 107 108 try { 109 if (rebind) { 110 context.rebind(name, value); 111 } else { 112 context.bind(name, value); 113 } 114 return true; 115 } catch (OperationNotSupportedException ignored) { 116 } 117 } 118 return false; 119 } 120 121 protected boolean removeBinding(String name) throws NamingException { 122 for (Iterator iterator = getFederatedContexts().iterator(); iterator.hasNext();) { 123 Context context = (Context) iterator.next(); 124 125 try { 126 context.unbind(name); 127 return true; 128 } catch (OperationNotSupportedException ignored) { 129 } 130 } 131 return false; 132 } 133 134 public Object lookup(Name name) { 135 for (Iterator iterator = getFederatedContexts().iterator(); iterator.hasNext();) { 136 try { 137 Context federatedContext = (Context) iterator.next(); 138 Object value = federatedContext.lookup(name); 139 if (value instanceof Context) { 140 return new VirtualSubcontext(name, actualContext); 141 } else { 142 return value; 143 } 144 } catch (NamingException ignored) { 145 } 146 } 147 return null; 148 } 149 150 public ContextFederation createSubcontextFederation(String subcontextName, Context actualSubcontext) throws NamingException { 151 Name parsedSubcontextName = actualContext.getNameParser("").parse(subcontextName); 152 153 ContextFederation subcontextFederation = new ContextFederation(actualSubcontext); 154 for (Iterator iterator = getFederatedContexts().iterator(); iterator.hasNext();) { 155 Context federatedContext = (Context) iterator.next(); 156 VirtualSubcontext virtualSubcontext = new VirtualSubcontext(parsedSubcontextName, federatedContext); 157 subcontextFederation.addContext(virtualSubcontext); 158 } 159 return subcontextFederation; 160 } 161 }