📄 xmlimporter.java
字号:
buf[i] = (byte)((getHexValue(value.charAt(i*2)) << 4) | getHexValue(value.charAt(i*2+1)));
}
return new Key(buf);
}
case ClassDescriptor.tpDate:
if (value.equals("null")) {
date = null;
} else {
date = httpFormatter.parse(value, new ParsePosition(0));
if (date == null) {
throwException("Invalid date");
}
}
return new Key(date);
default:
throwException("Bad key type");
}
} catch (NumberFormatException x) {
throwException("Failed to convert key value");
}
return null;
}
final int parseInt(String str) throws XMLImportException
{
try {
return Integer.parseInt(str);
} catch (NumberFormatException x) {
throwException("Bad integer constant");
}
return -1;
}
final void createIndex(String indexType) throws XMLImportException
{
Btree btree = null;
int tkn;
int oid = 0;
boolean unique = false;
String className = null;
String fieldName = null;
String[] fieldNames = null;
int[] types = null;
long autoinc = 0;
String type = null;
while ((tkn = scanner.scan()) == XMLScanner.XML_IDENT) {
String attrName = scanner.getIdentifier();
if (scanner.scan() != XMLScanner.XML_EQ || scanner.scan() != XMLScanner.XML_SCONST) {
throwException("Attribute value expected");
}
String attrValue = scanner.getString();
if (attrName.equals("id")) {
oid = mapId(parseInt(attrValue));
} else if (attrName.equals("unique")) {
unique = parseInt(attrValue) != 0;
} else if (attrName.equals("class")) {
className = attrValue;
} else if (attrName.equals("type")) {
type = attrValue;
} else if (attrName.equals("autoinc")) {
autoinc = parseInt(attrValue);
} else if (attrName.equals("field")) {
fieldName = attrValue;
} else if (attrName.startsWith("type")) {
int typeNo = Integer.parseInt(attrName.substring(4));
if (types == null || types.length <= typeNo) {
int[] newTypes = new int[typeNo+1];
if (types != null) {
System.arraycopy(types, 0, newTypes, 0, types.length);
}
types = newTypes;
}
types[typeNo] = mapType(attrValue);
} else if (attrName.startsWith("field")) {
int fieldNo = Integer.parseInt(attrName.substring(5));
if (fieldNames == null || fieldNames.length <= fieldNo) {
String[] newFieldNames = new String[fieldNo+1];
if (fieldNames != null) {
System.arraycopy(fieldNames, 0, newFieldNames, 0, fieldNames.length);
}
fieldNames = newFieldNames;
}
fieldNames[fieldNo] = attrValue;
}
}
if (tkn != XMLScanner.XML_GT) {
throwException("Unclosed element tag");
}
if (oid == 0) {
throwException("ID is not specified or index");
}
if (className != null) {
Class cls = ClassDescriptor.loadClass(storage, className);
if (fieldName != null) {
btree = new BtreeFieldIndex(cls, fieldName, unique, autoinc);
} else if (fieldNames != null) {
btree = new BtreeMultiFieldIndex(cls, fieldNames, unique);
} else {
throwException("Field name is not specified for field index");
}
} else {
if (types != null) {
btree = new BtreeCompoundIndex(types, unique);
} else if (type == null) {
if (indexType.equals("org.garret.perst.impl.PersistentSet")) {
btree = new PersistentSet();
} else {
throwException("Key type is not specified for index");
}
} else {
if (indexType.equals("org.garret.perst.impl.BitIndexImpl")) {
btree = new BitIndexImpl();
} else {
btree = new Btree(mapType(type), unique);
}
}
}
storage.assignOid(btree, oid);
while ((tkn = scanner.scan()) == XMLScanner.XML_LT) {
if (scanner.scan() != XMLScanner.XML_IDENT
|| !scanner.getIdentifier().equals("ref"))
{
throwException("<ref> element expected");
}
XMLElement ref = readElement("ref");
Key key = null;
int mask = 0;
if (fieldNames != null) {
String[] values = new String[fieldNames.length];
for (int i = 0; i < values.length; i++) {
values[i] = getAttribute(ref, "key"+i);
}
key = createCompoundKey(((BtreeMultiFieldIndex)btree).types, values);
} else if (types != null) {
String[] values = new String[types.length];
for (int i = 0; i < values.length; i++) {
values[i] = getAttribute(ref, "key"+i);
}
key = createCompoundKey(types, values);
} else {
if (btree instanceof BitIndex) {
mask = getIntAttribute(ref, "key");
} else {
key = createKey(btree.type, getAttribute(ref, "key"));
}
}
IPersistent obj = new PersistentStub(storage, mapId(getIntAttribute(ref, "id")));
if (btree instanceof BitIndex) {
((BitIndex)btree).put(obj, mask);
} else {
btree.insert(key, obj, false);
}
}
if (tkn != XMLScanner.XML_LTS
|| scanner.scan() != XMLScanner.XML_IDENT
|| !scanner.getIdentifier().equals(indexType)
|| scanner.scan() != XMLScanner.XML_GT)
{
throwException("Element is not closed");
}
byte[] data = storage.packObject(btree, false);
int size = ObjectHeader.getSize(data, 0);
long pos = storage.allocate(size, 0);
storage.setPos(oid, pos | StorageImpl.dbModifiedFlag);
storage.pool.put(pos & ~StorageImpl.dbFlagsMask, data, size);
}
final void createObject(XMLElement elem) throws XMLImportException
{
Class cls = ClassDescriptor.loadClass(storage, elem.name);
ClassDescriptor desc = storage.getClassDescriptor(cls);
int oid = mapId(getIntAttribute(elem, "id"));
ByteBuffer buf = new ByteBuffer();
int offs = ObjectHeader.sizeof;
buf.extend(offs);
offs = packObject(elem, desc, offs, buf);
ObjectHeader.setSize(buf.arr, 0, offs);
ObjectHeader.setType(buf.arr, 0, desc.getOid());
long pos = storage.allocate(offs, 0);
storage.setPos(oid, pos | StorageImpl.dbModifiedFlag);
storage.pool.put(pos, buf.arr, offs);
}
final int getHexValue(char ch) throws XMLImportException
{
if (ch >= '0' && ch <= '9') {
return ch - '0';
} else if (ch >= 'A' && ch <= 'F') {
return ch - 'A' + 10;
} else if (ch >= 'a' && ch <= 'f') {
return ch - 'a' + 10;
} else {
throwException("Bad hexadecimal constant");
}
return -1;
}
final int importBinary(XMLElement elem, int offs, ByteBuffer buf, String fieldName)
throws XMLImportException
{
if (elem == null || elem.isNullValue()) {
buf.extend(offs + 4);
Bytes.pack4(buf.arr, offs, -1);
offs += 4;
} else if (elem.isStringValue()) {
String hexStr = elem.getStringValue();
int len = hexStr.length();
if (hexStr.startsWith("#")) {
buf.extend(offs + 4 + len/2-1);
Bytes.pack4(buf.arr, offs, -2-getHexValue(hexStr.charAt(1)));
offs += 4;
for (int j = 2; j < len; j += 2) {
buf.arr[offs++] = (byte)((getHexValue(hexStr.charAt(j)) << 4) | getHexValue(hexStr.charAt(j+1)));
}
} else {
buf.extend(offs + 4 + len/2);
Bytes.pack4(buf.arr, offs, len/2);
offs += 4;
for (int j = 0; j < len; j += 2) {
buf.arr[offs++] = (byte)((getHexValue(hexStr.charAt(j)) << 4) | getHexValue(hexStr.charAt(j+1)));
}
}
} else {
XMLElement ref = elem.getSibling("ref");
if (ref != null) {
buf.extend(offs + 4);
Bytes.pack4(buf.arr, offs, mapId(getIntAttribute(ref, "id")));
offs += 4;
} else {
XMLElement item = elem.getSibling("element");
int len = (item == null) ? 0 : item.getCounter();
buf.extend(offs + 4 + len);
Bytes.pack4(buf.arr, offs, len);
offs += 4;
while (--len >= 0) {
if (item.isIntValue()) {
buf.arr[offs] = (byte)item.getIntValue();
} else if (item.isRealValue()) {
buf.arr[offs] = (byte)item.getRealValue();
} else {
throwException("Conversion for field " + fieldName + " is not possible");
}
item = item.getNextSibling();
offs += 1;
}
}
}
return offs;
}
final int packObject(XMLElement objElem, ClassDescriptor desc, int offs, ByteBuffer buf)
throws XMLImportException
{
ClassDescriptor.FieldDescriptor[] flds = desc.allFields;
for (int i = 0, n = flds.length; i < n; i++) {
ClassDescriptor.FieldDescriptor fd = flds[i];
String fieldName = fd.fieldName;
XMLElement elem = (objElem != null) ? objElem.getSibling(fieldName) : null;
switch(fd.type) {
case ClassDescriptor.tpByte:
buf.extend(offs + 1);
if (elem != null) {
if (elem.isIntValue()) {
buf.arr[offs] = (byte)elem.getIntValue();
} else if (elem.isRealValue()) {
buf.arr[offs] = (byte)elem.getRealValue();
} else {
throwException("Conversion for field " + fieldName + " is not possible");
}
}
offs += 1;
continue;
case ClassDescriptor.tpBoolean:
buf.extend(offs + 1);
if (elem != null) {
if (elem.isIntValue()) {
buf.arr[offs] = (byte)(elem.getIntValue() != 0 ? 1 : 0);
} else if (elem.isRealValue()) {
buf.arr[offs] = (byte)(elem.getRealValue() != 0.0 ? 1 : 0);
} else {
throwException("Conversion for field " + fieldName + " is not possible");
}
}
offs += 1;
continue;
case ClassDescriptor.tpShort:
case ClassDescriptor.tpChar:
buf.extend(offs + 2);
if (elem != null) {
if (elem.isIntValue()) {
Bytes.pack2(buf.arr, offs, (short)elem.getIntValue());
} else if (elem.isRealValue()) {
Bytes.pack2(buf.arr, offs, (short)elem.getRealValue());
} else {
throwException("Conversion for field " + fieldName + " is not possible");
}
}
offs += 2;
continue;
case ClassDescriptor.tpInt:
buf.extend(offs + 4);
if (elem != null) {
if (elem.isIntValue()) {
Bytes.pack4(buf.arr, offs, (int)elem.getIntValue());
} else if (elem.isRealValue()) {
Bytes.pack4(buf.arr, offs, (int)elem.getRealValue());
} else {
throwException("Conversion for field " + fieldName + " is not possible");
}
}
offs += 4;
continue;
case ClassDescriptor.tpLong:
buf.extend(offs + 8);
if (elem != null) {
if (elem.isIntValue()) {
Bytes.pack8(buf.arr, offs, elem.getIntValue());
} else if (elem.isRealValue()) {
Bytes.pack8(buf.arr, offs, (long)elem.getRealValue());
} else {
throwException("Conversion for field " + fieldName + " is not possible");
}
}
offs += 8;
continue;
case ClassDescriptor.tpFloat:
buf.extend(offs + 4);
if (elem != null) {
if (elem.isIntValue()) {
Bytes.pack4(buf.arr, offs, Float.floatToIntBits((float)elem.getIntValue()));
} else if (elem.isRealValue()) {
Bytes.pack4(buf.arr, offs, Float.floatToIntBits((float)elem.getRealValue()));
} else {
throwException("Conversion for field " + fieldName + " is not possible");
}
}
offs += 4;
continue;
case ClassDescriptor.tpDouble:
buf.extend(offs + 8);
if (elem != null) {
if (elem.isIntValue()) {
Bytes.pack8(buf.arr, offs, Double.doubleToLongBits((double)elem.getIntValue()));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -