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.Collections;
019import java.util.HashSet;
020import java.util.List;
021import java.util.Set;
022
023import org.apache.tapestry.BaseComponent;
024import org.apache.tapestry.IComponent;
025import org.apache.tapestry.INamespace;
026import org.apache.tapestry.IRequestCycle;
027import org.apache.tapestry.engine.ISpecificationSource;
028import org.apache.tapestry.form.IPropertySelectionModel;
029import 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
039public 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}