Project

General

Profile

read-xmlschema.diff

Igor Skornyakov, 11/16/2022 11:57 AM

Download (15.3 KB)

View differences:

src/com/goldencode/p2j/persist/AbstractTempTable.java 2022-11-16 14:15:36 +0000
57 57
**                  delete it instead of handle.delete.
58 58
**     IAS 20221003 Fixed error message for error 3131
59 59
**     IAS 20221111 Added setter for the 'schemaMarshalLevel', fixed one for the 'namespaceURI'.
60
**     IAS 20221116 Added 'buffer()' method.
60 61
*/
61 62

  
62 63
/*
......
1200 1201
      return new handle();
1201 1202
   }
1202 1203
   
1204
   public Iterator<Buffer> buffers()
1205
   {
1206
      return allBuffers.iterator();
1207
   }
1208
   
1203 1209
   /**
1204 1210
    * Get the handle of the after-image table that corresponds to the before-image table
1205 1211
    * currently associated with this temp-table handle.
src/com/goldencode/p2j/persist/serial/XmlImport.java 2022-11-16 14:32:04 +0000
43 43
**     IAS 20220926 Fixed READ-XMLSCHEMA support.
44 44
**     IAS 20221014 More fixes to READ-XMLSCHEMA support.
45 45
**     IAS 20221018 Fixed processing of 'now' and 'today' INITIAL attribute value.
46
**     IAS 20221116 Fixed READ-XMLSCHEMA support for DATASET..
46 47
*/
47 48

  
48 49
/*
......
102 103

  
103 104
import java.io.*;
104 105
import java.lang.reflect.*;
106
import java.nio.file.*;
105 107
import java.util.*;
106 108
import java.util.function.*;
107 109
import java.util.logging.*;
......
177 179
   /** The future name of the read temp-table. */
178 180
   private String ttName = null;
179 181
   
182
   /** The future namesapece prefix of the read temp-table. */
183
   private String ttPrefix = null;
184

  
180 185
   /** The desired mapping of fields to new type, if one is defined. */
181 186
   private final Map<String, String> fieldTypeMapping;
182 187
   
183 188
   /** 'External' schema location, if one is provided. */
184 189
   private final String schemaLocation;
185 190
   
191
   /** Flag indicating that we're reading external schema */
192
   private boolean external = false;
