@SuppressWarnings({"unchecked", "rawtypes"}) private void setReturnType(JavaFactory<?> newFactory) { try { Method method = newFactory.getClass().getMethod("instance", new Class[] {Object[].class}); newFactory.setReturnType((Class) method.getReturnType()); } catch (NoSuchMethodException e) { throw new FactoryException( "JavaFactoryBuilder", "INSTANCE_METHOD_NOT_FOUND", "instance method not found for factory", e); } }
/** * Adds a Java factory to the container. * * @param name The name to identify this factory by in the container. * @param returnType The type of component the added factory produces. * @param newFactory The Java factory to add to the container. */ public <T> void replaceFactory(String name, Class<T> returnType, JavaFactory<T> newFactory) { if (returnType == null) { setReturnType(newFactory); } else { newFactory.setReturnType(returnType); } injectFactories(name, newFactory); container.replaceFactory(name, newFactory); }
private void injectFactories(String name, JavaFactory<?> newFactory) { Class<?> factoryClass = newFactory.getClass(); for (Field field : factoryClass.getFields()) { Class<?> rawType = field.getType(); if (isFactory(rawType)) { String factoryName = field.getName(); Factory factoryAnnotation = field.getAnnotation(Factory.class); if (factoryAnnotation != null) { factoryName = factoryAnnotation.value(); } GlobalFactory<?> factory = container.getFactory(factoryName); if (factory == null) { throw new FactoryException( "JavaFactoryBuilder", "INJECT_FACTORIES", "Factory field/annotation name '" + factoryName + "' does not match a factory name in the container"); } Class<?> factoryReturnType = factory.getReturnType(); Type type = field.getGenericType(); if (type instanceof ParameterizedType) { Class<?> genericType = null; ParameterizedType pType = (ParameterizedType) type; genericType = (Class<?>) pType.getActualTypeArguments()[0]; if (!FactoryUtil.isSubstitutableFor(factoryReturnType, genericType)) { throw new FactoryException( "JavaFactoryBuilder", "MIS_MATCHING_RETURN_TYPE", "Mismatching return type in factory named '" + name + "' for factory field '" + field.getName() + "'. " + "Factory " + field.getName() + " returns " + factory.getReturnType() + ". " + "Factory field " + field.getName() + " is parameterized to " + genericType); } } try { field.set(newFactory, factory); } catch (IllegalAccessException e) { throw new FactoryException( "JavaFactoryBuilder", "INSTANCE_METHOD_NOT_ACCESSIBLE", "Error setting factory field " + field.getName(), e); } } } }
@Override public JClass getObjectClass() { return JavaFactory.getInstance().buildClass(boolean.class); }