View Javadoc
1 package com.bonevich.erj.app; 2 3 import com.bonevich.erj.model.Schema; 4 import com.bonevich.erj.model.ModelElement; 5 import com.bonevich.erj.model.ModelElementTraverser; 6 import com.bonevich.erj.ErjConstants; 7 import com.bonevich.erj.db.*; 8 import com.bonevich.erj.diagram.ERDiagram; 9 10 import com.bonevich.util.Functor; 11 import com.bonevich.util.dependency.Dynamic; 12 import com.bonevich.java.util.ImmutableIterator; 13 14 import org.tigris.gef.base.*; 15 16 import java.util.*; 17 import java.util.zip.*; 18 import java.io.*; 19 import java.beans.PropertyChangeEvent; 20 import java.beans.PropertyChangeListener; 21 22 public final class Project implements PropertyChangeListener, ErjConstants 23 { 24 ////////////////////////////////////////////////////////// 25 // Constants 26 private static final String FILE_EXTENSION_STR = ".zerj"; 27 28 ////////////////////////////////////////////////////////// 29 // Attributes 30 private String _name; 31 private String _author = EMPTY_STR; 32 private String _version = EMPTY_STR; 33 private String _description = EMPTY_STR; 34 35 private Application _parentApp; 36 private DatabaseLogin _targetDatabase; 37 38 private transient String _filepath = EMPTY_STR; 39 private transient boolean _modified = false; 40 private transient boolean _new = false; 41 42 private Schema _model; 43 private HashMap _modelRegistry; 44 45 private List _diagrams = new ArrayList(); // of Diagram instances 46 private int _diagramCount = 0; 47 48 private ProjectComponents _components = new ProjectComponents(); 49 50 ////////////////////////////////////////////////////////// 51 // Dynamic sentries 52 private Dynamic _dyn_name = new Dynamic(); 53 private Dynamic _dyn_diagrams = new Dynamic(); 54 private Dynamic _dyn_modified = new Dynamic(); 55 56 ////////////////////////////////////////////////////////// 57 // Constructors 58 /*** 59 * Prevent instantiation by anyone but me. 60 */ 61 protected Project(Application app) 62 { 63 _parentApp = app; 64 _components.addComponent(new ProjectProperties(this)); 65 } 66 67 ////////////////////////////////////////////////////////// 68 // Operations 69 70 // Vector cuz JList wants it that way 71 public Vector getComponents() 72 { 73 return _components.getComponents(); 74 } 75 76 public void addComponent(ProjectComponent cmp) 77 { 78 _components.addComponent(cmp); 79 } 80 81 /*** 82 * Returns an instance of one of the well-known project component types. 83 */ 84 public ProjectComponent createComponent(String type) 85 { 86 // FIXME: setup a ProjectComponentFactory class 87 ProjectComponent newCmp = null; 88 if (ProjectComponent.ERJ.equals(type)) 89 { 90 newCmp = new ProjectProperties(this); 91 } 92 else if (ProjectComponent.XMI.equals(type)) 93 { 94 _model = new Schema(); 95 newCmp = new ProjectModel(this, _model); 96 initModelRegistry(); 97 } 98 else if (ProjectComponent.SVG.equals(type)) 99 { 100 newCmp = new ProjectDiagram(this, null); 101 } 102 //System.err.println("newCmp = " + newCmp); 103 addComponent(newCmp); 104 return newCmp; 105 } 106 107 public void createDiagram() 108 { 109 ERDiagram d = new ERDiagram(_model); 110 try 111 { 112 d.setName("diagram_" + (++_diagramCount)); 113 } 114 catch (Exception e) {} 115 116 ProjectDiagram cmp = new ProjectDiagram(this, d); 117 addComponent(cmp); 118 addDiagram(d); 119 } 120 121 /*** 122 * Needed by ProjectDiagram during loading, but should not be 123 * utilized by anyone else. 124 */ 125 protected void addDiagram(Diagram d) 126 { 127 if (!_diagrams.contains(d)) 128 { 129 _dyn_diagrams.onSet(); 130 _diagrams.add(d); 131 setModified(true); 132 } 133 } 134 135 public void removeDiagram(Diagram d) 136 { 137 if (_diagrams.remove(d)) 138 { 139 _dyn_diagrams.onSet(); 140 _components.removeDiagramComponent(d); 141 setModified(true); 142 } 143 } 144 145 public Iterator getDiagramIterator() 146 { 147 _dyn_diagrams.onGet(); 148 return new ImmutableIterator(_diagrams.iterator()); 149 } 150 151 public Schema getModel() 152 { 153 return _model; 154 } 155 156 public void setModel(Schema model) 157 { 158 _model = model; 159 initModelRegistry(); 160 addComponent(new ProjectModel(this, _model)); 161 } 162 163 /*** 164 * Provides a map of model elements owned by the model schema. 165 */ 166 protected HashMap getModelRegistry() 167 { 168 return _modelRegistry; 169 } 170 private void initModelRegistry() 171 { 172 if (_model != null) 173 { 174 _modelRegistry = new HashMap(); 175 176 // key = {{ModelElement instance class name}}:{{ModelElement instance identifier value}} 177 // value = {{ModelElement instance}} 178 ModelElementTraverser traverser = new ModelElementTraverser 179 ( 180 new Functor() 181 { 182 public Object function(Object arg) 183 { 184 ModelElement me = (ModelElement) arg; 185 String key = me.getOclReferenceId(); 186 _modelRegistry.put(key, me); 187 return key; 188 } 189 } 190 ); 191 traverser.traverse(_model); 192 } 193 } 194 195 public String getName() 196 { 197 _dyn_name.onGet(); 198 return _name; 199 } 200 public void setName(String name) 201 { 202 if (!name.equals(_name)) 203 { 204 _dyn_name.onSet(); 205 _name = name; 206 setModified(true); 207 } 208 } 209 210 public String getDescription() 211 { 212 return _description; 213 } 214 public void setDescription(String description) 215 { 216 if (!description.equals(_description)) 217 { 218 _description = description; 219 setModified(true); 220 } 221 } 222 223 public String getAuthor() 224 { 225 return _author; 226 } 227 public void setAuthor(String author) 228 { 229 if (!author.equals(_author)) 230 { 231 _author = author; 232 setModified(true); 233 } 234 } 235 236 public String getVersion() 237 { 238 return _version; 239 } 240 public void setVersion(String version) 241 { 242 if (!version.equals(_version)) 243 { 244 _version = version; 245 setModified(true); 246 } 247 } 248 249 public String getFilepath() 250 { 251 return _filepath; 252 } 253 public void setFilepath(String filepath) 254 { 255 if (filepath.endsWith(FILE_EXTENSION_STR)) 256 { 257 _filepath = filepath; 258 } 259 else 260 { 261 _filepath = filepath + FILE_EXTENSION_STR; 262 } 263 264 if (_name == null || EMPTY_STR.equals(_name)) 265 { 266 int nameIdx = _filepath.lastIndexOf(System.getProperty("file.separator")); 267 int dotIdx = _filepath.lastIndexOf('.'); 268 if (nameIdx < 0) nameIdx = 0; 269 if (dotIdx < 0) dotIdx = _filepath.length(); 270 setName(_filepath.substring(nameIdx + 1, dotIdx)); 271 } 272 } 273 274 public DatabaseLogin getTargetDatabase() 275 { 276 return _targetDatabase; 277 } 278 public void setTargetDatabase(DatabaseLogin targetDatabase) 279 { 280 _targetDatabase = targetDatabase; 281 setModified(true); 282 } 283 284 public DatabaseLogin createDatabaseLogin(String dbName) 285 { 286 SupportedDatabase db = _parentApp.getSupportedDatabase(dbName); 287 DatabaseLogin newLogin = db.createDatabaseLogin(); 288 setTargetDatabase(newLogin); 289 return newLogin; 290 } 291 292 public Application getParent() 293 { 294 return _parentApp; 295 } 296 297 public void load() 298 { 299 Globals.showStatus("Loading project from " + _filepath + "..."); 300 301 // Load the properties file first - this sets up all the other 302 // components 303 ProjectComponent cmp = _components.getPropertiesComponent(); 304 loadComponent(cmp, cmp.getEntryExtension()); 305 306 cmp = _components.getModelComponent(); 307 // FIXME: cmp could be null! 308 loadComponent(cmp, cmp.getEntryFilename()); 309 _model = ((ProjectModel) cmp).getModel(); 310 initModelRegistry(); 311 312 Iterator diagrams = _components.getDiagramComponentIterator(); 313 while (diagrams.hasNext()) 314 { 315 cmp = (ProjectDiagram) diagrams.next(); 316 loadComponent(cmp, cmp.getEntryFilename()); 317 } 318 319 Globals.showStatus("Project " + _name + " loaded"); 320 321 //loaded projects are never marked as new! 322 setModified(false); 323 _new = false; 324 } 325 326 private void loadComponent(ProjectComponent cmp, String targetPattern) 327 { 328 try 329 { 330 File file = new File(_filepath); 331 ZipInputStream zis = new ZipInputStream(new FileInputStream(file)); 332 String entryName = zis.getNextEntry().getName(); 333 while (!entryName.endsWith(targetPattern)) 334 { 335 ZipEntry next = zis.getNextEntry(); 336 if (next != null) 337 { 338 entryName = next.getName(); 339 } 340 else 341 { 342 break; 343 } 344 } 345 //System.err.println("entryName = " + entryName); 346 //System.err.println("targetPattern = " + targetPattern); 347 cmp.load(zis); 348 zis.close(); 349 } 350 catch (FileNotFoundException e) 351 { 352 e.printStackTrace(); 353 Globals.showStatus("ERROR loading project " + _name); 354 } 355 catch (IOException e) 356 { 357 e.printStackTrace(); 358 Globals.showStatus("ERROR loading project " + _name); 359 } 360 } 361 362 public void save() 363 { 364 try 365 { 366 Globals.showStatus("Saving project to " + _filepath + "..."); 367 368 File file = new File(_filepath); 369 ZipOutputStream zos = new ZipOutputStream(new FileOutputStream(file)); 370 371 // save the components of this project 372 _components.prepareForSave(); 373 Iterator itr = _components.iterator(); 374 while (itr.hasNext()) 375 { 376 ProjectComponent pc = (ProjectComponent) itr.next(); 377 378 System.err.println("saving component as " + pc.getEntryFilename()); 379 ZipEntry cmpEntry = new ZipEntry(pc.getEntryFilename()); 380 zos.putNextEntry(cmpEntry); 381 382 pc.save(zos); 383 384 zos.closeEntry(); 385 } 386 zos.close(); 387 388 Globals.showStatus("Project " + _name + " saved"); 389 390 setModified(false); 391 _new = false; 392 } 393 catch (FileNotFoundException e) 394 { 395 e.printStackTrace(); 396 Globals.showStatus("ERROR saving project " + _name); 397 } 398 catch (IOException e) 399 { 400 e.printStackTrace(); 401 Globals.showStatus("ERROR saving project " + _name); 402 } 403 } 404 405 public void save(String projectFile) 406 { 407 setFilepath(projectFile); 408 save(); 409 } 410 411 public boolean isModified() 412 { 413 _dyn_modified.onGet(); 414 return _modified; 415 } 416 private void setModified(boolean modified) 417 { 418 if (_modified ^ modified) 419 { 420 _dyn_modified.onSet(); 421 _modified = modified; 422 } 423 } 424 425 public void markAsModified() 426 { 427 setModified(true); 428 } 429 430 public boolean isNew() 431 { 432 return _new; 433 } 434 435 public void markAsNew() 436 { 437 _new = true; 438 setModified(false); 439 } 440 441 protected String convertNameToIdentifier() 442 { 443 StringBuffer buf = new StringBuffer(); 444 char[] chars = _name.toCharArray(); 445 boolean first = true; 446 for (int i = 0; i < _name.length(); i++) 447 { 448 char chr = Character.toLowerCase(chars[i]); 449 if (first) 450 { 451 if (Character.isUnicodeIdentifierStart(chr)) 452 { 453 buf.append(chr); 454 first = false; 455 } 456 } 457 else 458 { 459 if (Character.isUnicodeIdentifierPart(chr)) 460 { 461 buf.append(chr); 462 } 463 } 464 } 465 466 return buf.toString(); 467 } 468 469 ////////////////////////////////////////////////////////// 470 // PropertyChangeListener implementation 471 472 /*** 473 * Receive diagram property change notification and, if appropriate, 474 * mark the project as modified. 475 */ 476 public void propertyChange(PropertyChangeEvent e) 477 { 478 //System.err.println("propertyChanged: property = " + e.getPropertyName() + 479 // " from " + e.getOldValue() + " to " + e.getNewValue()); 480 // FIXME: for now we always mark modified; be more selective based on 481 // source Fig and/or newVal <> oldVal?? 482 markAsModified(); 483 } 484 485 486 ////////////////////////////////////////////////////////// 487 // Inner Classes 488 class ProjectComponents 489 { 490 private ProjectProperties _propertiesCmp; 491 private ProjectModel _modelCmp; 492 private List _diagramCmps = new LinkedList(); 493 494 public void addComponent(ProjectComponent cmp) 495 { 496 if (cmp == null) return; 497 if (cmp instanceof ProjectProperties) _propertiesCmp = (ProjectProperties) cmp; 498 else if (cmp instanceof ProjectModel) _modelCmp = (ProjectModel) cmp; 499 else if (cmp instanceof ProjectDiagram) _diagramCmps.add(cmp); 500 } 501 502 public Vector getComponents() 503 { 504 Vector tmp = new Vector(); 505 tmp.add(_propertiesCmp); 506 tmp.add(_modelCmp); 507 tmp.addAll(_diagramCmps); 508 return tmp; 509 } 510 511 public ProjectProperties getPropertiesComponent() 512 { 513 return _propertiesCmp; 514 } 515 516 public ProjectModel getModelComponent() 517 { 518 return _modelCmp; 519 } 520 521 public Iterator getDiagramComponentIterator() 522 { 523 return _diagramCmps.iterator(); 524 } 525 526 public void removeDiagramComponent(Diagram d) 527 { 528 Iterator itr = getDiagramComponentIterator(); 529 while (itr.hasNext()) 530 { 531 ProjectDiagram cmp = (ProjectDiagram) itr.next(); 532 if (cmp.getDiagram() == d) 533 { 534 itr.remove(); 535 break; 536 } 537 } 538 } 539 540 public Iterator iterator() 541 { 542 return getComponents().iterator(); 543 } 544 545 public void prepareForSave() 546 { 547 _propertiesCmp.initEntryFilename(); 548 _modelCmp.initEntryFilename(); 549 Iterator diagrams = _diagramCmps.iterator(); 550 while (diagrams.hasNext()) 551 { 552 ((ProjectComponent) diagrams.next()).initEntryFilename(); 553 } 554 } 555 556 } /* end inner class ProjectComponents */ 557 558 } /* end class Project */

This page was automatically generated by Maven