if (getProxyBuilder().getContexts().isEmpty()) { getProxyBuilder().newContext(); needToPopContext = true; } else { node = getProxyBuilder().createNode(name, namedArgs, arg); Object current = getProxyBuilder().getCurrent(); if (current != null) { getProxyBuilder().setParent(current, node); Factory parentFactory = getProxyBuilder().getCurrentFactory(); if (parentFactory.isLeaf()) { throw new RuntimeException("'" + name + "' doesn't support nesting."); String parentName = getProxyBuilder().getCurrentName(); Map parentContext = getProxyBuilder().getContext(); getProxyBuilder().newContext(); try { getProxyBuilder().getContext().put(OWNER, closure.getOwner()); getProxyBuilder().getContext().put(CURRENT_NODE, node); getProxyBuilder().getContext().put(PARENT_FACTORY, parentFactory); getProxyBuilder().getContext().put(PARENT_NODE, current); getProxyBuilder().getContext().put(PARENT_CONTEXT, parentContext); getProxyBuilder().getContext().put(PARENT_NAME, parentName); getProxyBuilder().getContext().put(PARENT_BUILDER, parentContext.get(CURRENT_BUILDER)); getProxyBuilder().getContext().put(CURRENT_BUILDER, parentContext.get(CHILD_BUILDER));
/** * Switches the builder's proxyBuilder during the execution of a closure.<br> * This is useful to temporary change the building context to another builder * without the need for a contrived setup. It will also take care of restoring * the previous proxyBuilder when the execution finishes, even if an exception * was thrown from inside the closure. Additionally it will use the closure's * result as the value for the node identified by 'name'. * * @param builder the temporary builder to switch to as proxyBuilder. * @param name the node to build on the 'parent' builder. * @param closure the closure to be executed under the temporary builder. * @return a node that responds to value of name with the closure's result as its * value. * @throws RuntimeException - any exception the closure might have thrown during * execution. */ public Object withBuilder(FactoryBuilderSupport builder, String name, Closure closure) { if (name == null) { return null; } Object result = getProxyBuilder().withBuilder(builder, closure); return getProxyBuilder().invokeMethod(name, new Object[]{result}); }
/** * Registers a factory for a JavaBean.<br> * The JavaBean class should have a no-args constructor. * * @param theName name of the node * @param groupName thr group to register this node in * @param beanClass the factory to handle the name */ public void registerBeanFactory(String theName, String groupName, final Class beanClass) { getProxyBuilder().registerFactory(theName, new AbstractFactory() { public Object newInstance(FactoryBuilderSupport builder, Object name, Object value, Map properties) throws InstantiationException, IllegalAccessException { if (checkValueIsTypeNotString(value, name, beanClass)) { return value; } else { return beanClass.newInstance(); } } }); getRegistrationGroup(groupName).add(theName); }
/** * Convenience method when no arguments are required * * @param methodName the name of the method to invoke * @return the result of the call */ public Object invokeMethod(String methodName) { return getProxyBuilder().invokeMethod(methodName, null); }
public Object invokeMethod(String methodName, Object args) { Object name = getProxyBuilder().getName(methodName); Object result; Object previousContext = getProxyBuilder().getContext(); try { result = getProxyBuilder().doInvokeMethod(methodName, name, args); } catch (RuntimeException e) { // remove contexts created after we started if (getContexts().contains(previousContext)) { Map<String, Object> context = getProxyBuilder().getContext(); while (context != null && context != previousContext) { getProxyBuilder().popContext(); context = getProxyBuilder().getContext(); } } throw e; } return result; }
/** * Removes the last context from the stack. * * @return the content just removed */ protected Map<String, Object> popContext() { if (!getProxyBuilder().getContexts().isEmpty()) { return getProxyBuilder().getContexts().removeFirst(); } return null; }
Object node; Factory factory = getProxyBuilder().resolveFactory(name, attributes, value); if (factory == null) { LOG.log(Level.WARNING, "Could not find match for name '" + name + "'"); getProxyBuilder().getContext().put(CURRENT_FACTORY, factory); getProxyBuilder().getContext().put(CURRENT_NAME, String.valueOf(name)); getProxyBuilder().preInstantiate(name, attributes, value); try { node = factory.newInstance(getProxyBuilder().getChildBuilder(), name, value, attributes); if (node == null) { LOG.log(Level.WARNING, "Factory for name '" + name + "' returned null"); + e, e); getProxyBuilder().postInstantiate(name, attributes, node); getProxyBuilder().handleNodeAttributes(node, attributes); return node;
Object previousContext = getProxyBuilder().getContext(); FactoryBuilderSupport previousProxyBuilder = localProxyBuilder.get(); try { if (getProxyBuilder().getContexts().contains(previousContext)) { Map<String, Object> context = getProxyBuilder().getContext(); while (context != null && context != previousContext) { getProxyBuilder().popContext(); context = getProxyBuilder().getContext();
public Object invokeMethod(Object object, String methodName, Object arguments) { try { return delegate.invokeMethod(object, methodName, arguments); } catch (MissingMethodException mme) { // attempt builder resolution try { if (builder.getMetaClass().respondsTo(builder, methodName).isEmpty()) { // dispatch to factories if it is not a literal method return builder.invokeMethod(methodName, arguments); } else { return InvokerHelper.invokeMethod(builder, methodName, arguments); } } catch (MissingMethodException mme2) { // chain secondary exception Throwable root = mme; while (root.getCause() != null) { root = root.getCause(); } root.initCause(mme2); // throw original throw mme; } } }
/** * This is a hook for subclasses to plugin a custom strategy for mapping * names to factories. * * @param name the name of the factory * @param attributes the attributes from the node * @param value value arguments from te node * @return the Factory associated with name.<br> */ protected Factory resolveFactory(Object name, Map attributes, Object value) { getProxyBuilder().getContext().put(CHILD_BUILDER, getProxyBuilder()); return getProxyBuilder().getFactories().get(name); }
/** * @return the factory that built the current node. */ public Factory getCurrentFactory() { return (Factory) getContextAttribute(CURRENT_FACTORY); }
/** * Overloaded to make variables appear as bean properties or via the subscript operator */ public Object getProperty(String property) { try { return getProxyBuilder().doGetProperty(property); } catch (MissingPropertyException mpe) { if ((getContext() != null) && (getContext().containsKey(property))) { return getContext().get(property); } else { try { return getMetaClass().getProperty(this, property); } catch(MissingPropertyException mpe2) { if(mpe2.getProperty().equals(property) && propertyMissingDelegate != null) { return propertyMissingDelegate.call(new Object[]{property}); } throw mpe2; } } } }
public Object getContextAttribute(String key) { Map context = getContext(); if (context != null) { return context.get(key); } return null; }
public Object invokeMethod( String methodName, Object args ) { Object name = proxyBuilder.getName( methodName ); Object result = null; Object previousContext = proxyBuilder.getContext(); try{ result = proxyBuilder.doInvokeMethod( methodName, name, args ); }catch( RuntimeException e ){ // remove contexts created after we started if (proxyBuilder.contexts.contains(previousContext)) { while (proxyBuilder.getContext() != previousContext) { proxyBuilder.popContext(); } } throw e; } return result; }
protected void rootNodePostNodeCompletionDelegate(FactoryBuilderSupport builder, Object parent, Object node) { Object hasRootNode = builder.getVariables().get(ROOT_NODE_IDENTIFIED_BY_ATTRIBUTE); if (hasRootNode != null && castToBoolean(hasRootNode)) { return; } String name = String.valueOf(builder.getContext().get(FactoryBuilderSupport.CURRENT_NAME)); if (builder.getVariable(KEY_ROOT_NODE_NAME).equals(name) && builder.hasVariable(MVC_ID)) { String mvcId = String.valueOf(builder.getVariable(MVC_ID)); builder.getVariables().put(mvcId + "-rootNode", node); } } }
public Object build(Class viewClass) { if (Script.class.isAssignableFrom(viewClass)) { Script script = InvokerHelper.createScript(viewClass, this); return build(script); } else { throw new RuntimeException("Only scripts can be executed via build(Class)"); } }
/** * Registers a factory for a node name. * * @param name the name of the node * @param factory the factory to return the values */ public void registerFactory(String name, Factory factory) { registerFactory(name, registrationGroupName, factory); }
protected void rootNodePreInstantiateDelegate(FactoryBuilderSupport builder, Map attributes, Object value) { String name = String.valueOf(builder.getContext().get(FactoryBuilderSupport.CURRENT_NAME)); if (!builder.hasVariable(KEY_ROOT_NODE_NAME)) { builder.setVariable(KEY_ROOT_NODE_NAME, name); } }
/** * Registers a factory for a JavaBean.<br> * The JavaBean clas should have a no-args constructor. * * @param theName name of the node * @param groupName thr group to register this node in * @param beanClass the factory to handle the name */ public void registerBeanFactory(String theName, String groupName, final Class beanClass) { getProxyBuilder().registerFactory(theName, new AbstractFactory() { public Object newInstance(FactoryBuilderSupport builder, Object name, Object value, Map properties) throws InstantiationException, IllegalAccessException { if (checkValueIsTypeNotString(value, name, beanClass)) { return value; } else { return beanClass.newInstance(); } } }); registrationGroup.get(groupName).add(theName); }
/** * Pushes a new context on the stack. */ protected void newContext() { getContexts().addFirst(new HashMap<String, Object>()); }