package org.mindswap.swoop.popup; import java.awt.BorderLayout; import java.awt.Container; import java.awt.Font; import java.awt.GridLayout; import java.awt.event.ActionEvent; import java.awt.event.ActionListener; import java.awt.event.KeyEvent; import java.awt.event.KeyListener; import java.net.URI; import java.net.URL; import java.util.ArrayList; import java.util.HashSet; import java.util.Iterator; import java.util.List; import java.util.Set; import java.util.TreeSet; import javax.swing.JButton; import javax.swing.JComboBox; import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JList; import javax.swing.JPanel; import javax.swing.JScrollPane; import javax.swing.JSplitPane; import javax.swing.JTabbedPane; import javax.swing.JTextArea; import javax.swing.JTextField; import javax.swing.event.ListSelectionEvent; import javax.swing.event.ListSelectionListener; import org.mindswap.swoop.SwoopModel; import org.mindswap.swoop.renderer.CellRenderer; import org.mindswap.swoop.renderer.SwoopCellRenderer; import org.mindswap.swoop.utils.ui.EntityComparator; import org.semanticweb.owl.io.vocabulary.OWLVocabularyAdapter; import org.semanticweb.owl.io.vocabulary.RDFSVocabularyAdapter; import org.semanticweb.owl.model.OWLAnnotationProperty; import org.semanticweb.owl.model.OWLDataValue; import org.semanticweb.owl.model.OWLException; import org.semanticweb.owl.model.OWLNamedObject; import org.semanticweb.owl.model.OWLOntology; import org.semanticweb.owl.model.change.AddAnnotationInstance; import org.semanticweb.owl.model.helper.OntologyHelper; import com.hexidec.ekit.EkitCore; /** * @author Aditya * This class pops up when the user clicks on the 'Add Annotation' link * in the ConciseFormatEntityRenderer. It allows the user to select the annotation * property, specify the content and add/apply the annotation instance on the * current selected Swoop entity * */ public class PopupAddAnnotation extends JFrame implements ActionListener, ListSelectionListener, KeyListener { SwoopModel swoopModel; public List changes; Font tahoma = new Font("Tahoma", Font.PLAIN, 11); JButton applyBtn, addAnnotBtn, cancelBtn; JList ontList, propList; JComboBox defaultAP; JComboBox langBox; JTextField newPropFld; JTextArea annotFld; JTabbedPane annotContentTabs; EkitCore ekitCore; JPanel ekitPanel; static String RDFS = RDFSVocabularyAdapter.RDFS; static String OWL = OWLVocabularyAdapter.OWL; public PopupAddAnnotation(SwoopModel swoopModel, boolean isOntology) { // setModal(true); this.swoopModel = swoopModel; this.changes = new ArrayList(); setDefaultAnnotProps(isOntology); setupUI(); } private OWLAnnotationProperty getAnnotProp(String uriStr) { try { URI uri = new URI(uriStr); OWLAnnotationProperty prop = swoopModel.getSelectedOntology().getOWLDataFactory().getOWLAnnotationProperty(uri); return prop; } catch (Exception e) { e.printStackTrace(); } return null; } /** * Set the list of default OWL annotation properties for the user * @param isOntology */ private void setDefaultAnnotProps(boolean isOntology) { defaultAP = new JComboBox(); Set defaultSet = new TreeSet(EntityComparator.INSTANCE); if (isOntology) { defaultSet.add(getAnnotProp(OWL+"versionInfo")); } defaultSet.add(getAnnotProp(RDFS+"label")); defaultSet.add(getAnnotProp(RDFS+"comment")); defaultSet.add(getAnnotProp(RDFS+"seeAlso")); defaultSet.add(getAnnotProp(RDFS+"isDefinedBy")); // AK: only for Swoop 2.2 beta 2 // list all annotation properties in selected ontology in swoopmodel Set ontologies = new HashSet(); try { ontologies = OntologyHelper.importClosure(swoopModel.getSelectedOntology()); } catch (OWLException e1) { e1.printStackTrace(); } Iterator iter = ontologies.iterator(); while (iter.hasNext()) { OWLOntology ont = (OWLOntology) iter.next(); try { defaultSet.addAll(ont.getAnnotationProperties()); } catch (OWLException e) { e.printStackTrace(); } } Iterator apIter = defaultSet.iterator(); while (apIter.hasNext()) { defaultAP.addItem((OWLAnnotationProperty) apIter.next()); } // select rdfs:comment as the default annotation property defaultAP.setSelectedItem(getAnnotProp(RDFS+"comment")); defaultAP.setRenderer(new SwoopCellRenderer(swoopModel)); defaultAP.addActionListener(new ActionListener() { public void actionPerformed(ActionEvent arg0) { ontList.clearSelection(); propList.clearSelection(); } }); } private void setupUI() { JSplitPane tab1 = new JSplitPane(JSplitPane.VERTICAL_SPLIT); ontList = new JList(); ontList.setFont(tahoma); ontList.setCellRenderer(new CellRenderer()); propList = new JList(); propList.setFont(tahoma); propList.setCellRenderer(new SwoopCellRenderer(swoopModel)); propList.addKeyListener(this); applyBtn = new JButton("Add"); applyBtn.setFont(tahoma); applyBtn.addActionListener(this); addAnnotBtn = new JButton("Add & Close"); addAnnotBtn.setFont(tahoma); addAnnotBtn.addActionListener(this); JLabel ontLbl = new JLabel("2. OR Select Ontology:"); ontLbl.setFont(tahoma); JLabel propLbl = new JLabel("Select Property:"); propLbl.setFont(tahoma); JPanel tab1W = new JPanel(); tab1W.setLayout(new BorderLayout()); tab1W.add(ontLbl, "North"); tab1W.add(new JScrollPane(ontList), "Center"); JPanel tab1E = new JPanel(); tab1E.setLayout(new BorderLayout()); tab1E.add(propLbl, "North"); tab1E.add(new JScrollPane(propList), "Center"); JSplitPane tab1Split = new JSplitPane(JSplitPane.HORIZONTAL_SPLIT); tab1Split.setLeftComponent(tab1W); tab1Split.setRightComponent(tab1E); JPanel btnPanel = new JPanel(); btnPanel.setLayout(new GridLayout(1,3)); btnPanel.add(applyBtn); btnPanel.add(addAnnotBtn); cancelBtn = new JButton("Cancel"); cancelBtn.setFont(tahoma); cancelBtn.addActionListener(this); btnPanel.add(cancelBtn); newPropFld = new JTextField(); newPropFld.setFont(tahoma); newPropFld.addKeyListener(this); JPanel newPanel = new JPanel(); newPanel.setLayout(new BorderLayout()); JLabel newLbl = new JLabel("3. OR Specify New Property Name/URI: "); newLbl.setFont(tahoma); newPanel.add(newLbl, "West"); newPanel.add(newPropFld, "Center"); // create default annotation prop list at top JPanel topPanel = new JPanel(); topPanel.setLayout(new GridLayout(2,1)); JLabel defaultLbl = new JLabel("Select OWL Annotation Property: "); defaultLbl.setFont(tahoma); JPanel defBar = new JPanel(); defBar.setLayout(new BorderLayout()); defBar.add(defaultLbl,"West"); defBar.add(defaultAP, "Center"); JPanel langBar = new JPanel(); langBar.setLayout(new BorderLayout()); JLabel langLbl = new JLabel("Specify Language Tag (eg. en, fr, ja): "); langLbl.setFont(tahoma); langBox = new JComboBox(); langBox.setFont(tahoma); langBox.addItem(" (plain literals)"); langBox.addItem("ar (Arabic)"); langBox.addItem("zh (Chinese - Mandarin)"); langBox.addItem("nl (Dutch)"); langBox.addItem("en (English)"); langBox.addItem("fr (French)"); langBox.addItem("de (German)"); langBox.addItem("he (Hebrew)"); langBox.addItem("hi (Hindi)"); langBox.addItem("it (Italian)"); langBox.addItem("ja (Japanese)"); langBox.addItem("ko (Korean)"); langBox.addItem("fa (Persian - Farsi)"); langBox.addItem("po (Portuguese)"); langBox.addItem("ru (Russian)"); langBox.addItem("es (Spanish)"); langBox.addItem("sw (Swahili)"); // bzhao //langBox.setSelectedIndex(3); langBox.setSelectedIndex(4); langBar.add(langLbl, "West"); langBar.add(langBox, "Center"); topPanel.add(defBar); topPanel.add(langBar); JPanel tab1P = new JPanel(); tab1P.setLayout(new BorderLayout()); tab1P.add(topPanel, "North"); tab1P.add(tab1Split, "Center"); tab1P.add(newPanel, "South"); // setup Ekit ekitPanel = new JPanel(); ekitPanel.setLayout(new BorderLayout()); ekitCore = new EkitCore(null, null, null, null, false, true, true, null, null, false, false); JPanel ekitTopPanel = new JPanel(); ekitTopPanel.setLayout(new GridLayout(2,1)); ekitTopPanel.add(ekitCore.getMenuBar()); ekitTopPanel.add(ekitCore.getToolBar(true)); ekitPanel.add(ekitTopPanel, "North"); ekitPanel.add(ekitCore, "Center"); annotFld = new JTextArea(); annotFld.setFont(tahoma); annotContentTabs = new JTabbedPane(); annotContentTabs.setFont(tahoma); annotContentTabs.add("Text", new JScrollPane(annotFld)); annotContentTabs.add("HTML", ekitPanel); JPanel lowerPanel = new JPanel(); lowerPanel.setLayout(new BorderLayout()); JLabel acLbl = new JLabel("Specify Annotation Content"); acLbl.setFont(new Font("Tahoma", Font.PLAIN, 11)); lowerPanel.add(acLbl, "North"); lowerPanel.add(annotContentTabs, "Center"); lowerPanel.add(btnPanel, "South"); //AK: only for Swoop 2.2 beta 2 release JPanel mergePanel = new JPanel(); mergePanel.setLayout(new BorderLayout()); mergePanel.add(topPanel, "North"); mergePanel.add(lowerPanel, "Center"); tab1.setBottomComponent(mergePanel); fillValues(); // add tabbed pane to frame container Container content = getContentPane(); content.setLayout(new BorderLayout()); JLabel typeLbl = new JLabel("[ ADDING ANNOTATION.. ]"); typeLbl.setFont(tahoma); content.add(typeLbl, "North"); content.add(tab1, "Center"); setSize(500,400); setTitle("Specify Annotation"); setResizable(true); tab1.setDividerLocation(25); tab1.setOneTouchExpandable(true); } private void fillValues() { Set ont = swoopModel.getOntologyURIs(); ontList.setListData(ont.toArray()); // turn on listeners ontList.addListSelectionListener(this); } /** * Method that is called when add/apply annotation change button is pressed * It obtains the OWL property specified by the user * and passes it to makeChange(..) to create the corresponding * AddAnnotationInstance Change */ private void addAnnotationChange() { try { OWLAnnotationProperty prop = null; if ((newPropFld.getText()!=null) && (!newPropFld.getText().trim().equals(""))) { // user-specified property name/uri String propStr = newPropFld.getText(); if (!isURL(propStr)) propStr = swoopModel.getSelectedOntology().getLogicalURI()+"#"+propStr; URI propURI = new URI(propStr); // **create new object property by default prop = swoopModel.getSelectedOntology().getOWLDataFactory().getOWLAnnotationProperty(propURI); makeChange(prop); } else if (propList.getSelectedIndex()==-1) { // get default prop prop = (OWLAnnotationProperty) defaultAP.getSelectedItem(); makeChange(prop); } else { // get existing property Object[] props = (Object[]) propList.getSelectedValues(); for (int i=0; i<props.length; i++) { prop = (OWLAnnotationProperty) props[i]; makeChange(prop); } } } catch (Exception ex) { ex.printStackTrace(); } } /** * Method that creates the AddAnnotationInstance change based on currently * selected ontology, entity and the OWL Annotation Property passed to it * The content is obtained from either the text area or HTML pane (Ekit) * @param prop - OWL Annotation property used to specify annotation */ private void makeChange(OWLAnnotationProperty prop) { // get change parameters OWLOntology dispOnt = swoopModel.getSelectedOntology(); OWLNamedObject dispObject = swoopModel.getSelectedObject(); String annotationData = ""; if (annotContentTabs.getSelectedIndex()==0) { annotationData = annotFld.getText().trim(); } else { // create Datatype XML Literal // or escape parser using < > & annotationData = ekitCore.getTextPane().getText(); } // escape tags - No, don't! (-Ron) // annotationData = annotationData.replaceAll("&", "&"); // annotationData = annotationData.replaceAll("<", "<"); // annotationData = annotationData.replaceAll(">", ">"); OWLDataValue dVal = null; try { // bzhao // create owl data value // String langFld = langBox.getSelectedItem().toString(); String langFld = null; if (langBox.getSelectedIndex() != 0) { langFld = langBox.getSelectedItem().toString(); langFld = langFld.substring(0, langFld.indexOf("(")).trim(); } //langFld = langFld.substring(0, langFld.indexOf("(")).trim(); dVal = dispOnt.getOWLDataFactory().getOWLConcreteData(null, langFld, annotationData); } catch (OWLException e1) { e1.printStackTrace(); } // create add-annotation-instance change AddAnnotationInstance change = null; change = new AddAnnotationInstance(dispOnt, dispObject, prop, dVal, null); swoopModel.addUncommittedChange(change); } private boolean isURL(String str) { try { URL url = new URL(str); return true; } catch (Exception ex) {} return false; } public void actionPerformed(ActionEvent e) { if (e.getSource()==addAnnotBtn) { addAnnotationChange(); dispose(); } if (e.getSource()==applyBtn) { addAnnotationChange(); } if (e.getSource()==cancelBtn) { dispose(); } } private void fillPropBox() { try { // fill props in PropBox based on selected ontology if (ontList.getSelectedIndex()==-1) return; URI ontURI = (URI) ontList.getSelectedValue(); OWLOntology currOnt = swoopModel.getOntology(ontURI); Set propSet = new TreeSet(EntityComparator.INSTANCE); propSet.addAll(currOnt.getAnnotationProperties()); propList.setListData(propSet.toArray()); } catch (Exception ex) { ex.printStackTrace(); } } public void keyTyped(KeyEvent arg0) { } public void keyPressed(KeyEvent e) { if (e.getSource()==propList) { String alpha = Character.toString(e.getKeyChar()).toLowerCase(); PopupCommon.listSelector(swoopModel, (JList) e.getSource(), alpha); } if (e.getSource()==newPropFld) { // clear selection in other choices defaultAP.setSelectedIndex(-1); propList.clearSelection(); if (e.getKeyCode()==10) { addAnnotBtn.doClick(); } } } public void keyReleased(KeyEvent arg0) { } public void valueChanged(ListSelectionEvent e) { if (e.getSource()==ontList) { fillPropBox(); } } }