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
015package org.apache.tapestry.contrib.inspector;
016
017import java.util.ArrayList;
018import java.util.Collection;
019import java.util.Collections;
020import java.util.Comparator;
021import java.util.List;
022import java.util.Map;
023
024import org.apache.tapestry.BaseComponent;
025import org.apache.tapestry.IAsset;
026import org.apache.tapestry.IBinding;
027import org.apache.tapestry.IComponent;
028import org.apache.tapestry.event.PageBeginRenderListener;
029import org.apache.tapestry.event.PageEndRenderListener;
030import org.apache.tapestry.event.PageEvent;
031import org.apache.tapestry.spec.IBeanSpecification;
032import org.apache.tapestry.spec.IComponentSpecification;
033import 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
042public 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}