@XmlTransient
public List<BeanMetaData> getBeans() {
List<BeanMetaData> beanMetaDataList = new ArrayList<BeanMetaData>();
for (ThreadGroupMetaData metaData : threadGroups) {
final String name = metaData.getName();
final BeanMetaDataBuilder builder = BeanMetaDataBuilder.createBuilder(name, ThreadGroup.class.getName());
builder.setMode(ControllerMode.ON_DEMAND);
final String parent = metaData.getParent();
if (parent != null && parent.length() > 0) {
builder.addConstructorParameter(ThreadGroup.class.getName(), builder.createInject(parent));
}
builder.addConstructorParameter(String.class.getName(), builder.createValue(name));
if (metaData.isDaemon() != null) {
builder.addPropertyMetaData("daemon", builder.createValue(metaData.isDaemon()));
}
final Integer maxPriorityMeta = metaData.getMaxPriority();
if (maxPriorityMeta != null) {
builder.addPropertyMetaData("maxPriority", builder.createValue(maxPriorityMeta));
}
builder.ignoreStop();
builder.ignoreDestroy();
beanMetaDataList.add(builder.getBeanMetaData());
}
for (ThreadFactoryMetaData metaData : threadFactories) {
final String name = metaData.getName();
final BeanMetaDataBuilder builder = BeanMetaDataBuilder.createBuilder(name, JBossThreadFactory.class.getName());
builder.setMode(ControllerMode.ON_DEMAND);
final String group = metaData.getGroup();
builder.addConstructorParameter(ThreadGroup.class.getName(), group == null ? builder.createNull() : builder.createInject(group));
final Boolean daemon = metaData.getDaemon();
builder.addConstructorParameter(Boolean.class.getName(), daemon == null ? builder.createNull() : builder.createValue(daemon));
final Integer priorityMeta = metaData.getInitialPriority();
final Integer actualPriorityMeta;
if (priorityMeta != null) {
actualPriorityMeta = priorityMeta;
} else {
actualPriorityMeta = null;
}
builder.addConstructorParameter(Integer.class.getName(), actualPriorityMeta == null ? builder.createNull() : builder.createValue(actualPriorityMeta));
builder.addConstructorParameter(String.class.getName(), builder.createValue(metaData.getThreadNamePattern()));
final List<ValueMetaData> interruptHandlers = builder.createArray(InterruptHandler[].class.getName(), InterruptHandler.class.getName());
for (InterruptHandlerRefMetaData ihmd : metaData.getInterruptHandlers()) {
interruptHandlers.add(builder.createInject(ihmd.getName()));
}
builder.addConstructorParameter(InterruptHandler[].class.getName(), (ValueMetaData) interruptHandlers);
final ExceptionHandlerRefMetaData ehmd = metaData.getExceptionHandler();
builder.addConstructorParameter(Thread.UncaughtExceptionHandler.class.getName(), ehmd == null ? builder.createNull() : builder.createInject(ehmd.getName()));
final Long stackSize = metaData.getStackSize();
builder.addConstructorParameter(Long.class.getName(), stackSize == null ? builder.createNull() : builder.createValue(stackSize));
beanMetaDataList.add(builder.getBeanMetaData());
}
for (ThreadPoolExecutorMetaData metaData : threadPoolExecutors) {
final String name = metaData.getName();
final PoolSizeMetaData corePoolSizeMetaData = metaData.getCorePoolSize();
final int corePoolSize;
if (corePoolSizeMetaData == null) {
corePoolSize = 0;
} else {
corePoolSize = max(calcPoolSize(corePoolSizeMetaData), 0);
}
final PoolSizeMetaData maxPoolSizeMetaData = metaData.getMaxPoolSize();
final int maxPoolSize;
if (maxPoolSizeMetaData == null) {
maxPoolSize = max(corePoolSize, 1);
} else {
maxPoolSize = max(calcPoolSize(maxPoolSizeMetaData), max(1, corePoolSize));
}
final TimeMetaData timeMetaData = metaData.getKeepAliveTime();
final long time;
final TimeUnit unit;
if (timeMetaData == null) {
time = Long.MAX_VALUE;
unit = TimeUnit.NANOSECONDS;
} else {
time = max(0L, timeMetaData.getTime());
final String unitName = timeMetaData.getUnit();
if (unitName == null) {
unit = TimeUnit.MILLISECONDS;
} else {
final String upperUnitName = unitName.toUpperCase();
if (UNIT_NICK_NAMES.containsKey(upperUnitName)) {
unit = TimeUnit.valueOf(UNIT_NICK_NAMES.get(upperUnitName));
} else {
unit = TimeUnit.valueOf(upperUnitName);
}
}
}
final String threadFactory = metaData.getThreadFactory();
if (threadFactory == null) {
throw new IllegalArgumentException("threadFactory is not defined");
}
final Integer queueLength = metaData.getQueueLength();
final RejectPolicyMetaData rejectPolicyMetaData = metaData.getRejectPolicyMetaData();
final String policyName = rejectPolicyMetaData == null ? "block" : rejectPolicyMetaData.getName();
final BeanMetaDataBuilder executorBuilder;
// here is where we decide which thread pool implementation to use
// right now, our criteria is simple - if blocking is desired or if core threads can time out, use the queue executor instead
if (metaData.isAllowCoreTimeout() || "block".equals(policyName)) {
// use SimpleQueueExecutor
executorBuilder = BeanMetaDataBuilder.createBuilder(SimpleQueueExecutor.class.getName());
final RejectionPolicy rejectionPolicy;
final ValueMetaData handoffExecutorValue;
if ("abort".equals(policyName)) {
rejectionPolicy = RejectionPolicy.ABORT;
handoffExecutorValue = executorBuilder.createNull();
} else if ("block".equals(policyName)) {
rejectionPolicy = RejectionPolicy.BLOCK;
handoffExecutorValue = executorBuilder.createNull();
} else if ("caller-runs".equals(policyName)) {
rejectionPolicy = RejectionPolicy.HANDOFF;
handoffExecutorValue = executorBuilder.createValue(JBossExecutors.directExecutor());
} else if ("discard".equals(policyName)) {
rejectionPolicy = RejectionPolicy.DISCARD;
handoffExecutorValue = executorBuilder.createNull();
} else if ("discard-oldest".equals(policyName)) {
rejectionPolicy = RejectionPolicy.DISCARD_OLDEST;
handoffExecutorValue = executorBuilder.createNull();
} else if ("handoff".equals(policyName)) {
rejectionPolicy = RejectionPolicy.HANDOFF;
handoffExecutorValue = executorBuilder.createInject(rejectPolicyMetaData.getExecutorName());
} else {
throw new IllegalStateException();
}
final Queue<Runnable> queue;
if (queueLength == null) {
queue = new LinkedList<Runnable>();
} else {
queue = new ArrayQueue<Runnable>(queueLength.intValue());
}
executorBuilder.addConstructorParameter(String.class.getName(), name);
executorBuilder.addConstructorParameter("int", Integer.valueOf(corePoolSize));
executorBuilder.addConstructorParameter("int", Integer.valueOf(maxPoolSize));
executorBuilder.addConstructorParameter("long", Long.valueOf(time));
executorBuilder.addConstructorParameter(TimeUnit.class.getName(), unit);
executorBuilder.addConstructorParameter(Queue.class.getName(), executorBuilder.createValue(queue));
executorBuilder.addConstructorParameter(ThreadFactory.class.getName(), executorBuilder.createInject(threadFactory));
executorBuilder.addConstructorParameter(RejectionPolicy.class.getName(), rejectionPolicy);
executorBuilder.addConstructorParameter(Executor.class.getName(), handoffExecutorValue);
if (metaData.isAllowCoreTimeout()) {
executorBuilder.addPropertyMetaData("allowCoreTimeout", Boolean.TRUE);
}
} else {
// use ThreadPoolExecutor
executorBuilder = BeanMetaDataBuilder.createBuilder(JBossThreadPoolExecutor.class.getName());
final ValueMetaData policyValue;
if ("abort".equals(policyName)) {
policyValue = executorBuilder.createValue(JBossExecutors.abortPolicy());
} else if ("block".equals(policyName)) {
throw new IllegalStateException();
} else if ("caller-runs".equals(policyName)) {
policyValue = executorBuilder.createValue(JBossExecutors.callerRunsPolicy());
} else if ("discard".equals(policyName)) {
policyValue = executorBuilder.createValue(JBossExecutors.discardPolicy());
} else if ("discard-oldest".equals(policyName)) {
policyValue = executorBuilder.createValue(JBossExecutors.discardOldestPolicy());
} else if ("handoff".equals(policyName)) {
final BeanMetaDataBuilder policyBuilder = BeanMetaDataBuilder.createBuilder(RejectedExecutionHandler.class.getName());
policyBuilder.setFactoryClass(JBossExecutors.class.getName());
policyBuilder.setFactoryMethod("handoffPolicy");
policyBuilder.addConstructorParameter(Executor.class.getName(), policyBuilder.createInject(rejectPolicyMetaData.getExecutorName()));
policyValue = policyBuilder.getBeanMetaData();
} else {
throw new IllegalStateException();
}
final BlockingQueue<Runnable> queue;
if (queueLength == null) {
// todo: try LinkedTransferQueue
queue = new LinkedBlockingQueue<Runnable>();
} else {
queue = new ArrayBlockingQueue<Runnable>(queueLength.intValue());
}
executorBuilder.addConstructorParameter(String.class.getName(), name);
executorBuilder.addConstructorParameter("int", Integer.valueOf(corePoolSize));
executorBuilder.addConstructorParameter("int", Integer.valueOf(maxPoolSize));
executorBuilder.addConstructorParameter("long", Long.valueOf(time));
executorBuilder.addConstructorParameter(TimeUnit.class.getName(), unit);
executorBuilder.addConstructorParameter(BlockingQueue.class.getName(), executorBuilder.createValue(queue));
executorBuilder.addConstructorParameter(ThreadFactory.class.getName(), executorBuilder.createInject(threadFactory));
executorBuilder.addConstructorParameter(RejectedExecutionHandler.class.getName(), policyValue);
}
executorBuilder.addAnnotation(new JMX() {
public Class<?> exposedInterface() {
return ThreadPoolExecutorMBean.class;
}
public String name() {
return "jboss.threads:service=ThreadPoolExecutor,name=" + name;
}
public boolean registerDirectly() {
return false;
}
public Class<? extends Annotation> annotationType() {
return JMX.class;
}
});
executorBuilder.setMode(ControllerMode.ON_DEMAND);
// final BeanMetaDataBuilder builder = BeanMetaDataBuilder.createBuilder(name, ExecutorService.class.getName());
// builder.setFactoryClass(JBossExecutors.class.getName());
// builder.setFactoryMethod("protectedExecutorService");
// builder.addConstructorParameter(Executor.class.getName(), executorBuilder.getBeanMetaData());
// builder.setMode(ControllerMode.ON_DEMAND);
// beanMetaDataList.add(builder.getBeanMetaData());
executorBuilder.setName(name);
beanMetaDataList.add(executorBuilder.getBeanMetaData());
}
for (DirectExecutorMetaData metaData : directExecutors) {
final String name = metaData.getName();
final BeanMetaDataBuilder builder = BeanMetaDataBuilder.createBuilder(name, ExecutorService.class.getName());
builder.setFactoryClass(JBossExecutors.class.getName());
builder.setFactoryMethod("directExecutorService");
builder.setMode(ControllerMode.ON_DEMAND);
beanMetaDataList.add(builder.getBeanMetaData());
}
for (NotatingExecutorMetaData metaData : notatingExecutors) {
final String name = metaData.getName();
final BeanMetaDataBuilder builder = BeanMetaDataBuilder.createBuilder(name, DirectExecutor.class.getName());
builder.setMode(ControllerMode.ON_DEMAND);
builder.setFactoryClass(JBossExecutors.class.getName());
builder.setFactoryMethod("notatingExecutor");
builder.addConstructorParameter(Executor.class.getName(), builder.createInject(metaData.getParent()));
builder.addConstructorParameter(String.class.getName(), metaData.getNote());
beanMetaDataList.add(builder.getBeanMetaData());
}
for (ScheduledThreadPoolExecutorMetaData metaData : scheduledThreadPoolExecutors) {
final String name = metaData.getName();
final BeanMetaDataBuilder builder = BeanMetaDataBuilder.createBuilder(name, ScheduledThreadPoolExecutor.class.getName());
builder.setMode(ControllerMode.ON_DEMAND);
final PoolSizeMetaData poolSizeMetaData = metaData.getPoolSize();
final int size;
if (poolSizeMetaData != null) {
size = max(1, calcPoolSize(poolSizeMetaData));
} else {
size = 1;
}
builder.addConstructorParameter("int", Integer.valueOf(size));
final String threadFactoryName = metaData.getThreadFactory();
if (threadFactoryName != null) {
builder.addConstructorParameter(ThreadFactory.class.getName(), builder.createInject(threadFactoryName));
}
beanMetaDataList.add(builder.getBeanMetaData());
}
return beanMetaDataList;
}