PivotUtils.groovy
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.pivot
019 
020 import org.apache.pivot.collections.Dictionary
021 import org.apache.pivot.collections.List as PivotList
022 import org.apache.pivot.collections.Map as PivotMap
023 import org.apache.pivot.collections.Sequence
024 import org.apache.pivot.collections.Set as PivotSet
025 import org.apache.pivot.util.ListenerList
026 import org.apache.pivot.wtk.Component
027 import org.apache.pivot.wtk.Form
028 import org.apache.pivot.wtk.TabPane
029 import org.apache.pivot.wtk.text.Span
030 
031 import static griffon.util.GriffonNameUtils.getSetterName
032 
033 /**
034  @author Andres Almiray
035  */
036 final class PivotUtils {
037     private PivotUtils() {
038         // prevent instantiation
039     }
040 
041     private static final String ENHANCED = "_ENHANCED_METACLASS_"
042 
043     static boolean hasBeenEnhanced(Class klass) {
044         MetaClassRegistry mcr = GroovySystem.metaClassRegistry
045         MetaClass mc = mcr.getMetaClass(klass)
046         if (!(mc instanceof ExpandoMetaClass)) return false
047         return mc.hasMetaProperty(ENHANCED)
048     }
049 
050     static void enhance(Class klass, Map enhancedMethods) {
051         MetaClassRegistry mcr = GroovySystem.metaClassRegistry
052         MetaClass mc = mcr.getMetaClass(klass)
053         boolean init = false
054         if (!(mc instanceof ExpandoMetaClass||
055             (mc instanceof ExpandoMetaClass && !mc.isModified())) {
056             mcr.removeMetaClass klass
057             mc = new ExpandoMetaClass(klass)
058             init = true
059         }
060         // if mc is an EMC that was initialized previously
061         // with additional methods/properties and it does
062         // not allow modifications after init, then the next
063         // block will throw an exception
064         enhancedMethods.each k, v ->
065             if (mc.getMetaMethod(k== null) {
066                 mc.registerInstanceMethod(k, v)
067             }
068         }
069         mc.registerBeanProperty(ENHANCED, true)
070         if (init) {
071             mc.initialize()
072             mcr.setMetaClass(klass, mc)
073         }
074     }
075 
076     static enhanceClasses() {
077         enhance(Sequence, [
078             iterator: {-> new FixedIterator(delegate, true) },
079             size: {-> delegate.getLength() },
080             getAt: i -> delegate.get(i) },
081             putAt: i, e -> delegate.update(i, e) }
082         ])
083         enhance(ListenerList, [
084             leftShift: e -> delegate.add(e) }
085         ])
086         enhance(PivotList, [
087             leftShift: e -> delegate.add(e) }
088         ])
089         enhance(PivotSet, [
090             leftShift: e -> delegate.add(e) },
091             size: {-> delegate.getCount() }
092         ])
093         enhance(Dictionary, [
094             putAt: k, v -> delegate.put(k, v) },
095             getAt: k -> delegate.get(k) }
096         ])
097         enhance(PivotMap, [
098             size: {-> delegate.getCount() }
099         ])
100         enhance(Span, [
101             asRange: {-> new IntRange(delegate.start, delegate.end) },
102             size: {-> delegate.getLength() }
103         ])
104         enhance(Component, [
105             setFormLabel: label -> Form.setLabel(delegate, label ? label.toString() null) },
106             setFormFlag: flag -> flag ? Form.setFlag(delegate, flag: Form.setFlag(delegate, (Form.Flagnull) },
107             setTabLabel: label -> TabPane.setLabel(delegate, label ? label.toString() null) },
108         ])
109     }
110 
111     static void setBeanProperty(String propertyName, value, bean) {
112         try {
113             // use setter method instead of property access
114             // workaround to multiple property setters & single property getter
115             String setter = getSetterName(propertyName)
116             bean."$setter"(value)
117         catch (MissingPropertyException mpe) {
118             bean.styles.put(propertyName, value)
119         }
120     }
121 }