1 19 20 package org.netbeans.modules.xml.xam.ui.customizer; 21 22 import java.awt.BorderLayout ; 23 import java.beans.PropertyChangeEvent ; 24 import java.beans.PropertyChangeListener ; 25 import java.io.IOException ; 26 import java.net.URISyntaxException ; 27 import java.util.ArrayList ; 28 import java.util.List ; 29 import java.util.Map ; 30 import java.util.Set ; 31 import javax.swing.ImageIcon ; 32 import javax.swing.event.DocumentEvent ; 33 import javax.swing.event.DocumentListener ; 34 import javax.swing.tree.TreeSelectionModel ; 35 import org.netbeans.api.project.FileOwnerQuery; 36 import org.netbeans.api.project.Project; 37 import org.netbeans.modules.xml.catalogsupport.DefaultProjectCatalogSupport; 38 import org.netbeans.modules.xml.xam.locator.CatalogModelException; 39 import org.netbeans.spi.project.ui.LogicalViewProvider; 40 import org.openide.explorer.view.BeanTreeView; 41 import org.netbeans.modules.xml.xam.Component; 42 import org.netbeans.modules.xml.xam.Model; 43 import org.openide.explorer.ExplorerManager; 44 import org.openide.filesystems.FileObject; 45 import org.openide.nodes.AbstractNode; 46 import org.openide.nodes.Children; 47 import org.openide.nodes.Node; 48 import org.openide.util.NbBundle; 49 import org.openide.util.Utilities; 50 51 57 public abstract class ExternalReferenceCustomizer<T extends Component> 58 extends AbstractReferenceCustomizer<T> 59 implements DocumentListener , ExplorerManager.Provider, 60 PropertyChangeListener { 61 62 private static final long serialVersionUID = 1L; 63 64 private transient boolean prefixGenerated; 65 66 private transient FileObject sourceFO; 67 68 private transient FileObject referencedFO; 69 70 private transient DefaultProjectCatalogSupport catalogSupport; 71 72 77 public ExternalReferenceCustomizer(T component, Model model) { 78 super(component); 79 initComponents(); 80 sourceFO = (FileObject) component.getModel().getModelSource(). 81 getLookup().lookup(FileObject.class); 82 catalogSupport = DefaultProjectCatalogSupport.getInstance(sourceFO); 83 init(component, model); 84 initializeUI(); 85 BeanTreeView locationView = new BeanTreeView(); 87 locationView.setPopupAllowed(false); 88 locationView.setDefaultActionAllowed(false); 89 locationView.setSelectionMode(TreeSelectionModel.SINGLE_TREE_SELECTION); 90 locationView.setRootVisible(false); 91 locationView.getAccessibleContext().setAccessibleName(locationLabel.getToolTipText()); 92 locationView.getAccessibleContext().setAccessibleDescription(locationLabel.getToolTipText()); 93 locationPanel.add(locationView, BorderLayout.CENTER); 94 explorerManager = new ExplorerManager(); 95 explorerManager.addPropertyChangeListener(this); 96 explorerManager.setRootContext(createRootNode()); 97 } 98 99 @Override 100 public void addNotify() { 101 super.addNotify(); 102 firePropertyChange(PROP_ACTION_APPLY, true, false); 104 } 105 106 public void applyChanges() throws IOException { 107 if (mustNamespaceDiffer() && isPrefixChanged()) { 108 prefixTextField.setEditable(false); 109 } 110 if (isLocationChanged() && referencedFO != null && 111 catalogSupport.needsCatalogEntry(sourceFO, referencedFO)) { 112 try { 113 catalogSupport.createCatalogEntry(sourceFO, referencedFO); 114 } catch (IOException ioe) { 115 } catch (CatalogModelException cme) { 116 } 117 } 118 } 119 120 125 protected String getEditedLocation() { 126 if (referencedFO == null) { 127 return getReferenceLocation(); 128 } 129 try { 130 return catalogSupport.getReferenceURI(sourceFO, referencedFO).toString(); 131 } catch (URISyntaxException ex) { 132 } 133 return null; 134 } 135 136 141 protected String getEditedNamespace() { 142 return namespaceTextField.getText().trim(); 143 } 144 145 150 protected String getEditedPrefix() { 151 return prefixTextField.getText().trim(); 152 } 153 154 159 protected abstract String getReferenceLocation(); 160 161 166 protected abstract String getNamespace(); 167 168 173 protected abstract String getPrefix(); 174 175 180 protected abstract String generatePrefix(); 181 182 187 protected boolean isLocationChanged() { 188 String rl = getReferenceLocation(); 189 String el = getEditedLocation(); 190 if (rl == null) { 191 return el != null; 192 } 193 return !rl.equals(el); 194 } 195 196 201 protected boolean isNamespaceChanged() { 202 if (!mustNamespaceDiffer()) { 203 return false; 204 } 205 String ns = getNamespace(); 206 String ens = getEditedNamespace(); 207 if (ns == null) { 208 return ens.length() > 0; 209 } 210 return !ns.equals(ens); 211 } 212 213 218 protected boolean isPrefixChanged() { 219 if (!mustNamespaceDiffer()) { 220 return false; 221 } 222 if (prefixGenerated) { 223 return false; 225 } 226 String p = getPrefix(); 227 String ep = getEditedPrefix(); 228 if (p == null) { 229 return ep.length() > 0; 230 } 231 return !p.equals(ep); 232 } 233 234 242 protected void init(T component, Model model) { 243 } 246 247 public void changedUpdate(DocumentEvent e) { 248 } 249 250 public void insertUpdate(DocumentEvent e) { 251 prefixGenerated = false; 252 validateInput(); 253 } 254 255 public void removeUpdate(DocumentEvent e) { 256 prefixGenerated = false; 257 validateInput(); 258 } 259 260 protected void initializeUI() { 261 if (mustNamespaceDiffer()) { 263 namespaceTextField.setText(getNamespace()); 264 prefixTextField.getDocument().removeDocumentListener(this); 265 String prefix = getPrefix(); 266 if (prefix != null) { 267 prefixTextField.setText(prefix); 268 prefixTextField.setEditable(false); 269 prefixGenerated = false; 270 } else { 271 prefix = generatePrefix(); 272 prefixGenerated = true; 273 prefixTextField.setText(prefix); 274 prefixTextField.getDocument().addDocumentListener(this); 275 } 276 } else { 277 namespaceLabel.setVisible(false); 278 namespaceTextField.setVisible(false); 279 prefixLabel.setVisible(false); 280 prefixTextField.setVisible(false); 281 } 282 } 283 284 public ExternalReferenceDataNode createExternalReferenceNode(Node original) { 285 return new ExternalReferenceDataNode(original, getNodeDecorator()); 286 } 287 288 293 private void validateInput() { 294 boolean lChanged = isLocationChanged(); 295 boolean nsChanged = isNamespaceChanged(); 296 boolean pChanged = isPrefixChanged(); 297 if (!lChanged && !nsChanged && !pChanged) { 298 setSaveEnabled(false); 299 setResetEnabled(false); 300 } else { 301 setResetEnabled(true); 302 String msg = null; 303 if (mustNamespaceDiffer()) { 304 if (lChanged && getEditedLocation() == null) { 305 msg = NbBundle.getMessage(ExternalReferenceCustomizer.class, 306 "LBL_ExternalReferenceCustomizer_InvalidLocation"); 307 } 308 Map <String , String > prefixMap = getPrefixes(getModelComponent().getModel()); 309 String ep = getEditedPrefix(); 310 if (pChanged && (ep.length() == 0 || prefixMap.containsKey(ep))) { 311 msg = NbBundle.getMessage(ExternalReferenceCustomizer.class, 312 "LBL_ExternalReferenceCustomizer_InvalidPrefix"); 313 } 314 } 315 prefixTextField.setEditable(lChanged); 317 if (msg != null) { 318 showMessage(msg); 319 } 320 setSaveEnabled(msg == null); 321 } 322 } 323 324 protected void showMessage(String msg) { 325 if (msg == null) { 326 messageLabel.setText(" "); 327 messageLabel.setIcon(null); 328 } else { 329 messageLabel.setText(msg); 330 messageLabel.setIcon(new ImageIcon (Utilities.loadImage( 332 "org/openide/resources/error.gif"))); } 334 } 335 336 protected Node createRootNode() { 337 Set refProjects = null; 338 if (catalogSupport.supportsCrossProject()) { 339 refProjects = catalogSupport.getProjectReferences(); 340 } 341 ExternalReferenceDecorator decorator = getNodeDecorator(); 342 Node[] rootNodes = new Node[1 + (refProjects == null ? 0 : refProjects.size())]; 343 Project prj = FileOwnerQuery.getOwner(sourceFO); 344 LogicalViewProvider viewProvider = (LogicalViewProvider) prj.getLookup(). 345 lookup(LogicalViewProvider.class); 346 rootNodes[0] = decorator.createExternalReferenceNode( 347 viewProvider.createLogicalView()); 348 int rootIndex = 1; 349 List <FileObject> projectRoots = new ArrayList <FileObject>(); 350 projectRoots.add(prj.getProjectDirectory()); 351 if (refProjects != null) { 352 for (Object o : refProjects) { 353 Project refPrj = (Project) o; 354 viewProvider = (LogicalViewProvider) refPrj.getLookup(). 355 lookup(LogicalViewProvider.class); 356 rootNodes[rootIndex++] = decorator.createExternalReferenceNode( 357 viewProvider.createLogicalView()); 358 projectRoots.add(refPrj.getProjectDirectory()); 359 } 360 } 361 FileObject[] roots = projectRoots.toArray( 362 new FileObject[projectRoots.size()]); 363 Children fileChildren = new Children.Array(); 364 fileChildren.add(rootNodes); 365 Node byFilesNode = new FolderNode(fileChildren); 366 byFilesNode.setDisplayName(NbBundle.getMessage( 367 ExternalReferenceCustomizer.class, 368 "LBL_ExternalReferenceCustomizer_Category_By_File")); 369 370 Children nsChildren = new NamespaceChildren(roots, decorator); 372 Node byNSNode = new FolderNode(nsChildren); 373 byNSNode.setDisplayName(NbBundle.getMessage( 374 ExternalReferenceCustomizer.class, 375 "LBL_ExternalReferenceCustomizer_Category_By_Namespace")); 376 Children categories = new Children.Array(); 390 categories.add(new Node[] { byFilesNode, byNSNode }); 392 return new AbstractNode(categories); 393 } 394 395 407 public void propertyChange(PropertyChangeEvent event) { 408 if (ExplorerManager.PROP_SELECTED_NODES.equals(event.getPropertyName())) { 409 showMessage(null); 411 setSaveEnabled(false); 412 String ns = null; 413 referencedFO = null; 414 Node[] nodes = (Node[]) event.getNewValue(); 415 if (nodes != null && nodes.length > 0 && 417 nodes[0] instanceof ExternalReferenceNode) { 418 ExternalReferenceNode node = (ExternalReferenceNode) nodes[0]; 419 Model model = node.getModel(); 420 if (model != null) { 422 ns = getTargetNamespace(model); 423 if (model != getModelComponent().getModel()) { 424 referencedFO = (FileObject) model.getModelSource(). 425 getLookup().lookup(FileObject.class); 426 } 427 String msg = getNodeDecorator().validate(node); 429 if (msg != null) { 430 showMessage(msg); 431 } else { 432 validateInput(); 434 } 435 } 436 } 437 namespaceTextField.setText(ns); 438 } 439 } 440 441 public ExplorerManager getExplorerManager() { 442 return explorerManager; 443 } 444 445 451 private void initComponents() { 453 locationLabel = new javax.swing.JLabel (); 454 locationPanel = new javax.swing.JPanel (); 455 namespaceLabel = new javax.swing.JLabel (); 456 namespaceTextField = new javax.swing.JTextField (); 457 prefixLabel = new javax.swing.JLabel (); 458 prefixTextField = new javax.swing.JTextField (); 459 messageLabel = new javax.swing.JLabel (); 460 461 locationLabel.setLabelFor(locationPanel); 462 org.openide.awt.Mnemonics.setLocalizedText(locationLabel, java.util.ResourceBundle.getBundle("org/netbeans/modules/xml/xam/ui/customizer/Bundle").getString("LBL_ExternalReferenceCustomizer_Location")); 463 locationLabel.setToolTipText(java.util.ResourceBundle.getBundle("org/netbeans/modules/xml/xam/ui/customizer/Bundle").getString("TIP_ExternalReferenceCustomizer_Location")); 464 465 locationPanel.setLayout(new java.awt.BorderLayout ()); 466 467 locationPanel.setBorder(javax.swing.BorderFactory.createEtchedBorder()); 468 469 namespaceLabel.setLabelFor(namespaceTextField); 470 org.openide.awt.Mnemonics.setLocalizedText(namespaceLabel, java.util.ResourceBundle.getBundle("org/netbeans/modules/xml/xam/ui/customizer/Bundle").getString("LBL_ExternalReferenceCustomizer_Namespace")); 471 namespaceLabel.setToolTipText(java.util.ResourceBundle.getBundle("org/netbeans/modules/xml/xam/ui/customizer/Bundle").getString("TIP_ExternalReferenceCustomizer_Namespace")); 472 473 namespaceTextField.setEditable(false); 474 475 prefixLabel.setLabelFor(prefixTextField); 476 org.openide.awt.Mnemonics.setLocalizedText(prefixLabel, java.util.ResourceBundle.getBundle("org/netbeans/modules/xml/xam/ui/customizer/Bundle").getString("LBL_ExternalReferenceCustomizer_Prefix")); 477 prefixLabel.setToolTipText(java.util.ResourceBundle.getBundle("org/netbeans/modules/xml/xam/ui/customizer/Bundle").getString("TIP_ExternalReferenceCustomizer_Prefix")); 478 479 prefixTextField.setToolTipText(java.util.ResourceBundle.getBundle("org/netbeans/modules/xml/xam/ui/customizer/Bundle").getString("TIP_ExternalReferenceCustomizer_Prefix")); 480 481 messageLabel.setForeground(new java.awt.Color (255, 0, 0)); 482 org.openide.awt.Mnemonics.setLocalizedText(messageLabel, " "); 483 484 org.jdesktop.layout.GroupLayout layout = new org.jdesktop.layout.GroupLayout(this); 485 this.setLayout(layout); 486 layout.setHorizontalGroup( 487 layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) 488 .add(layout.createSequentialGroup() 489 .addContainerGap() 490 .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) 491 .add(messageLabel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE) 492 .add(locationPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 382, Short.MAX_VALUE) 493 .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup() 494 .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) 495 .add(namespaceLabel) 496 .add(prefixLabel)) 497 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) 498 .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) 499 .add(prefixTextField, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 297, Short.MAX_VALUE) 500 .add(namespaceTextField, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 297, Short.MAX_VALUE))) 501 .add(locationLabel)) 502 .addContainerGap()) 503 ); 504 layout.setVerticalGroup( 505 layout.createParallelGroup(org.jdesktop.layout.GroupLayout.LEADING) 506 .add(org.jdesktop.layout.GroupLayout.TRAILING, layout.createSequentialGroup() 507 .addContainerGap() 508 .add(locationLabel) 509 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) 510 .add(locationPanel, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, 330, Short.MAX_VALUE) 511 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) 512 .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.TRAILING) 513 .add(namespaceLabel) 514 .add(namespaceTextField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) 515 .add(12, 12, 12) 516 .add(layout.createParallelGroup(org.jdesktop.layout.GroupLayout.BASELINE) 517 .add(prefixLabel) 518 .add(prefixTextField, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE, org.jdesktop.layout.GroupLayout.DEFAULT_SIZE, org.jdesktop.layout.GroupLayout.PREFERRED_SIZE)) 519 .addPreferredGap(org.jdesktop.layout.LayoutStyle.RELATED) 520 .add(messageLabel) 521 .addContainerGap()) 522 ); 523 } 525 public javax.swing.JLabel locationLabel; 527 public javax.swing.JPanel locationPanel; 528 public javax.swing.JLabel messageLabel; 529 public javax.swing.JLabel namespaceLabel; 530 public javax.swing.JTextField namespaceTextField; 531 public javax.swing.JLabel prefixLabel; 532 public javax.swing.JTextField prefixTextField; 533 } 535 | Popular Tags |