001 /*
002 * Copyright 2008-2014 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.buildMVCGroup(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 }
|