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 018 package org.apache.geronimo.gbean.runtime; 019 020 import org.apache.geronimo.gbean.AbstractName; 021 import org.apache.geronimo.gbean.GReferenceInfo; 022 import org.apache.geronimo.gbean.InvalidConfigurationException; 023 import org.apache.geronimo.gbean.ReferencePatterns; 024 import org.apache.geronimo.gbean.AbstractNameQuery; 025 import org.apache.geronimo.kernel.Kernel; 026 import org.apache.geronimo.kernel.lifecycle.LifecycleAdapter; 027 import org.apache.geronimo.kernel.lifecycle.LifecycleListener; 028 029 import java.util.Collections; 030 import java.util.HashSet; 031 import java.util.Iterator; 032 import java.util.Set; 033 034 /** 035 * @version $Rev:386515 $ $Date: 2006-11-16 23:35:17 -0500 (Thu, 16 Nov 2006) $ 036 */ 037 public class GBeanCollectionReference extends AbstractGBeanReference { 038 /** 039 * is this reference online 040 */ 041 private boolean isOnline = false; 042 043 /** 044 * The target objectName patterns to watch for a connection. 045 */ 046 private Set patterns = Collections.EMPTY_SET; 047 048 /** 049 * Current set of targets 050 */ 051 private final Set targets = new HashSet(); 052 053 /** 054 * Our listener for lifecycle events 055 */ 056 private final LifecycleListener listener; 057 058 public GBeanCollectionReference(GBeanInstance gbeanInstance, GReferenceInfo referenceInfo, Kernel kernel, ReferencePatterns referencePatterns) throws InvalidConfigurationException { 059 super(gbeanInstance, referenceInfo, kernel, hasTargets(referencePatterns)); 060 listener = createLifecycleListener(); 061 if (referencePatterns != null) { 062 setReferencePatterns(referencePatterns); 063 } 064 } 065 066 private static boolean hasTargets(ReferencePatterns referencePatterns) { 067 if (referencePatterns == null) { 068 return false; 069 } 070 if (referencePatterns.isResolved()) { 071 return true; 072 } 073 return !referencePatterns.getPatterns().isEmpty(); 074 } 075 076 public synchronized boolean start() { 077 // We only need to start if there are patterns and we don't already have a proxy 078 if (!patterns.isEmpty() && getProxy() == null) { 079 // add a dependency on our target and create the proxy 080 setProxy(new ProxyCollection(getName(), getReferenceType(), getTargets(), getKernel())); 081 } 082 return true; 083 } 084 085 public synchronized void stop() { 086 ProxyCollection proxy = (ProxyCollection) getProxy(); 087 if (proxy != null) { 088 proxy.destroy(); 089 setProxy(null); 090 } 091 } 092 093 protected synchronized void targetAdded(AbstractName target) { 094 ProxyCollection proxy = (ProxyCollection) getProxy(); 095 if (proxy != null) { 096 proxy.addTarget(target); 097 } 098 } 099 100 protected synchronized void targetRemoved(AbstractName target) { 101 ProxyCollection proxy = (ProxyCollection) getProxy(); 102 if (proxy != null) { 103 proxy.removeTarget(target); 104 } 105 } 106 107 protected LifecycleListener createLifecycleListener() { 108 return new LifecycleAdapter() { 109 public void running(AbstractName abstractName) { 110 addTarget(abstractName); 111 } 112 113 public void stopping(AbstractName abstractName) { 114 removeTarget(abstractName); 115 } 116 117 public void stopped(AbstractName abstractName) { 118 removeTarget(abstractName); 119 } 120 121 public void failed(AbstractName abstractName) { 122 removeTarget(abstractName); 123 } 124 125 public void unloaded(AbstractName abstractName) { 126 removeTarget(abstractName); 127 } 128 }; 129 } 130 131 public final synchronized Set getPatterns() { 132 return patterns; 133 } 134 135 public final synchronized void setReferencePatterns(ReferencePatterns referencePatterns) { 136 if (isOnline) { 137 throw new IllegalStateException("Pattern set can not be modified while online"); 138 } 139 if (referencePatterns.isResolved()) { 140 this.patterns = Collections.unmodifiableSet(Collections.singleton(new AbstractNameQuery(referencePatterns.getAbstractName()))); 141 } else { 142 this.patterns = Collections.unmodifiableSet(referencePatterns.getPatterns()); 143 } 144 } 145 146 public final synchronized void online() { 147 Set gbeans = getKernel().listGBeans(patterns); 148 for (Iterator objectNameIterator = gbeans.iterator(); objectNameIterator.hasNext();) { 149 AbstractName target = (AbstractName) objectNameIterator.next(); 150 if (!targets.contains(target)) { 151 152 // if the bean is running add it to the runningTargets list 153 if (isRunning(getKernel(), target)) { 154 targets.add(target); 155 } 156 } 157 } 158 159 getKernel().getLifecycleMonitor().addLifecycleListener(listener, patterns); 160 isOnline = true; 161 } 162 163 public final synchronized void offline() { 164 // make sure we are stoped 165 stop(); 166 167 getKernel().getLifecycleMonitor().removeLifecycleListener(listener); 168 169 targets.clear(); 170 isOnline = false; 171 } 172 173 protected final Set getTargets() { 174 return targets; 175 } 176 177 protected final void addTarget(AbstractName abstractName) { 178 if (!targets.contains(abstractName)) { 179 targets.add(abstractName); 180 targetAdded(abstractName); 181 } 182 } 183 184 protected final void removeTarget(AbstractName abstractName) { 185 boolean wasTarget = targets.remove(abstractName); 186 if (wasTarget) { 187 targetRemoved(abstractName); 188 } 189 } 190 191 }