001    /**
002     * Copyright (C) 2007-2008, Jens Lehmann
003     *
004     * This file is part of DL-Learner.
005     * 
006     * DL-Learner is free software; you can redistribute it and/or modify
007     * it under the terms of the GNU General Public License as published by
008     * the Free Software Foundation; either version 3 of the License, or
009     * (at your option) any later version.
010     *
011     * DL-Learner is distributed in the hope that it will be useful,
012     * but WITHOUT ANY WARRANTY; without even the implied warranty of
013     * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
014     * GNU General Public License for more details.
015     *
016     * You should have received a copy of the GNU General Public License
017     * along with this program.  If not, see <http://www.gnu.org/licenses/>.
018     *
019     */
020    
021    package org.dllearner.tools.ore;
022    
023    import java.awt.BorderLayout;
024    import java.awt.Component;
025    import java.awt.Cursor;
026    import java.awt.GridBagConstraints;
027    import java.awt.GridBagLayout;
028    import java.awt.Insets;
029    import java.awt.event.ActionEvent;
030    import java.awt.event.ActionListener;
031    import java.awt.event.MouseEvent;
032    import java.awt.event.MouseListener;
033    import java.awt.event.WindowAdapter;
034    import java.awt.event.WindowEvent;
035    import java.util.HashSet;
036    import java.util.List;
037    import java.util.Map;
038    import java.util.Set;
039    
040    import javax.swing.Box;
041    import javax.swing.BoxLayout;
042    import javax.swing.JButton;
043    import javax.swing.JDialog;
044    import javax.swing.JOptionPane;
045    import javax.swing.JPanel;
046    import javax.swing.JScrollPane;
047    import javax.swing.JSeparator;
048    import javax.swing.border.EmptyBorder;
049    
050    import org.dllearner.core.owl.Description;
051    import org.dllearner.core.owl.Individual;
052    import org.dllearner.core.owl.NamedClass;
053    import org.dllearner.core.owl.ObjectQuantorRestriction;
054    import org.dllearner.core.owl.ObjectSomeRestriction;
055    import org.semanticweb.owl.model.OWLOntologyChange;
056    
057    /**
058     * The repair dialog where the learned class description (including error parts), 
059     * the statistics and the undo options are shown.
060     * @author Lorenz Buehmann
061     *
062     */
063    public class RepairDialog extends JDialog implements ActionListener, MouseListener{
064            
065            /**
066             * 
067             */
068            private static final long serialVersionUID = 1L;
069            
070              
071        public static final int CANCEL_RETURN_CODE = 1;
072        public static final int OK_RETURN_CODE = 2;
073            public static final int VALID_RETURN_CODE = 3;
074        
075        private int returncode;
076            
077            private StatsPanel statsPanel;
078            private DescriptionPanel descPanel;
079            private JPanel okCancelPanel;
080            private JPanel actionStatsPanel;
081            
082            private ChangesPanel changesPanel;
083            private JScrollPane changesScroll;
084            
085            private JButton okButton;
086            private JButton cancelButton;
087            
088            private String mode;
089                    
090            private OntologyModifier modifier;
091            private ORE ore;
092            private Individual ind;
093            private Description actualDesc;
094            private Description newDesc;
095            private Set<OWLOntologyChange> allChanges;
096            private String baseURI;
097            private Map<String, String> prefixes;
098            
099            
100            public RepairDialog(Individual ind, JDialog dialog, final ORE ore, String mode){
101                    super(dialog, true);
102                    final Component dialogd = this.getParent();
103                    setDefaultCloseOperation(DO_NOTHING_ON_CLOSE);
104                    addWindowListener(new WindowAdapter() {
105                            @Override
106                        public void windowClosing(WindowEvent we) {
107                            if(allChanges.size() > 0){
108                                            if (JOptionPane.showConfirmDialog(dialogd,
109                                                    "All changes will be lost!", "Warning!", 
110                                                    JOptionPane.YES_NO_OPTION)
111                                                 == JOptionPane.YES_OPTION){
112                    
113                                                    modifier.undoChanges(allChanges);
114                                                    ore.updateReasoner();
115                                                    allChanges.clear();
116                                                    returncode = CANCEL_RETURN_CODE;
117                                                    setVisible(false);
118                                                    dispose();
119                                            }
120                                    } else{
121                                            returncode = CANCEL_RETURN_CODE;
122                                            setVisible(false);
123                                            dispose();
124                                    }
125                                            
126                            }
127                        
128                    });
129    
130                    
131                    this.ind = ind;
132                    this.ore = ore;
133                    this.modifier = ore.getModifier();
134                    this.mode = mode;
135                    allChanges = new HashSet<OWLOntologyChange>();
136                    
137            }
138            
139            /**
140             * Initializing and making dialog visible.
141             * @return integer value
142             */
143            public int showDialog(){
144                    baseURI = ore.getBaseURI();
145                    prefixes = ore.getPrefixes();
146                    if(mode.equals("neg")){
147                            this.setTitle("Repair negative example");
148                    } else if(mode.equals("pos")){
149                            this.setTitle("Repair positive example");
150                    }
151                    this.setSize(700, 700);
152                    this.setLayout(new BorderLayout());
153                    
154                    descPanel = new DescriptionPanel(ore, ind, this, mode);         
155                    JScrollPane descScroll = new JScrollPane();
156                    descScroll.setViewportView(descPanel);
157                    
158                    statsPanel = new StatsPanel(ore, ind);
159                    statsPanel.init();
160                    JScrollPane statsScroll = new JScrollPane();
161                    statsScroll.setViewportView(statsPanel);
162                            
163                                    
164                    changesPanel = new ChangesPanel();
165                    changesScroll = new JScrollPane();
166                    changesScroll.setViewportView(changesPanel);
167                    
168                actionStatsPanel = new JPanel();
169                    
170                    GridBagLayout gbl = new GridBagLayout();
171                    gbl.rowWeights = new double[] {0.0, 0.1, 0.1};
172                    gbl.rowHeights = new int[] {64, 7, 7};
173                    gbl.columnWeights = new double[] {0.1};
174                    gbl.columnWidths = new int[] {7};
175                    actionStatsPanel.setLayout(gbl);
176                    
177                    
178                    actionStatsPanel.add(descScroll, new GridBagConstraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 5, 5), 0, 0));
179                    actionStatsPanel.add(statsScroll, new GridBagConstraints(0, 1, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 0, 5), 0, 0));
180                    actionStatsPanel.add(changesScroll, new GridBagConstraints(0, 2, 1, 1, 0.0, 0.0, GridBagConstraints.CENTER, GridBagConstraints.BOTH, new Insets(5, 5, 0, 5), 0, 0));
181                    
182                    
183                    JSeparator separator = new JSeparator();
184                    Box buttonBox = new Box(BoxLayout.X_AXIS);
185                    
186                    okCancelPanel = new JPanel();
187                    okCancelPanel.setLayout(new BorderLayout());
188                    okCancelPanel.add(separator, BorderLayout.NORTH);
189                    okButton = new JButton("Ok");
190                    okButton.addActionListener(this);
191                    cancelButton = new JButton("Cancel");
192                    cancelButton.addActionListener(this);
193                    
194           
195            getContentPane().add(actionStatsPanel, java.awt.BorderLayout.CENTER);
196                    
197                    
198            buttonBox.setBorder(new EmptyBorder(new Insets(5, 10, 5, 10)));       
199            buttonBox.add(okButton);
200            buttonBox.add(Box.createHorizontalStrut(10));
201            buttonBox.add(cancelButton);
202                    okCancelPanel.add(buttonBox, BorderLayout.EAST);
203            
204                    getContentPane().add(okCancelPanel, BorderLayout.SOUTH);
205                    
206                    
207                    this.setModal(true);
208                    this.setVisible(true);
209                    
210                    return returncode;
211    
212            }
213    
214            /**
215             * Method controls action events triggered by clicking on red labels in class description at the top of the dialog.
216             */
217            public void actionPerformed(ActionEvent e) {
218                    
219                    if(e.getSource() instanceof DescriptionMenuItem){
220                            DescriptionMenuItem item =(DescriptionMenuItem) e.getSource();
221                            actualDesc = item.getDescription();
222                            int action = item.getActionID();
223                            if(action == 4){
224                                    Individual obj = new Individual(e.getActionCommand());
225                                    
226                                    List<OWLOntologyChange> changes  = modifier.addObjectProperty(ind, (ObjectQuantorRestriction) actualDesc, obj);
227                                    allChanges.addAll(changes);
228                                    
229                                    descPanel.updatePanel();
230                                    
231                                    statsPanel.updatePanel();
232                                    changesPanel.add(new ChangePanel("added property assertion " + ((ObjectQuantorRestriction) actualDesc).getRole().toKBSyntaxString(baseURI, prefixes) 
233                                                                                                            + " to " + obj.toManchesterSyntaxString(baseURI, prefixes), changes, this));
234                                    changesScroll.updateUI();
235                            } else if(action == 5){
236                                    ObjectQuantorRestriction property = (ObjectQuantorRestriction) actualDesc;
237                                    List<OWLOntologyChange> changes = null;
238                                    for(Individual i : ore.getIndividualsInPropertyRange(property, ind)){
239                                            changes = modifier.removeObjectPropertyAssertion(ind, property, i);
240                                            allChanges.addAll(changes);
241                                    }
242                                    
243                                    descPanel.updatePanel();
244                                    statsPanel.updatePanel();
245                                    changesPanel.add(new ChangePanel("removed property assertions "  
246                                                                                                    + ((ObjectSomeRestriction) actualDesc).getRole().toKBSyntaxString(baseURI, prefixes)  
247                                                                                                    + " to range " + ((ObjectSomeRestriction) actualDesc).getChild(0).toManchesterSyntaxString(baseURI, prefixes), changes, this));
248                                    changesScroll.updateUI();
249                            } else if(action == 6){
250                                    List<OWLOntologyChange> changes = modifier.deleteObjectProperty(ind, (ObjectQuantorRestriction) actualDesc);
251                                    allChanges.addAll(changes);
252                                    descPanel.updatePanel();
253                                    statsPanel.updatePanel();
254                                    changesPanel.add(new ChangePanel("deleted property " + ((ObjectQuantorRestriction) actualDesc).getRole().toKBSyntaxString(baseURI, prefixes), changes, this));
255                                    changesScroll.updateUI();
256                            } else if(action == 0){
257                                    newDesc = new NamedClass(item.getName());
258                                    List<OWLOntologyChange> changes  = modifier.moveIndividual(ind, actualDesc, newDesc);
259                                    allChanges.addAll(changes);
260                                    descPanel.updatePanel();
261                                    statsPanel.updatePanel();
262                                    changesPanel.add(new ChangePanel("moved class assertion from " + actualDesc.toManchesterSyntaxString(baseURI, prefixes)  
263                                                                                                    + " to " + newDesc.toManchesterSyntaxString(baseURI, prefixes), changes, this));
264                                    changesScroll.updateUI();
265                            } else if(action == 3){
266                                    List<OWLOntologyChange> changes  = modifier.removeClassAssertion(ind, actualDesc);
267                                    allChanges.addAll(changes);
268                                    descPanel.updatePanel();
269                                    statsPanel.updatePanel();
270                                    changesPanel.add(new ChangePanel("removed class assertion to " + actualDesc.toManchesterSyntaxString(baseURI, prefixes), changes, this));
271                                    changesScroll.updateUI();
272                            } else if(action == 2){
273                                    List<OWLOntologyChange> changes  = modifier.addClassAssertion(ind, actualDesc);
274                                    allChanges.addAll(changes);
275                                    descPanel.updatePanel();
276                                    statsPanel.updatePanel();
277                                    changesPanel.add(new ChangePanel("added class assertion to " + actualDesc.toManchesterSyntaxString(baseURI, prefixes), changes, this));
278                                    changesScroll.updateUI();
279                            } else if(action == 7){
280                                    ObjectQuantorRestriction property = (ObjectQuantorRestriction) actualDesc;
281                                    List<OWLOntologyChange> changes = null;
282                                    for(Individual i : ore.getIndividualsNotInPropertyRange(property, ind)){
283                                            changes = modifier.removeObjectPropertyAssertion(ind, property, i);
284                                            allChanges.addAll(changes);
285                                    }
286                                    
287                                    
288                                    descPanel.updatePanel();
289                                    statsPanel.updatePanel();
290                                    changesPanel.add(new ChangePanel("removed property assertion " + property.getRole().toKBSyntaxString(baseURI, prefixes) 
291                                                                                           + " to " + ind.toManchesterSyntaxString(baseURI, prefixes), changes, this));
292                                    changesScroll.updateUI();
293                            } else if(action == 1){
294                                    Description oldDesc = new NamedClass(item.getName());
295                                    List<OWLOntologyChange> changes  = modifier.moveIndividual(ind, oldDesc, actualDesc);
296                                    allChanges.addAll(changes);
297                                    descPanel.updatePanel();
298                                    statsPanel.updatePanel();
299                                    changesPanel.add(new ChangePanel("moved class assertion from " + oldDesc.toManchesterSyntaxString(baseURI, prefixes) 
300                                                                                                    + " to " + actualDesc.toManchesterSyntaxString(baseURI, prefixes), changes, this));
301                                    changesScroll.updateUI();
302                            }
303                    } else if(e.getActionCommand().equals("Ok")){
304                            if(descPanel.isCorrect()){
305                                    returncode = VALID_RETURN_CODE;
306                            } else{
307                                    returncode = OK_RETURN_CODE;
308                            }
309                            ore.updateReasoner();
310                            setVisible(false);
311                            dispose();
312                    } else if(e.getActionCommand().equals("Cancel")){
313                            if(allChanges.size() > 0){
314                                    if (JOptionPane.showConfirmDialog(this,
315                                            "All changes will be lost!", "Warning!", 
316                                            JOptionPane.YES_NO_OPTION)
317                                         == JOptionPane.YES_OPTION){
318            
319                                            modifier.undoChanges(allChanges);
320                                            ore.updateReasoner();
321                                            allChanges.clear();
322                                            returncode = CANCEL_RETURN_CODE;
323                                            setVisible(false);
324                                            dispose();
325                                    }
326                            } else{
327                                    returncode = CANCEL_RETURN_CODE;
328                                    setVisible(false);
329                                    dispose();
330                            }
331                                    
332                    }
333                            
334    
335            }
336                            
337    
338            public void mouseClicked(MouseEvent e) {
339                    if(e.getSource() instanceof UndoLabel){
340                            List<OWLOntologyChange> changes = ((UndoLabel) e.getSource()).getChanges();
341                            modifier.undoChanges(changes);
342                            allChanges.removeAll(changes);
343                            descPanel.updatePanel();
344                            statsPanel.updatePanel();
345                            changesPanel.updatePanel(((UndoLabel) e.getSource()).getParent());
346                            setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
347                            
348                    }
349            }
350    
351            public void mouseEntered(MouseEvent e) {
352                    if(e.getSource() instanceof UndoLabel){
353                            ((UndoLabel) e.getSource()).setText("<html><u>Undo</u></html>");
354                            setCursor(new Cursor(Cursor.HAND_CURSOR));
355                    }
356                    
357            }
358    
359            public void mouseExited(MouseEvent e) {
360                    if(e.getSource() instanceof UndoLabel){
361                            ((UndoLabel) e.getSource()).setText("Undo");
362                            setCursor(new Cursor(Cursor.DEFAULT_CURSOR));
363                    }
364                    
365            }
366    
367            public void mousePressed(MouseEvent e) {
368                                    
369            }
370    
371            public void mouseReleased(MouseEvent e) {
372                                    
373            }
374    
375            public Set<OWLOntologyChange> getAllChanges() {
376                    return allChanges;
377            }
378    
379                    
380    
381            
382    }