001    // This file is part of AceWiki.
002    // Copyright 2008-2012, AceWiki developers.
003    // 
004    // AceWiki is free software: you can redistribute it and/or modify it under the terms of the GNU
005    // Lesser General Public License as published by the Free Software Foundation, either version 3 of
006    // the License, or (at your option) any later version.
007    // 
008    // AceWiki is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without
009    // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
010    // Lesser General Public License for more details.
011    // 
012    // You should have received a copy of the GNU Lesser General Public License along with AceWiki. If
013    // not, see http://www.gnu.org/licenses/.
014    
015    package ch.uzh.ifi.attempto.acewiki.gui;
016    
017    import java.util.ArrayList;
018    import java.util.Collections;
019    import java.util.Comparator;
020    import java.util.List;
021    
022    import nextapp.echo.app.Column;
023    import nextapp.echo.app.Extent;
024    import nextapp.echo.app.Font;
025    import nextapp.echo.app.Insets;
026    import nextapp.echo.app.Row;
027    import nextapp.echo.app.event.ActionEvent;
028    import nextapp.echo.app.event.ActionListener;
029    import ch.uzh.ifi.attempto.acewiki.Task;
030    import ch.uzh.ifi.attempto.acewiki.core.Concept;
031    import ch.uzh.ifi.attempto.acewiki.core.Individual;
032    import ch.uzh.ifi.attempto.acewiki.core.OntologyElement;
033    import ch.uzh.ifi.attempto.acewiki.core.CachingReasoner;
034    import ch.uzh.ifi.attempto.acewiki.core.Sentence;
035    import ch.uzh.ifi.attempto.acewiki.core.StatementFactory;
036    import ch.uzh.ifi.attempto.echocomp.SolidLabel;
037    import ch.uzh.ifi.attempto.echocomp.VSpace;
038    
039    /**
040     * This class represents a page that shows all individuals that belong to a certain concept.
041     * 
042     * @author Tobias Kuhn
043     */
044    public class IndividualsPage extends WikiPage implements ActionListener {
045    
046            private static final long serialVersionUID = 4273564259160715684L;
047    
048            private static final int pageSize = 50;
049            
050            private ConceptPage page;
051            private Column individualsColumn = new Column();
052            private int chosenPage = 0;
053            private Title title;
054            
055            /**
056             * Creates a new individuals page.
057             * 
058             * @param page The main page that contains the article.
059             */
060            public IndividualsPage(ConceptPage page) {
061                    super(page.getWiki());
062                    this.page = page;
063                    
064                    addTab("Article", this);
065                    addTab("References", this);
066                    addSelectedTab("Individuals");
067                    addTab("Hierarchy", this);
068                    
069                    OntologyElement oe = page.getOntologyElement();
070                    title = new Title(getHeading(oe), "- Individuals", oe.getType(), this);
071                    add(title);
072                    addHorizontalLine();
073                    
074                    add(individualsColumn);
075            }
076            
077            protected void doUpdate() {
078                    title.setText(getHeading(page.getOntologyElement()));
079                    individualsColumn.removeAll();
080                    
081                    final Column waitComp = new Column();
082                    waitComp.setInsets(new Insets(10, 0, 0, 0));
083                    waitComp.add(new RecalcIcon("This list is being updated."));
084    
085                    CachingReasoner cr = getWiki().getOntology().getReasoner();
086                    
087                    if (cr.areCachedIndividualsUpToDate((Concept) page.getOntologyElement())) {
088                            individualsColumn.add(new VSpace(18));
089                            individualsColumn.add(new IndividualsComponent(true));
090                    } else {
091                            individualsColumn.add(new VSpace(4));
092                            individualsColumn.add(waitComp);
093                            individualsColumn.add(new IndividualsComponent(true));
094                            page.getWiki().enqueueWeakAsyncTask(new Task() {
095                                    
096                                    private IndividualsComponent delayedComp;
097                                    
098                                    public void run() {
099                                            delayedComp = new IndividualsComponent(false);
100                                    }
101                                    
102                                    public void updateGUI() {
103                                            individualsColumn.removeAll();
104                                            individualsColumn.add(new VSpace(18));
105                                            individualsColumn.add(delayedComp);
106                                    }
107                                    
108                            });
109                    }
110            }
111    
112            public void actionPerformed(ActionEvent e) {
113                    if ("Article".equals(e.getActionCommand())) {
114                            log("page", "pressed: article");
115                            getWiki().showPage(page);
116                    } else if ("References".equals(e.getActionCommand())) {
117                            log("page", "pressed: references");
118                            getWiki().showPage(new ReferencesPage(page));
119                    } else if ("Hierarchy".equals(e.getActionCommand())) {
120                            log("page", "pressed: hierarchy");
121                            getWiki().showPage(new HierarchyPage(page));
122                    } else if (e.getSource() == title) {
123                            getWiki().showEditorWindow(page.getOntologyElement());
124                    }
125            }
126    
127            public boolean equals(Object obj) {
128                    if (obj instanceof IndividualsPage) {
129                            return page.equals(((IndividualsPage) obj).page);
130                    }
131                    return false;
132            }
133            
134            public boolean isExpired() {
135                    return page.isExpired();
136            }
137            
138            public String toString() {
139                    return "-IND- " + page.getOntologyElement().getWord();
140            }
141            
142            
143            private class IndividualsComponent extends Column implements ActionListener {
144                    
145                    private static final long serialVersionUID = -2897618204616741456L;
146                    
147                    private Column sentencesColumn = new Column();
148                    private IndexBar indexBar;
149                    private List<Sentence> sentences;
150                    
151                    
152                    public IndividualsComponent(boolean cached) {
153                            indexBar = new IndexBar("Page:", 0, this);
154                            add(indexBar);
155                            
156                            sentencesColumn.setInsets(new Insets(10, 2, 5, 20));
157                            sentencesColumn.setCellSpacing(new Extent(2));
158                            add(sentencesColumn);
159                            
160                            Concept concept = (Concept) page.getOntologyElement();
161                            CachingReasoner cr = getWiki().getOntology().getReasoner();
162                            List<Individual> individuals;
163                            
164                            if (cached) {
165                                    individuals = cr.getCachedIndividuals(concept);
166                            } else {
167                                    individuals = cr.getIndividuals(concept);
168                            }
169                            if (individuals != null) {
170                                    sentences = new ArrayList<Sentence>();
171                                    
172                                    Comparator<Individual> comparator = new Comparator<Individual>() {
173                                            public int compare(Individual o1, Individual o2) {
174                                                    return o1.getWord(3).compareToIgnoreCase(o2.getWord(3));
175                                            }
176                                    };
177                                    
178                                    Collections.sort(individuals, comparator);
179                                    for (Individual ind : individuals) {
180                                            StatementFactory sf = getWiki().getOntology().getStatementFactory();
181                                            sentences.add(sf.createAssignmentSentence(ind, concept));
182                                    }
183                                    if (sentences.size() == 0) {
184                                            indexBar.setVisible(false);
185                                            sentencesColumn.add(new SolidLabel("(no individual found)", Font.ITALIC, 10));
186                                    } else {
187                                            int i = ((sentences.size()-1) / pageSize) + 1;
188                                            if (chosenPage > i) chosenPage = 0;
189                                            indexBar.setNumbers(i);
190                                            indexBar.setActiveButton(chosenPage);
191                                            updatePage();
192                                    }
193                            } else {
194                                    indexBar.setVisible(false);
195                                    sentencesColumn.add(new SolidLabel("...", Font.ITALIC, 10));
196                            }
197                    }
198                    
199                    private void updatePage() {
200                            sentencesColumn.removeAll();
201                            
202                            indexBar.setVisible(sentences.size() > pageSize);
203                            
204                            int max = sentences.size();
205                            if (max > (chosenPage + 1) * pageSize) max = (chosenPage + 1) * pageSize;
206                            
207                            for (int i = chosenPage * pageSize; i < max; i++) {
208                                    Row r = new Row();
209                                    r.add(new SentenceComponent(sentences.get(i), IndividualsPage.this));
210                                    sentencesColumn.add(r);
211                            }
212                    }
213    
214                    public void actionPerformed(ActionEvent e) {
215                            if (e.getSource() == indexBar) {
216                                    chosenPage = Integer.parseInt(e.getActionCommand()) - 1;
217                                    log("page", "pressed: page " + (chosenPage+1));
218                                    updatePage();
219                            }
220                    }
221                    
222            }
223    
224    }