protected GlobalFactory<?> buildGlobalFactory(Container container, FactoryDefinition definition) { GlobalFactoryBase globalFactory = null; LocalFactory instantiationFactory = buildLocalFactoryRecursively(container, definition); definition.setLocalProductType(definition.getName(), instantiationFactory.getReturnType()); if (definition.isNewInstance() || definition.isLocalizedMap()) { globalFactory = new GlobalNewInstanceFactory(); } else if (definition.isSingleton()) { globalFactory = new GlobalSingletonFactory(); } else if (definition.isThreadSingleton()) { globalFactory = new GlobalThreadSingletonFactory(); } else if (definition.isFlyweight()) { globalFactory = new GlobalFlyweightFactory(); } int namedLocalProductCount = definition.getNamedLocalProductCount(); globalFactory.setLocalProductCount(namedLocalProductCount); /* * todo optimize this... so far all global factories have at least 1 * named local product (the returned product)... but far from all global * factories actually reference it from life cycle phases. */ if (definition.getNamedLocalProductCount() > 0) { instantiationFactory = new LocalProductProducerFactory(instantiationFactory, 0); } globalFactory.setLocalInstantiationFactory(instantiationFactory); if (definition.getPhaseFactories() != null && definition.getPhaseFactories().size() > 0) { for (String phase : definition.getPhaseFactories().keySet()) { List<FactoryDefinition> phaseFactories = definition.getPhaseFactories().get(phase); globalFactory.setPhase(phase, buildLocalFactories(container, phaseFactories)); } } return globalFactory; }
protected LocalFactory buildLocalFactoryRecursively( Container container, FactoryDefinition definition) { LocalFactory factory = null; try { List<LocalFactory> argumentFactories = buildLocalFactories(container, definition.getInstantiationArgFactories()); // todo get this from castings in factory definition. Casting will // force a specific return type. Class<?>[] forcedArgumentTypes = getForcedArgumentTypes(argumentFactories, definition); if (definition.isConstructorFactory()) { // constructor factory factory = builder.createConstructorFactory( definition.getIdentifierOwnerClass(), argumentFactories, forcedArgumentTypes); } else if (definition.isStaticMethodFactory()) { // method invocation factory factory = builder.createStaticMethodFactory( definition.getIdentifier(), definition.getIdentifierOwnerClass(), argumentFactories, forcedArgumentTypes); } else if (definition.isInstanceMethodFactory()) { LocalFactory methodInvocationTargetFactory = buildLocalFactoryRecursively(container, definition.getIdentifierTargetFactory()); factory = builder.createInstanceMethodFactory( definition.getIdentifier(), methodInvocationTargetFactory, argumentFactories, forcedArgumentTypes); } else if (definition.isInstanceFieldFactory()) { LocalFactory fieldTargetFactory = buildLocalFactoryRecursively(container, definition.getIdentifierTargetFactory()); factory = builder.createFieldFactory(definition.getIdentifier(), fieldTargetFactory); } else if (definition.isStaticFieldFactory()) { factory = builder.createFieldFactory( definition.getIdentifier(), definition.getIdentifierOwnerClass()); } else if (definition.isInstanceFieldAssignmentFactory()) { LocalFactory assignmentTargetFactory = buildLocalFactoryRecursively(container, definition.getIdentifierTargetFactory()); factory = builder.createFieldAssignmentFactory( definition.getIdentifier(), assignmentTargetFactory, argumentFactories.get(0)); } else if (definition.isStaticFieldAssignmentFactory()) { factory = builder.createFieldAssignmentFactory( definition.getIdentifier(), definition.getIdentifierOwnerClass(), argumentFactories.get(0)); } else if (definition.isFactoryCallFactory()) { // existing factory // reference if (container.getFactory(definition.getIdentifier()) == null) throw new ParserException( "ScriptFactoryBuilder", "UNKNOWN_FACTORY", "Error in factory definition [" + definition.getRoot().getName() + "]: Unknown Factory: " + definition.getIdentifier()); factory = new InputAdaptingFactory( container.getFactory(definition.getIdentifier()), argumentFactories); } else if (definition.isFactoryFactory()) { factory = new FactoryFactory(container, definition.getIdentifier()); } else if (definition.isCollectionFactory()) { factory = new CollectionFactory(argumentFactories); } else if (definition.isMapFactory()) { List<LocalFactory> keyFactories = buildLocalFactories(container, definition.getInstantiationArgKeyFactories()); factory = new MapFactory(keyFactories, argumentFactories); if (definition.isLocalizedMap()) { ((MapFactory) factory).setFactoryMap(true); GlobalFactory<?> localeFactory = container.getFactory("locale"); if (localeFactory == null) { new ParserException( "ScriptFactoryBuilder", "NO_LOCALE_FACTORY_FOUND", "Error in factory definition " + definition.getRoot().getName() + ": No 'locale' factory found. " + "A 'locale' factory must be present in order to use localized resource factories"); } factory = new LocalizedResourceFactory(factory, localeFactory); } } else if (definition.isValueFactory()) { // value factory if (isString(definition.getIdentifier())) factory = new ValueFactory( definition.getIdentifier().substring(1, definition.getIdentifier().length() - 1)); else if ("null".equals(definition.getIdentifier())) { factory = new ValueFactory(null); } else factory = new ValueFactory(definition.getIdentifier()); } else if (definition.isInputParameterFactory()) { // input // consuming // factory factory = new InputConsumerFactory(Integer.parseInt(definition.getIdentifier())); } else if (definition.isLocalProductFactory()) { factory = new LocalProductConsumerFactory( definition.getLocalProductType(), definition.getLocalProductIndex()); } // only local factories with a name (named local factories) can be // something else than "new instance" // factories. if (definition.isNamedLocalFactory()) { if (definition.isSingleton()) { factory = new LocalSingletonFactory(factory); } else if (definition.isThreadSingleton()) { factory = new LocalThreadSingletonFactory(factory); } else if (definition.isFlyweight()) { factory = new LocalFlyweightFactory(factory); } factory = new LocalProductProducerFactory(factory, definition.getLocalProductIndex()); definition.setLocalProductType(definition.getName(), factory.getReturnType()); } return factory; } catch (ContainerException e) { if (e.getCode().indexOf("ScriptFactoryBuilder") == -1) { e.addInfo( "ScriptFactoryBuilder", "ERROR_CREATING_FACTORY", "Error in factory definition " + definition.getRoot().getName()); } throw e; } }