📄 xmlimporter.java
字号:
package org.garret.perst.impl;
import org.garret.perst.*;
import java.io.*;
import java.util.HashMap;
import java.util.Locale;
import java.util.Date;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.text.ParsePosition;
import java.lang.reflect.Field;
public class XMLImporter {
public XMLImporter(StorageImpl storage, Reader reader) {
this.storage = storage;
scanner = new XMLScanner(reader);
}
public void importDatabase() throws XMLImportException {
if (scanner.scan() != XMLScanner.XML_LT
|| scanner.scan() != XMLScanner.XML_IDENT
|| !scanner.getIdentifier().equals("database"))
{
throwException("No root element");
}
if (scanner.scan() != XMLScanner.XML_IDENT
|| !scanner.getIdentifier().equals("root")
|| scanner.scan() != XMLScanner.XML_EQ
|| scanner.scan() != XMLScanner.XML_SCONST
|| scanner.scan() != XMLScanner.XML_GT)
{
throwException("Database element should have \"root\" attribute");
}
int rootId = 0;
try {
rootId = Integer.parseInt(scanner.getString());
} catch (NumberFormatException x) {
throwException("Incorrect root object specification");
}
idMap = new int[rootId*2];
idMap[rootId] = storage.allocateId();
storage.header.root[1-storage.currIndex].rootObject = idMap[rootId];
XMLElement elem;
int tkn;
while ((tkn = scanner.scan()) == XMLScanner.XML_LT) {
if (scanner.scan() != XMLScanner.XML_IDENT) {
throwException("Element name expected");
}
String elemName = scanner.getIdentifier();
if (elemName.equals("org.garret.perst.impl.Btree")
|| elemName.equals("org.garret.perst.impl.BitIndexImpl")
|| elemName.equals("org.garret.perst.impl.PersistentSet")
|| elemName.equals("org.garret.perst.impl.BtreeFieldIndex")
|| elemName.equals("org.garret.perst.impl.BtreeCompoundIndex")
|| elemName.equals("org.garret.perst.impl.BtreeMultiFieldIndex"))
{
createIndex(elemName);
} else {
createObject(readElement(elemName));
}
}
if (tkn != XMLScanner.XML_LTS
|| scanner.scan() != XMLScanner.XML_IDENT
|| !scanner.getIdentifier().equals("database")
|| scanner.scan() != XMLScanner.XML_GT)
{
throwException("Root element is not closed");
}
}
static class XMLElement {
private XMLElement next;
private XMLElement prev;
private String name;
private HashMap siblings;
private HashMap attributes;
private String svalue;
private long ivalue;
private double rvalue;
private int valueType;
private int counter;
static final int NO_VALUE = 0;
static final int STRING_VALUE = 1;
static final int INT_VALUE = 2;
static final int REAL_VALUE = 3;
static final int NULL_VALUE = 4;
XMLElement(String name) {
this.name = name;
valueType = NO_VALUE;
}
final void addSibling(XMLElement elem) {
if (siblings == null) {
siblings = new HashMap();
}
XMLElement prev = (XMLElement)siblings.get(elem.name);
if (prev != null) {
elem.next = null;
elem.prev = prev.prev;
elem.prev.next = elem;
prev.prev = elem;
prev.counter += 1;
} else {
siblings.put(elem.name, elem);
elem.prev = elem;
elem.counter = 1;
}
}
final void addAttribute(String name, String value) {
if (attributes == null) {
attributes = new HashMap();
}
attributes.put(name, value);
}
final XMLElement getSibling(String name) {
if (siblings != null) {
return (XMLElement)siblings.get(name);
}
return null;
}
final XMLElement getNextSibling() {
return next;
}
final int getCounter() {
return counter;
}
final String getAttribute(String name) {
return attributes != null ? (String)attributes.get(name) : null;
}
final void setIntValue(long val) {
ivalue = val;
valueType = INT_VALUE;
}
final void setRealValue(double val) {
rvalue = val;
valueType = REAL_VALUE;
}
final void setStringValue(String val) {
svalue = val;
valueType = STRING_VALUE;
}
final void setNullValue() {
valueType = NULL_VALUE;
}
final String getStringValue() {
return svalue;
}
final long getIntValue() {
return ivalue;
}
final double getRealValue() {
return rvalue;
}
final boolean isIntValue() {
return valueType == INT_VALUE;
}
final boolean isRealValue() {
return valueType == REAL_VALUE;
}
final boolean isStringValue() {
return valueType == STRING_VALUE;
}
final boolean isNullValue() {
return valueType == NULL_VALUE;
}
}
final String getAttribute(XMLElement elem, String name) throws XMLImportException
{
String value = elem.getAttribute(name);
if (value == null) {
throwException("Attribute " + name + " is not set");
}
return value;
}
final int getIntAttribute(XMLElement elem, String name) throws XMLImportException
{
String value = elem.getAttribute(name);
if (value == null) {
throwException("Attribute " + name + " is not set");
}
try {
return Integer.parseInt(value);
} catch (NumberFormatException x) {
throwException("Attribute " + name + " should has integer value");
}
return -1;
}
final int mapId(int id)
{
int oid = 0;
if (id != 0) {
if (id >= idMap.length) {
int[] newMap = new int[id*2];
System.arraycopy(idMap, 0, newMap, 0, idMap.length);
idMap = newMap;
idMap[id] = oid = storage.allocateId();
} else {
oid = idMap[id];
if (oid == 0) {
idMap[id] = oid = storage.allocateId();
}
}
}
return oid;
}
final int mapType(String signature) throws XMLImportException
{
for (int i = 0; i < ClassDescriptor.signature.length; i++) {
if (ClassDescriptor.signature[i].equals(signature)) {
return i;
}
}
throwException("Bad type");
return -1;
}
final Key createCompoundKey(int[] types, String[] values) throws XMLImportException
{
IPersistent obj;
Date date;
ByteBuffer buf = new ByteBuffer();
int dst = 0;
try {
for (int i = 0; i < types.length; i++) {
String value = values[i];
switch (types[i]) {
case ClassDescriptor.tpBoolean:
buf.extend(dst+1);
buf.arr[dst++] = (byte)(Integer.parseInt(value) != 0 ? 1 : 0);
break;
case ClassDescriptor.tpByte:
buf.extend(dst+1);
buf.arr[dst++] = Byte.parseByte(value);
break;
case ClassDescriptor.tpChar:
buf.extend(dst+2);
Bytes.pack2(buf.arr, dst, (short)Integer.parseInt(value));
dst += 2;
break;
case ClassDescriptor.tpShort:
buf.extend(dst+2);
Bytes.pack2(buf.arr, dst, Short.parseShort(value));
dst += 2;
break;
case ClassDescriptor.tpInt:
case ClassDescriptor.tpEnum:
buf.extend(dst+4);
Bytes.pack4(buf.arr, dst, Integer.parseInt(value));
dst += 4;
break;
case ClassDescriptor.tpObject:
buf.extend(dst+4);
Bytes.pack4(buf.arr, dst, mapId(Integer.parseInt(value)));
dst += 4;
break;
case ClassDescriptor.tpLong:
case ClassDescriptor.tpDate:
buf.extend(dst+8);
Bytes.pack8(buf.arr, dst, Long.parseLong(value));
dst += 8;
break;
case ClassDescriptor.tpFloat:
buf.extend(dst+4);
Bytes.pack4(buf.arr, dst, Float.floatToIntBits(Float.parseFloat(value)));
dst += 4;
break;
case ClassDescriptor.tpDouble:
buf.extend(dst+8);
Bytes.pack8(buf.arr, dst, Double.doubleToLongBits(Double.parseDouble(value)));
dst += 8;
break;
case ClassDescriptor.tpString:
dst = buf.packString(dst, value, storage.encoding);
break;
case ClassDescriptor.tpArrayOfByte:
buf.extend(dst + 4 + (value.length() >>> 1));
Bytes.pack4(buf.arr, dst, value.length() >>> 1);
dst += 4;
for (int j = 0, n = value.length(); j < n; j+=2) {
buf.arr[dst++] = (byte)((getHexValue(value.charAt(j)) << 4)
| getHexValue(value.charAt(j+1)));
}
break;
default:
throwException("Bad key type");
}
}
} catch (NumberFormatException x) {
throwException("Failed to convert key value");
}
return new Key(buf.toArray());
}
final Key createKey(int type, String value) throws XMLImportException
{
try {
Date date;
switch (type) {
case ClassDescriptor.tpBoolean:
return new Key(Integer.parseInt(value) != 0);
case ClassDescriptor.tpByte:
return new Key(Byte.parseByte(value));
case ClassDescriptor.tpChar:
return new Key((char)Integer.parseInt(value));
case ClassDescriptor.tpShort:
return new Key(Short.parseShort(value));
case ClassDescriptor.tpInt:
case ClassDescriptor.tpEnum:
return new Key(Integer.parseInt(value));
case ClassDescriptor.tpObject:
return new Key(new PersistentStub(storage, mapId(Integer.parseInt(value))));
case ClassDescriptor.tpLong:
return new Key(Long.parseLong(value));
case ClassDescriptor.tpFloat:
return new Key(Float.parseFloat(value));
case ClassDescriptor.tpDouble:
return new Key(Double.parseDouble(value));
case ClassDescriptor.tpString:
return new Key(value);
case ClassDescriptor.tpArrayOfByte:
{
byte[] buf = new byte[value.length() >> 1];
for (int i = 0; i < buf.length; i++) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -