| 1 30 package com.genimen.djeneric.repository; 31 32 import java.io.ByteArrayInputStream ; 33 import java.io.ByteArrayOutputStream ; 34 import java.io.InputStream ; 35 import java.io.UnsupportedEncodingException ; 36 import java.security.MessageDigest ; 37 import java.security.NoSuchAlgorithmException ; 38 import java.text.SimpleDateFormat ; 39 import java.util.ArrayList ; 40 import java.util.Arrays ; 41 import java.util.Collections ; 42 import java.util.Date ; 43 import java.util.HashMap ; 44 import java.util.Iterator ; 45 46 import javax.xml.parsers.DocumentBuilder ; 47 import javax.xml.parsers.DocumentBuilderFactory ; 48 import javax.xml.transform.OutputKeys ; 49 import javax.xml.transform.Transformer ; 50 import javax.xml.transform.TransformerException ; 51 import javax.xml.transform.TransformerFactory ; 52 import javax.xml.transform.dom.DOMSource ; 53 import javax.xml.transform.stream.StreamResult ; 54 55 import org.apache.xpath.XPathAPI; 56 import org.w3c.dom.CDATASection ; 57 import org.w3c.dom.Document ; 58 import org.w3c.dom.Element ; 59 import org.w3c.dom.NodeList ; 60 import org.w3c.dom.traversal.NodeIterator; 61 62 import com.genimen.djeneric.language.Messages; 63 import com.genimen.djeneric.repository.exceptions.CatalogException; 64 import com.genimen.djeneric.repository.exceptions.DjenericException; 65 import com.genimen.djeneric.repository.exceptions.LogonException; 66 import com.genimen.djeneric.repository.exceptions.ObjectNotDefinedException; 67 import com.genimen.djeneric.util.DjExtentComparator; 68 import com.genimen.djeneric.util.DjLogger; 69 import com.genimen.djeneric.util.DjProgressDisplayer; 70 import com.genimen.djeneric.util.DjStringComparator; 71 import com.genimen.djeneric.util.DjVersion; 72 73 76 public abstract class DjPersistenceManager implements DjMessenger 77 { 78 79 81 public static final String EMPTY_MODEL_XML_DOC = "<schema></schema>"; 82 private static final String ORG_DJENERIC_DOMAINS = "org.djeneric.domains"; 83 86 public final static String ENCODING_METHOD = "Cp1252"; 87 public final static String LINE_SEPARATOR = System.getProperty("line.separator", "\n"); 88 89 public final static String MAPPING_OBJECT_ID = "object_id"; 90 public final static String MAPPING_STR = "str"; 91 public final static String MAPPING_NUM = "num"; 92 public final static String MAPPING_REL = "rel"; 93 public final static String MAPPING_TXT = "txt"; 94 public final static String MAPPING_LNG = "lng"; 95 public final static String MAPPING_DAT = "dat"; 96 97 public final static int MAPPING_COLUMN_COUNT_STR = 30; 98 public final static int MAPPING_COLUMN_COUNT_NUM = 30; 99 public final static int MAPPING_COLUMN_COUNT_REL = 20; 100 public final static int MAPPING_COLUMN_COUNT_TXT = 20; 101 public final static int MAPPING_COLUMN_COUNT_DAT = 20; 102 public final static int MAPPING_COLUMN_COUNT_LNG = 1; 103 104 public final static int MAPPING_ID_COLUMN_SIZE = 15; 105 public final static String INTERNAL_ID_COLUMN_TYPE = "long"; 106 public final static int MAPPING_STR_MAX = 250; 107 public final static int MAPPING_NUM_MAX = 15; 108 public final static int MAPPING_TXT_MAX = 4000; 109 public final static int MAPPING_LNG_MAX = 99999999; 110 111 public final static int MAX_INTERNAL_CODE_LENGTH = 10; 112 113 public final static String SCHEMA = "schema"; 114 public final static String SCHEMA_HISTORY = "history"; 115 public final static String SCHEMA_VERSION = "version"; 116 public final static String SCHEMA_STRUCTURE_VERSION = "structureversion"; 117 public final static int SCHEMA_STRUCTURE_VERSION_NUMBER = 102; 118 119 public final static String EXTENT_ELEMENT = "extent"; 120 public final static String EXTENT_OBJECT_TYPE = "objecttype"; 121 public final static String EXTENT_NAME = "name"; 122 public final static String EXTENT_SUPER = "super"; 123 public final static String EXTENT_ALIAS = "alias"; 124 public final static String EXTENT_TITLE = "title"; 125 public final static String EXTENT_DESCRIPTOR = "descriptor"; 126 public final static String EXTENT_NAME_SINGULAR = "namesingular"; 127 public final static String EXTENT_NAME_PLURAL = "nameplural"; 128 public final static String EXTENT_LARGE = "large"; 129 public final static String EXTENT_TRANSIENT = "transient"; 130 public final static String EXTENT_PACKAGE = "package"; 131 132 public final static String DESCRIPTION_ELEMENT = "description"; 133 134 public final static String PROPERTY_ELEMENT = "property"; 135 public final static String PROPERTY_NAME = "name"; 136 public final static String PROPERTY_ALIAS = "alias"; 137 public final static String PROPERTY_PROMPT = "prompt"; 138 public final static String PROPERTY_MAPPING = "mapping"; 139 public final static String PROPERTY_TYPE = "type"; 140 public final static String PROPERTY_REQUIRED = "required"; 141 public final static String PROPERTY_SEQ = "seq"; 142 public final static String PROPERTY_SORT_ORDER = "sortorder"; 143 public final static String PROPERTY_QUERYABLE = "queryable"; 144 public final static String PROPERTY_PART_OF_UID = "partofuid"; 145 public final static String PROPERTY_DESCRIPTION = "description"; 146 public final static String PROPERTY_DEFAULT_VALUE = "default"; 147 148 public final static String RELATION_ELEMENT = "relation"; 149 public final static String RELATION_NAME = "name"; 150 public final static String RELATION_RESTRICTION = "restriction"; 151 public final static String RELATION_DESCRIPTION = "description"; 152 public final static String RELATION_MASTEREXTENT = "masterextent"; 153 public final static String RELATION_DETAILPROPERTY = "detailproperty"; 154 public final static String RELATION_TYPE = "type"; 155 public final static String RELATION_UNICITY = "unicity"; 156 public final static String RELATION_TYPE_CONTAINS = "contains"; 157 public final static String RELATION_TYPE_REFERENCES = "references"; 158 159 public final static String DOMAIN_ELEMENT = "domain"; 160 public final static String DOMAIN_NAME = "name"; 161 public final static String DOMAIN_PACKAGE = "package"; 162 public final static String DOMAIN_SUPER = "super"; 163 public final static String DOMAIN_LENGTH = "length"; 164 public final static String DOMAIN_DECIMALS = "decimals"; 165 public final static String DOMAIN_CASE_CONVERSION = "caseconversion"; 166 public final static String DOMAIN_DESCRIPTION = "description"; 167 public final static String DOMAIN_TYPE = "type"; 168 public final static String DOMAIN_COMPONENT = "component"; 169 public final static String DOMAIN_ENFORCE = "enforce"; 170 public final static String DOMAIN_DISPLAY_WIDTH = "displaywidth"; 171 public final static String DOMAIN_DISPLAY_HEIGHT = "displayheight"; 172 public final static String DOMAIN_VALUE_ELEMENT = "domainvalue"; 173 public final static String DOMAIN_VALUE_SEQ = "seq"; 174 public final static String DOMAIN_VALUE_VALUE = "value"; 175 public final static String DOMAIN_VALUE_HIGH = "high"; 176 public final static String DOMAIN_FORMAT_MASK = "format"; 177 public final static String DOMAIN_RE_MASK = "remask"; 178 public final static String DOMAIN_RE_FAIL_MSG = "refailmsg"; 179 public final static String DOMAIN_VALUE_DESCRIPTION = "description"; 180 181 public final static String PACKAGE_ELEMENT = "package"; 182 public final static String PACKAGE_NAME = "name"; 183 184 public final static String ROLE_ELEMENT = "role"; 185 public final static String ROLE_NAME = "name"; 186 187 public final static int TRACE_NOTHING = 0; 188 public final static int TRACE_FLOW = 5; 189 public final static int TRACE_INTERNAL = 10; 190 public final static int TRACE_ALL = 100; 191 192 private DjIdProvider _idProvider = null; 193 private boolean _commitAllowed = true; 194 private boolean _useGlobalContext = false; 195 private boolean _checkReferentialIntegrity = true; 196 private String _originalModel = null; 197 private int _traceLevel = TRACE_NOTHING; 198 private int _schemaStructureVersion = 101; 199 200 DjMessenger _messenger; 201 HashMap _extentsByName; 202 HashMap _extentsByInternalCode; 203 HashMap _extentsByObjectType; 204 HashMap _extentsByQualifiedObjectType; 205 HashMap _extentsUnQualifiedClashed; 206 ArrayList _allExtents; 207 ArrayList _allRoles; 208 209 HashMap _domainsByName; 210 ArrayList _allDomains; 211 HashMap _packagesByName = new HashMap (); 212 ArrayList _allPackages; 213 214 String _djenericUser = null; 215 String _djenericPassword = null; 216 217 String _repositoryUser = null; 218 String _repositoryPassword = null; 219 220 DjContextManager _contextManager = null; 221 DjRepositoryDescriptor _currentRepository; 222 String _modelLoadLog = ""; 223 String _modelHistory = ""; 224 int _modelVersion = 0; 225 SimpleDateFormat _traceTimestampFormatter = new SimpleDateFormat ("yyyy.MM.dd HH:mm:ss"); 226 private static boolean _bannerDisplayed = false; 227 228 static long _internalId = 0; 229 230 238 protected abstract String retrieveModelXml() throws DjenericException; 239 240 248 protected abstract void storeModelXml(String xml) throws DjenericException; 249 250 257 public abstract DjModelView[] getViews() throws DjenericException; 258 259 262 public abstract void close(); 263 264 271 public abstract DjSession createSession() throws DjenericException; 272 273 280 public abstract DjContextManager createContextManager(DjPersistenceManager mgr); 281 282 301 public abstract DjExtent createExtent(String objectType, String name, String alias, String internalCode, 302 String title, String nameSingular, String namePlural); 303 304 309 public abstract DjIdProvider createIdProvider(); 310 311 328 public abstract DjRelation createRelation(String name, DjExtent masterExtent, DjExtent detailExtent, 329 DjProperty detailProperty, boolean isContainedRelation, String description); 330 331 338 public abstract DjModelView createModelView() throws DjenericException; 339 340 346 public abstract void lockModel() throws CatalogException; 347 348 354 public abstract void unlockModel() throws CatalogException; 355 356 362 public abstract void forceUnlockModel() throws CatalogException; 363 364 369 public abstract boolean isModelLocked(); 370 371 378 public abstract String getCurrentLockTag() throws CatalogException; 379 380 386 public abstract void setEstimatedConcurrentSessions(int estimate); 387 388 398 public DjPersistenceManager(DjMessenger messenger, DjRepositoryDescriptor rdesc) 399 400 { 401 if (!_bannerDisplayed) DjLogger.log("Running on Djeneric Persistence Manager version " + DjVersion.getVersion()); 403 _bannerDisplayed = true; 404 setTraceLevel(rdesc.getTraceLevel()); 405 406 if (rdesc.getTraceLevel() != TRACE_NOTHING) 407 { 408 DjLogger.log(Messages.getString("DjPersistenceManager.TraceLevel", String.valueOf(rdesc.getTraceLevel()))); 409 } 410 411 if (messenger == null) _messenger = this; 412 else _messenger = messenger; 413 414 _idProvider = createIdProvider(); 415 _currentRepository = rdesc; 416 _contextManager = createContextManager(this); 417 418 if (rdesc.isSharedConnection()) 420 { 421 _repositoryUser = rdesc.getSharedUser(); 422 _repositoryPassword = rdesc.getSharedPassword(); 423 424 _djenericUser = null; 426 _djenericPassword = null; 427 } 428 else 429 { 430 _repositoryUser = rdesc.getUser(); 431 _repositoryPassword = rdesc.getPassword(); 433 435 _djenericUser = rdesc.getUser(); 436 _djenericPassword = rdesc.getPassword(); 438 } 440 } 441 442 448 public void loadModel() throws DjenericException 449 { 450 String src = retrieveModelXml(); 451 if (src.trim().length() == 0) 452 { 453 src = EMPTY_MODEL_XML_DOC; 454 } 455 456 setOriginalModel(src); 457 rebuildModelDefinition(src); 458 } 459 460 public boolean isModelUpdatedExternally() throws DjenericException 461 { 462 String orgModel = getOriginalModel(); 463 if (orgModel == null) orgModel = ""; 464 465 String src = retrieveModelXml(); 466 if (src == null) src = ""; 467 468 return !src.equals(orgModel); 469 } 470 471 public boolean isModelModified() throws DjenericException 472 { 473 String orgModel = getOriginalModel(); 474 if (orgModel == null) orgModel = ""; 475 476 String src = getModel(); 477 if (src == null) src = ""; 478 479 return !src.equals(orgModel); 480 } 481 482 488 protected void setOriginalModel(String orgModel) 489 { 490 _originalModel = orgModel; 491 } 492 493 498 protected String getOriginalModel() 499 { 500 return _originalModel; 501 } 502 503 508 public int getModelVersion() 509 { 510 return _modelVersion; 511 } 512 513 519 public void setModelVersion(int version) 520 { 521 _modelVersion = version; 522 } 523 524 529 public String getModelHistory() 530 { 531 return _modelHistory; 532 } 533 534 540 public void setModelHistory(String history) 541 { 542 _modelHistory = history; 543 } 544 545 550 public String getSchemaLoadLog() 551 { 552 return _modelLoadLog.trim(); 553 } 554 555 561 public void saveModel() throws DjenericException 562 { 563 validateModel(true); 564 565 String model = getModel(); 568 if (!getOriginalModel().equals(model)) 569 { 570 setModelVersion(getModelVersion() + 1); 571 572 SimpleDateFormat sf = new SimpleDateFormat ("dd-MM-yyyy HH:mm:ss"); 573 574 Date date = new Date (System.currentTimeMillis()); 575 576 String djuser = getDjenericUser(); 577 if (djuser == null) djuser = getRepositoryUser(); 578 579 setModelHistory(Messages.getString("DjPersistenceManager.VersionString", String.valueOf(getModelVersion()), sf 580 .format(date), djuser, getConnectionTitle()) 581 + "\n" + getModelHistory()); 582 model = getModel(); 583 } 584 storeModelXml(model); 585 setOriginalModel(model); 586 } 587 588 596 public void setModel(String modelXml) throws DjenericException 597 { 598 rebuildModelDefinition(modelXml); 599 } 600 601 public void mergeModel(String modelXml, boolean overwriteExisting) throws DjenericException, 602 UnsupportedEncodingException  603 { 604 InputStream is = new ByteArrayInputStream (modelXml.getBytes(ENCODING_METHOD)); 605 mergeModelDefinition(is, overwriteExisting); 606 } 607 608 616 public void setModel(InputStream modelXml) throws DjenericException 617 { 618 rebuildModelDefinition(modelXml); 619 } 620 621 627 public void setCheckReferentialIntegrity(boolean b) 628 { 629 _checkReferentialIntegrity = b; 630 } 631 632 637 public boolean isCheckReferentialIntegrity() 638 { 639 return _checkReferentialIntegrity; 640 } 641 642 648 public void setCurrentContext(DjContext ctxt) 649 { 650 getContextManager().setCurrentContext(ctxt); 651 } 652 653 663 public void setCurrentContext(String ctxt) throws ObjectNotDefinedException, DjenericException 664 { 665 getContextManager().setCurrentContext(ctxt); 666 } 667 668 673 public DjContext getCurrentContext() 674 { 675 return getContextManager().getCurrentContext(); 676 } 677 678 private String nvl(String value) 679 { 680 if (value == null) return ""; 681 return value; 682 } 683 684 public String getModel() throws DjenericException 685 { 686 DjExtent[] extents = getExtents(); 687 DjDomain[] domains = getDomains(); 688 return getModel(extents, domains); 689 } 690 691 public String getModel(DjExtent[] extents) throws DjenericException 692 { 693 DjDomain[] domains = getDomainsUsed(extents); 694 return getModel(extents, domains); 695 } 696 697 public DjDomain[] getDomainsUsed(DjExtent[] extents) 698 { 699 HashMap usedDomains = new HashMap (); 700 for (int i = 0; i < extents.length; i++) 701 { 702 DjProperty[] props = extents[i].getPersonalProperties(); 703 for (int p = 0; p < props.length; p++) 704 { 705 if (props[p].getType() instanceof DjDomain) 706 { 707 DjDomain dom = (DjDomain) props[p].getType(); 708 while (dom != null) 709 { 710 usedDomains.put(dom.getName(), dom); 711 dom = dom.getSuperDomain(); 712 } 713 } 714 } 715 } 716 DjDomain[] domains = new DjDomain[usedDomains.size()]; 717 Iterator it = usedDomains.keySet().iterator(); 718 int i = 0; 719 while (it.hasNext()) 720 domains[i++] = (DjDomain) usedDomains.get(it.next()); 721 return domains; 722 } 723 724 731 public String getModel(DjExtent[] extents, DjDomain[] domains) throws DjenericException 732 { 733 try 734 { 735 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 736 DocumentBuilder builder = factory.newDocumentBuilder(); 737 Document doc = builder.newDocument(); 738 739 Element root = doc.createElement(SCHEMA); 740 root.setAttribute(SCHEMA_STRUCTURE_VERSION, String.valueOf(SCHEMA_STRUCTURE_VERSION_NUMBER)); 741 742 doc.appendChild(root); 743 744 updateModelHistory(doc, root); 745 746 for (int i = 0; i < extents.length; i++) 747 { 748 Element extent = doc.createElement(EXTENT_ELEMENT); 749 750 extent.setAttribute(EXTENT_NAME, extents[i].getName()); 751 if (extents[i].getSuper() != null) extent.setAttribute(EXTENT_SUPER, extents[i].getSuper().getName()); 752 extent.setAttribute(EXTENT_ALIAS, extents[i].getInternalCode()); 753 extent.setAttribute(EXTENT_OBJECT_TYPE, extents[i].getObjectType()); 754 extent.setAttribute(EXTENT_DESCRIPTOR, extents[i].getPersonalDescriptorExpression()); 755 extent.setAttribute(EXTENT_TITLE, extents[i].getTitle()); 756 extent.setAttribute(EXTENT_NAME_SINGULAR, extents[i].getNameSingular()); 757 extent.setAttribute(EXTENT_NAME_PLURAL, extents[i].getNamePlural()); 758 extent.setAttribute(EXTENT_LARGE, String.valueOf(extents[i].isLarge())); 759 extent.setAttribute(EXTENT_TRANSIENT, String.valueOf(extents[i].isTransient())); 760 761 if ((extents[i].getDescription() != null) && (extents[i].getDescription().trim().length() > 0)) 762 { 763 Element descrElem = doc.createElement(DESCRIPTION_ELEMENT); 764 CDATASection descr = doc.createCDATASection(extents[i].getDescription()); 765 descrElem.appendChild(descr); 766 extent.appendChild(descrElem); 767 } 768 769 if (extents[i].getPackage() != null) 770 { 771 extent.setAttribute(EXTENT_PACKAGE, extents[i].getPackage().getName()); 772 } 773 774 root.appendChild(extent); 775 776 DjProperty[] cols = extents[i].getPersonalProperties(); 777 for (int c = 0; c < cols.length; c++) 778 { 779 Element property = doc.createElement(PROPERTY_ELEMENT); 780 781 property.setAttribute(PROPERTY_SEQ, "" + cols[c].getSeq()); 782 property.setAttribute(PROPERTY_NAME, cols[c].getName()); 783 property.setAttribute(PROPERTY_ALIAS, cols[c].getAlias()); 784 property.setAttribute(PROPERTY_MAPPING, cols[c].getMapping()); 785 property.setAttribute(PROPERTY_PROMPT, cols[c].getPrompt()); 786 property.setAttribute(PROPERTY_TYPE, cols[c].getTypeName()); 787 property.setAttribute(PROPERTY_REQUIRED, "" + cols[c].isRequired()); 788 property.setAttribute(PROPERTY_QUERYABLE, "" + cols[c].isQueryable()); 789 property.setAttribute(PROPERTY_PART_OF_UID, "" + cols[c].isPartOfUID()); 790 property.setAttribute(PROPERTY_SORT_ORDER, "" + cols[c].getSortOrder());
|