*/
@Override
public ScannerOutput<SwitchYardModel> scan(ScannerInput<SwitchYardModel> input) throws IOException {
SwitchYardNamespace switchyardNamespace = input.getSwitchyardNamespace();
SwitchYardModel switchyardModel = new V1SwitchYardModel(switchyardNamespace.uri());
CompositeModel compositeModel = new V1CompositeModel();
compositeModel.setName(input.getCompositeName());
BeanNamespace beanNamespace = BeanNamespace.DEFAULT;
for (BeanNamespace value : BeanNamespace.values()) {
if (value.versionMatches(switchyardNamespace)) {
beanNamespace = value;
break;
}
}
List<Class<?>> serviceClasses = scanForServiceBeans(input);
for (Class<?> serviceClass : serviceClasses) {
if (serviceClass.isInterface()) {
continue;
}
if (Modifier.isAbstract(serviceClass.getModifiers())) {
continue;
}
ComponentModel componentModel = new V1ComponentModel();
ComponentServiceModel serviceModel = new V1ComponentServiceModel(switchyardNamespace.uri());
String name = serviceClass.getSimpleName();
BeanComponentImplementationModel beanModel = new V1BeanComponentImplementationModel(beanNamespace.uri());
beanModel.setClazz(serviceClass.getName());
componentModel.setImplementation(beanModel);
Service service = serviceClass.getAnnotation(Service.class);
if (service != null) {
Class<?> iface = service.value();
if (iface == Service.class) {
Class<?>[] interfaces = serviceClass.getInterfaces();
if (interfaces.length == 1) {
iface = interfaces[0];
} else {
throw BeanMessages.MESSAGES.unexpectedExceptionTheServiceAnnotationHasNoValueItCannotBeOmmittedUnlessTheBeanImplementsExactlyOneInterface();
}
}
InterfaceModel csiModel = new V1InterfaceModel(InterfaceModel.JAVA);
if (service.name().equals(Service.EMPTY)) {
name = iface.getSimpleName();
} else {
name = service.name();
}
serviceModel.setName(name);
serviceModel.setInterface(csiModel);
csiModel.setInterface(iface.getName());
componentModel.addService(serviceModel);
}
// Check to see if a policy requirements have been defined
Requires requires = serviceClass.getAnnotation(Requires.class);
if (requires != null) {
for (SecurityPolicy secPolicy : requires.security()) {
if (secPolicy == SecurityPolicy.AUTHORIZATION) {
// authorization supports both interaction and implementation,
// and we want to add it as implementation to be more correct.
beanModel.addPolicyRequirement(secPolicy.getQName());
} else if (secPolicy.supports(PolicyType.INTERACTION)) {
serviceModel.addPolicyRequirement(secPolicy.getQName());
} else if (secPolicy.supports(PolicyType.IMPLEMENTATION)) {
beanModel.addPolicyRequirement(secPolicy.getQName());
} else {
throw BeanMessages.MESSAGES.unknownPolicy(secPolicy.toString());
}
}
for (TransactionPolicy txPolicy : requires.transaction()) {
if (txPolicy.supports(PolicyType.INTERACTION)) {
serviceModel.addPolicyRequirement(txPolicy.getQName());
} else if (txPolicy.supports(PolicyType.IMPLEMENTATION)) {
beanModel.addPolicyRequirement(txPolicy.getQName());
} else {
throw BeanMessages.MESSAGES.unknownPolicy(txPolicy.toString());
}
}
// Make sure we don't have conflicting policies
QName ptx = TransactionPolicy.PROPAGATES_TRANSACTION.getQName();
QName stx = TransactionPolicy.SUSPENDS_TRANSACTION.getQName();
if (serviceModel.hasPolicyRequirement(ptx) && serviceModel.hasPolicyRequirement(stx)) {
throw BeanMessages.MESSAGES.transactionPoliciesCannotCoexistService(ptx, stx, name);
}
QName gtx = TransactionPolicy.MANAGED_TRANSACTION_GLOBAL.getQName();
QName ltx = TransactionPolicy.MANAGED_TRANSACTION_LOCAL.getQName();
QName ntx = TransactionPolicy.NO_MANAGED_TRANSACTION.getQName();
if (beanModel.hasPolicyRequirement(gtx) && beanModel.hasPolicyRequirement(ltx)
|| beanModel.hasPolicyRequirement(gtx) && beanModel.hasPolicyRequirement(ntx)
|| beanModel.hasPolicyRequirement(ltx) && beanModel.hasPolicyRequirement(ntx)) {
throw BeanMessages.MESSAGES.transactionPoliciesCannotCoexistImplementation(gtx, ltx, ntx, name);
}
}
// Add any references
for (ComponentReferenceModel reference : getReferences(switchyardNamespace, serviceClass, name)) {
componentModel.addReference(reference);
}
compositeModel.addComponent(componentModel);
componentModel.setName(getComponentName(name, service));
compositeModel.addComponent(componentModel);
}
if (!compositeModel.getModelChildren().isEmpty()) {
switchyardModel.setComposite(compositeModel);
}
return new ScannerOutput<SwitchYardModel>().setModel(switchyardModel);
}