}
}
final String providerType = getProviderType(service);
final ServiceProvider provider = resolveServiceProvider(service, infoType);
if (provider == null) {
final List<ServiceProvider> providers = ServiceUtils.getServiceProvidersByServiceType(providerType);
final StringBuilder sb = new StringBuilder();
final List<String> types = new ArrayList<String>();
for (final ServiceProvider p : providers) {
for (final String type : p.getTypes()) {
if (types.contains(type)) {
continue;
}
types.add(type);
sb.append(System.getProperty("line.separator"));
sb.append(" <").append(p.getService());
sb.append(" id=\"").append(service.getId()).append('"');
sb.append(" type=\"").append(type).append("\"/>");
}
}
final String noProviderMessage = messages.format("configureService.noProviderForService", providerType, service.getId(), service.getType(), service.getProvider(), sb.toString());
throw new NoSuchProviderException(noProviderMessage);
}
if (service.getId() == null) {
service.setId(provider.getId());
}
final Properties overrides = trim(getSystemProperties(overrideKey(service), provider.getService()));
final Properties serviceProperties = service.getProperties();
trim(serviceProperties);
trim(provider.getProperties());
logger.info("configureService.configuring", service.getId(), provider.getService(), provider.getId());
if (logger.isDebugEnabled()) {
for (final Map.Entry<Object, Object> entry : serviceProperties.entrySet()) {
final Object key = entry.getKey();
Object value = entry.getValue();
if (key instanceof String && "password".equalsIgnoreCase((String) key)) {
value = "<hidden>";
}
logger.debug("[" + key + "=" + value + "]");
}
for (final Map.Entry<Object, Object> entry : overrides.entrySet()) {
final Object key = entry.getKey();
Object value = entry.getValue();
if (key instanceof String && "password".equalsIgnoreCase((String) key)) {
value = "<hidden>";
}
logger.debug("Override [" + key + "=" + value + "]");
}
}
final Properties props = new SuperProperties().caseInsensitive(true);
// weird hack but sometimes we don't want default values when we want null for instance
if (serviceProperties == null || "false".equals(serviceProperties.getProperty(IGNORE_DEFAULT_VALUES_PROP, "false"))) {
props.putAll(provider.getProperties());
}
props.putAll(serviceProperties);
props.putAll(overrides);
// force user properties last
String propertiesProvider = service.getPropertiesProvider();
if (propertiesProvider == null) {
propertiesProvider = SystemInstance.get().getProperty(PropertiesResourceProvider.class.getName());
}
if (propertiesProvider != null) {
// don't trim them, user wants to handle it himself, let him do it
final ObjectRecipe recipe = new ObjectRecipe(propertiesProvider);
recipe.allow(Option.CASE_INSENSITIVE_PROPERTIES);
recipe.allow(Option.PRIVATE_PROPERTIES);
recipe.allow(Option.FIELD_INJECTION);
recipe.allow(Option.NAMED_PARAMETERS);
recipe.allow(Option.IGNORE_MISSING_PROPERTIES);
recipe.setFactoryMethod("provides");
recipe.setProperty("serviceId", service.getId());
recipe.setProperties(props);
recipe.setProperty("properties", props); // let user get all config
final Properties p = Properties.class.cast(recipe.create());
props.putAll(p);
}
props.remove(IGNORE_DEFAULT_VALUES_PROP);
if (providerType != null && !provider.getService().equals(providerType)) {
throw new OpenEJBException(messages.format("configureService.wrongProviderType", service.getId(), providerType));
}
final T info;
try {
info = infoType.newInstance();
} catch (final Exception e) {
throw new OpenEJBException(messages.format("configureService.cannotInstantiateClass", infoType.getName()), e);
}
info.service = provider.getService();
info.types.addAll(provider.getTypes());
info.description = provider.getDescription();
info.displayName = provider.getDisplayName();
info.className = provider.getClassName();
info.factoryMethod = provider.getFactoryName();
info.id = service.getId();
info.properties = props;
info.constructorArgs.addAll(parseConstructorArgs(provider));
if (info instanceof ResourceInfo && service instanceof Resource) {
((ResourceInfo) info).jndiName = ((Resource) service).getJndi();