001: /*
002: * JBoss, Home of Professional Open Source.
003: * Copyright 2006, Red Hat Middleware LLC, and individual contributors
004: * as indicated by the @author tags. See the copyright.txt file in the
005: * distribution for a full listing of individual contributors.
006: *
007: * This is free software; you can redistribute it and/or modify it
008: * under the terms of the GNU Lesser General Public License as
009: * published by the Free Software Foundation; either version 2.1 of
010: * the License, or (at your option) any later version.
011: *
012: * This software is distributed in the hope that it will be useful,
013: * but WITHOUT ANY WARRANTY; without even the implied warranty of
014: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
015: * Lesser General Public License for more details.
016: *
017: * You should have received a copy of the GNU Lesser General Public
018: * License along with this software; if not, write to the Free
019: * Software Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
020: * 02110-1301 USA, or see the FSF site: http://www.fsf.org.
021: */
022: package org.jboss.aop.deployment;
023:
024: import java.net.URL;
025:
026: import javax.management.InstanceNotFoundException;
027: import javax.management.MBeanServer;
028: import javax.management.Notification;
029: import javax.management.NotificationListener;
030: import javax.management.ObjectName;
031:
032: import org.jboss.mx.loading.HeirarchicalLoaderRepository3;
033: import org.jboss.mx.loading.LoaderRepository;
034: import org.jboss.mx.util.MBeanServerLocator;
035:
036: /**
037: *
038: * @author <a href="kabir.khan@jboss.com">Kabir Khan</a>
039: * @version $Revision: 1.1 $
040: */
041: public class LoaderRepositoryUrlUtil implements NotificationListener {
042: final static MBeanServer SERVER;
043: final static ObjectName MAIN_LOADER_REPOSITORY_OBJECT_NAME;
044: final static LoaderRepository MAIN_LOADER_REPOSITORY;
045: static {
046: SERVER = MBeanServerLocator.locateJBoss();
047: try {
048: MAIN_LOADER_REPOSITORY_OBJECT_NAME = new ObjectName(
049: "JMImplementation:name=Default,service=LoaderRepository");
050: MAIN_LOADER_REPOSITORY = (LoaderRepository) SERVER.invoke(
051: MAIN_LOADER_REPOSITORY_OBJECT_NAME, "getInstance",
052: new Object[0], new String[0]);
053: } catch (Exception e) {
054: throw new RuntimeException(e);
055: }
056: }
057:
058: long currentSequenceNumber;
059: long lastSequenceNumber = -1;
060: URL[] urls;
061:
062: public LoaderRepositoryUrlUtil() {
063: try {
064: SERVER.addNotificationListener(
065: MAIN_LOADER_REPOSITORY_OBJECT_NAME, this , null,
066: null);
067: } catch (InstanceNotFoundException e) {
068: throw new RuntimeException(e);
069: }
070: }
071:
072: public synchronized void handleNotification(
073: Notification notification, Object handback) {
074: if (notification.getType().equals(
075: LoaderRepository.CLASSLOADER_ADDED)) {
076: currentSequenceNumber = notification.getSequenceNumber();
077: } else if (notification.getType().equals(
078: LoaderRepository.CLASSLOADER_REMOVED)) {
079: currentSequenceNumber = notification.getSequenceNumber();
080: }
081: }
082:
083: public synchronized UrlInfo getURLInfo(
084: HeirarchicalLoaderRepository3 scopedLoader, UrlInfo urlInfo) {
085: boolean changed = false;
086: if (lastSequenceNumber != currentSequenceNumber) {
087: urls = MAIN_LOADER_REPOSITORY.getURLs();
088: lastSequenceNumber = currentSequenceNumber;
089: changed = true;
090: }
091: if (!changed) {
092: changed = urlInfo != null
093: && (urlInfo.getSequenceNumber() != lastSequenceNumber);
094: }
095: if (urlInfo == null || changed) {
096: URL[] localUrls = getLocalUrls(scopedLoader, urls);
097: urlInfo = new UrlInfo(urls, localUrls, lastSequenceNumber);
098: }
099: return urlInfo;
100: }
101:
102: public long getCurrentSequenceNumber() {
103: return currentSequenceNumber;
104: }
105:
106: private URL[] getLocalUrls(
107: HeirarchicalLoaderRepository3 scopedRepository,
108: URL[] globalUrls) {
109: URL[] scopedRepositoryUrls = scopedRepository.getURLs();
110:
111: //This is a bit of a hack, since this relies on the order of the urls returned by HeirarchicalLoaderRepository3
112: //My urls, followed by parent urls.
113: int scopedLength = 0;
114: for (int i = 0; i < scopedRepositoryUrls.length; i++) {
115: URL scopedUrl = scopedRepositoryUrls[i];
116: for (int j = 0; j < globalUrls.length; j++) {
117: URL globalUrl = globalUrls[j];
118: if (scopedRepositoryUrls[i].equals(globalUrls[j])) {
119: scopedLength = i;
120: break;
121: }
122: }
123: if (scopedLength > 0) {
124: break;
125: }
126: }
127:
128: URL[] localUrls = new URL[scopedLength];
129: System.arraycopy(scopedRepositoryUrls, 0, localUrls, 0,
130: scopedLength);
131: return localUrls;
132: }
133:
134: public class UrlInfo {
135:
136: URL[] globalUrls;
137: URL[] localUrls;
138: long sequenceNumber;
139:
140: public UrlInfo(URL[] globalUrls, URL[] localUrls,
141: long sequenceNumber) {
142: super ();
143: this .globalUrls = globalUrls;
144: this .localUrls = localUrls;
145: this .sequenceNumber = sequenceNumber;
146: }
147:
148: public URL[] getGlobalUrls() {
149: return globalUrls;
150: }
151:
152: public URL[] getLocalUrls() {
153: return localUrls;
154: }
155:
156: public long getSequenceNumber() {
157: return sequenceNumber;
158: }
159: }
160:
161: }
|