View Javadoc
1   /*
2    WSMO Studio - a Semantic Web Service Editor
3    Copyright (c) 2004-2006, OntoText Lab. / SIRMA Group
4    
5    This library is free software; you can redistribute it and/or modify it under
6    the terms of the GNU Lesser General Public License as published by the Free
7    Software Foundation; either version 2.1 of the License, or (at your option)
8    any later version.
9    This library is distributed in the hope that it will be useful, but WITHOUT
10   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11   FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
12   details.
13   You should have received a copy of the GNU Lesser General Public License along
14   with this library; if not, write to the Free Software Foundation, Inc.,
15   59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16   */
17  
18  /***
19   * <p>Title: WSMO Studio</p>
20   * <p>Description: Semantic Web Service Editor</p>
21   * <p>Copyright:  Copyright (c) 2004-2006</p>
22   * <p>Company: OntoText Lab. / SIRMA </p>
23   */
24  
25  package org.wsmostudio.ui.editors.common;
26  
27  
28  import java.util.*;
29  
30  import org.eclipse.jface.action.*;
31  import org.eclipse.jface.dialogs.*;
32  import org.eclipse.jface.resource.JFaceResources;
33  import org.eclipse.jface.window.Window;
34  import org.eclipse.swt.SWT;
35  import org.eclipse.swt.custom.TreeEditor;
36  import org.eclipse.swt.events.*;
37  import org.eclipse.swt.graphics.*;
38  import org.eclipse.swt.layout.*;
39  import org.eclipse.swt.widgets.*;
40  import org.omwg.ontology.*;
41  import org.wsmo.common.*;
42  import org.wsmo.common.exception.InvalidModelException;
43  import org.wsmo.factory.WsmoFactory;
44  import org.wsmostudio.runtime.*;
45  import org.wsmostudio.ui.*;
46  import org.wsmostudio.ui.editors.model.EntityModel;
47  
48  
49  /***
50   * An editor component which supports editing of NonFunctionalProperties part of
51   * the WSMO-API objects (where applicable, i.e. implementations of Entity).
52   * The editor appears in a standalone modal window on top of the main studio 
53   * workbench.
54   * It can be invoked either from an appropriate editor component, or from the
55   * <i>WSMO Navigator</i> view (via context menu).
56   *
57   * @author not attributable
58   * @version $Revision: 1389 $ $Date: 2007-12-04 17:25:33 +0200 $
59   */
60  
61  public class NFPEditor implements MouseListener {
62      
63      private static final String[] nfpKeys = new String[] {
64              NFP.DC_TITLE,
65              NFP.DC_CREATOR,
66              NFP.DC_SUBJECT,
67              NFP.DC_DESCRIPTION,
68              NFP.DC_PUBLISHER,
69              NFP.DC_CONTRIBUTOR,
70              NFP.DC_DATE,
71              NFP.DC_TYPE,
72              NFP.DC_FORMAT,
73              NFP.DC_IDENTIFIER,
74              NFP.DC_SOURCE,
75              NFP.DC_LANGUAGE,
76              NFP.DC_RELATION,
77              NFP.DC_COVERAGE,
78              NFP.DC_RIGHTS,
79              NFP.VERSION 
80      };
81      
82      private EntityModel model;
83      
84      private Tree tableTree;
85      private TreeEditor editor;
86      private Shell shell;
87      
88      private Map<IRI, Set<Object>> sourceData;
89      private boolean dirty = false;
90      
91      private Action addDataValueAction,
92                     addInstanceValueAction,
93                     addIRIAction,
94                     addPropertyAction,
95                     editValueAction,
96                     removeValueAction,
97                     removeValuesAction,
98                     removePropertyAction;
99  
100     
101     public NFPEditor(Shell parent, EntityModel model) {
102         this.model = model;
103         shell = new Shell(parent, SWT.DIALOG_TRIM | SWT.RESIZE | SWT.SYSTEM_MODAL);
104         Image icon = JFaceResources.getImageRegistry().get(WsmoImageRegistry.DEFAULT_WINDOW_ICON);
105         shell.setImage(icon);
106         shell.setText("Non Functional Properties");
107         shell.setSize(450, 300);
108         shell.setLayout(new GridLayout(1, false));
109 
110         sourceData = new HashMap<IRI, Set<Object>>();
111         readEditorContent (sourceData, (Entity)model.getAdapter(Entity.class));
112         initInputData();
113         createDialogArea(shell);
114         createControlArea(shell);
115         initAtions();
116         createContextMenu();
117         
118         shell.pack();
119 
120         Point pLocation = parent.getLocation();
121         Point pSize = parent.getSize();
122         shell.setLocation(pLocation.x + pSize.x / 2 - shell.getSize().x / 2,
123                 pLocation.y + pSize.y / 2 - shell.getSize().y / 2);
124     }
125     
126     private void createDialogArea(Composite comp) {
127         
128     	tableTree = new Tree(comp, SWT.FULL_SELECTION | SWT.SINGLE | SWT.BORDER);
129     	tableTree.setLayoutData(new GridData(GridData.FILL_BOTH));
130 		tableTree.setLinesVisible(true);
131 		tableTree.setHeaderVisible(true);
132 
133     	TreeColumn column = new TreeColumn(tableTree, SWT.CENTER);
134     	column.setWidth(comp.getShell().getBounds().width - 10);
135     	column.setText("Properties");
136     	column.setAlignment(SWT.CENTER);
137     	
138     	for(IRI key : sourceData.keySet()) {
139     	    Set<Object> values = sourceData.get(key);
140 
141     	    TreeItem item = new TreeItem(tableTree, SWT.NONE);
142         	item.setText(0, prepareLabel(key));
143         	item.setData(key);
144         	if (isPropertyEditable(key)) {
145                 item.setForeground(comp.getDisplay().getSystemColor(SWT.COLOR_BLUE));
146             }
147             else {
148                 item.setForeground(comp.getDisplay().getSystemColor(SWT.COLOR_DARK_BLUE));
149             }
150             item.setImage(JFaceResources.getImage(WsmoImageRegistry.NFP_KEY_ICON));
151 
152         	for(Object value : values) {
153     			TreeItem subitem = new TreeItem(item, SWT.NONE);
154     			subitem.setText(0, (value instanceof Instance) 
155                                         ? ((Instance)value).getIdentifier().toString() 
156                                         : Utils.normalizeSpaces(value.toString()));
157     			subitem.setData(value);
158                 subitem.setImage(WsmoImageRegistry.getImageForObject(value));
159         	}
160     	}
161     	
162     	editor = new TreeEditor(tableTree);
163     	editor.horizontalAlignment = SWT.TRAIL;
164     	editor.grabHorizontal = true;
165     	editor.minimumWidth = 50;
166     	
167     	tableTree.addMouseListener(this);
168     } 
169 
170     private void initInputData() {
171         WsmoFactory factory = WSMORuntime.getRuntime().getWsmoFactory();
172         IRI tempKey;
173         for(int i = 0; i < nfpKeys.length; i++) {
174             try {
175                 tempKey = factory.createIRI(nfpKeys[i]);
176                 if (false == sourceData.containsKey(tempKey)) {
177                     sourceData.put(tempKey, new HashSet<Object>());
178                 }
179             }
180             catch(Exception ex) {
181                 LogManager.logError("Invalid NFP key : " + nfpKeys[i], ex);
182             }
183         }
184     }
185     
186     private void readEditorContent(Map<IRI,Set<Object>> sourceData, 
187                                    Entity nfpHolder) {
188         for (IRI key : nfpHolder.listNFPValues().keySet()) {
189             HashSet<Object> vals = new HashSet<Object>();
190             vals.addAll(nfpHolder.listNFPValues(key));
191             sourceData.put(key, vals);
192         }
193     }
194 
195     private void createControlArea(Composite mainContainer) {
196         Composite buttons = new Composite(mainContainer, SWT.NONE);
197         buttons.setLayoutData(new GridData(GridData.HORIZONTAL_ALIGN_END));
198         FillLayout layout = new FillLayout(SWT.HORIZONTAL);
199         layout.spacing = 3;
200         buttons.setLayout(layout);
201 
202         Button okButton = new Button(buttons, SWT.PUSH);
203         okButton.setText("OK");
204         okButton.addSelectionListener(new SelectionAdapter() {
205             public void widgetSelected(SelectionEvent e) {
206                 try {
207                     doUpdate();
208                 }
209                 catch(Exception ime) {
210                     MessageDialog.openError(shell, "Error", ime.getMessage());
211                     LogManager.logError(ime);
212                     return;
213                 }
214                 shell.dispose();
215             }
216         });
217         shell.setDefaultButton(okButton);
218         
219         Button noButton = new Button(buttons, SWT.PUSH);
220         noButton.setText("Cancel");
221         noButton.addSelectionListener(new SelectionAdapter() {
222             public void widgetSelected(SelectionEvent e) {
223                 dirty = false;
224                 shell.dispose();
225             }
226         });
227     }
228     
229     public boolean open() {
230         shell.open();
231         Display display = shell.getDisplay();
232         while (!shell.isDisposed()) {
233             if (!display.readAndDispatch()) {
234                 display.sleep();
235             }
236         }
237         return dirty;
238     }
239     
240     public void dispose() {
241         tableTree.dispose();
242         editor.dispose();
243 
244     }
245   
246     public String prepareLabel(IRI key) {
247         return Utils.getEntityLocalName(key.toString(), 
248                 Utils.findTopContainer(this.model));
249     }
250 
251     public void mouseDoubleClick(MouseEvent e) {
252         TreeItem[] sel = tableTree.getSelection();
253         if (sel.length == 0) {
254             return;
255         }
256         Control oldEditor = editor.getEditor();
257 		if (oldEditor != null) {
258             oldEditor.dispose();
259         }
260         if (sel[0].getParentItem() == null) {
261             return;
262         }
263         if (sel[0].getParentItem().getData() instanceof IRI
264                 && false == isPropertyEditable((IRI)sel[0].getParentItem().getData())) {
265             return;
266         }
267         doEditCell(sel[0]);
268     }
269     
270     private void doEditCell(TreeItem cell) {
271         if (cell.getData() instanceof Instance) {
272             return; // no instance editing here
273         }
274 		if (cell.getData() instanceof DataValue) {
275             DataValue newVal = DataValueEditor.createEditor(shell, (DataValue)cell.getData(), null);
276             if (newVal != null && 
277                     false == newVal.equals(cell.getData())) {
278                 cell.setData(newVal);
279                 cell.setText(newVal.toString());
280                 dirty = true;
281             }
282             return;
283         }
284         
285         if (cell.getData() instanceof Identifier) {
286             IdentifierInputDialog iid = new IdentifierInputDialog(
287                                             shell, 
288                                             "Edit Identifier",
289                                             "IRI :",
290                                             cell.getData().toString(),
291                                             (TopEntity)model.getAdapter(TopEntity.class),
292                                             WSMORuntime.getRuntime().getWsmoFactory(),
293                                             false);
294 
295             if (iid.open() != Window.OK) {
296                 return;
297             }
298             IRI newIRI = (IRI)iid.getIdentifier();
299             if (newIRI != null && 
300                     false == newIRI.equals(cell.getData())) {
301                 cell.setData(newIRI);
302                 cell.setText(newIRI.toString());
303                 dirty = true;
304             }
305         }
306     }
307     
308     public void mouseDown(MouseEvent e) {
309         Control oldEditor = editor.getEditor();
310         if (oldEditor == null) {
311             return;
312         }
313         TreeItem[] sel = tableTree.getSelection();
314         if (sel.length == 0) {
315             return;
316         }
317 		if (editor.getItem() != sel[0]) {
318 		    oldEditor.dispose();
319 		}
320     }
321     public void mouseUp(MouseEvent e) {}
322     
323 
324     private void createContextMenu() {
325         final MenuManager menuMgr = new MenuManager();
326         menuMgr.setRemoveAllWhenShown(true);
327         menuMgr.addMenuListener(new IMenuListener() {
328                 public void menuAboutToShow(IMenuManager mgr) {
329                     fillContextMenu(menuMgr);
330                 }
331         });
332         
333         // Create menu.
334         tableTree.setMenu(menuMgr.createContextMenu(tableTree));
335     }
336 
337     private void fillContextMenu(MenuManager menuMgr) {
338 
339     	if (false == GUIHelper.containsCursor(tableTree)) {
340     		return;
341     	}
342         
343     	TreeItem target = tableTree.getSelection()[0];
344         final boolean onAKey = target.getParentItem() == null;
345         
346         Action[] actions;
347         if (onAKey) {
348             if (target.getData() instanceof IRI
349                     && false == isPropertyEditable((IRI)target.getData())) {
350                 actions = new Action[] { addPropertyAction };
351             }
352             else {
353                 actions = new Action[] { 
354             		addDataValueAction, 
355             		addInstanceValueAction, 
356             		addIRIAction, 
357             		null, 
358             		addPropertyAction, 
359             		null, 
360             		removeValuesAction, 
361             		removePropertyAction };
362             }
363         }
364         else {
365             if (target.getParentItem().getData() instanceof IRI
366                     && false == isPropertyEditable((IRI)target.getParentItem().getData())) {
367                 return;
368             }
369             actions = new Action[] { editValueAction, null, removeValueAction };
370         }
371         
372         for (int i = 0; i < actions.length; i++) {
373             if (actions[i] == null) {
374             	menuMgr.add(new Separator());
375             }
376             else {
377             	menuMgr.add(actions[i]);
378                 if (actions[i].getText().equals("Remove Property")) {
379                     actions[i].setEnabled(!isRequiredProperty(target.getData()));
380                 }
381             }
382         }
383     }
384 
385     @SuppressWarnings("unchecked")
386     public void initAtions() {
387     	addDataValueAction = new Action("Add Data Value") {
388     		public void run() {
389                 DataValue newVal = DataValueEditor.createEditor(shell);
390                 if (newVal == null) {
391                     return;
392                 }
393             	TreeItem[] sel = tableTree.getSelection();
394                 TreeItem subitem = new TreeItem(sel[0], SWT.NONE);
395                 subitem.setData(newVal);
396                 subitem.setText(newVal.toString());
397                 subitem.setImage(WsmoImageRegistry.getImageForObject(newVal));
398     			sel[0].setExpanded(true);
399             	tableTree.setSelection(new TreeItem[] { subitem });
400             	tableTree.showSelection();
401     			tableTree.redraw();
402     			sourceData.get(sel[0].getData()).add(newVal);
403     			dirty = true;
404     		}
405     	};
406         addInstanceValueAction = new Action("Add Instance Value") {
407     		public void run() {
408         	TreeItem[] sel = tableTree.getSelection();
409             WSMOChooser chooser = WSMOChooser.createInstanceChooser(
410                                                     shell,
411                                                     WSMORuntime.getRuntime()); 
412                 
413             Instance newInstance = (Instance)chooser.open();
414             if (newInstance == null) {
415                 return;
416             }
417             TreeItem subitem = new TreeItem(sel[0], SWT.NONE);
418             subitem.setData(newInstance);
419             subitem.setText(newInstance.getIdentifier().toString());
420             subitem.setImage(WsmoImageRegistry.getImageForObject(newInstance));
421             sel[0].setExpanded(true);
422             tableTree.setSelection(new TreeItem[] { subitem });
423             tableTree.showSelection();
424             tableTree.redraw();
425             sourceData.get(sel[0].getData()).add(newInstance);
426             dirty = true;
427     		}
428         };
429         addIRIAction = new Action("Add IRI") {
430     		public void run() {
431         	TreeItem[] sel = tableTree.getSelection();
432             IdentifierInputDialog iid = new IdentifierInputDialog(shell, 
433                     "New Identifier",
434                     "IRI : ",
435                     Utils.findTopContainer(model),
436                     WSMORuntime.getRuntime().getWsmoFactory(),
437                     false);
438 
439             if (iid.open() != Window.OK) {
440                 return;
441             }
442             IRI newIRI = (IRI)iid.getIdentifier();
443             TreeItem subitem = new TreeItem(sel[0], SWT.NONE);
444             subitem.setText(0, newIRI.toString());
445             subitem.setData(newIRI);
446             subitem.setImage(WsmoImageRegistry.getImageForObject(newIRI));
447             sel[0].setExpanded(true);
448             tableTree.setSelection(new TreeItem[] { subitem });
449             tableTree.showSelection();
450             tableTree.redraw();
451             sourceData.get(sel[0].getData()).add(newIRI);
452             dirty = true;
453     		}
454         };
455     	
456         addPropertyAction = new Action("Add Property") {
457     		public void run() {
458             final IdentifierInputDialog inputDialog = new IdentifierInputDialog(
459                     shell, 
460                     "New Property Name", 
461                     "Please supply a property URI", 
462                     "", // initial value
463                     Utils.findTopContainer(model),
464                     WSMORuntime.getRuntime().getWsmoFactory(),
465                     false);
466             inputDialog.setInputValidator(new IInputValidator() {
467                         public String isValid(String input) {
468                             Identifier id = inputDialog.getIdentifier();
469                             if (id != null 
470                                     && id instanceof IRI) { 
471                                 if (false == isPropertyEditable((IRI)id)) {
472                                     return "Using wsmostudio namespace as NFP key is not allowed";
473                                 }
474                                 TreeItem[] propsItems = tableTree.getItems();
475                                 for(int i = 0; i < propsItems.length; i++) {
476                                     if (id.equals(propsItems[i].getData())) {
477                                         return "Duplicated NFP key.";
478                                     }
479                                 }
480 
481                             }
482                             return null;
483                         }
484                     });
485 
486             if (inputDialog.open() != Window.OK) {
487                 return;
488             }
489             IRI newProperty = (IRI)inputDialog.getIdentifier();
490             if (sourceData.containsKey(newProperty)) {
491                 return;
492             }
493             
494             TreeItem item = new TreeItem(tableTree, SWT.NONE);
495             item.setText(0, prepareLabel(newProperty));
496             item.setData(newProperty);
497         	item.setForeground(tableTree.getDisplay().getSystemColor(SWT.COLOR_BLUE));
498             item.setImage(JFaceResources.getImage(WsmoImageRegistry.NFP_KEY_ICON));
499         	tableTree.setSelection(new TreeItem[] { item });
500         	tableTree.showSelection();
501         	tableTree.redraw();
502         	sourceData.put(newProperty, new HashSet());
503         	dirty = true;
504     		}
505         };
506         editValueAction = new Action("Edit Value") {
507     		public void run() {
508             	TreeItem[] sel = tableTree.getSelection();
509                 doEditCell(sel[0]);
510     		}
511 
512         };
513         removeValueAction = new Action("Remove Value") {
514         	public void run() {
515             	TreeItem[] sel = tableTree.getSelection();
516                 TreeItem parentItem = sel[0].getParentItem();
517                 sourceData.get(parentItem.getData()).remove(sel[0].getData());
518 
519                 sel[0].dispose();
520                 tableTree.setSelection(new TreeItem[] { parentItem });
521                 tableTree.redraw();
522                 dirty = true;
523         	}
524         };
525         removeValuesAction = new Action("Remove Values") {
526         	public void run() {
527             	TreeItem[] sel = tableTree.getSelection();
528                 TreeItem[] subItems = sel[0].getItems();
529                 if (subItems.length == 0) {
530                     return;
531                 }
532                 for(int i = 0; i < subItems.length; i++) {
533                     subItems[i].dispose();
534                 }
535                 sourceData.get(sel[0].getData()).clear();
536                 tableTree.redraw();
537                 dirty = true;
538         	}
539         };
540         removePropertyAction = new Action("Remove Property") {
541         	public void run() {
542             	TreeItem[] sel = tableTree.getSelection();
543                 if (sel[0].getData() == null) {
544                     return;
545                 }
546                 sourceData.remove(sel[0].getData());
547                 sel[0].dispose();
548                 tableTree.redraw();
549                 dirty = true;
550         	}
551         };
552     }
553 
554     @SuppressWarnings("unchecked")
555     private void doUpdate() throws Exception {
556         if (!dirty) {
557             return;
558         }
559         Entity targetHolder = (Entity)model.getAdapter(Entity.class);
560         Map oldNFPState = targetHolder.listNFPValues();
561         updateValuesFromUI();
562         // searching for removed properties
563         for (Iterator it = oldNFPState.keySet().iterator(); it.hasNext(); ) {
564             IRI iriKey = (IRI)it.next();
565             if (false == sourceData.containsKey(iriKey)) {
566                 clearProperty(iriKey, targetHolder);
567                 continue;
568             }
569             Set newValues = sourceData.get(iriKey);
570             if (newValues.size() == 0) {
571                 clearProperty(iriKey, targetHolder);
572                 continue;
573             }
574             
575             // searching for removed / changed values
576             for (Object oldValue : new HashSet<Object>(targetHolder.listNFPValues(iriKey))) {
577                 if (false == newValues.contains(oldValue)) {
578                     if (oldValue instanceof Identifier) {
579                         model.removeNFPValue(iriKey, (Identifier)oldValue);
580                     }
581                     else {
582                         model.removeNFPValue(iriKey, (Value)oldValue);
583                     }
584                 }
585             }
586             // adding the new values
587             for (Object val : newValues) {
588                 if (val instanceof Identifier) {
589                     model.addNFPValue(iriKey, (Identifier)val);
590                 }
591                 else {
592                     model.addNFPValue(iriKey, (Value)val);
593                 }
594             }
595         }
596         
597         // adding all new properties
598         
599         for (Iterator it = sourceData.keySet().iterator(); it.hasNext(); ) {
600             IRI propName = (IRI)it.next();
601             for (Object val : sourceData.get(propName)) {
602                 if (val instanceof Identifier) {
603                     model.addNFPValue(propName, (Identifier)val);
604                 }
605                 else {
606                     model.addNFPValue(propName, (Value)val);
607                 }
608             }
609         }
610     }
611     
612     private void updateValuesFromUI() throws Exception {
613         sourceData.clear();
614         TreeItem[] propsItems = tableTree.getItems();
615         WsmoFactory factory = WSMORuntime.getRuntime().getWsmoFactory();
616         for(int i = 0; i < propsItems.length; i++) {
617             IRI property = (IRI)propsItems[i].getData();
618             TreeItem[] valsItems = propsItems[i].getItems();
619             Set<Object> valsSet = new HashSet<Object>();
620             for(int k = 0; k < valsItems.length; k++) {
621                 if(valsItems[k].getText(0).trim().length() > 0) {
622                     Object oldValue = valsItems[k].getData();
623                     if (oldValue instanceof Identifier 
624                             && false == oldValue.toString().equals(
625                                              valsItems[k].getText(0).trim())) {
626                         try {    
627                             oldValue = factory.createIRI(valsItems[k].getText(0).trim());
628                         }
629                         catch(Exception ex) {
630                             throw new Exception("Invalid value for property '"
631                                     + property.toString()
632                                     + "'\n(" + valsItems[k].getText(0).trim() + ")"
633                                     + "\n" + ex.getMessage()
634                                     , ex);
635                         }
636                     }
637                     valsSet.add(oldValue);
638                 }
639                 sourceData.put(property, valsSet);
640             }
641         }
642     }
643     
644     @SuppressWarnings("unchecked")
645     private void clearProperty(IRI property, Entity nfpHolder) {
646         try {
647             for(Object val : new HashSet<Object>(nfpHolder.listNFPValues(property))) {
648                 if (val instanceof Identifier) {
649                     model.removeNFPValue(property, (Identifier)val);
650                 }
651                 else {
652                     model.removeNFPValue(property, (Value)val);
653                 }
654             }
655         }
656         catch(InvalidModelException ime) {
657             LogManager.logError(ime);
658         }
659         dirty = true;
660     }
661     
662     private boolean isRequiredProperty(Object propName) {
663         if (propName == null ||
664                 false == propName instanceof IRI) {
665             return false;
666         }
667         String name = ((IRI)propName).toString();
668         for(int i = 0; i < nfpKeys.length; i++) {
669             if (nfpKeys[i].equals(name)) {
670                 return true;
671             }
672         }
673         return false;
674     }
675     
676     /***
677      * Extenders may customize the editability of the properties
678      * @param nfpKey
679      * @return
680      */
681     protected boolean isPropertyEditable(IRI nfpKey) {
682         return false == nfpKey.toString().startsWith("http://www.wsmostudio.org#");
683     }
684 }
685 
686 /*
687  * $Log$
688  * Revision 1.29  2007/07/19 13:08:31  alex_simov
689  * - rfe [1751326] Navigation through the editor tab
690  * - concepts/attributes which are from a different namespace are prefixed
691  *
692  * Revision 1.28  2007/04/17 14:35:33  alex_simov
693  * migration to the latest wsmo4j (java 5)
694  *
695  * Revision 1.27  2007/02/22 13:04:02  alex_simov
696  * Feature request [1665303]: new line characters are filtered from the content in
697  * non-editable fields
698  *
699  * Revision 1.26  2007/02/19 14:45:31  alex_simov
700  * bugfix [1663285]: NFP editor shows property names as :
701  * <namespace_prefix>:<local name> (if a suitable namespece is defined).
702  * System NFPs (having wsmostudio prefix) are read-only and coloured differently
703  *
704  * Revision 1.25  2006/12/20 11:56:56  alex_simov
705  * no message
706  *
707  * Revision 1.24  2006/11/29 13:55:29  alex_simov
708  * bugfix: modifying NFP datatype values did not raise dirty flag to true,
709  * loosing the changes during update
710  *
711  * Revision 1.23  2006/08/01 11:21:12  alex_simov
712  * bugfix[1531709]: Context menus relied on right button mouse click instead of
713  * being registered as dedicated context menus for the corresponding UI
714  * controls
715  *
716  * Revision 1.22  2006/07/20 15:15:52  alex_simov
717  * ui fixes
718  *
719  * Revision 1.21  2006/07/18 13:27:14  alex_simov
720  * bugfix/workaround [1484820] : usage of FillLayout replaced by GridLayout,
721  * previously causing empty dialog windows under Linux - gtk
722  *
723  * Revision 1.20  2006/01/20 16:42:03  alex_simov
724  * IRI creation wrapped in try-catch to produce adequate UI error message
725  *
726  * Revision 1.19  2006/01/09 12:51:13  alex_simov
727  * Copyright message in header updated
728  *
729  * Revision 1.18  2005/12/21 15:30:26  alex_simov
730  * default namespace support fix
731  *
732  * Revision 1.17  2005/12/06 09:42:04  alex_simov
733  * DataValue editor made aware of type restriction depending on usage
734  *
735  * Revision 1.16  2005/11/09 16:16:27  alex_simov
736  * UIModels notification improved
737  *
738  * Revision 1.15  2005/09/20 14:40:23  alex_simov
739  * small updates
740  *
741  * Revision 1.14  2005/09/19 15:14:46  alex_simov
742  * UI support improved
743  * Instances support added
744  *
745  * Revision 1.13  2005/09/16 14:25:11  alex_simov
746  * Identifier.asString() removed, use Object.toString() instead
747  *
748  * Revision 1.12  2005/09/08 16:46:25  alex_simov
749  * Migrating to Java 1.5
750  *
751  * Revision 1.11  2005/08/08 12:12:29  alex_simov
752  * refactoring: prepareLabel(String) moved to Utils.getLocalName(String)
753  *
754  * Revision 1.10  2005/08/02 10:33:21  alex_simov
755  * minor code and/or javadoc fixes
756  *
757  * Revision 1.9  2005/07/29 15:08:02  alex_simov
758  * added javadoc: class description, footer
759  *
760  *
761  */