001    // Copyright 2004, 2005 The Apache Software Foundation
002    //
003    // Licensed under the Apache License, Version 2.0 (the "License");
004    // you may not use this file except in compliance with the License.
005    // You may obtain a copy of the License at
006    //
007    //     http://www.apache.org/licenses/LICENSE-2.0
008    //
009    // Unless required by applicable law or agreed to in writing, software
010    // distributed under the License is distributed on an "AS IS" BASIS,
011    // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
012    // See the License for the specific language governing permissions and
013    // limitations under the License.
014    
015    package org.apache.tapestry.contrib.inspector;
016    
017    import java.util.ArrayList;
018    import java.util.Collection;
019    import java.util.Collections;
020    import java.util.Comparator;
021    import java.util.List;
022    import java.util.Map;
023    
024    import org.apache.tapestry.BaseComponent;
025    import org.apache.tapestry.IAsset;
026    import org.apache.tapestry.IBinding;
027    import org.apache.tapestry.IComponent;
028    import org.apache.tapestry.event.PageBeginRenderListener;
029    import org.apache.tapestry.event.PageEndRenderListener;
030    import org.apache.tapestry.event.PageEvent;
031    import org.apache.tapestry.spec.IBeanSpecification;
032    import org.apache.tapestry.spec.IComponentSpecification;
033    import org.apache.tapestry.spec.IParameterSpecification;
034    
035    /**
036     * Component of the {@link Inspector} page used to display the specification, parameters and
037     * bindings and assets of the inspected component.
038     * 
039     * @author Howard Lewis Ship
040     */
041    
042    public abstract class ShowSpecification extends BaseComponent implements PageBeginRenderListener,
043            PageEndRenderListener
044    {
045        private IComponent _inspectedComponent;
046    
047        private IComponentSpecification _inspectedSpecification;
048    
049        private String _parameterName;
050    
051        private String _assetName;
052    
053        private List _sortedComponents;
054    
055        private List _assetNames;
056    
057        private List _formalParameterNames;
058    
059        private List _informalParameterNames;
060    
061        private List _sortedPropertyNames;
062    
063        private String _propertyName;
064    
065        private List _beanNames;
066    
067        private String _beanName;
068    
069        private IBeanSpecification _beanSpecification;
070    
071        /**
072         * 
073         * @author hls
074         */
075        private static class ComponentComparitor implements Comparator
076        {
077            public int compare(Object left, Object right)
078            {
079                IComponent leftComponent;
080                String leftId;
081                IComponent rightComponent;
082                String rightId;
083    
084                if (left == right)
085                    return 0;
086    
087                leftComponent = (IComponent) left;
088                rightComponent = (IComponent) right;
089    
090                leftId = leftComponent.getId();
091                rightId = rightComponent.getId();
092    
093                return leftId.compareTo(rightId);
094            }
095        }
096    
097        /**
098         * Clears all cached information about the component and such after each render (including the
099         * rewind phase render used to process the tab view).
100         * 
101         * @since 1.0.5
102         */
103    
104        public void pageEndRender(PageEvent event)
105        {
106            _inspectedComponent = null;
107            _inspectedSpecification = null;
108            _parameterName = null;
109            _assetName = null;
110            _sortedComponents = null;
111            _assetNames = null;
112            _formalParameterNames = null;
113            _informalParameterNames = null;
114            _sortedPropertyNames = null;
115            _propertyName = null;
116            _beanNames = null;
117            _beanName = null;
118            _beanSpecification = null;
119        }
120    
121        /**
122         * Gets the inspected component and specification from the {@link Inspector} page.
123         * 
124         * @since 1.0.5
125         */
126    
127        public void pageBeginRender(PageEvent event)
128        {
129            Inspector inspector = (Inspector) getPage();
130    
131            _inspectedComponent = inspector.getInspectedComponent();
132            _inspectedSpecification = _inspectedComponent.getSpecification();
133        }
134    
135        public IComponent getInspectedComponent()
136        {
137            return _inspectedComponent;
138        }
139    
140        public IComponentSpecification getInspectedSpecification()
141        {
142            return _inspectedSpecification;
143        }
144    
145        /**
146         * Returns a sorted list of formal parameter names.
147         */
148    
149        public List getFormalParameterNames()
150        {
151            if (_formalParameterNames == null)
152                _formalParameterNames = sort(_inspectedSpecification.getParameterNames());
153    
154            return _formalParameterNames;
155        }
156    
157        /**
158         * Returns a sorted list of informal parameter names. This is the list of all bindings, with the
159         * list of parameter names removed, sorted.
160         */
161    
162        public List getInformalParameterNames()
163        {
164            if (_informalParameterNames != null)
165                return _informalParameterNames;
166    
167            Collection names = _inspectedComponent.getBindingNames();
168            if (names != null && names.size() > 0)
169            {
170                _informalParameterNames = new ArrayList(names);
171    
172                // Remove the names of any formal parameters. This leaves
173                // just the names of informal parameters (informal parameters
174                // are any parameters/bindings that don't match a formal parameter
175                // name).
176    
177                names = _inspectedSpecification.getParameterNames();
178                if (names != null)
179                    _informalParameterNames.removeAll(names);
180    
181                Collections.sort(_informalParameterNames);
182            }
183    
184            return _informalParameterNames;
185        }
186    
187        public String getParameterName()
188        {
189            return _parameterName;
190        }
191    
192        public void setParameterName(String value)
193        {
194            _parameterName = value;
195        }
196    
197        /**
198         * Returns the {@link org.apache.tapestry.spec.ParameterSpecification} corresponding to the
199         * value of the parameterName property.
200         */
201    
202        public IParameterSpecification getParameterSpecification()
203        {
204            return _inspectedSpecification.getParameter(_parameterName);
205        }
206    
207        /**
208         * Returns the {@link IBinding} corresponding to the value of the parameterName property.
209         */
210    
211        public IBinding getBinding()
212        {
213            return _inspectedComponent.getBinding(_parameterName);
214        }
215    
216        public void setAssetName(String value)
217        {
218            _assetName = value;
219        }
220    
221        public String getAssetName()
222        {
223            return _assetName;
224        }
225    
226        /**
227         * Returns the {@link IAsset} corresponding to the value of the assetName property.
228         */
229    
230        public IAsset getAsset()
231        {
232            return (IAsset) _inspectedComponent.getAssets().get(_assetName);
233        }
234    
235        /**
236         * Returns a sorted list of asset names, or null if the component contains no assets.
237         */
238    
239        public List getAssetNames()
240        {
241            if (_assetNames == null)
242                _assetNames = sort(_inspectedComponent.getAssets().keySet());
243    
244            return _assetNames;
245        }
246    
247        public List getSortedComponents()
248        {
249            if (_sortedComponents != null)
250                return _sortedComponents;
251    
252            Inspector inspector = (Inspector) getPage();
253            IComponent inspectedComponent = inspector.getInspectedComponent();
254    
255            // Get a Map of the components and simply return null if there
256            // are none.
257    
258            Map components = inspectedComponent.getComponents();
259    
260            _sortedComponents = new ArrayList(components.values());
261    
262            Collections.sort(_sortedComponents, new ComponentComparitor());
263    
264            return _sortedComponents;
265        }
266    
267        public abstract void setCurrentComponent(IComponent value);
268    
269        public abstract IComponent getCurrentComponent();
270    
271        /**
272         * Returns a list of the properties for the component (from its specification), or null if the
273         * component has no properties.
274         */
275    
276        public List getSortedPropertyNames()
277        {
278            if (_sortedPropertyNames == null)
279                _sortedPropertyNames = sort(_inspectedSpecification.getPropertyNames());
280    
281            return _sortedPropertyNames;
282        }
283    
284        public void setPropertyName(String value)
285        {
286            _propertyName = value;
287        }
288    
289        public String getPropertyName()
290        {
291            return _propertyName;
292        }
293    
294        public String getPropertyValue()
295        {
296            return _inspectedSpecification.getProperty(_propertyName);
297        }
298    
299        public List getBeanNames()
300        {
301            if (_beanNames == null)
302                _beanNames = sort(_inspectedSpecification.getBeanNames());
303    
304            return _beanNames;
305        }
306    
307        public void setBeanName(String value)
308        {
309            _beanName = value;
310            _beanSpecification = _inspectedSpecification.getBeanSpecification(_beanName);
311        }
312    
313        public String getBeanName()
314        {
315            return _beanName;
316        }
317    
318        public IBeanSpecification getBeanSpecification()
319        {
320            return _beanSpecification;
321        }
322    
323        private List sort(Collection c)
324        {
325            if (c == null || c.size() == 0)
326                return null;
327    
328            List result = new ArrayList(c);
329    
330            Collections.sort(result);
331    
332            return result;
333        }
334    }