CoreBuilderCustomizer.java
001 /*
002  * SPDX-License-Identifier: Apache-2.0
003  *
004  * Copyright 2008-2017 the original author or authors.
005  *
006  * Licensed under the Apache License, Version 2.0 (the "License");
007  * you may not use this file except in compliance with the License.
008  * You may obtain a copy of the License at
009  *
010  *     http://www.apache.org/licenses/LICENSE-2.0
011  *
012  * Unless required by applicable law or agreed to in writing, software
013  * distributed under the License is distributed on an "AS IS" BASIS,
014  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015  * See the License for the specific language governing permissions and
016  * limitations under the License.
017  */
018 package griffon.builder.core;
019 
020 import griffon.builder.core.factory.MetaComponentFactory;
021 import griffon.core.threading.UIThreadManager;
022 import groovy.lang.Closure;
023 import groovy.util.Factory;
024 import groovy.util.FactoryBuilderSupport;
025 import org.codehaus.griffon.runtime.groovy.view.AbstractBuilderCustomizer;
026 import org.codehaus.groovy.runtime.MethodClosure;
027 
028 import javax.annotation.Nonnull;
029 import javax.annotation.PostConstruct;
030 import javax.inject.Inject;
031 import javax.inject.Named;
032 import java.util.Arrays;
033 import java.util.LinkedHashMap;
034 import java.util.List;
035 import java.util.Map;
036 
037 import static griffon.util.TypeUtils.castToBoolean;
038 
039 /**
040  @author Andres Almiray
041  */
042 @Named("core")
043 public class CoreBuilderCustomizer extends AbstractBuilderCustomizer {
044     private static final String KEY_ROOT_NODE_NAME = "ROOT_NODE_NAME";
045     private static final String MVC_ID = "mvcId";
046     private static final String ROOT_NODE_IDENTIFIED_BY_ATTRIBUTE = "rootNodeIdentifiedByAttribute";
047 
048     @Inject
049     private UIThreadManager uiThreadManager;
050 
051     public CoreBuilderCustomizer() {
052         Map<String, Factory> factories = new LinkedHashMap<>();
053         factories.put("metaComponent"new MetaComponentFactory());
054         setFactories(factories);
055     }
056 
057     @PostConstruct
058     private void setup() {
059         Map<String, Closure> methods = new LinkedHashMap<>();
060         methods.put("runInsideUISync"new MethodClosure(uiThreadManager, "runInsideUISync"));
061         methods.put("runInsideUIAsync"new MethodClosure(uiThreadManager, "runInsideUIAsync"));
062         methods.put("runOutsideUI"new MethodClosure(uiThreadManager, "runOutsideUI"));
063         methods.put("runOutsideUIAsync"new MethodClosure(uiThreadManager, "runOutsideUIAsync"));
064         methods.put("runFuture"new MethodClosure(uiThreadManager, "runFuture"));
065         methods.put("isUIThread"new MethodClosure(uiThreadManager, "isUIThread"));
066         setMethods(methods);
067     }
068 
069     @Nonnull
070     @Override
071     public List<Closure> getAttributeDelegates() {
072         return Arrays.<Closure>asList(new MethodClosure(this, "rootAttributeDelegate"));
073     }
074 
075     @Nonnull
076     @Override
077     public List<Closure> getPreInstantiateDelegates() {
078         return Arrays.<Closure>asList(new MethodClosure(this, "rootNodePreInstantiateDelegate"));
079     }
080 
081     @Nonnull
082     @Override
083     public List<Closure> getPostNodeCompletionDelegates() {
084         return Arrays.<Closure>asList(new MethodClosure(this, "rootNodePostNodeCompletionDelegate"));
085     }
086 
087     protected void rootAttributeDelegate(FactoryBuilderSupport builder, Object node, Map attributes) {
088         Object isRootNode = attributes.remove("rootNode");
089         if (isRootNode != null && castToBoolean(isRootNode)) {
090             String mvcId = String.valueOf(builder.getVariable(MVC_ID));
091             builder.getVariables().put(ROOT_NODE_IDENTIFIED_BY_ATTRIBUTE, true);
092             builder.getVariables().put(mvcId + "-rootNode", node);
093         }
094     }
095 
096     protected void rootNodePreInstantiateDelegate(FactoryBuilderSupport builder, Map attributes, Object value) {
097         String name = String.valueOf(builder.getContext().get(FactoryBuilderSupport.CURRENT_NAME));
098         if (!builder.hasVariable(KEY_ROOT_NODE_NAME)) {
099             builder.setVariable(KEY_ROOT_NODE_NAME, name);
100         }
101     }
102 
103     protected void rootNodePostNodeCompletionDelegate(FactoryBuilderSupport builder, Object parent, Object node) {
104         Object hasRootNode = builder.getVariables().get(ROOT_NODE_IDENTIFIED_BY_ATTRIBUTE);
105         if (hasRootNode != null && castToBoolean(hasRootNode)) {
106             return;
107         }
108 
109         String name = String.valueOf(builder.getContext().get(FactoryBuilderSupport.CURRENT_NAME));
110         if (builder.getVariable(KEY_ROOT_NODE_NAME).equals(name&& builder.hasVariable(MVC_ID)) {
111             String mvcId = String.valueOf(builder.getVariable(MVC_ID));
112             builder.getVariables().put(mvcId + "-rootNode", node);
113         }
114     }
115 }