/*
* Licensed 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.
*
* Other licenses:
* -----------------------------------------------------------------------------
* Commercial licenses for this work are available. These replace the above
* ASL 2.0 and offer limited warranties, support, maintenance, and commercial
* database integrations.
*
* For more information, please visit: http://www.jooq.org/licenses
*
*
*
*
*
*
*
*
*
*
*
*
*
*/
package org.jooq.util;
import static org.jooq.tools.StringUtils.isBlank;
import static org.jooq.util.xml.jaxb.TableConstraintType.CHECK;
import static org.jooq.util.xml.jaxb.TableConstraintType.FOREIGN_KEY;
import static org.jooq.util.xml.jaxb.TableConstraintType.PRIMARY_KEY;
import static org.jooq.util.xml.jaxb.TableConstraintType.UNIQUE;
import java.io.StringWriter;
import java.util.List;
import javax.xml.bind.JAXB;
import org.jooq.tools.JooqLogger;
import org.jooq.util.xml.jaxb.Column;
import org.jooq.util.xml.jaxb.InformationSchema;
import org.jooq.util.xml.jaxb.KeyColumnUsage;
import org.jooq.util.xml.jaxb.Parameter;
import org.jooq.util.xml.jaxb.ParameterMode;
import org.jooq.util.xml.jaxb.ReferentialConstraint;
import org.jooq.util.xml.jaxb.Routine;
import org.jooq.util.xml.jaxb.RoutineType;
import org.jooq.util.xml.jaxb.Schema;
import org.jooq.util.xml.jaxb.Sequence;
import org.jooq.util.xml.jaxb.Table;
import org.jooq.util.xml.jaxb.TableConstraint;
/**
* @author Lukas Eder
*/
public class XMLGenerator extends AbstractGenerator {
private static final JooqLogger log = JooqLogger.getLogger(XMLGenerator.class);
public XMLGenerator() {
super(Language.XML);
}
@Override
public void generate(Database db) {
logDatabaseParameters(db);
log.info("");
logGenerationRemarks(db);
log.info("");
log.info("----------------------------------------------------------");
TextWriter out = new TextWriter(getStrategy().getFile("information_schema.xml"), targetEncoding);
log.info("");
log.info("Generating XML", out.file().getName());
log.info("==========================================================");
InformationSchema is = new InformationSchema();
for (CatalogDefinition c : db.getCatalogs()) {
String catalogName = c.getOutputName();
for (SchemaDefinition s : c.getSchemata()) {
String schemaName = s.getOutputName();
Schema schema = new Schema();
schema.setCatalogName(catalogName);
schema.setSchemaName(schemaName);
is.getSchemata().add(schema);
for (TableDefinition t : s.getTables()) {
String tableName = t.getOutputName();
Table table = new Table();
table.setTableCatalog(catalogName);
table.setTableSchema(schemaName);
table.setTableName(tableName);
is.getTables().add(table);
for (ColumnDefinition co : t.getColumns()) {
String columnName = co.getOutputName();
DataTypeDefinition type = co.getType();
Column column = new Column();
column.setTableCatalog(catalogName);
column.setTableSchema(schemaName);
column.setTableName(tableName);
column.setColumnName(columnName);
column.setCharacterMaximumLength(type.getLength());
column.setColumnDefault(type.getDefaultValue());
column.setDataType(type.getType());
if (co.isIdentity())
column.setIdentityGeneration("YES");
column.setIsNullable(type.isNullable());
column.setNumericPrecision(type.getPrecision());
column.setNumericScale(type.getScale());
column.setOrdinalPosition(co.getPosition());
is.getColumns().add(column);
}
}
for (UniqueKeyDefinition u : db.getUniqueKeys(s)) {
String constraintName = u.getOutputName();
TableDefinition table = u.getTable();
List<ColumnDefinition> columns = u.getKeyColumns();
TableConstraint constraint = new TableConstraint();
constraint.setConstraintCatalog(catalogName);
constraint.setConstraintSchema(schemaName);
constraint.setConstraintName(constraintName);
constraint.setConstraintType(u.isPrimaryKey() ? PRIMARY_KEY : UNIQUE);
constraint.setTableCatalog(table.getCatalog().getOutputName());
constraint.setTableSchema(table.getSchema().getOutputName());
constraint.setTableName(table.getOutputName());
is.getTableConstraints().add(constraint);
for (int i = 0; i < columns.size(); i++) {
ColumnDefinition column = columns.get(i);
KeyColumnUsage kc = new KeyColumnUsage();
kc.setConstraintCatalog(catalogName);
kc.setConstraintSchema(schemaName);
kc.setConstraintName(constraintName);
kc.setColumnName(column.getOutputName());
kc.setOrdinalPosition(i);
kc.setTableCatalog(table.getCatalog().getOutputName());
kc.setTableSchema(table.getSchema().getOutputName());
kc.setTableName(table.getOutputName());
is.getKeyColumnUsages().add(kc);
}
}
for (ForeignKeyDefinition f : db.getForeignKeys(s)) {
String constraintName = f.getOutputName();
UniqueKeyDefinition referenced = f.getReferencedKey();
TableDefinition table = f.getKeyTable();
List<ColumnDefinition> columns = f.getKeyColumns();
TableConstraint tc = new TableConstraint();
tc.setConstraintCatalog(catalogName);
tc.setConstraintSchema(schemaName);
tc.setConstraintName(constraintName);
tc.setConstraintType(FOREIGN_KEY);
tc.setTableCatalog(table.getCatalog().getOutputName());
tc.setTableSchema(table.getSchema().getOutputName());
tc.setTableName(table.getOutputName());
ReferentialConstraint rc = new ReferentialConstraint();
rc.setConstraintCatalog(catalogName);
rc.setConstraintSchema(schemaName);
rc.setConstraintName(constraintName);
rc.setUniqueConstraintCatalog(referenced.getOutputName());
rc.setUniqueConstraintSchema(referenced.getSchema().getOutputName());
rc.setUniqueConstraintName(referenced.getOutputName());
is.getTableConstraints().add(tc);
is.getReferentialConstraints().add(rc);
for (int i = 0; i < columns.size(); i++) {
ColumnDefinition column = columns.get(i);
KeyColumnUsage kc = new KeyColumnUsage();
kc.setConstraintCatalog(catalogName);
kc.setConstraintSchema(schemaName);
kc.setConstraintName(constraintName);
kc.setColumnName(column.getOutputName());
kc.setOrdinalPosition(i);
kc.setTableCatalog(table.getCatalog().getOutputName());
kc.setTableSchema(table.getSchema().getOutputName());
kc.setTableName(table.getOutputName());
is.getKeyColumnUsages().add(kc);
}
}
for (CheckConstraintDefinition ch : db.getCheckConstraints(s)) {
String constraintName = ch.getOutputName();
TableDefinition table = ch.getTable();
TableConstraint constraint = new TableConstraint();
constraint.setConstraintCatalog(catalogName);
constraint.setConstraintSchema(schemaName);
constraint.setConstraintName(constraintName);
constraint.setConstraintType(CHECK);
constraint.setTableCatalog(table.getCatalog().getOutputName());
constraint.setTableSchema(table.getSchema().getOutputName());
constraint.setTableName(table.getOutputName());
is.getTableConstraints().add(constraint);
}
for (SequenceDefinition se : db.getSequences(s)) {
String sequenceName = se.getOutputName();
DataTypeDefinition type = se.getType();
Sequence sequence = new Sequence();
sequence.setSequenceCatalog(catalogName);
sequence.setSequenceSchema(schemaName);
sequence.setSequenceName(sequenceName);
sequence.setCharacterMaximumLength(type.getLength());
sequence.setDataType(type.getType());
sequence.setNumericPrecision(type.getPrecision());
sequence.setNumericScale(type.getScale());
is.getSequences().add(sequence);
}
for (PackageDefinition pkg : db.getPackages(s))
for (RoutineDefinition r : pkg.getRoutines())
exportRoutine(is, r, catalogName, schemaName);
for (RoutineDefinition r : db.getRoutines(s))
exportRoutine(is, r, catalogName, schemaName);
}
}
StringWriter writer = new StringWriter();
JAXB.marshal(is, writer);
out.print(writer.toString());
out.close();
}
private void exportRoutine(InformationSchema is, RoutineDefinition r, String catalogName, String schemaName) {
String specificName = r.getName() + (isBlank(r.getOverload()) ? "" : "_" + r.getOverload());
Routine routine = new Routine();
routine.setRoutineCatalog(catalogName);
routine.setSpecificCatalog(catalogName);
routine.setRoutineSchema(schemaName);
routine.setSpecificSchema(schemaName);
if (r.getPackage() != null) {
routine.setRoutinePackage(r.getPackage().getName());
routine.setSpecificPackage(r.getPackage().getName());
}
routine.setRoutineName(r.getName());
routine.setSpecificName(specificName);
if (r.getReturnValue() == null) {
routine.setRoutineType(RoutineType.PROCEDURE);
}
else {
routine.setRoutineType(RoutineType.FUNCTION);
routine.setDataType(r.getReturnType().getType());
routine.setCharacterMaximumLength(r.getReturnType().getLength());
routine.setNumericPrecision(r.getReturnType().getPrecision());
routine.setNumericScale(r.getReturnType().getScale());
}
is.getRoutines().add(routine);
int i = 1;
for (ParameterDefinition p : r.getAllParameters()) {
if (p != r.getReturnValue()) {
Parameter parameter = new Parameter();
parameter.setSpecificCatalog(catalogName);
parameter.setSpecificSchema(schemaName);
if (r.getPackage() != null)
parameter.setSpecificPackage(r.getPackage().getName());
parameter.setSpecificName(specificName);
parameter.setOrdinalPosition(i++);
parameter.setParameterName(p.getName());
boolean in = r.getInParameters().contains(p);
boolean out = r.getOutParameters().contains(p);
if (in && out)
parameter.setParameterMode(ParameterMode.INOUT);
else if (in)
parameter.setParameterMode(ParameterMode.IN);
else if (out)
parameter.setParameterMode(ParameterMode.OUT);
parameter.setDataType(p.getType().getType());
parameter.setCharacterMaximumLength(p.getType().getLength());
parameter.setNumericPrecision(p.getType().getPrecision());
parameter.setNumericScale(p.getType().getScale());
parameter.setParameterDefault(p.getType().getDefaultValue());
is.getParameters().add(parameter);
}
}
}
}