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        private static class ComponentComparitor implements Comparator
072        {
073            public int compare(Object left, Object right)
074            {
075                IComponent leftComponent;
076                String leftId;
077                IComponent rightComponent;
078                String rightId;
079    
080                if (left == right)
081                    return 0;
082    
083                leftComponent = (IComponent) left;
084                rightComponent = (IComponent) right;
085    
086                leftId = leftComponent.getId();
087                rightId = rightComponent.getId();
088    
089                return leftId.compareTo(rightId);
090            }
091        }
092    
093        /**
094         * Clears all cached information about the component and such after each render (including the
095         * rewind phase render used to process the tab view).
096         * 
097         * @since 1.0.5
098         */
099    
100        public void pageEndRender(PageEvent event)
101        {
102            _inspectedComponent = null;
103            _inspectedSpecification = null;
104            _parameterName = null;
105            _assetName = null;
106            _sortedComponents = null;
107            _assetNames = null;
108            _formalParameterNames = null;
109            _informalParameterNames = null;
110            _sortedPropertyNames = null;
111            _propertyName = null;
112            _beanNames = null;
113            _beanName = null;
114            _beanSpecification = null;
115        }
116    
117        /**
118         * Gets the inspected component and specification from the {@link Inspector} page.
119         * 
120         * @since 1.0.5
121         */
122    
123        public void pageBeginRender(PageEvent event)
124        {
125            Inspector inspector = (Inspector) getPage();
126    
127            _inspectedComponent = inspector.getInspectedComponent();
128            _inspectedSpecification = _inspectedComponent.getSpecification();
129        }
130    
131        public IComponent getInspectedComponent()
132        {
133            return _inspectedComponent;
134        }
135    
136        public IComponentSpecification getInspectedSpecification()
137        {
138            return _inspectedSpecification;
139        }
140    
141        /**
142         * Returns a sorted list of formal parameter names.
143         */
144    
145        public List getFormalParameterNames()
146        {
147            if (_formalParameterNames == null)
148                _formalParameterNames = sort(_inspectedSpecification.getParameterNames());
149    
150            return _formalParameterNames;
151        }
152    
153        /**
154         * Returns a sorted list of informal parameter names. This is the list of all bindings, with the
155         * list of parameter names removed, sorted.
156         */
157    
158        public List getInformalParameterNames()
159        {
160            if (_informalParameterNames != null)
161                return _informalParameterNames;
162    
163            Collection names = _inspectedComponent.getBindingNames();
164            if (names != null && names.size() > 0)
165            {
166                _informalParameterNames = new ArrayList(names);
167    
168                // Remove the names of any formal parameters. This leaves
169                // just the names of informal parameters (informal parameters
170                // are any parameters/bindings that don't match a formal parameter
171                // name).
172    
173                names = _inspectedSpecification.getParameterNames();
174                if (names != null)
175                    _informalParameterNames.removeAll(names);
176    
177                Collections.sort(_informalParameterNames);
178            }
179    
180            return _informalParameterNames;
181        }
182    
183        public String getParameterName()
184        {
185            return _parameterName;
186        }
187    
188        public void setParameterName(String value)
189        {
190            _parameterName = value;
191        }
192    
193        /**
194         * Returns the {@link org.apache.tapestry.spec.ParameterSpecification} corresponding to the
195         * value of the parameterName property.
196         */
197    
198        public IParameterSpecification getParameterSpecification()
199        {
200            return _inspectedSpecification.getParameter(_parameterName);
201        }
202    
203        /**
204         * Returns the {@link IBinding} corresponding to the value of the parameterName property.
205         */
206    
207        public IBinding getBinding()
208        {
209            return _inspectedComponent.getBinding(_parameterName);
210        }
211    
212        public void setAssetName(String value)
213        {
214            _assetName = value;
215        }
216    
217        public String getAssetName()
218        {
219            return _assetName;
220        }
221    
222        /**
223         * Returns the {@link IAsset} corresponding to the value of the assetName property.
224         */
225    
226        public IAsset getAsset()
227        {
228            return (IAsset) _inspectedComponent.getAssets().get(_assetName);
229        }
230    
231        /**
232         * Returns a sorted list of asset names, or null if the component contains no assets.
233         */
234    
235        public List getAssetNames()
236        {
237            if (_assetNames == null)
238                _assetNames = sort(_inspectedComponent.getAssets().keySet());
239    
240            return _assetNames;
241        }
242    
243        public List getSortedComponents()
244        {
245            if (_sortedComponents != null)
246                return _sortedComponents;
247    
248            Inspector inspector = (Inspector) getPage();
249            IComponent inspectedComponent = inspector.getInspectedComponent();
250    
251            // Get a Map of the components and simply return null if there
252            // are none.
253    
254            Map components = inspectedComponent.getComponents();
255    
256            _sortedComponents = new ArrayList(components.values());
257    
258            Collections.sort(_sortedComponents, new ComponentComparitor());
259    
260            return _sortedComponents;
261        }
262    
263        public abstract void setCurrentComponent(IComponent value);
264    
265        public abstract IComponent getCurrentComponent();
266    
267        /**
268         * Returns a list of the properties for the component (from its specification), or null if the
269         * component has no properties.
270         */
271    
272        public List getSortedPropertyNames()
273        {
274            if (_sortedPropertyNames == null)
275                _sortedPropertyNames = sort(_inspectedSpecification.getPropertyNames());
276    
277            return _sortedPropertyNames;
278        }
279    
280        public void setPropertyName(String value)
281        {
282            _propertyName = value;
283        }
284    
285        public String getPropertyName()
286        {
287            return _propertyName;
288        }
289    
290        public String getPropertyValue()
291        {
292            return _inspectedSpecification.getProperty(_propertyName);
293        }
294    
295        public List getBeanNames()
296        {
297            if (_beanNames == null)
298                _beanNames = sort(_inspectedSpecification.getBeanNames());
299    
300            return _beanNames;
301        }
302    
303        public void setBeanName(String value)
304        {
305            _beanName = value;
306            _beanSpecification = _inspectedSpecification.getBeanSpecification(_beanName);
307        }
308    
309        public String getBeanName()
310        {
311            return _beanName;
312        }
313    
314        public IBeanSpecification getBeanSpecification()
315        {
316            return _beanSpecification;
317        }
318    
319        private List sort(Collection c)
320        {
321            if (c == null || c.size() == 0)
322                return null;
323    
324            List result = new ArrayList(c);
325    
326            Collections.sort(result);
327    
328            return result;
329        }
330    }