1 20 21 package org.apache.directory.ldapstudio.schemas.model; 22 23 24 import java.io.File ; 25 import java.io.FileNotFoundException ; 26 import java.io.IOException ; 27 import java.net.MalformedURLException ; 28 import java.net.URL ; 29 import java.text.ParseException ; 30 import java.util.ArrayList ; 31 import java.util.HashSet ; 32 import java.util.Hashtable ; 33 import java.util.Set ; 34 35 import org.apache.directory.ldapstudio.schemas.Activator; 36 import org.apache.directory.ldapstudio.schemas.Messages; 37 import org.apache.directory.ldapstudio.schemas.PluginConstants; 38 import org.apache.directory.ldapstudio.schemas.io.SchemaParser; 39 import org.apache.directory.ldapstudio.schemas.io.SchemaWriter; 40 import org.apache.directory.server.core.tools.schema.AttributeTypeLiteral; 41 import org.apache.directory.server.core.tools.schema.ObjectClassLiteral; 42 import org.apache.log4j.Logger; 43 import org.eclipse.swt.SWT; 44 import org.eclipse.swt.widgets.FileDialog; 45 import org.eclipse.swt.widgets.MessageBox; 46 import org.eclipse.swt.widgets.Shell; 47 import org.eclipse.ui.PlatformUI; 48 49 50 public class Schema implements SchemaElementListener 51 { 52 private static Logger logger = Logger.getLogger( Schema.class ); 53 54 private String name; 55 private URL url; 56 private Hashtable <String , ObjectClass> objectClassTable; 59 private Hashtable <String , AttributeType> attributeTypeTable; 60 private ArrayList <SchemaListener> listeners; 61 private boolean hasBeenModified = false; 63 64 68 public enum SchemaType 69 { 70 userSchema, coreSchema 71 } 72 73 76 public SchemaType type; 77 78 79 82 83 88 public static String URLtoFileName( URL url ) 89 { 90 try 91 { 92 String separator = "/"; if ( url.getProtocol().equals( "bundleresource" ) ) separator = "/"; else 98 { 99 separator = File.separator; 101 102 if ( separator.equals( "\\" ) ) { separator = "\\\\"; } 107 } 108 109 String path = url.getPath(); 110 String [] splFileName = path.split( separator ); 111 String fileNoPath = splFileName[splFileName.length - 1]; 112 113 if ( fileNoPath.endsWith( ".schema" ) ) { 115 String [] fileName = fileNoPath.split( "\\." ); return fileName[0]; 117 } 118 } 119 catch ( Exception e ) 120 { 121 logger.debug( "error when converting " + url + " to filename" ); } 123 return null; 124 } 125 126 127 133 public static URL localPathToURL( String path ) throws SchemaCreationException 134 { 135 URL tempURL = null; 136 try 137 { 138 tempURL = new URL ( "file", "localhost", -1, path ); } 140 catch ( MalformedURLException e ) 141 { 142 throw new SchemaCreationException( "malformed path:" + path, e ); } 144 return tempURL; 145 146 } 147 148 149 155 private static boolean isASchemaFile( URL url ) 156 { 157 return URLtoFileName( url ) != null; 158 } 159 160 161 164 165 169 public Schema( String name ) 170 { 171 this( name, null, SchemaType.userSchema ); 172 } 173 174 175 180 public Schema( SchemaType type, String name ) 181 { 182 this( name, null, type ); 183 } 184 185 186 192 public Schema( String path, SchemaType type ) throws SchemaCreationException 193 { 194 this( localPathToURL( path ), type ); 195 } 196 197 198 204 public Schema( URL url, SchemaType type ) throws SchemaCreationException 205 { 206 this( URLtoFileName( url ), url, type ); 207 208 if ( !isASchemaFile( url ) ) 210 throw new SchemaCreationException( "not a .schema file: " + url, null ); 212 try 214 { 215 read(); 216 } 217 catch ( IOException e ) 218 { 219 throw new SchemaCreationException( "error opening " + url.toString(), e ); } 221 catch ( ParseException e ) 222 { 223 throw new SchemaCreationException( "error during parsing of " + url.toString(), e ); } 225 } 226 227 228 235 private Schema( String name, URL url, SchemaType type ) 236 { 237 this.name = name; 238 this.url = url; 239 this.type = type; 240 241 objectClassTable = new Hashtable <String , ObjectClass>(); 242 attributeTypeTable = new Hashtable <String , AttributeType>(); 243 listeners = new ArrayList <SchemaListener>(); 244 245 this.modified(); 247 } 248 249 250 253 254 257 public String getName() 258 { 259 return name; 260 } 261 262 263 266 public URL getURL() 267 { 268 return url; 269 } 270 271 272 276 public Hashtable <String , ObjectClass> getObjectClassesAsHashTable() 277 { 278 return objectClassTable; 279 } 280 281 282 286 public Hashtable <String , AttributeType> getAttributeTypesAsHashTable() 287 { 288 return attributeTypeTable; 289 } 290 291 292 296 public ObjectClass[] getObjectClassesAsArray() 297 { 298 Set <ObjectClass> set = new HashSet <ObjectClass>(); 299 set.addAll( objectClassTable.values() ); 300 return set.toArray( new ObjectClass[0] ); 301 } 302 303 304 308 public AttributeType[] getAttributeTypesAsArray() 309 { 310 Set <AttributeType> set = new HashSet <AttributeType>(); 311 set.addAll( attributeTypeTable.values() ); 312 return set.toArray( new AttributeType[0] ); 313 } 314 315 316 319 320 324 public boolean hasBeenModified() 325 { 326 return hasBeenModified; 327 } 328 329 330 335 public boolean hasPendingModification() 336 { 337 ObjectClass[] OCs = getObjectClassesAsArray(); 338 for ( ObjectClass objectClass : OCs ) 339 { 340 if ( objectClass.hasPendingModifications() ) 341 { 342 return true; 343 } 344 } 345 346 AttributeType[] ATs = getAttributeTypesAsArray(); 347 for ( AttributeType attributeType : ATs ) 348 { 349 if ( attributeType.hasPendingModifications() ) 350 { 351 return true; 352 } 353 } 354 return false; 355 } 356 357 358 361 public void applyPendingModifications() 362 { 363 ObjectClass[] OCs = getObjectClassesAsArray(); 364 for ( ObjectClass objectClass : OCs ) 365 { 366 if ( objectClass.hasPendingModifications() ) 367 { 368 objectClass.applyPendingModifications(); 369 } 370 } 371 372 AttributeType[] ATs = getAttributeTypesAsArray(); 373 for ( AttributeType attributeType : ATs ) 374 { 375 if ( attributeType.hasPendingModifications() ) 376 { 377 attributeType.applyPendingModifications(); 378 } 379 } 380 } 381 382 383 387 public void closeAssociatedEditors() 388 { 389 ObjectClass[] OCs = getObjectClassesAsArray(); 390 for ( ObjectClass objectClass : OCs ) 391 { 392 objectClass.closeAssociatedEditor(); 393 } 394 395 AttributeType[] ATs = getAttributeTypesAsArray(); 396 for ( AttributeType attributeType : ATs ) 397 { 398 attributeType.closeAssociatedEditor(); 399 } 400 } 401 402 403 407 private void modified() 408 { 409 this.hasBeenModified = true; 410 } 411 412 413 417 private void saved() 418 { 419 this.hasBeenModified = false; 420 } 421 422 423 427 public void addObjectClass( ObjectClass oc ) 428 { 429 for ( String alias : oc.getNames() ) 430 objectClassTable.put( alias, oc ); 431 oc.addListener( this ); 432 this.modified(); 433 notifyChanged( LDAPModelEvent.Reason.OCAdded, null, oc ); 434 } 435 436 437 441 public void addAttributeType( AttributeType at ) 442 { 443 for ( String alias : at.getNames() ) 444 attributeTypeTable.put( alias, at ); 445 at.addListener( this ); 446 this.modified(); 447 notifyChanged( LDAPModelEvent.Reason.ATAdded, null, at ); 448 } 449 450 451 455 public void removeObjectClass( ObjectClass oc ) 456 { 457 for ( String alias : oc.getNames() ) 458 objectClassTable.remove( alias ); 459 oc.removeListener( this ); 460 this.modified(); 461 notifyChanged( LDAPModelEvent.Reason.OCRemoved, oc, null ); 462 } 463 464 465 469 public void removeAttributeType( AttributeType at ) 470 { 471 for ( String alias : at.getNames() ) 472 attributeTypeTable.remove( alias ); 473 at.removeListener( this ); 474 this.modified(); 475 notifyChanged( LDAPModelEvent.Reason.ATRemoved, at, null ); 476 } 477 478 479 482 483 489 public void read() throws IOException , ParseException 490 { 491 SchemaParser parser = null; 492 parser = SchemaParser.parserFromURL( url ); 493 494 if ( parser == null ) 495 throw new FileNotFoundException ( "Schema model object: no path or url specified !" ); 497 parser.parse(); 498 499 ObjectClassLiteral[] objectClasses = parser.getObjectClasses(); 500 AttributeTypeLiteral[] attributeTypes = parser.getAttributeTypes(); 501 502 for ( AttributeTypeLiteral literal : attributeTypes ) 503 { 504 AttributeType AT = new AttributeType( literal, this ); 505 AT.addListener( this ); 506 for ( String alias : literal.getNames() ) 507 attributeTypeTable.put( alias, AT ); 508 } 509 510 for ( ObjectClassLiteral literal : objectClasses ) 511 { 512 ObjectClass OC = new ObjectClass( literal, this ); 513 OC.addListener( this ); 514 for ( String alias : literal.getNames() ) 515 objectClassTable.put( alias, OC ); 516 } 517 518 this.saved(); 521 } 522 523 524 528 public void save() throws Exception 529 { 530 save( false ); 531 } 532 533 534 539 public void save( boolean askForConfirmation ) throws Exception 540 { 541 if ( this.type == SchemaType.coreSchema ) 542 return; 543 544 if ( this.hasPendingModification() ) 545 { 546 MessageBox messageBox = new MessageBox( PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), 547 SWT.YES | SWT.NO | SWT.ICON_QUESTION ); 548 messageBox 549 .setMessage( Messages.getString( "Schema.The_schema" ) + this.getName() + Messages.getString( "Schema.Has_pending_modifications_in_editors_Do_you_want_to_apply_them" ) ); if ( messageBox.open() == SWT.YES ) 551 { 552 this.applyPendingModifications(); 553 } 554 else 555 { 556 this.closeAssociatedEditors(); 557 } 558 } 559 560 if ( !this.hasBeenModified() ) 561 return; 562 563 if ( askForConfirmation ) 564 { 565 MessageBox messageBox = new MessageBox( new Shell(), SWT.YES | SWT.NO | SWT.ICON_QUESTION ); 566 messageBox 567 .setMessage( Messages.getString( "Schema.The_schema" ) + this.getName() + Messages.getString( "Schema.Has_been_modified_Do_you_want_to_save_it" ) ); if ( messageBox.open() != SWT.YES ) 569 { 570 return; 571 } 572 } 573 574 String savePath = null; 575 576 if ( this.url == null ) 577 { 578 FileDialog fd = new FileDialog( new Shell(), SWT.SAVE ); 579 fd.setText( Messages.getString( "Schema.Save_this_schema" ) + this.getName() ); fd.setFilterPath( Activator.getDefault().getPreferenceStore().getString( 581 PluginConstants.PREFS_SAVE_FILE_DIALOG ) ); 582 fd.setFileName( this.name + ".schema" ); fd.setFilterExtensions( new String [] 584 { "*.schema", "*.*" } ); fd.setFilterNames( new String [] 586 { Messages.getString( "Schema.Schema_files" ), Messages.getString( "Schema.All_files" ) } ); savePath = fd.open(); 588 if ( savePath != null ) 590 this.url = localPathToURL( savePath ); 591 } 592 else 593 savePath = url.getPath(); 594 595 if ( savePath != null ) 596 { 597 write( savePath ); 598 this.saved(); 600 notifyChanged( LDAPModelEvent.Reason.SchemaSaved, this, null ); 601 Activator.getDefault().getPreferenceStore().putValue( PluginConstants.PREFS_SAVE_FILE_DIALOG, 602 new File ( savePath ).getParent() ); 603 } 604 } 605 606 607 611 public void saveas() throws Exception 612 { 613 if ( this.hasPendingModification() ) 614 { 615 MessageBox messageBox = new MessageBox( PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), 616 SWT.YES | SWT.NO | SWT.ICON_QUESTION ); 617 messageBox 618 .setMessage( Messages.getString( "Schema.The_schema" ) + this.getName() + Messages.getString( "Schema.Has_pending_modifications_in_editors_Do_you_want_to_apply_them" ) ); if ( messageBox.open() == SWT.YES ) 620 { 621 this.applyPendingModifications(); 622 } 623 } 624 625 FileDialog fd = new FileDialog( PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell(), SWT.SAVE ); 626 fd.setText( Messages.getString( "Schema.Save_this_schema" ) + this.getName() ); fd.setFilterPath( Activator.getDefault().getPreferenceStore() 628 .getString( PluginConstants.PREFS_SAVE_FILE_DIALOG ) ); 629 fd.setFileName( this.name + ".schema" ); fd.setFilterExtensions( new String [] 631 { "*.schema", "*.*" } ); fd.setFilterNames( new String [] 633 { Messages.getString( "Schema.Schema_files" ), Messages.getString( "Schema.All_files" ) } ); String savePath = fd.open(); 635 if ( savePath != null ) 637 { 638 URL newURL = localPathToURL( savePath ); 639 String newName = URLtoFileName( newURL ); 640 if ( newName != null ) 642 { 643 if ( SchemaPool.getInstance().getSchema( newName ) != null ) 644 { 645 MessageBox messageBox = new MessageBox( PlatformUI.getWorkbench().getActiveWorkbenchWindow() 646 .getShell(), SWT.OK | SWT.ICON_ERROR ); 647 messageBox.setMessage( Messages 648 .getString( "Schema.A_schema_of_the_same_name_is_already_loaded_in_the_pool" ) ); messageBox.open(); 650 return; 651 } 652 this.name = newName; 654 this.url = newURL; 655 656 write( savePath ); 657 this.saved(); 659 notifyChanged( LDAPModelEvent.Reason.SchemaSaved, this, null ); 660 Activator.getDefault().getPreferenceStore().putValue( PluginConstants.PREFS_SAVE_FILE_DIALOG, 661 new File ( newName ).getParent() ); 662 } 663 } 664 } 665 666 667 private void write( String path ) throws Exception 668 { 669 if ( path != null && path != "" ) { SchemaWriter writer = new SchemaWriter(); 671 writer.write( this, path ); 672 } 673 } 674 675 676 679 680 public void addListener( SchemaListener listener ) 681 { 682 if ( !listeners.contains( listener ) ) 683 listeners.add( listener ); 684 } 685 686 687 public void removeListener( SchemaListener listener ) 688 { 689 listeners.remove( listener ); 690 } 691 692 693 private void notifyChanged( LDAPModelEvent.Reason reason, Object oldValue, Object newValue ) 694 { 695 for ( SchemaListener listener : listeners ) 696 { 697 try 698 { 699 if ( ( oldValue instanceof ObjectClass ) || ( newValue instanceof ObjectClass ) ) 700 { 701 listener.schemaChanged( this, new LDAPModelEvent( reason, ( ObjectClass ) oldValue, 702 ( ObjectClass ) newValue ) ); 703 } 704 else if ( ( oldValue instanceof AttributeType ) || ( newValue instanceof AttributeType ) ) 705 { 706 listener.schemaChanged( this, new LDAPModelEvent( reason, ( AttributeType ) oldValue, 707 ( AttributeType ) newValue ) ); 708 } 709 else 710 { 711 listener.schemaChanged( this, new LDAPModelEvent( reason ) ); 712 } 713 } 714 catch ( Exception e ) 715 { 716 logger.debug( "error when notifying listener: " + listener ); } 718 } 719 } 720 721 722 725 726 public void schemaElementChanged( SchemaElement originatingSchemaElement, LDAPModelEvent e ) 727 { 728 this.modified(); 730 731 for ( SchemaListener listener : listeners ) 733 { 734 listener.schemaChanged( this, e ); 735 } 736 } 737 } 738 | Popular Tags |