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