| 
001 /*002  * Copyright 2008-2015 the original author or authors.
 003  *
 004  * Licensed under the Apache License, Version 2.0 (the "License");
 005  * you may not use this file except in compliance with the License.
 006  * You may obtain a copy of the License at
 007  *
 008  *     http://www.apache.org/licenses/LICENSE-2.0
 009  *
 010  * Unless required by applicable law or agreed to in writing, software
 011  * distributed under the License is distributed on an "AS IS" BASIS,
 012  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 013  * See the License for the specific language governing permissions and
 014  * limitations under the License.
 015  */
 016 package griffon.builder.core.factory
 017
 018 import griffon.core.ApplicationEvent
 019 import griffon.core.mvc.MVCGroup
 020
 021 /**
 022  * Enables MVC groups to be used as component nodes
 023  *
 024  * @author Andres Almiray
 025  * @author Alexander Klein
 026  */
 027 @SuppressWarnings("rawtypes")
 028 class MetaComponentFactory extends AbstractFactory {
 029     Object newInstance(FactoryBuilderSupport builder, Object name, Object value, Map attributes) {
 030         String mvcType = ''
 031         if (value != null && value instanceof CharSequence) {
 032             mvcType = value.toString()
 033         } else {
 034             throw new IllegalArgumentException("In $name value must be an MVC group type")
 035         }
 036
 037         String mvcId = attributes.remove('mvcId')
 038         mvcId = attributes.containsKey('mvcId') ? attributes.remove('mvcId') : mvcId
 039
 040         MVCGroup mvcGroup = builder.application.createMVCGroup(mvcType, mvcId, attributes)
 041         def root = mvcGroup.getScriptResult('view')
 042
 043         Closure destroyEventHandler
 044         destroyEventHandler = { String parentId, MVCGroup childGroup, MVCGroup destroyedGroup ->
 045             if (destroyedGroup.mvcId == parentId) {
 046                 childGroup.destroy()
 047                 builder.application.removeApplicationEventListener(ApplicationEvent.DESTROY_MVC_GROUP.name, destroyEventHandler)
 048             }
 049         }.curry(mvcId, mvcGroup)
 050         builder.application.addApplicationEventListener(ApplicationEvent.DESTROY_MVC_GROUP.name, destroyEventHandler)
 051
 052         builder.context.root = root
 053         builder.context.mvcGroup = mvcGroup
 054         root
 055     }
 056
 057     boolean onHandleNodeAttributes(FactoryBuilderSupport builder, Object node, Map attributes) {
 058         try {
 059             return builder.context.mvcGroup.controller.metaClass.invokeMethod(builder.context.mvcGroup.controller, 'onHandleNodeAttributes', builder, node, attributes)
 060         } catch (MissingMethodException e) {
 061             return false
 062         }
 063     }
 064
 065     boolean onNodeChildren(FactoryBuilderSupport builder, Object node, Closure childContent) {
 066         def root = builder.context.root
 067         builder = builder.context.mvcGroup.builder
 068         Closure handleChildContent = builder.getVariables().get('handleChildContent')
 069         if (handleChildContent != null) {
 070             handleChildContent(childContent)
 071         } else {
 072             builder.container(root, childContent)
 073         }
 074         false
 075     }
 076
 077     boolean isHandlesNodeChildren() {
 078         false
 079     }
 080
 081     @Override
 082     void setChild(FactoryBuilderSupport builder, Object parent, Object child) {
 083         safeInvoke(builder.parentContext.mvcGroup.builder, 'setChild', builder, parent, child)
 084     }
 085
 086     @Override
 087     void setParent(FactoryBuilderSupport builder, Object parent, Object child) {
 088         safeInvoke(builder.context.mvcGroup.builder, 'setParent', builder, parent, child)
 089     }
 090
 091     @Override
 092     void onNodeCompleted(FactoryBuilderSupport builder, Object parent, Object node) {
 093         safeInvoke(builder.context.mvcGroup.builder, 'onNodeCompleted', builder, parent, node)
 094     }
 095
 096     static protected def safeInvoke(Object obj, String method, Object... args) {
 097         try {
 098             return obj.metaClass.invokeMethod(obj, method, args)
 099         } catch (MissingMethodException e) {
 100             return null
 101         }
 102     }
 103 }
 |