193

  
186 194
   /**
187 195
    * The set of temp-table builders for a dataset. They are mapped by their (XML-) names. They
188 196
    * are collected while parsing the schema and since their indexes are available only at the end
......
1016 1024
   private boolean readDatasetSchema(boolean verify)
1017 1025
   throws XMLStreamException
1018 1026
   {
1027
      Map<String, TempTableBuilder> extenalSchemas = new HashMap<>();
1019 1028
      Relation keyrefRel = null;
1029
      String nsPrefix = null;
1020 1030
      while (reader.hasNext())
1021 1031
      {
1022 1032
         int type = reader.next();
......
1052 1062
                        if (ds._dynamic())
1053 1063
                        {
1054 1064
                           ds.name(datasetName);
1065
                           nsPrefix = getXmlAttribute("prodata:prefix");
1066
                           ds.namespacePrefix(nsPrefix);
1055 1067
                        }
1056 1068
                        // else simply ignore it (?)
1057 1069
                     }
1058 1070
                     else 
1059 1071
                     {
1060 1072
                        String tableName = getXmlAttribute("prodata:tableName");
1073
                        TempTableBuilder ttb = null;
1074
                        String tableRef = null;
1061 1075
                        if (tableName == null)
1062 1076
                        {
1063 1077
                           // if dedicated attribute not found, use the xml name attribute
1064 1078
                           tableName = getXmlAttribute("name");
1065 1079
                        }
1080
                        if (tableName == null)
1081
                        {
1082
                          tableRef = getXmlAttribute("ref");
1083
                          ttb = extenalSchemas.get(tableRef);
1084
                          if (ttb == null)
1085
                          {
1086
                             throw new IllegalStateException("Unknown table reference: [" 
1087
                                                              + tableRef + "]");
1088
                          }
1089
                          tableName = removeNsPrefix(tableRef);
1090
                        }
1066 1091
                        handle buffer = ds.bufferHandle(tableName);
1067 1092
                        if (verifySchemaMode == Verify.STRICT && verify && !buffer._isValid())
1068 1093
                        {
......
1074 1099
                           // Temp-table '<table>' not found in XML Schema
1075 1100
                           return false;
1076 1101
                        }
1077
                        if (!readTableSchema(tableName, null))
1102
                        if (ttb != null)
1103
                        {
1104
                           tables.put(tableName, ttb);
1105
                           String xmlNodeName = ttb.getXmlNodeName().getValue();
1106
                           tablesByXmlName.put(
1107
                                 new CaseInsensitiveString(xmlNodeName == null ? tableName : 
1108
                                                                                 xmlNodeName), 
1109
                                 tableName);
1110
                           
1111
                        }
1112
                        else 
1113
                        {
1114
                           if (!readTableSchema(tableName, null))
1115
                           {
1116
                              return false;
1117
                           }
1118
                        }
1119
                     }
1120
                     break;
1121
                     
1122
                  case "import":
1123
                     if (ds != null)
1124
                     {
1125
                        String schemaLocation = getXmlAttribute("schemaLocation");
1126
                        String extPath = !Serializator.TYPE_FILE.equals(
1127
                                 source.getType().toUpperCase()) ? null : 
1128
                                 Paths.get(source.getFileName()).getParent().toString() + 
1129
                                                                  "/" + schemaLocation;
1130
                        if (extPath == null)
1131
                        {
1132
                           ErrorManager.recordOrThrowError(
1133
                              new int[] {293, 13101, 13032}, 
1134
                              new String[] {
1135
                                 "** \"" + schemaLocation + "\" was not found",
1136
                                 "Unable to load imported or included schema: " + schemaLocation,
1137
                                 "Unable to create Temp-Table or dataset schema from XML Schema"
1138
                              }, 
1139
                              false, false, true);
1140
                        }
1141
                        String ns = getXmlAttribute("namespace");
1142
                        XmlImport ext = new XmlImport(new SourceData("file", extPath), 
1143
                                 null, schemaLocation, false, null, null);
1144
                        ext.external = true;
1145
                        TempTableBuilder ttb = new TempTableBuilder();
1146
                        if (!ext.importTempTableSchema(ttb)) 
1078 1147
                        {
1079 1148
                           return false;
1080 1149
                        }
1150
                        String tableName = ext.ttName;
1151
                        String tableRef = (ext.ttPrefix == null ? "" : 
1152
                                                            ext.ttPrefix + ":") + tableName;
1153
                        extenalSchemas.put(tableRef, ttb);
1081 1154
                     }
1082 1155
                     break;
1083 1156
                     
1084 1157
                  case ELEM_SCHEMA:
1085 1158
                     // check "xmlns:xsd", "xmlns", and "xmlns:prodata" attributes
1159
                     ds.namespaceURI(getXmlAttribute("targetNamespace"));
1086 1160
                     break;
1087 1161
                     
1088 1162
                  case "unique":
......
1090 1164
                     indexName = getXmlAttribute("prodata:indexName");
1091 1165
                     primary = Boolean.parseBoolean(getXmlAttribute("prodata:primaryIndex"));
1092 1166
                     word = Boolean.parseBoolean(getXmlAttribute("prodata:wordIndex"));
1093
                     if (!readIndex(getXmlAttribute("name"), indexName, null, primary, true, word))
1167
                     if (!readIndex(getXmlAttribute("name"), indexName, nsPrefix, primary, true, word))
1094 1168
                     {
1095 1169
                        return false;
1096 1170
                     }
......
1101 1175
                     indexName = getXmlAttribute("prodata:indexName");
1102 1176
                     primary = Boolean.parseBoolean(getXmlAttribute("prodata:primaryIndex"));
1103 1177
                     word = Boolean.parseBoolean(getXmlAttribute("prodata:wordIndex"));
1104
                     if (!readIndex(getXmlAttribute("name"), indexName, null, primary, false, word))
1178
                     if (!readIndex(getXmlAttribute("name"), indexName, nsPrefix, primary, false, word))
1105 1179
                     {
1106 1180
                        return false;
1107 1181
                     }
......
1116 1190
                     
1117 1191
                     // found a relation based on a unique index
1118 1192
                     indexName = getXmlAttribute("refer");
1119
                     P2JIndex uidx = uniqueIndexes.get(indexName);
1193
                     P2JIndex uidx = uniqueIndexes.get(removeNsPrefix(indexName));
1120 1194
                     if (uidx == null)
1121 1195
                     {
1122 1196
                        throw new XMLStreamException(
......
1141 1215
                  case "selector":
1142 1216
                     if (keyrefRel != null)
1143 1217
                     {
1144
                        keyrefRel.setChild(getXmlAttribute("xpath"));
1218
                        keyrefRel.setChild(nsPrefix, getXmlAttribute("xpath"));
1145 1219
                     }
1146 1220
                     
1147 1221
                     // otherwise, it is not related to unique index based relation
......
1150 1224
                  case "field":
1151 1225
                     if (keyrefRel != null)
1152 1226
                     {
1153
                        keyrefRel.addChildField(getXmlAttribute("xpath"));
1227
                        keyrefRel.addChildField(nsPrefix, getXmlAttribute("xpath"));
1154 1228
                     }
1155 1229
                     
1156 1230
                     // otherwise, it is not related to unique index based relation
......
1171 1245
               switch(name)
1172 1246
               {
1173 1247
                  case ELEM_SCHEMA:
1248
                     processDsBuffers();
1174 1249
                     int numTables = ds.numBuffers().intValue();
1175 1250
                     if (verifySchemaMode == Verify.STRICT)
1176 1251
                     {
......
1343 1418
      
1344 1419
      throw new XMLStreamException("Unexpected EOS in readDatasetSchema().", reader.getLocation());
1345 1420
   }
1421

  
1422
   /**
1423
    * Remove the namespace prefix from the qualified name
1424
    * @param  qname
1425
    *         qualified name to be simplified
1426
    * @return name w/o prefix
1427
    */
