41 package com.sun.jmx.examples.scandir;
49 import java.io.IOException;
50 import java.lang.management.ManagementFactory;
51 import java.util.ArrayList;
52 import java.util.Collections;
53 import java.util.EnumSet;
54 import java.util.HashMap;
56 import java.util.Map.Entry;
57 import java.util.Timer;
58 import java.util.TimerTask;
59 import java.util.concurrent.BlockingQueue;
60 import java.util.concurrent.ConcurrentHashMap;
61 import java.util.concurrent.ConcurrentLinkedQueue;
62 import java.util.concurrent.LinkedBlockingQueue;
63 import java.util.concurrent.Semaphore;
64 import java.util.concurrent.TimeUnit;
65 import java.util.logging.Level;
66 import java.util.logging.Logger;
67 import javax.management.AttributeChangeNotification;
68 import javax.management.InstanceNotFoundException;
69 import javax.management.JMException;
70 import javax.management.JMX;
71 import javax.management.ListenerNotFoundException;
72 import javax.management.MBeanNotificationInfo;
73 import javax.management.MBeanRegistration;
74 import javax.management.MBeanServer;
75 import javax.management.MBeanServerConnection;
76 import javax.management.MalformedObjectNameException;
77 import javax.management.Notification;
78 import javax.management.NotificationBroadcasterSupport;
79 import javax.management.NotificationEmitter;
80 import javax.management.NotificationFilter;
81 import javax.management.NotificationListener;
82 import javax.management.ObjectInstance;
83 import javax.management.ObjectName;
104 NotificationEmitter, MBeanRegistration {
109 private static final Logger
LOG =
152 private final Map<ObjectName,DirectoryScannerMXBean>
scanmap;
157 private final Map<ObjectName, ScanDirConfigMXBean>
configmap;
177 return new ConcurrentHashMap<K, V>();
183 return new HashMap<K, V>();
199 final Package p = clazz.getPackage();
200 final String packageName = (p==
null)?
null:p.getName();
201 final String className = clazz.getSimpleName();
203 if (packageName ==
null || packageName.length()==0) {
208 domain = packageName;
210 final ObjectName
name =
new ObjectName(domain,
"type",className);
212 }
catch (Exception x) {
213 final IllegalArgumentException iae =
214 new IllegalArgumentException(String.valueOf(clazz),x);
235 .toString()+
",name="+
name);
236 }
catch (MalformedObjectNameException x) {
237 final IllegalArgumentException iae =
238 new IllegalArgumentException(String.valueOf(
name),x);
276 throws IOException, JMException {
277 final ObjectInstance moi =
280 JMX.newMXBeanProxy(mbs,moi.getObjectName(),
323 throws IOException, JMException {
324 final MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
325 return register(mbs);
332 broadcaster =
new NotificationBroadcasterSupport();
352 throws IOException, JMException {
353 if (bean ==
null)
return;
355 throw new IllegalStateException(
"Can't acquire lock");
360 if (scans ==
null)
return;
372 throws IOException, JMException {
379 throws IOException, JMException {
406 final ObjectName scanName;
407 synchronized (
this) {
409 throw new IllegalStateException(
state.toString());
414 LOG.fine(
"scanner: "+scanner);
415 LOG.fine(
"scanName: "+scanName);
416 final ObjectInstance moi =
418 final ObjectName moiName = moi.getObjectName();
424 }
catch (RuntimeException x) {
425 final String msg =
"Operation failed: "+x;
426 if (
LOG.isLoggable(Level.FINEST))
427 LOG.log(Level.FINEST,msg,x);
430 }
catch (JMException x) {
431 final String msg =
"Operation failed: "+x;
432 if (
LOG.isLoggable(Level.FINEST))
433 LOG.log(Level.FINEST,msg,x);
445 final ObjectInstance moi =
mbeanServer.registerMBean(profile,profName);
449 configmap.put(moi.getObjectName(),proxy);
456 final Map<String,DirectoryScannerMXBean> proxyMap =
newHashMap();
457 for (Entry<ObjectName,DirectoryScannerMXBean> item :
scanmap.entrySet()){
458 proxyMap.put(item.getKey().getKeyProperty(
"name"),item.getValue());
481 allowedStates.put(
"close",EnumSet.of(STOPPED,COMPLETED,CLOSED));
516 final AttributeChangeNotification n =
518 "ScanManager State changed to "+current,
"State",
519 ScanState.class.getName(),old.toString(),current.toString());
524 LOG.fine(
"Can't queue Notification: "+n);
526 }
catch (InterruptedException x) {
527 LOG.fine(
"Can't queue Notification: "+x);
559 final long timestamp;
563 if (!allowed.contains(
state))
564 throw new IllegalStateException(
state.toString());
566 timestamp = System.currentTimeMillis();
569 LOG.fine(
"switched state: "+old+
" -> "+desired);
589 throw new IllegalStateException(
"Can't acquire lock");
592 LOG.fine(
"scheduling new task: state="+
state);
594 final boolean scheduled =
597 LOG.fine(
"new task scheduled: state="+
state);
612 if (
state == STOPPED)
return false;
613 if (
timer ==
null)
timer =
new Timer(
"ScanManager");
615 timer.schedule(task,delay);
624 public void start() throws IOException, InstanceNotFoundException {
638 throw new IllegalStateException(
"Can't acquire lock");
640 final StringBuilder b =
new StringBuilder();
653 b.insert(0,
"stop partially failed with "+errcount+
" error(s):");
654 throw new RuntimeException(b.toString());
666 private void append(StringBuilder b,String prefix,Throwable
t) {
667 final String first = (prefix==
null)?
"\n":
"\n"+prefix;
668 b.append(first).append(String.valueOf(
t));
670 while ((cause = cause.getCause())!=
null) {
671 b.append(first).append(
"Caused by:").append(first);
672 b.append(
'\t').append(String.valueOf(cause));
686 }
catch (Exception ex) {
703 }
catch (Exception ex) {
718 throws IOException, InstanceNotFoundException {
721 final StringBuilder b =
new StringBuilder();
722 for (ObjectName key :
scanmap.keySet()) {
725 if (
state == STOPPED)
return;
727 }
catch (Exception ex) {
728 LOG.log(Level.FINE,key +
" failed to scan: "+ex,ex);
734 b.insert(0,
"scan partially performed with "+errcount+
" error(s):");
735 throw new RuntimeException(b.toString());
743 private final ConcurrentLinkedQueue<SessionTask>
tasklist =
744 new ConcurrentLinkedQueue<SessionTask>();
805 if (
state == STOPPED ||
state == CLOSED)
return false;
815 return super.cancel();
823 final String tag =
"Scheduled session["+
taskid+
"]";
826 LOG.finer(tag+
" cancelled: done");
830 LOG.finer(tag+
" stopped: done");
834 }
catch (Exception x) {
835 if (
LOG.isLoggable(Level.FINEST)) {
836 LOG.log(Level.FINEST,
837 tag+
" failed to scan: "+x,x);
838 }
else if (
LOG.isLoggable(Level.FINE)) {
839 LOG.fine(tag+
" failed to scan: "+x);
849 final String tag =
"Scheduled session["+
taskid+
"]";
855 LOG.finer(tag+
" stopped: do not reschedule");
860 LOG.finer(tag+
": next session successfully scheduled");
861 }
catch (Exception x) {
862 if (
LOG.isLoggable(Level.FINEST)) {
863 LOG.log(Level.FINEST,tag+
864 " failed to schedule next session: "+x,x);
865 }
else if (
LOG.isLoggable(Level.FINE)) {
866 LOG.fine(tag+
" failed to schedule next session: "+x);
878 final String tag =
"Scheduled session["+
taskid+
"]";
880 LOG.finer(tag+
" starting...");
884 LOG.finer(tag+
" terminating - state is "+
state+
886 " no additional session scheduled"));
892 LOG.finer(tag+
" stopped: done");
894 LOG.finer(tag+
" completed: done");
903 LOG.finer(tag+
" finished...");
921 public void addNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback)
throws IllegalArgumentException {
922 broadcaster.addNotificationListener(listener, filter, handback);
931 return new MBeanNotificationInfo[] {
932 new MBeanNotificationInfo(
new String[] {
933 AttributeChangeNotification.ATTRIBUTE_CHANGE},
934 AttributeChangeNotification.class.getName(),
935 "Emitted when the State attribute changes")
951 public void removeNotificationListener(NotificationListener listener, NotificationFilter filter, Object handback)
throws ListenerNotFoundException {
952 broadcaster.removeNotificationListener(listener, filter, handback);
1004 throw new IllegalArgumentException(String.valueOf(
name));
1014 final String
user = System.getProperty(
"user.home");
1015 final String defconf =
user+File.separator+
"jmx-scandir.xml";
1042 if (!registrationDone)
return;
1043 Exception test=
null;
1048 final String conf = System.getProperty(
"scandir.config.file",defconf);
1050 final ObjectName defaultProfileName =
1052 if (!
mbeanServer.isRegistered(defaultProfileName))
1054 defaultProfileName);
1058 }
catch (Exception x) {
1059 LOG.config(
"Failed to populate MBeanServer: "+x);
1065 }
catch (Exception x) {
1066 LOG.finest(
"No config to load: "+x);
1072 }
catch (Exception x) {
1073 if (
LOG.isLoggable(Level.FINEST))
1074 LOG.log(Level.FINEST,
"Failed to apply config: "+x,x);
1075 LOG.config(
"Failed to apply config: "+x);
1092 for (ObjectName key : map.keySet()) {
1122 throw new IllegalStateException(
"can't acquire lock");
1130 }
catch (Exception x) {
1131 LOG.log(Level.FINEST,
"Failed to unregister: "+x,x);
1142 if (
timer !=
null) {
1145 }
catch (Exception x) {
1146 if (
LOG.isLoggable(Level.FINEST))
1147 LOG.log(Level.FINEST,
"Failed to cancel timer",x);
1148 else if (
LOG.isLoggable(Level.FINE))
1149 LOG.fine(
"Failed to cancel timer: "+x);