001    // This file is part of the Attempto Java Packages.
002    // Copyright 2008-2009, Attempto Group, University of Zurich (see http://attempto.ifi.uzh.ch).
003    //
004    // The Attempto Java Packages is free software: you can redistribute it and/or modify it under the
005    // terms of the GNU Lesser General Public License as published by the Free Software Foundation,
006    // either version 3 of the License, or (at your option) any later version.
007    //
008    // The Attempto Java Packages is distributed in the hope that it will be useful, but WITHOUT ANY
009    // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
010    // PURPOSE. See the GNU Lesser General Public License for more details.
011    //
012    // You should have received a copy of the GNU Lesser General Public License along with the Attempto
013    // Java Packages. If not, see http://www.gnu.org/licenses/.
014    
015    package ch.uzh.ifi.attempto.acewiki.gui.page;
016    
017    import java.util.ArrayList;
018    import java.util.Collections;
019    import java.util.List;
020    
021    import nextapp.echo2.app.Column;
022    import nextapp.echo2.app.Component;
023    import nextapp.echo2.app.Extent;
024    import nextapp.echo2.app.Font;
025    import nextapp.echo2.app.Insets;
026    import nextapp.echo2.app.ResourceImageReference;
027    import nextapp.echo2.app.Row;
028    import nextapp.echo2.app.event.ActionEvent;
029    import nextapp.echo2.app.event.ActionListener;
030    import ch.uzh.ifi.attempto.acewiki.core.ontology.Concept;
031    import ch.uzh.ifi.attempto.acewiki.core.ontology.Sentence;
032    import ch.uzh.ifi.attempto.acewiki.gui.IndexBar;
033    import ch.uzh.ifi.attempto.acewiki.gui.TextRow;
034    import ch.uzh.ifi.attempto.acewiki.gui.Title;
035    import ch.uzh.ifi.attempto.echocomp.DelayedComponent;
036    import ch.uzh.ifi.attempto.echocomp.Label;
037    import ch.uzh.ifi.attempto.echocomp.SolidLabel;
038    import ch.uzh.ifi.attempto.echocomp.VSpace;
039    
040    /**
041     * This class represents a page that shows the super-concepts and sub-concepts for a given concept.
042     * Such super- and sub-concept relations are called "hierarchy" in AceWiki.
043     * 
044     * @author Tobias Kuhn
045     */
046    public class HierarchyPage extends WikiPage implements ActionListener {
047    
048            private static final long serialVersionUID = 3126817139010810197L;
049    
050            private static final int pageSize = 15;
051            
052            private ConceptPage page;
053            private Label upWaitIcon = new Label(new ResourceImageReference("ch/uzh/ifi/attempto/acewiki/gui/img/wait.gif"));
054            private Label downWaitIcon = new Label(new ResourceImageReference("ch/uzh/ifi/attempto/acewiki/gui/img/wait.gif"));
055    
056            private Column upHierarchyColumn = new Column();
057            private Column downHierarchyColumn = new Column();
058            private int upChosenPage = 0;
059            private int downChosenPage = 0;
060            
061            /**
062             * Creates a new hierarchy page.
063             * 
064             * @param page The main page that contains the article.
065             */
066            public HierarchyPage(ConceptPage page) {
067                    super(page.getWiki(), new Title(page.getOntologyElement().getHeadword(), "- Hierarchy"));
068                    this.page = page;
069                    
070                    addTab("Article", this);
071                    addTab("Noun", this);
072                    addTab("References", this);
073                    addTab("Individuals", this);
074                    addSelectedTab("Hierarchy");
075                    
076                    add(new VSpace(12));
077                    
078                    upWaitIcon.setVisible(false);
079                    addHeadline("Upward", upWaitIcon);
080                    add(new VSpace(5));
081                    add(upHierarchyColumn);
082                    
083                    downWaitIcon.setVisible(false);
084                    addHeadline("Downward", downWaitIcon);
085                    add(new VSpace(5));
086                    add(downHierarchyColumn);
087            }
088            
089            protected void doUpdate() {
090                    getTitle().setText(page.getOntologyElement().getHeadword());
091                    upHierarchyColumn.removeAll();
092                    downHierarchyColumn.removeAll();
093                    
094                    Concept c = (Concept) page.getOntologyElement();
095                    
096                    if (c.areSuperConceptsCached()) {
097                            upHierarchyColumn.add(new HierarchyComponent(true, true));
098                    } else {
099                            upWaitIcon.setVisible(true);
100                            upHierarchyColumn.add(
101                                    new DelayedComponent(new HierarchyComponent(true, true), true) {
102                                    
103                                            private static final long serialVersionUID = -5068057863490522605L;
104            
105                                            public Component initComponent() {
106                                                    return new HierarchyComponent(true, false);
107                                            }
108                                            
109                                            public void finalizeAction() {
110                                                    upWaitIcon.setVisible(false);
111                                            }
112                                            
113                                    }
114                            );
115                    }
116                    
117                    if (c.areSubConceptsCached()) {
118                            downHierarchyColumn.add(new HierarchyComponent(false, true));
119                    } else {
120                            downWaitIcon.setVisible(true);
121                            downHierarchyColumn.add(
122                                    new DelayedComponent(new HierarchyComponent(false, true), true) {
123                                    
124                                            private static final long serialVersionUID = 2782291841490690030L;
125            
126                                            public Component initComponent() {
127                                                    return new HierarchyComponent(false, false);
128                                            }
129                                            
130                                            public void finalizeAction() {
131                                                    downWaitIcon.setVisible(false);
132                                            }
133                                            
134                                    }
135                            );
136                    }
137            }
138    
139            public void actionPerformed(ActionEvent e) {
140                    if ("Article".equals(e.getActionCommand())) {
141                            log("page", "pressed: article");
142                            getWiki().showPage(page);
143                    } else if ("Noun".equals(e.getActionCommand())) {
144                            log("page", "pressed: word");
145                            getWiki().showPage(new WordPage(page));
146                    } else if ("References".equals(e.getActionCommand())) {
147                            log("page", "pressed: references");
148                            getWiki().showPage(new ReferencesPage(page));
149                    } else if ("Individuals".equals(e.getActionCommand())) {
150                            log("page", "pressed: individuals");
151                            getWiki().showPage(new IndividualsPage(page));
152                    }
153            }
154    
155            public boolean equals(Object obj) {
156                    if (obj instanceof HierarchyPage) {
157                            return page.equals(((HierarchyPage) obj).page);
158                    }
159                    return false;
160            }
161            
162            public boolean isExpired() {
163                    return page.isExpired();
164            }
165            
166            public String toString() {
167                    return "-IND- " + page.getOntologyElement().getWord();
168            }
169    
170            private class HierarchyComponent extends Column implements ActionListener {
171                    
172                    private static final long serialVersionUID = 6461817187189387351L;
173                    
174                    private boolean up;
175                    private Column column = new Column();
176                    private IndexBar indexBar;
177                    private ArrayList<Sentence> sentences;
178                    
179                    
180                    public HierarchyComponent(boolean up, boolean cached) {
181                            this.up = up;
182                            indexBar = new IndexBar("Page:", 0, this);
183                            add(indexBar);
184                            column.setInsets(new Insets(10, 2, 5, 10));
185                            column.setCellSpacing(new Extent(2));
186                            add(column);
187                            
188                            Concept concept = (Concept) page.getOntologyElement();
189                            List<Concept> concepts;
190                            
191                            if (up) {
192                                    if (cached) {
193                                            concepts = concept.getCachedSuperConcepts();
194                                    } else {
195                                            concepts = concept.getSuperConcepts();
196                                    }
197                            } else {
198                                    if (cached) {
199                                            concepts = concept.getCachedSubConcepts();
200                                    } else {
201                                            concepts = concept.getSubConcepts();
202                                    }
203                            }
204                            if (concepts != null) {
205                                    sentences = new ArrayList<Sentence>();
206                                    Collections.sort(concepts);
207                                    for (Concept c : concepts) {
208                                            if (up) {
209                                                    sentences.add(new Sentence("Every " + concept.getWord() + " is a " + c.getWord() + ".", concept.getOntology()));
210                                            } else {
211                                                    sentences.add(new Sentence("Every " + c.getWord() + " is a " + concept.getWord() + ".", concept.getOntology()));
212                                            }
213                                    }
214                            }
215                            
216                            updatePage();
217                    }
218                    
219                    private void updatePage() {
220                            column.removeAll();
221                            
222                            String t;
223                            int chosenPage;
224                            if (up) {
225                                    t = "upward";
226                                    chosenPage = upChosenPage;
227                            } else {
228                                    t = "downward";
229                                    chosenPage = downChosenPage;
230                            }
231                            
232                            if (sentences == null) {
233                                    column.add(new SolidLabel("...", Font.ITALIC, 10));
234                                    indexBar.setVisible(false);
235                            } else {
236                                    if (sentences.size() == 0) {
237                                            indexBar.setVisible(false);
238                                            column.add(new SolidLabel("(" + t + " hierarchy is empty)", Font.ITALIC, 10));
239                                    } else {
240                                            int i = ((sentences.size()-1) / pageSize) + 1;
241                                            if (chosenPage > i) chosenPage = 0;
242                                            indexBar.setNumbers(i);
243                                            indexBar.setActiveButton(chosenPage);
244                                    }
245                                    
246                                    indexBar.setVisible(sentences.size() > pageSize);
247                                    
248                                    int max = sentences.size();
249                                    if (max > (chosenPage + 1) * pageSize) max = (chosenPage + 1) * pageSize;
250                                    for (int i = chosenPage * pageSize; i < max; i++) {
251                                            Row r = new Row();
252                                            r.add(new TextRow(sentences.get(i), HierarchyPage.this));
253                                            column.add(r);
254                                    }
255                            }
256                    }
257                    
258                    public void actionPerformed(ActionEvent e) {
259                            if (e.getSource() == indexBar) {
260                                    if (up) {
261                                            upChosenPage = Integer.parseInt(e.getActionCommand()) - 1;
262                                            log("page", "pressed: page up:" + (upChosenPage+1));
263                                            updatePage();
264                                    } else {
265                                            downChosenPage = Integer.parseInt(e.getActionCommand()) - 1;
266                                            log("page", "pressed: page down:" + (downChosenPage+1));
267                                            updatePage();
268                                    }
269                            }
270                    }
271                    
272            }
273    
274    }