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.Collections;
019    import java.util.HashSet;
020    import java.util.List;
021    import java.util.Set;
022    
023    import org.apache.tapestry.BaseComponent;
024    import org.apache.tapestry.IComponent;
025    import org.apache.tapestry.INamespace;
026    import org.apache.tapestry.IRequestCycle;
027    import org.apache.tapestry.engine.ISpecificationSource;
028    import org.apache.tapestry.form.IPropertySelectionModel;
029    import org.apache.tapestry.form.StringPropertySelectionModel;
030    
031    /**
032     *  Component of the {@link Inspector} page used to select the page and "crumb trail"
033     *  of the inspected component.
034     *
035     *  @author Howard Lewis Ship
036     *
037     **/
038    
039    public abstract class Selector extends BaseComponent
040    {
041        /**
042         *  When the form is submitted,
043         *  the inspectedPageName of the {@link Inspector} page will be updated,
044         *  but we need to reset the inspectedIdPath as well.
045         *
046         **/
047    
048        public void formSubmit(IRequestCycle cycle)
049        {
050            Inspector inspector = (Inspector) getPage();
051    
052            inspector.selectComponent((String) null);
053        }
054    
055        /**
056         *  Returns an {IPropertySelectionModel} used to select the name of the page
057         *  to inspect.  The page names are sorted.
058         *
059         **/
060    
061        public IPropertySelectionModel getPageModel()
062        {
063            return new StringPropertySelectionModel(getPageNames());
064        }
065    
066        /**
067         *  The crumb trail is all the components from the inspected component up to
068         *  (but not including) the page.
069         *
070         **/
071    
072        public List getCrumbTrail()
073        {
074            List result = null;
075    
076            Inspector inspector = (Inspector) getPage();
077            IComponent component = inspector.getInspectedComponent();
078            IComponent container = null;
079    
080            while (true)
081            {
082                container = component.getContainer();
083                if (container == null)
084                    break;
085    
086                if (result == null)
087                    result = new ArrayList();
088    
089                result.add(component);
090    
091                component = container;
092            }
093    
094            if (result == null)
095                return null;
096    
097            // Reverse the list, such that the inspected component is last, and the
098            // top-most container is first.
099    
100            Collections.reverse(result);
101    
102            return result;
103        }
104    
105        private String[] getPageNames()
106        {
107            Set names = new HashSet();
108    
109            ISpecificationSource source = getPage().getEngine().getSpecificationSource();
110    
111            addPageNames(names, source.getFrameworkNamespace());
112            addPageNames(names, source.getApplicationNamespace());
113    
114            List l = new ArrayList(names);
115            Collections.sort(l);
116    
117            return (String[]) l.toArray(new String[l.size()]);
118        }
119    
120        private void addPageNames(Set names, INamespace namespace)
121        {
122            String idPrefix = namespace.getExtendedId();
123    
124            List pageNames = namespace.getPageNames();
125            int count = pageNames.size();
126    
127            for (int i = 0; i < count; i++)
128            {
129                String name = (String) pageNames.get(i);
130    
131                if (idPrefix == null)
132                    names.add(name);
133                else
134                    names.add(idPrefix + ":" + name);
135            }
136    
137            List ids = namespace.getChildIds();
138            count = ids.size();
139    
140            for (int i = 0; i < count; i++)
141            {
142                String id = (String) ids.get(i);
143    
144                addPageNames(names, namespace.getChildNamespace(id));
145            }
146        }
147    
148    }