Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance. Project price only 1 $
You can buy this project and download/modify it how often you want.
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
package org.apache.openjpa.jdbc.schema;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.Reader;
import java.util.Collection;
import java.util.Iterator;
import java.util.LinkedList;
import org.xml.sax.Attributes;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import org.apache.openjpa.jdbc.conf.JDBCConfiguration;
import org.apache.openjpa.jdbc.sql.DBDictionary;
import org.apache.openjpa.lib.meta.SourceTracker;
import org.apache.openjpa.lib.meta.XMLMetaDataParser;
import org.apache.openjpa.lib.util.Localizer;
import org.apache.openjpa.lib.util.Localizer.Message;
import org.apache.openjpa.util.UserException;
/**
* Custom SAX parser used to parse {@link Schema} objects. The parser
* will place all parsed schemas into the current {@link SchemaGroup}, set
* via the {@link #setSchemaGroup} method. This allows parsing of
* multiple files into a single schema group.
* The parser deserializes from the following XML format:
* <!ELEMENT schemas (schema)+>
* <!ELEMENT schema (table|sequence)+>
* <!ATTLIST schema name CDATA #IMPLIED>
* <!ELEMENT table (column|index|pk|fk|unique)+>
* <!ATTLIST table name CDATA #REQUIRED>
* <!ELEMENT column EMPTY>
* <!ATTLIST column name CDATA #REQUIRED>
* <!ATTLIST column type (array|bigint|binary|bit|blob|char|clob
* |date|decimal|distinct|double|float|integer|java_object
* |longvarbinary|longvarchar|null|numeric|other|real|ref|smallint|struct
* |time|timstamp|tinyint|varbinary|varchar) #REQUIRED>
* <!ATTLIST column type-name CDATA #IMPLIED>
* <!ATTLIST column size CDATA #IMPLIED>
* <!ATTLIST column decimal-digits CDATA #IMPLIED>
* <!ATTLIST column not-null (true|false) "false">
* <!ATTLIST column default CDATA #IMPLIED>
* <!ATTLIST column auto-assign (true|false) "false">
* <!ELEMENT index (on)*>
* <!ATTLIST index name CDATA #REQUIRED>
* <!ATTLIST index column CDATA #IMPLIED>
* <!ATTLIST index unique (true|false) "false">
* <!ELEMENT on EMPTY>
* <!ATTLIST on column CDATA #REQUIRED>
* <!ELEMENT pk (on)*> <!ATTLIST pk name CDATA #IMPLIED>
* <!ATTLIST pk column CDATA #IMPLIED>
* <!ELEMENT fk (join)*>
* <!ATTLIST fk name CDATA #IMPLIED>
* <!ATTLIST fk deferred (true|false) "false">
* <!ATTLIST fk column CDATA #IMPLIED>
* <!ATTLIST fk to-table CDATA #REQUIRED>
* <!ATTLIST fk delete-action (cascade|default|restrict|none|null)
* "none">
* <!ATTLIST fk update-action (cascade|default|restrict|none|null)
* "none"> <!ELEMENT unique (on)*>
* <!ATTLIST unique name CDATA #IMPLIED>
* <!ATTLIST unique column CDATA #IMPLIED>
* <!ATTLIST unique deferred (true|false) "false">
* <!ELEMENT join EMPTY>
* <!ATTLIST join column CDATA #IMPLIED>
* <!ATTLIST join value CDATA #IMPLIED>
* <!ATTLIST join to-column CDATA #REQUIRED>
* <!ELEMENT sequence EMPTY>
* <!ATTLIST sequence name CDATA #REQUIRED>
* <!ATTLIST sequence initial-value CDATA #IMPLIED>
* <!ATTLIST sequence increment CDATA #IMPLIED>
* <!ATTLIST sequence allocate CDATA #IMPLIED>
*
* Schema parsers are not threadsafe.
*
* @author Abe White
* @nojavadoc
*/
public class XMLSchemaParser
extends XMLMetaDataParser
implements SchemaParser {
private static final Localizer _loc = Localizer.forPackage
(XMLSchemaParser.class);
private final DBDictionary _dict;
// state for current parse
private SchemaGroup _group = null;
private Schema _schema = null;
private Table _table = null;
private PrimaryKeyInfo _pk = null;
private IndexInfo _index = null;
private UniqueInfo _unq = null;
private ForeignKeyInfo _fk = null;
private boolean _delay = false;
// used to collect info on schema elements before they're resolved
private final Collection _pkInfos = new LinkedList();
private final Collection _indexInfos = new LinkedList();
private final Collection _unqInfos = new LinkedList();
private final Collection _fkInfos = new LinkedList();
/**
* Constructor. Supply configuration.
*/
public XMLSchemaParser(JDBCConfiguration conf) {
_dict = conf.getDBDictionaryInstance();
setLog(conf.getLog(JDBCConfiguration.LOG_SCHEMA));
setParseText(false);
setSuffix(".schema");
}
public boolean getDelayConstraintResolve() {
return _delay;
}
public void setDelayConstraintResolve(boolean delay) {
_delay = delay;
}
public void resolveConstraints() {
resolvePrimaryKeys();
resolveIndexes();
resolveForeignKeys();
resolveUniques();
clearConstraintInfo();
}
/**
* Clear constraint infos.
*/
private void clearConstraintInfo() {
_pkInfos.clear();
_indexInfos.clear();
_fkInfos.clear();
_unqInfos.clear();
}
public SchemaGroup getSchemaGroup() {
if (_group == null)
_group = new SchemaGroup();
return _group;
}
public void setSchemaGroup(SchemaGroup group) {
_group = group;
}
/**
* Parse the schema relating to the given class. The schemas will
* be added to the current schema group.
*/
protected void finish() {
// now resolve pk, idx, fk info
super.finish();
if (!_delay)
resolveConstraints();
}
/**
* Transforms the collected primary key information into actual
* primary keys on the schema tables.
*/
private void resolvePrimaryKeys() {
PrimaryKeyInfo pkInfo;
String colName;
Column col;
for (Iterator itr = _pkInfos.iterator(); itr.hasNext();) {
pkInfo = itr.next();
for (Iterator cols = pkInfo.cols.iterator(); cols.hasNext();) {
colName = cols.next();
col = pkInfo.pk.getTable().getColumn(colName);
if (col == null)
throwUserException(_loc.get("pk-resolve", new Object[]
{ colName, pkInfo.pk.getTable() }));
pkInfo.pk.addColumn(col);
}
}
}
/**
* Transforms the collected index information into actual
* indexes on the schema tables.
*/
private void resolveIndexes() {
IndexInfo indexInfo;
String colName;
Column col;
for (Iterator itr = _indexInfos.iterator(); itr.hasNext();) {
indexInfo = itr.next();
for (Iterator cols = indexInfo.cols.iterator(); cols.hasNext();) {
colName = cols.next();
col = indexInfo.index.getTable().getColumn(colName);
if (col == null)
throwUserException(_loc.get("index-resolve", new Object[]
{ indexInfo.index, colName,
indexInfo.index.getTable() }));
indexInfo.index.addColumn(col);
}
}
}
/**
* Transforms the collected foreign key information into actual
* foreign keys on the schema tables.
*/
private void resolveForeignKeys() {
ForeignKeyInfo fkInfo;
Table toTable;
Column col;
String colName;
Column pkCol;
String pkColName;
PrimaryKey pk;
Iterator pks;
Iterator cols;
for (Iterator itr = _fkInfos.iterator(); itr.hasNext();) {
fkInfo = itr.next();
toTable = _group.findTable(fkInfo.toTable);
if (toTable == null || toTable.getPrimaryKey() == null)
throwUserException(_loc.get("fk-totable", new Object[]
{ fkInfo.fk, fkInfo.toTable, fkInfo.fk.getTable() }));
// check if only one fk column listed using shortcut
pk = toTable.getPrimaryKey();
if (fkInfo.cols.size() == 1 && fkInfo.pks.size() == 0)
fkInfo.pks.add(pk.getColumns()[0].getName());
// make joins
pks = fkInfo.pks.iterator();
for (cols = fkInfo.cols.iterator(); cols.hasNext();) {
colName = (String) cols.next();
col = fkInfo.fk.getTable().getColumn(colName);
if (col == null)
throwUserException(_loc.get("fk-nocol",
fkInfo.fk, colName, fkInfo.fk.getTable()));
pkColName = (String) pks.next();
pkCol = toTable.getColumn(pkColName);
if (pkCol == null)
throwUserException(_loc.get("fk-nopkcol", new Object[]
{ fkInfo.fk, pkColName, toTable,
fkInfo.fk.getTable() }));
fkInfo.fk.join(col, pkCol);
}
// make constant joins
cols = fkInfo.constCols.iterator();
for (Iterator