1428
   private String removeNsPrefix(String qname)
1429
   {
1430
      int pos = qname.indexOf(':');
1431
      return pos > 0 ? qname.substring(pos+1) : qname;
1432
      
1433
   }
1434
   /**
1435
    * Process buffers for the found dataset tables.
1436
    */
1437
   private void processDsBuffers()
1438
   {
1439
      BufferImpl[] dsBuffers = new BufferImpl[tables.size()];
1440
      int nb = 0; 
1441
      for (Map.Entry<String, AbstractTempTable> e: tables.entrySet())
1442
      {
1443
         TempTableBuilder ttb = (TempTableBuilder)e.getValue();
1444
         ttb.tempTablePrepare(e.getKey());
1445
         Iterator<Buffer> ib = ttb.buffers();
1446
         Buffer tbuffer =  ib.hasNext() ? ib.next() : null;
1447
         if (tbuffer != null)
1448
         {
1449
            dsBuffers[nb++] = (BufferImpl)tbuffer;
1450
         }
1451
         ds.setBuffers(dsBuffers);
1452
      }
1453
   }
1346 1454
   
1347 1455
   /**
1348 1456
    * Reads and processes an {@code AbstractTempTable} schema. If the {@code TempTable} is in CLEAR state, the
......
1379 1487
               }
1380 1488
               
1381 1489
               name = reader.getLocalName();
1382
               
1383 1490
               // index properties:
1384 1491
               String indexName = null;
1385 1492
               boolean primary = false;
......
1389 1496
               {
1390 1497
                  case "element":
1391 1498
                     boolean isTT = Boolean.parseBoolean(getXmlAttribute("prodata:proTempTable"));
1392
                     if (isTT) 
1499
                     if (isTT || external) 
1393 1500
                     {
1394 1501
                        String tableName = getXmlAttribute("prodata:tableName");
1395 1502
                        if (tableName == null)
......
1408 1515
                        undo = Boolean.parseBoolean(getXmlAttribute("prodata:undo"));
1409 1516
                        
1410 1517
                        ttName = tableName;
1518
                        ttPrefix = nsPrefix;
1411 1519
                        if (!readTableSchema(tableName, nsPrefix))
1412 1520
                        {
1413 1521
                           return false;
......
1479 1587
                     {
1480 1588
                        ttb.namespaceURI(nsUri);
1481 1589
                     }
1482
                     if (!ttb.tempTablePrepare(ttName).booleanValue())
1590
                     if (!external && !ttb.tempTablePrepare(ttName).booleanValue())
1483 1591
                     {
1484 1592
                        // TODO: report error? already reported? 
1485 1593
                        return false;
......
1561 1669
                        xpath = xpath.substring(3);
1562 1670
                     }
1563 1671
                     
1564
                     if (nsPrefix != null && xpath.startsWith(nsPrefix))
1565
                     {
1566
                        // drop the [nsPrefix], including the COLON, if any
1567
                        xpath = xpath.substring(nsPrefix.length() + 1);
1568
                     }
1672
                     xpath = removeNsPrefix(xpath);
1569 1673
                     
1570 1674
                     if (tablesByXmlName != null)
1571 1675
                     {
......
1600 1704
                     break;
1601 1705
                     
1602 1706
                  case "field":
1603
                     String field = getXmlAttribute(unique ? "xpath" : "name");
1604
                     if (nsPrefix != null && field.startsWith(nsPrefix))
1605
                     {
1606
                        // drop the [nsPrefix], including the COLON, if any
1607
                        field = field.substring(nsPrefix.length() + 1);
1608
                     }
1707
                     String field = removeNsPrefix(getXmlAttribute(unique ? "xpath" : "name"));
1609 1708
                     boolean desc = Boolean.parseBoolean(getXmlAttribute("prodata:descending"));
1610 1709
                     if (ttb != null && !ttb._prepared())
1611 1710
                     {
......
2934 3033
      /**
2935 3034
       * Sets the name of the child buffer. If needed the {@code "..//"} prefix is dropped.
2936 3035
       * 
3036
       * @param   nsPrefix
3037
       *          namespace prefix;
2937 3038
       * @param   xpath
2938 3039
       *          The name of the child buffer, as read from XML.
2939 3040
       */
2940
      public void setChild(String xpath)
3041
      public void setChild(String nsPrefix, String xpath)
2941 3042
      {
2942
         child = xpath.startsWith(".//") ? xpath.substring(3) : xpath; 
3043
         if (xpath.startsWith(".//"))
3044
         {
3045
            xpath = xpath.substring(3);
3046
         }
3047
         if (nsPrefix != null && xpath.startsWith(nsPrefix))
3048
         {
3049
            xpath = xpath.substring(nsPrefix.length() + 1);
3050
         }
3051

  
3052
         child = xpath; 
2943 3053
      }
2944 3054
      
2945 3055
      /**
2946 3056
       * Adds a new field to be used on child side of the relation.
2947
       * 
3057
       * @param   nsPrefix 
3058
       *          namespace prefix
2948 3059
       * @param   field
2949 3060
       *          The name of the field.
2950 3061
       */
2951
      public void addChildField(String field)
3062
      public void addChildField(String nsPrefix, String field)
2952 3063
      {
2953
         childFields.add(field);
3064
         childFields.add(nsPrefix != null && field.startsWith(nsPrefix) ?
3065
                  field.substring(nsPrefix.length() + 1) :
3066
                  field);
2954 3067
      }
2955 3068
      
2956 3069
      /**