H2 2.3.230

This commit is contained in:
Ralf Wisser
2024-07-26 16:37:24 +02:00
parent 9589e3fdf7
commit af81c1d7fc
26 changed files with 1089 additions and 320 deletions

View File

@@ -48,7 +48,7 @@
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<version>2.2.224</version>
<version>2.3.230</version>
</dependency>
<dependency>
<groupId>org.apache.logging.log4j</groupId>

View File

@@ -150,7 +150,7 @@
<span style="color: #000000; font-weight: bold;">new</span> BasicDataSource<span style="color: #009900;">&#40;</span>
<span style="color: #0000ff;">&quot;org.h2.Driver&quot;</span>, <span style="color: #0000ff;">&quot;jdbc:h2:&quot;</span> <span style="color: #339933;">+</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">File</span><span style="color: #009900;">&#40;</span>baseFolder, <span style="color: #0000ff;">&quot;demo-scott-h2&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getAbsolutePath</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #0000ff;">&quot;sa&quot;</span>, <span style="color: #0000ff;">&quot;&quot;</span>,
POOL_SIZE,
<span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">File</span><span style="color: #009900;">&#40;</span>baseFolder, <span style="color: #0000ff;">&quot;lib/h2-2.2.224.jar&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>,
<span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">File</span><span style="color: #009900;">&#40;</span>baseFolder, <span style="color: #0000ff;">&quot;lib/h2-2.3.230.jar&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span>,
<span style="color: #000066; font-weight: bold;">null</span>,
<span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">File</span><span style="color: #009900;">&#40;</span>baseFolder, <span style="color: #0000ff;">&quot;datamodel/Demo-Scott&quot;</span><span style="color: #009900;">&#41;</span>,
<span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">File</span><span style="color: #009900;">&#40;</span>baseFolder, <span style="color: #0000ff;">&quot;extractionmodel/Demo-Scott.jm&quot;</span><span style="color: #009900;">&#41;</span>,
@@ -162,7 +162,7 @@
<span style="color: #000000; font-weight: bold;">new</span> BasicDataSource<span style="color: #009900;">&#40;</span>
<span style="color: #0000ff;">&quot;org.h2.Driver&quot;</span>, <span style="color: #0000ff;">&quot;jdbc:h2:&quot;</span> <span style="color: #339933;">+</span> <span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">File</span><span style="color: #009900;">&#40;</span>baseFolder, <span style="color: #0000ff;">&quot;demo-scott-h2-subset&quot;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getAbsolutePath</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>, <span style="color: #0000ff;">&quot;sa&quot;</span>, <span style="color: #0000ff;">&quot;&quot;</span>,
POOL_SIZE,
<span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">File</span><span style="color: #009900;">&#40;</span>baseFolder, <span style="color: #0000ff;">&quot;lib/h2-2.2.224.jar&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">new</span> <span style="color: #003399;">File</span><span style="color: #009900;">&#40;</span>baseFolder, <span style="color: #0000ff;">&quot;lib/h2-2.3.230.jar&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #008000; font-style: italic; font-weight: bold;">/**
* Exports data related with employee &quot;SCOTT&quot;

Binary file not shown.

BIN
lib/h2-2.3.230.jar Normal file

Binary file not shown.

View File

@@ -45,7 +45,7 @@ public class APIExample {
new BasicDataSource(
"org.h2.Driver", "jdbc:h2:" + new File(baseFolder, "demo-scott-h2").getAbsolutePath(), "sa", "",
POOL_SIZE,
new File(baseFolder, "lib/h2-2.2.224.jar")),
new File(baseFolder, "lib/h2-2.3.230.jar")),
null,
new File(baseFolder, "datamodel/Demo-Scott"),
new File(baseFolder, "extractionmodel/Demo-Scott.jm"),
@@ -57,7 +57,7 @@ public class APIExample {
new BasicDataSource(
"org.h2.Driver", "jdbc:h2:" + new File(baseFolder, "demo-scott-h2-subset").getAbsolutePath(), "sa", "",
POOL_SIZE,
new File(baseFolder, "lib/h2-2.2.224.jar")));
new File(baseFolder, "lib/h2-2.3.230.jar")));
/**
* Exports data related with employee "SCOTT"

View File

@@ -35,7 +35,7 @@ public class LocalDatabaseConfiguration {
private String password = "";
private String driver = "org.h2.Driver";
private String lib = "lib/h2-2.2.224.jar";
private String lib = "lib/h2-2.3.230.jar";
/**
* @return the localPKType

View File

@@ -8,7 +8,7 @@
"user": "",
"password": "",
"driver": "org.h2.Driver",
"lib": "lib/h2-2.2.224.jar"
"lib": "lib/h2-2.3.230.jar"
},
"commentNullColumnPlaceholder": "For DBUnit flat XML files, null columns can carry a placeholder value which can later be replaced using a ReplacementDataSet. In Flat XML files the first row of a table defines the metadata. If a null column is omitted, none of the following rows can have this column! This is the default behaviour of Jailer. Thus, define a null placeholder and replace it with a null value when you load the data set with DBUnit.",

View File

@@ -434,7 +434,9 @@ public class Association extends ModelElement {
String tag;
Set<String> otherNames = null;
if (aggregationTagName == null) {
otherNames = source.associations.stream().map(a -> a.aggregationTagName).filter(t -> t != null).collect(Collectors.toSet());
otherNames = new HashSet<>();
otherNames.addAll(source.associations.stream().map(a -> a.aggregationTagName).filter(t -> t != null).collect(Collectors.toSet()));
otherNames.addAll(source.getColumns().stream().map(c -> c.name.toLowerCase()).collect(Collectors.toSet()));
tag = destination.getUnqualifiedName().toLowerCase(Locale.ENGLISH);
} else {
tag = aggregationTagName;

View File

@@ -405,10 +405,6 @@ public class Table extends ModelElement implements Comparable<Table> {
// TODO should use " as quot-char in GUI
// TODO whatabout MySQL/MariaBD? Requoting? How?
// TODO default-quoting("/caseIns.) + heuristic re-quoting in XmlRowWriter: if content like 'SQL:T."xy"' -> 'SQL:T.<requote('"xy"')
// TODO
// TODO (in ColumnMappinfDialog?)
// TODO if template equals default-template when "ok"-button is clicked: remove template-def in extraction-model.csv (if it is saved afterwards)
}
/**
@@ -421,7 +417,7 @@ public class Table extends ModelElement implements Comparable<Table> {
/**
* Gets template for XML exports as DOM.
*/
private Document getXmlTemplateAsDocument(String xmlTemplate, Quoting quoting) throws ParserConfigurationException, SAXException, IOException {
public Document getXmlTemplateAsDocument(String xmlTemplate, Quoting quoting) throws ParserConfigurationException, SAXException, IOException {
Document template;
if (xmlTemplate == null) {
template = createInitialXmlTemplate(quoting);

View File

@@ -0,0 +1,31 @@
/*
* Copyright 2007 - 2024 Ralf Wisser.
*
* 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.
*/
package net.sf.jailer.subsetting;
/**
* Thrown if something goes wrong when exporting to an XML/JSON/YAML file.
*
* @author Ralf Wisser
*/
public class ObjectNotationOutputException extends RuntimeException {
private static final long serialVersionUID = -3712636626146836549L;
public ObjectNotationOutputException(String message) {
super(message);
}
}

View File

@@ -16,7 +16,7 @@
package net.sf.jailer.subsetting;
/**
* Throws if row limit is exceeded.
* Thrown if row limit is exceeded.
*
* @author Ralf Wisser
*/

View File

@@ -1228,6 +1228,21 @@ public class SubsettingEngine {
} catch (TransformerConfigurationException e) {
throw new RuntimeException(e);
}
sortedTables.sort(new Comparator<Table>() {
@Override
public int compare(Table t1, Table t2) {
boolean s1 = subjects.contains(t1);
boolean s2 = subjects.contains(t2);
if (s1 && !s2) {
return -1;
}
if (!s1 && s2) {
return 1;
}
return 0;
}
});
for (Table table: sortedTables) {
entityGraph.markRoots(table);
@@ -1235,6 +1250,10 @@ public class SubsettingEngine {
for (Table table: sortedTables) {
_log.info("exporting table " + datamodel.getDisplayName(table));
reader.setTable(table);
reader.setTableIsSubject(subjects.contains(table));
if (executionContext.isIgnoreNonAggregated() && !subjects.contains(table)) {
continue;
}
entityGraph.readMarkedEntities(table, reader, reader.getTableMapping(table).selectionSchema, reader.getTableMapping(table).originalPKAliasPrefix, true);
}
reader.endDocument();
@@ -1697,7 +1716,7 @@ public class SubsettingEngine {
datamodel.transpose();
}
if (scriptFile != null && scriptFormat != ScriptFormat.XML && exportStatistic.getTotal() != exportedCount) {
if (scriptFile != null && !scriptFormat.isObjectNotation() && exportStatistic.getTotal() != exportedCount) {
String message =
"The number of rows collected (" + exportStatistic.getTotal() + ") differs from that of the exported ones (" + exportedCount + ").\n" +
"This may have been caused by an invalid primary key definition.\nPlease note that each primary key must be unique.\n" +

View File

@@ -0,0 +1,142 @@
/*
* Copyright 2007 - 2024 Ralf Wisser.
*
* 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.
*/
package net.sf.jailer.xml;
import java.io.IOException;
import java.io.Writer;
import java.math.BigDecimal;
import java.math.BigInteger;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import net.sf.jailer.xml.XmlUtil.ObjectNotationWriter;
/**
* A writer for JSON.
*
* @author Ralf Wisser
*/
public class JSONWriter implements ObjectNotationWriter {
private final JsonGenerator jGen;
public JSONWriter(Writer out) throws IOException {
JsonFactory jfactory = new JsonFactory();
this.jGen = jfactory.createGenerator(out);
this.jGen.useDefaultPrettyPrinter();
}
@Override
public void writeStartObject() throws IOException {
this.jGen.writeStartObject();
}
@Override
public void writeStartArray() throws IOException {
this.jGen.writeStartArray();;
}
@Override
public void writeEndObject() throws IOException {
this.jGen.writeEndObject();;
}
@Override
public void writeEndArray() throws IOException {
this.jGen.writeEndArray();
}
@Override
public void flush() throws IOException {
this.jGen.flush();
}
@Override
public void writeFieldName(String qName) throws IOException {
this.jGen.writeFieldName(qName);
}
@Override
public void writeArrayFieldStart(String qName) throws IOException {
this.jGen.writeArrayFieldStart(qName);
}
@Override
public void writeNull() throws IOException {
this.jGen.writeNull();
}
@Override
public void writeBinary(byte[] content) throws IOException {
this.jGen.writeBinary(content);
}
@Override
public void writeBoolean(Boolean content) throws IOException {
this.jGen.writeBoolean(content);
}
@Override
public void writeNumber(BigInteger content) throws IOException {
this.jGen.writeNumber(content);
}
@Override
public void writeNumber(BigDecimal content) throws IOException {
this.jGen.writeNumber(content);
}
@Override
public void writeNumber(Double content) throws IOException {
this.jGen.writeNumber(content);
}
@Override
public void writeNumber(Float content) throws IOException {
this.jGen.writeNumber(content);
}
@Override
public void writeNumber(Integer content) throws IOException {
this.jGen.writeNumber(content);
}
@Override
public void writeNumber(Long content) throws IOException {
this.jGen.writeNumber(content);
}
@Override
public void writeNumber(Short content) throws IOException {
this.jGen.writeNumber(content);
}
@Override
public void writeString(String string) throws IOException {
this.jGen.writeString(string);
}
@Override
public void writeComment(String comment) throws IOException {
try {
jGen.writeStringField("j:comment", comment + " /j:comment");
} catch (Exception e) {
e.printStackTrace();
// ignore
}
}
}

View File

@@ -44,6 +44,7 @@ import net.sf.jailer.datamodel.Column;
import net.sf.jailer.datamodel.RowIdSupport;
import net.sf.jailer.datamodel.Table;
import net.sf.jailer.entitygraph.EntityGraph;
import net.sf.jailer.subsetting.ObjectNotationOutputException;
import net.sf.jailer.subsetting.ScriptFormat;
import net.sf.jailer.util.CellContentConverter;
import net.sf.jailer.util.Quoting;
@@ -59,7 +60,12 @@ public class XmlExportTransformer extends AbstractResultSetReader {
* The table to read from.
*/
private Table table;
/**
* <code>true</code> iff table is subject.
*/
private boolean tableIsSubject;
/**
* For writing rows as xml.
*/
@@ -114,9 +120,13 @@ public class XmlExportTransformer extends AbstractResultSetReader {
* {@link RowIdSupport}.
*/
private final RowIdSupport rowIdSupport;
private final ExecutionContext executionContext;
private final Quoting quoting;
private ScriptFormat scriptFormat;
/**
* Constructor.
*
@@ -133,21 +143,33 @@ public class XmlExportTransformer extends AbstractResultSetReader {
public XmlExportTransformer(OutputStream out, String commentHeader,
EntityGraph entityGraph, Set<Table> totalProgress, Set<Table> cyclicAggregatedTables,
String rootTag, String datePattern, String timestampPattern, Session session, ScriptFormat scriptFormat, Charset charset, ExecutionContext executionContext) throws TransformerConfigurationException, SAXException, SQLException {
this.xmlRowWriter = new XmlRowWriter(out, commentHeader, rootTag, datePattern, timestampPattern, scriptFormat, charset);
this.xmlRowWriter = new XmlRowWriter(out, commentHeader, rootTag, datePattern, timestampPattern, scriptFormat, charset, executionContext);
this.entityGraph = entityGraph;
this.scriptFormat = scriptFormat;
this.totalProgress = totalProgress;
this.cyclicAggregatedTables = cyclicAggregatedTables;
this.session = session;
this.quoting = Quoting.getQuoting(session);
this.rowIdSupport = new RowIdSupport(entityGraph.getDatamodel(), session.dbms, executionContext);
this.executionContext = executionContext;
}
private int rootCount = 0;
/**
* Reads result-set and writes into export-script.
*/
@Override
public void readCurrentRow(ResultSet resultSet) throws SQLException {
try {
if (executionContext.isDisallowNonAggregated() && !tableIsSubject) {
throw new ObjectNotationOutputException("Non-aggregated objects (\"" + table.getName() + "\") are disallowed at root level.\n(" + scriptFormat + ")");
}
if (++rootCount > 1) {
if (executionContext.isSingleRoot()) {
throw new ObjectNotationOutputException("Multiple root objects are not allowed. (\"" + table.getName() + "\")\n(" + scriptFormat + ")");
}
}
writeEntity(table, null, resultSet, new ArrayList<String>(), getCellContentConverter(resultSet, session, session.dbms));
} catch (SAXException e) {
throw new RuntimeException(e);
@@ -225,7 +247,7 @@ public class XmlExportTransformer extends AbstractResultSetReader {
}
};
try {
xmlRowWriter.startList(sa);
xmlRowWriter.startList(sa, name);
entityGraph.readDependentEntities(sa.destination, sa, resultSet, getMetaData(resultSet), reader, getTypeCache(sa.destination), getTableMapping(sa.destination).selectionSchema, getTableMapping(sa.destination).originalPKAliasPrefix);
if (cyclicAggregatedTables.contains(sa.destination)) {
entityGraph.markDependentEntitiesAsTraversed(sa, resultSet, getMetaData(resultSet), getTypeCache(sa.destination));
@@ -265,6 +287,13 @@ public class XmlExportTransformer extends AbstractResultSetReader {
this.table = table;
}
/**
* @param tableIsSubject <code>true</code> iff table is subject
*/
public void setTableIsSubject(boolean tableIsSubject) {
this.tableIsSubject = tableIsSubject;
}
/**
* Closes the XML document.
*/

View File

@@ -30,6 +30,7 @@ import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.Locale;
import java.util.Map;
import java.util.Stack;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.sax.TransformerHandler;
@@ -38,6 +39,7 @@ import javax.xml.transform.stream.StreamResult;
import org.xml.sax.SAXException;
import org.xml.sax.helpers.AttributesImpl;
import net.sf.jailer.ExecutionContext;
import net.sf.jailer.configuration.DBMS;
import net.sf.jailer.database.Session;
import net.sf.jailer.datamodel.AggregationSchema;
@@ -50,7 +52,7 @@ import net.sf.jailer.util.SqlUtil;
/**
* Writes rows into XML file.
* Writes rows into XML/JSON/YAML file.
*
* @author Ralf Wisser
*/
@@ -86,6 +88,13 @@ public class XmlRowWriter {
*/
private final Map<Table, Map<String, Integer>> typeCachesForStringKey = new HashMap<Table, Map<String,Integer>>();
protected boolean forSketch = false;
/**
* Execution context.
*/
private final ExecutionContext executionContext;
/**
* Constructor.
*
@@ -95,41 +104,72 @@ public class XmlRowWriter {
* @param datePattern pattern for dates
* @param timestampPattern pattern for time-stamps
* @param scriptFormat
* @param executionContext
*/
public XmlRowWriter(OutputStream out, String commentHeader, String rootTag, String datePattern, String timestampPattern, ScriptFormat scriptFormat, Charset charset) throws SAXException, TransformerConfigurationException {
public XmlRowWriter(OutputStream out, String commentHeader, String rootTag, String datePattern, String timestampPattern, ScriptFormat scriptFormat, Charset charset, ExecutionContext executionContext) throws SAXException, TransformerConfigurationException {
this.rootTag = rootTag;
this.datePattern = new SimpleDateFormat(datePattern, Locale.ENGLISH);
this.timestampPattern = new SimpleDateFormat(timestampPattern, Locale.ENGLISH);
this.executionContext = executionContext;
this.datePattern = datePattern == null? new SimpleDateFormat() : new SimpleDateFormat(datePattern, Locale.ENGLISH);
this.timestampPattern = timestampPattern == null? new SimpleDateFormat() : new SimpleDateFormat(timestampPattern, Locale.ENGLISH);
StreamResult streamResult = new StreamResult(new OutputStreamWriter(out, charset));
transformerHandler = scriptFormat == ScriptFormat.JSON
? XmlUtil.createJSONTransformerHandler(commentHeader, rootTag, streamResult, charset)
: XmlUtil.createTransformerHandler(commentHeader, rootTag, streamResult, charset);
? XmlUtil.createObjectNotationTransformerHandler(commentHeader, executionContext.isSingleRoot()? "" : rootTag, streamResult.getWriter(), false, scriptFormat, executionContext)
: XmlUtil.createTransformerHandler(commentHeader, executionContext.isSingleRoot()? "" : rootTag, streamResult, charset);
}
/**
* Constructor.
*
* @param out output stream to write the xml into
* @param commentHeader comment at top of document
* @param rootTag root tag name
* @param datePattern pattern for dates
* @param timestampPattern pattern for time-stamps
* @param scriptFormat
* @param executionContext
*/
public XmlRowWriter(OutputStream out, String commentHeader, String rootTag, String datePattern, String timestampPattern, ScriptFormat scriptFormat, Charset charset, TransformerHandler transformerHandler, ExecutionContext executionContext) throws SAXException, TransformerConfigurationException {
this.rootTag = rootTag;
this.executionContext = executionContext;
this.datePattern = datePattern == null? new SimpleDateFormat() : new SimpleDateFormat(datePattern, Locale.ENGLISH);
this.timestampPattern = timestampPattern == null? new SimpleDateFormat() : new SimpleDateFormat(timestampPattern, Locale.ENGLISH);
forSketch = true;
this.transformerHandler = transformerHandler;
}
/**
* Closes the writer.
*/
public void close() throws SAXException {
// TODO
// TODO rootTag is never empty. multipleObject attribute
if (rootTag.length() > 0 && !(transformerHandler instanceof ObjectFormatTransformer)) {
if (!executionContext.isSingleRoot() && !(transformerHandler instanceof ObjectFormatTransformer)) {
transformerHandler.endElement("", "", rootTag);
}
transformerHandler.endDocument();
}
private Map<Association, Stack<String>> associationTempAggregationTagName = new HashMap<>();
/**
* Writes start element for a list of rows.
*
* @param association association describing the list
* @param name
*/
public void startList(Association association) throws SAXException {
public void startList(Association association, String name) throws SAXException {
if (association != null) {
Stack<String> stack = associationTempAggregationTagName.get(association);
if (stack == null) {
stack = new Stack<>();
associationTempAggregationTagName.put(association, stack);
}
stack.push(name);
}
if (association != null && getAggregationSchema(association) == AggregationSchema.EXPLICIT_LIST) {
if (ifLevel == 0) {
if (transformerHandler instanceof ObjectFormatTransformer) {
((ObjectFormatTransformer) transformerHandler).startArray();
}
transformerHandler.startElement(null, null, association.getAggregationTagName(), null);
transformerHandler.startElement(null, null, name != null? name : association.getAggregationTagName(), null);
}
}
}
@@ -148,6 +188,12 @@ public class XmlRowWriter {
}
}
}
if (association != null) {
Stack<String> stack = associationTempAggregationTagName.get(association);
if (stack != null && !stack.isEmpty()) {
stack.pop();
}
}
}
private AggregationSchema getAggregationSchema(Association association) {
@@ -200,6 +246,8 @@ public class XmlRowWriter {
*/
protected final CellContentConverter cellContentConverter;
private String lastElementName;
/**
* Constructor.
*
@@ -211,7 +259,7 @@ public class XmlRowWriter {
this.table = table;
this.association = association;
this.session = session;
this.cellContentConverter = new CellContentConverter(resultSetMetaData, session, session.dbms);
this.cellContentConverter = session == null? null : new CellContentConverter(resultSetMetaData, session, session.dbms);
}
/**
@@ -221,7 +269,7 @@ public class XmlRowWriter {
* @param returnNull if <code>true</code>, return null instead of empty string if sql-result is null
* @return the xml to write out
*/
private Object toContent(String text, boolean returnNull) {
protected Object toContent(String text, boolean returnNull) {
if (text != null && text.startsWith(XmlUtil.SQL_PREFIX)) {
String columnName = "C" + nr++;
int type;
@@ -231,45 +279,52 @@ public class XmlRowWriter {
typeCache = new HashMap<String, Integer>();
typeCachesForStringKey.put(table, typeCache);
}
type = SqlUtil.getColumnType(resultSet, resultSetMetaData, columnName, typeCache);
if ((type == Types.BLOB || type == Types.CLOB|| type == Types.NCLOB) && !DBMS.SQLITE.equals(session.dbms)) {
Object object = resultSet.getObject(columnName);
if (returnNull && (object == null || resultSet.wasNull())) {
return null;
}
if (object instanceof Blob) {
Blob blob = (Blob) object;
byte[] blobValue = blob.getBytes(1, (int) blob.length());
return Base64.encodeBytes(blobValue);
}
try {
type = SqlUtil.getColumnType(resultSet, resultSetMetaData, columnName, typeCache);
if ((type == Types.BLOB || type == Types.CLOB || type == Types.NCLOB)
&& !DBMS.SQLITE.equals(session.dbms)) {
Object object = resultSet.getObject(columnName);
if (returnNull && (object == null || resultSet.wasNull())) {
return null;
}
if (object instanceof Blob) {
Blob blob = (Blob) object;
byte[] blobValue = blob.getBytes(1, (int) blob.length());
return Base64.encodeBytes(blobValue);
}
if (object instanceof Clob) {
Clob clobValue = (Clob) object;
int length = (int) clobValue.length();
if (length > 0) {
return clobValue.getSubString(1, length);
if (object instanceof Clob) {
Clob clobValue = (Clob) object;
int length = (int) clobValue.length();
if (length > 0) {
return clobValue.getSubString(1, length);
}
return "";
}
return "";
}
} else {
Object o = cellContentConverter.getObject(resultSet, columnName);
if (returnNull && (o == null || resultSet.wasNull())) {
return null;
}
if (o != null) {
Object value;
if (o instanceof Timestamp) {
value = timestampPattern.format((Timestamp) o);
} else if (o instanceof Date) {
value = datePattern.format((Date) o);
} else {
value = o;
} else {
Object o = cellContentConverter.getObject(resultSet, columnName);
if (returnNull && (o == null || resultSet.wasNull())) {
return null;
}
if (o != null) {
Object value;
if (o instanceof Timestamp) {
value = timestampPattern.format((Timestamp) o);
} else if (o instanceof Date) {
value = datePattern.format((Date) o);
} else {
value = o;
}
return value;
}
return value;
}
return null;
} catch (OutOfMemoryError e) {
throw new OutOfMemoryError("Out of Memory. \nNot enough memory to read field "
+ (table == null ? "" : ("\"" + table.getName() + "\".")) + " \"" + lastElementName
+ "\"");
}
return null;
} catch (SQLException e) {
throw new RuntimeException(e);
}
@@ -280,7 +335,7 @@ public class XmlRowWriter {
@Override
public void visitComment(String comment) {
try {
if (ifLevel == 0) {
if (ifLevel == 0 && forSketch) {
transformerHandler.comment(comment.toCharArray(), 0, comment.length());
}
} catch (SAXException e) {
@@ -308,6 +363,7 @@ public class XmlRowWriter {
@Override
public void visitElementStart(String elementName, boolean isRoot, String[] aNames, String[] aValues) {
lastElementName = elementName;
if (ifLevel > 0) {
++ifLevel;
}
@@ -332,8 +388,6 @@ public class XmlRowWriter {
} else if (!aNames[i].equals(jailerNamespaceDeclaration)) {
Object content = toContent(aValues[i], false);
attr.addAttribute("", "", aNames[i], "CDATA", content == null? "" : content.toString());
// TODO
// TODO if instanceof ObjectFormatTransformer then startElement(); content(); endElement();
}
}
}
@@ -342,7 +396,19 @@ public class XmlRowWriter {
++ifLevel;
} else {
if (!isRoot || association == null || getAggregationSchema(association) != AggregationSchema.FLAT) {
String tagName = isRoot && association != null && getAggregationSchema(association) != AggregationSchema.EXPLICIT_LIST? association.getAggregationTagName() : elementName;
String tagName;
if (isRoot && association != null && getAggregationSchema(association) != AggregationSchema.EXPLICIT_LIST) {
tagName = null;
Stack<String> stack = associationTempAggregationTagName.get(association);
if (stack != null && !stack.isEmpty()) {
tagName = stack.peek();
}
if (tagName == null) {
tagName = association.getAggregationTagName();
}
} else {
tagName = elementName;
}
transformerHandler.startElement("", "", tagName, attr);
}
}
@@ -375,21 +441,14 @@ public class XmlRowWriter {
}
// TODO
// TODO Sketch also in JSON
// TODO no Sketch-view in ExMoEd, only in template-editor
// TODO "Sketch" dann in "Template"-Dialog (fuer beide Tabellen der Asoziation?)
// TODO
// TODO template-editor (GUI):
// TODO add sketch view (JScrollPane)
// TODO make it bigger
// TODO
// TODO docu about "j:if-not-null"/"j:is-null" in template dialog
// TODO 1
// TODO JSON/YAML/XML
// TODO "unformatted" export. in XMLSettingsDialog+CLI+SubesstingEngine(Facade)
// TODO
// TODO warn if "singleObject" and "incudeNonAggr" and later exists. "dont warn again" button (transient)
// TODO new maven dep, testen

View File

@@ -22,6 +22,7 @@ import java.io.Writer;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.nio.charset.Charset;
import java.util.HashMap;
import java.util.Map;
import java.util.Stack;
@@ -39,7 +40,6 @@ import javax.xml.transform.sax.SAXTransformerFactory;
import javax.xml.transform.sax.TransformerHandler;
import javax.xml.transform.stream.StreamResult;
import org.apache.commons.collections4.map.HashedMap;
import org.w3c.dom.Attr;
import org.w3c.dom.Comment;
import org.w3c.dom.Document;
@@ -53,9 +53,9 @@ import org.xml.sax.InputSource;
import org.xml.sax.Locator;
import org.xml.sax.SAXException;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import net.sf.jailer.ExecutionContext;
import net.sf.jailer.datamodel.Association;
import net.sf.jailer.subsetting.ScriptFormat;
import net.sf.jailer.util.PrintUtil;
import net.sf.jailer.xml.XmlRowWriter.ObjectFormatTransformer;
@@ -65,15 +65,41 @@ import net.sf.jailer.xml.XmlRowWriter.ObjectFormatTransformer;
* @author Ralf Wisser
*/
public class XmlUtil {
public static interface ObjectNotationWriter {
public void writeStartObject() throws IOException;
public void writeStartArray() throws IOException;
public void writeEndObject() throws IOException;
public void writeEndArray() throws IOException;
public void flush() throws IOException;
public void writeFieldName(String qName) throws IOException;
public void writeArrayFieldStart(String qName) throws IOException;
public void writeNull() throws IOException;
public void writeBinary(byte[] content) throws IOException;
public void writeBoolean(Boolean content) throws IOException;
public void writeNumber(BigInteger content) throws IOException;
public void writeNumber(BigDecimal content) throws IOException;
public void writeNumber(Double content) throws IOException;
public void writeNumber(Float content) throws IOException;
public void writeNumber(Integer content) throws IOException;
public void writeNumber(Long content) throws IOException;
public void writeNumber(Short content) throws IOException;
public void writeString(String string) throws IOException;
public void writeComment(String comment) throws IOException;
}
private static class JSONTransformerHandler implements TransformerHandler, ObjectFormatTransformer {
public static class ObjectNotationTransformerHandler implements TransformerHandler, ObjectFormatTransformer {
private final Writer out;
private final JsonGenerator jGenerator;
private final ObjectNotationWriter jGenerator;
private final ExecutionContext executionContext;
private final boolean forSketch;
Stack<Character> states = new Stack<>();
private JSONTransformerHandler(Writer out, JsonGenerator jGenerator) {
private ObjectNotationTransformerHandler(Writer out, ObjectNotationWriter jGenerator, boolean forSketch, ExecutionContext executionContext) {
this.out = out;
this.jGenerator = jGenerator;
this.forSketch = forSketch;
this.executionContext = executionContext;
}
@Override
@@ -83,8 +109,13 @@ public class XmlUtil {
@Override
public void startDocument() throws SAXException {
try {
jGenerator.writeStartObject();
states.push('{');
if (forSketch || executionContext.isSingleRoot()) {
jGenerator.writeStartObject();
states.push('R');
} else {
jGenerator.writeStartArray();
states.push('M');
}
} catch (IOException e) {
throw new RuntimeException(e);
}
@@ -93,8 +124,12 @@ public class XmlUtil {
@Override
public void endDocument() throws SAXException {
try {
jGenerator.writeEndObject();
states.pop();
Character c = states.pop();
if (c == 'R') {
jGenerator.writeEndObject();
} else if (c == 'M') {
jGenerator.writeEndArray();
}
jGenerator.flush();
} catch (IOException e) {
try {
@@ -124,12 +159,17 @@ public class XmlUtil {
jGenerator.writeStartObject();
states.push('=');
jGenerator.writeFieldName(qName);
} else if (states.peek() == 'M') {
jGenerator.writeStartObject();
states.push('m');
} else if (states.peek() == '[') {
jGenerator.writeArrayFieldStart(qName);
states.push('-');
} else if (states.peek() == '-') {
jGenerator.writeStartObject();
states.push('{');
} else if (states.peek() == 'R') {
states.push('r');
} else {
states.push('=');
jGenerator.writeFieldName(qName);
@@ -155,6 +195,9 @@ public class XmlUtil {
if (pop == '{') {
jGenerator.writeEndObject();
}
if (pop == 'm') {
jGenerator.writeEndObject();
}
if (pop == '-') {
jGenerator.writeEndArray();
}
@@ -163,7 +206,7 @@ public class XmlUtil {
}
}
private Map<String, Object> constants = new HashedMap<>();
private Map<String, Object> constants = new HashMap<>();
@Override
public void characters(char[] ch, int start, int length) throws SAXException {
@@ -242,6 +285,14 @@ public class XmlUtil {
@Override
public void comment(char[] ch, int start, int length) throws SAXException {
try {
String comment = new String(ch, start, length).trim();
if (!comment.isEmpty()) {
jGenerator.writeComment(comment);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
@@ -312,12 +363,56 @@ public class XmlUtil {
@Override
public void startArray() {
states.push('[');
try {
if (states.peek() == '=') {
jGenerator.writeStartObject();
states.push('[');
} else {
states.push('[');
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
@Override
public void endArray() {
states.pop();
try {
states.pop();
if (states.peek() == '=') {
jGenerator.writeEndObject();
states.pop();
states.push('?');
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
public void associationSketch(Association a, String associationName, String name) {
try {
if (states.peek() != '=') {
jGenerator.writeFieldName(name);
} else {
jGenerator.writeStartObject();
states.pop();
states.push('?');
associationSketch(a, associationName, name);
jGenerator.writeEndObject();
return;
}
boolean isArray = !a.isInsertDestinationBeforeSource();
if (isArray) {
jGenerator.writeStartArray();
jGenerator.writeEndArray();
} else {
jGenerator.writeStartObject();
jGenerator.writeEndObject();
}
} catch (IOException e) {
throw new RuntimeException(e);
}
}
}
@@ -538,35 +633,38 @@ public class XmlUtil {
return transformerHandler;
}
public static TransformerHandler createJSONTransformerHandler(String commentHeader, String rootTag,
StreamResult streamResult, Charset charset) {
public static ObjectNotationTransformerHandler createObjectNotationTransformerHandler(String commentHeader, String rootTag,
Writer out, boolean forSketch, ScriptFormat scriptFormat, ExecutionContext executionContext) {
Writer out = streamResult.getWriter();
JsonFactory jfactory = new JsonFactory();
JsonGenerator jGenerator;
ObjectNotationWriter jGenerator;
try {
jGenerator = jfactory
.createGenerator(out);
jGenerator.useDefaultPrettyPrinter();
if (scriptFormat == ScriptFormat.JSON) {
jGenerator = new JSONWriter(out);
} else if (scriptFormat == ScriptFormat.YAML) {
// TODO
jGenerator = new YAMLWriter(out);
} else {
throw new RuntimeException("unknown script format: " + scriptFormat);
}
} catch (IOException e) {
throw new RuntimeException(e);
}
// TODO
// TODO c|blob: size-limit (editable). As watch-dog (error if exceeded) (show path of field on error)
// TODO
// TODO count XML/JSON/YMAML exports (s16-19)
// TODO
// TODO ? default in XML/JSON/... Settings: dont allow arrays. max straenge. dann in der Fehlermeldung auf Mögl. Array zuzulassen aufmerksam machen?
// TODO ? gute gruende, das gegenteil zu machen. im fehlerfall nur warnen.
TransformerHandler th = new JSONTransformerHandler(out, jGenerator);
ObjectNotationTransformerHandler th = new ObjectNotationTransformerHandler(out, jGenerator, forSketch, executionContext);
try {
th.startDocument();
} catch (SAXException e) {
// TODO Auto-generated catch block
e.printStackTrace();
if (commentHeader != null && !commentHeader.isEmpty()) {
// TODO
// TODO nicht bei JSON, noch testen
if (!(jGenerator instanceof JSONWriter)) {
jGenerator.writeComment(commentHeader);
}
}
} catch (Exception e) {
throw new RuntimeException(e);
}
return th;
}

View File

@@ -0,0 +1,144 @@
/*
* Copyright 2007 - 2024 Ralf Wisser.
*
* 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.
*/
package net.sf.jailer.xml;
import java.io.IOException;
import java.io.Writer;
import java.math.BigDecimal;
import java.math.BigInteger;
import com.fasterxml.jackson.core.JsonFactory;
import com.fasterxml.jackson.core.JsonGenerator;
import net.sf.jailer.xml.XmlUtil.ObjectNotationWriter;
/**
* A writer for JSON.
*
* @author Ralf Wisser
*/
public class YAMLWriter implements ObjectNotationWriter {
private final JsonGenerator jGen;
public YAMLWriter(Writer out) throws IOException {
// TODO
// TODO implement using SnakeYaml
JsonFactory jfactory = new JsonFactory();
this.jGen = jfactory.createGenerator(out);
this.jGen.useDefaultPrettyPrinter();
}
@Override
public void writeStartObject() throws IOException {
this.jGen.writeStartObject();
}
@Override
public void writeStartArray() throws IOException {
this.jGen.writeStartArray();;
}
@Override
public void writeEndObject() throws IOException {
this.jGen.writeEndObject();;
}
@Override
public void writeEndArray() throws IOException {
this.jGen.writeEndArray();
}
@Override
public void flush() throws IOException {
this.jGen.flush();
}
@Override
public void writeFieldName(String qName) throws IOException {
this.jGen.writeFieldName(qName);
}
@Override
public void writeArrayFieldStart(String qName) throws IOException {
this.jGen.writeArrayFieldStart(qName);
}
@Override
public void writeNull() throws IOException {
this.jGen.writeNull();
}
@Override
public void writeBinary(byte[] content) throws IOException {
this.jGen.writeBinary(content);
}
@Override
public void writeBoolean(Boolean content) throws IOException {
this.jGen.writeBoolean(content);
}
@Override
public void writeNumber(BigInteger content) throws IOException {
this.jGen.writeNumber(content);
}
@Override
public void writeNumber(BigDecimal content) throws IOException {
this.jGen.writeNumber(content);
}
@Override
public void writeNumber(Double content) throws IOException {
this.jGen.writeNumber(content);
}
@Override
public void writeNumber(Float content) throws IOException {
this.jGen.writeNumber(content);
}
@Override
public void writeNumber(Integer content) throws IOException {
this.jGen.writeNumber(content);
}
@Override
public void writeNumber(Long content) throws IOException {
this.jGen.writeNumber(content);
}
@Override
public void writeNumber(Short content) throws IOException {
this.jGen.writeNumber(content);
}
@Override
public void writeString(String string) throws IOException {
this.jGen.writeString(string);
}
@Override
public void writeComment(String comment) throws IOException {
try {
jGen.writeStringField("j:comment", comment + " /j:comment");
} catch (Exception e) {
e.printStackTrace();
// ignore
}
}
}

View File

@@ -22,53 +22,129 @@
<AuxValue name="designerSize" type="java.awt.Dimension" value="-84,-19,0,5,115,114,0,18,106,97,118,97,46,97,119,116,46,68,105,109,101,110,115,105,111,110,65,-114,-39,-41,-84,95,68,20,2,0,2,73,0,6,104,101,105,103,104,116,73,0,5,119,105,100,116,104,120,112,0,0,1,44,0,0,1,-112"/>
</AuxValues>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="jPanel1">
<Container class="javax.swing.JPanel" name="jPanel3">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Component class="javax.swing.JLabel" name="jLabel1">
<Properties>
<Property name="text" type="java.lang.String" value=" Table "/>
</Properties>
<Container class="javax.swing.JPanel" name="jPanel1">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="4" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
<GridBagConstraints gridX="-1" gridY="-1" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JComboBox" name="tableCombobox">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="4">
<StringItem index="0" value="Eintrag 1"/>
<StringItem index="1" value="Eintrag 2"/>
<StringItem index="2" value="Eintrag 3"/>
<StringItem index="3" value="Eintrag 4"/>
</StringArray>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="2" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="4" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JLabel" name="jLabel2">
<Properties>
<Property name="text" type="java.lang.String" value=" Mapping "/>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="1" gridY="10" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="2" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Component class="javax.swing.JLabel" name="jLabel1">
<Properties>
<Property name="text" type="java.lang.String" value=" Table "/>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="4" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JComboBox" name="tableCombobox">
<Properties>
<Property name="model" type="javax.swing.ComboBoxModel" editor="org.netbeans.modules.form.editors2.ComboBoxModelEditor">
<StringArray count="4">
<StringItem index="0" value="Eintrag 1"/>
<StringItem index="1" value="Eintrag 2"/>
<StringItem index="2" value="Eintrag 3"/>
<StringItem index="3" value="Eintrag 4"/>
</StringArray>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="2" gridY="1" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="4" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Container class="javax.swing.JSplitPane" name="jSplitPane1">
<Properties>
<Property name="dividerLocation" type="int" value="300"/>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="1" gridY="10" gridWidth="2" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="1.0" weightY="1.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout"/>
<SubComponents>
<Container class="javax.swing.JPanel" name="jPanel4">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
<JSplitPaneConstraints position="left"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Component class="javax.swing.JLabel" name="jLabel2">
<Properties>
<Property name="text" type="java.lang.String" value=" Mapping "/>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="1" gridY="10" gridWidth="1" gridHeight="1" fill="0" ipadX="0" ipadY="0" insetsTop="2" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="17" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
<Container class="javax.swing.JPanel" name="paramPanel">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[150, 0]"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="3" gridY="20" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
</Container>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="jPanel5">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout" value="org.netbeans.modules.form.compat2.layouts.support.JSplitPaneSupportLayout$JSplitPaneConstraintsDescription">
<JSplitPaneConstraints position="right"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout"/>
<SubComponents>
<Component class="javax.swing.JLabel" name="jLabel3">
<Properties>
<Property name="text" type="java.lang.String" value="Sketch"/>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="1" gridY="1" gridWidth="1" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="2" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
</Component>
</SubComponents>
</Container>
</SubComponents>
</Container>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="jPanel2">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="1" gridY="30" gridWidth="3" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="4" insetsLeft="4" insetsBottom="4" insetsRight="4" anchor="10" weightX="1.0" weightY="0.0"/>
<GridBagConstraints gridX="0" gridY="30" gridWidth="3" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="4" insetsLeft="4" insetsBottom="4" insetsRight="4" anchor="10" weightX="1.0" weightY="0.0"/>
</Constraint>
</Constraints>
@@ -128,20 +204,6 @@
</Component>
</SubComponents>
</Container>
<Container class="javax.swing.JPanel" name="paramPanel">
<Properties>
<Property name="minimumSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
<Dimension value="[150, 0]"/>
</Property>
</Properties>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="3" gridY="20" gridWidth="1" gridHeight="1" fill="1" ipadX="0" ipadY="0" insetsTop="0" insetsLeft="0" insetsBottom="0" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>
<Layout class="org.netbeans.modules.form.compat2.layouts.DesignBoxLayout"/>
</Container>
</SubComponents>
</Container>
</SubComponents>

View File

@@ -15,10 +15,13 @@
*/
package net.sf.jailer.ui;
import java.awt.Container;
import java.awt.GridBagConstraints;
import java.awt.event.ActionListener;
import java.util.Collections;
import java.util.Vector;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.swing.DefaultComboBoxModel;
import javax.swing.ImageIcon;
@@ -28,8 +31,10 @@ import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import org.w3c.dom.Document;
import net.sf.jailer.ExecutionContext;
import net.sf.jailer.datamodel.DataModel;
import net.sf.jailer.datamodel.Table;
import net.sf.jailer.subsetting.ScriptFormat;
import net.sf.jailer.ui.syntaxtextarea.RSyntaxTextAreaWithTheme;
import net.sf.jailer.xml.XmlUtil;
@@ -43,13 +48,16 @@ public class ColumnMapperDialog extends javax.swing.JDialog {
private final java.awt.Frame parent;
private Table table;
private DataModel dataModel;
private ScriptFormat scriptFormat;
private boolean ok;
private ParameterSelector parameterSelector;
private String initialTemplate = "";
private ExecutionContext executionContext;
/** Creates new form ColumnMapperDialog */
public ColumnMapperDialog(java.awt.Frame parent, ParameterSelector.ParametersGetter parametersGetter) {
public ColumnMapperDialog(java.awt.Frame parent, ParameterSelector.ParametersGetter parametersGetter, ExecutionContext executionContext) {
super(parent, true);
this.executionContext = executionContext;
this.parent = parent;
this.mappingField = new RSyntaxTextAreaWithTheme();
mappingField.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_XML);
@@ -70,20 +78,42 @@ public class ColumnMapperDialog extends javax.swing.JDialog {
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 1.0;
gridBagConstraints.insets = new java.awt.Insets(4, 4, 0, 4);
jPanel1.add(jScrollPane2, gridBagConstraints);
jPanel4.add(jScrollPane2, gridBagConstraints);
jScrollPane2.setViewportView(mappingField);
AutoCompletion.enable(tableCombobox);
JScrollPane tab = new JScrollPane();
xmlSketch = new RSyntaxTextAreaWithTheme();
xmlSketch.setEditable(false);
tab.setViewportView(xmlSketch);
xmlSketch.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_XML);
xmlSketch.setCodeFoldingEnabled(true);
xmlSketch.setText("");
xmlSketch.setCaretPosition(0);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 2;
gridBagConstraints.weightx = 1;
gridBagConstraints.weighty = 1;
gridBagConstraints.fill = GridBagConstraints.BOTH;
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
gridBagConstraints.insets = new java.awt.Insets(4, 0, 0, 0);
jPanel5.add(tab, gridBagConstraints);
AutoCompletion.enable(tableCombobox);
paramPanel.add(parameterSelector = new ParameterSelector(this, mappingField, parametersGetter));
tableCombobox.addActionListener(new ActionListener() {
@Override
public void actionPerformed(java.awt.event.ActionEvent e) {
try {
if (table != null) {
table = dataModel.getTableByDisplayName((String) tableCombobox.getSelectedItem());
Table t = dataModel.getTableByDisplayName((String) tableCombobox.getSelectedItem());
if (t != null) {
table = t;
setMappingFieldText(XmlUtil.build(table.getXmlTemplateAsDocument(null)));
mappingField.discardAllEdits();
updateSketch(table);
}
} catch (Exception ex) {
UIUtil.showException(ColumnMapperDialog.this.parent, "Error", ex);
@@ -98,9 +128,11 @@ public class ColumnMapperDialog extends javax.swing.JDialog {
* @param dataModel the data model
* @param table the table
*/
public boolean edit(DataModel dataModel, Table table) {
public boolean edit(DataModel dataModel, Table table, ScriptFormat scriptFormat) {
this.table = table;
this.dataModel = dataModel;
this.scriptFormat = scriptFormat;
parameterSelector.updateParameters();
this.table = null;
Vector<String> tableNames = new Vector<String>();
for (Table t: dataModel.getTables()) {
tableNames.add(dataModel.getDisplayName(t));
@@ -109,11 +141,13 @@ public class ColumnMapperDialog extends javax.swing.JDialog {
tableCombobox.setModel(new DefaultComboBoxModel(tableNames));
tableCombobox.setMaximumRowCount(40);
tableCombobox.setSelectedItem(dataModel.getDisplayName(table));
int w = 600, h = 600;
int w = 1200, h = 600;
setSize(w, h);
setLocation(Math.max(0, parent.getX() + parent.getWidth() / 2 - w / 2),
Math.max(0, parent.getY() + parent.getHeight() / 2 - h / 2));
jSplitPane1.setDividerLocation((int) (w * 0.66));
invalidate();
updateSketch(table);
try {
setMappingFieldText(XmlUtil.build(table.getXmlTemplateAsDocument(null)));
initialTemplate = mappingField.getText();
@@ -130,12 +164,53 @@ public class ColumnMapperDialog extends javax.swing.JDialog {
}
mappingField.discardAllEdits();
ok = false;
this.table = table;
this.dataModel = dataModel;
setVisible(true);
return ok;
}
private RSyntaxTextArea xmlSketch;
/**
* Adds a tab to the sketch-tabbedpane for a given table.
*
* @param table the table
*/
private void updateSketch(Table table) {
String sketch = "";
try {
sketch = XmlSketchBuilder.buildSketch(table, 1, scriptFormat, executionContext);
if (scriptFormat == ScriptFormat.JSON) {
Pattern pattern = Pattern.compile("\"j\\:comment\"\\s*\\:\\s*\"(.*)/j\\:comment\"(?:\\,)?");
Matcher matcher = pattern.matcher(sketch);
boolean result = matcher.find();
StringBuffer sb = new StringBuffer();
if (result) {
do {
String comment = matcher.group(1);
matcher.appendReplacement(sb, "// " + Matcher.quoteReplacement(comment.replace("\\\"", "\f").replace("\"", "").replace("\f", "\"")));
result = matcher.find();
} while (result);
}
matcher.appendTail(sb);
sketch = sb.toString();
}
} catch (Exception e) {
e.printStackTrace();
sketch = e.getMessage();
}
if (scriptFormat == ScriptFormat.XML) {
xmlSketch.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_XML);
}
if (scriptFormat == ScriptFormat.JSON) {
xmlSketch.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_JSON_WITH_COMMENTS);
}
if (scriptFormat == ScriptFormat.YAML) {
xmlSketch.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_YAML);
}
Container sParent = xmlSketch.getParent();
xmlSketch.setText(sketch);
}
/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
@@ -145,20 +220,27 @@ public class ColumnMapperDialog extends javax.swing.JDialog {
private void initComponents() {
java.awt.GridBagConstraints gridBagConstraints;
jPanel3 = new javax.swing.JPanel();
jPanel1 = new javax.swing.JPanel();
jLabel1 = new javax.swing.JLabel();
tableCombobox = new JComboBox2();
jSplitPane1 = new javax.swing.JSplitPane();
jPanel4 = new javax.swing.JPanel();
jLabel2 = new javax.swing.JLabel();
paramPanel = new javax.swing.JPanel();
jPanel5 = new javax.swing.JPanel();
jLabel3 = new javax.swing.JLabel();
jPanel2 = new javax.swing.JPanel();
formatButton = new javax.swing.JButton();
resetButton = new javax.swing.JButton();
okButton = new javax.swing.JButton();
cancelButton = new javax.swing.JButton();
paramPanel = new javax.swing.JPanel();
setDefaultCloseOperation(javax.swing.WindowConstants.DISPOSE_ON_CLOSE);
setTitle("XML Column Mapping");
getContentPane().setLayout(new javax.swing.BoxLayout(getContentPane(), javax.swing.BoxLayout.LINE_AXIS));
getContentPane().setLayout(new java.awt.GridBagLayout());
jPanel3.setLayout(new java.awt.GridBagLayout());
jPanel1.setLayout(new java.awt.GridBagLayout());
@@ -178,13 +260,54 @@ public class ColumnMapperDialog extends javax.swing.JDialog {
gridBagConstraints.insets = new java.awt.Insets(4, 0, 0, 0);
jPanel1.add(tableCombobox, gridBagConstraints);
jSplitPane1.setDividerLocation(300);
jPanel4.setLayout(new java.awt.GridBagLayout());
jLabel2.setText(" Mapping ");
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 10;
gridBagConstraints.anchor = java.awt.GridBagConstraints.WEST;
gridBagConstraints.insets = new java.awt.Insets(2, 0, 0, 0);
jPanel1.add(jLabel2, gridBagConstraints);
jPanel4.add(jLabel2, gridBagConstraints);
paramPanel.setMinimumSize(new java.awt.Dimension(150, 0));
paramPanel.setLayout(new javax.swing.BoxLayout(paramPanel, javax.swing.BoxLayout.LINE_AXIS));
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 3;
gridBagConstraints.gridy = 20;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
jPanel4.add(paramPanel, gridBagConstraints);
jSplitPane1.setLeftComponent(jPanel4);
jPanel5.setLayout(new java.awt.GridBagLayout());
jLabel3.setText("Sketch");
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 1;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.insets = new java.awt.Insets(0, 2, 0, 0);
jPanel5.add(jLabel3, gridBagConstraints);
jSplitPane1.setRightComponent(jPanel5);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 10;
gridBagConstraints.gridwidth = 2;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 1.0;
jPanel1.add(jSplitPane1, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 1.0;
jPanel3.add(jPanel1, gridBagConstraints);
jPanel2.setLayout(new java.awt.GridBagLayout());
@@ -229,23 +352,19 @@ public class ColumnMapperDialog extends javax.swing.JDialog {
jPanel2.add(cancelButton, new java.awt.GridBagConstraints());
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 30;
gridBagConstraints.gridwidth = 3;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.insets = new java.awt.Insets(4, 4, 4, 4);
jPanel1.add(jPanel2, gridBagConstraints);
jPanel3.add(jPanel2, gridBagConstraints);
paramPanel.setMinimumSize(new java.awt.Dimension(150, 0));
paramPanel.setLayout(new javax.swing.BoxLayout(paramPanel, javax.swing.BoxLayout.LINE_AXIS));
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 3;
gridBagConstraints.gridy = 20;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
jPanel1.add(paramPanel, gridBagConstraints);
getContentPane().add(jPanel1);
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 1.0;
getContentPane().add(jPanel3, gridBagConstraints);
pack();
}// </editor-fold>//GEN-END:initComponents
@@ -253,7 +372,7 @@ public class ColumnMapperDialog extends javax.swing.JDialog {
private void resetButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_resetButtonActionPerformed
try {
mappingField.beginAtomicEdit();
setMappingFieldText(XmlUtil.build(table.getXmlTemplateAsDocument(null)));
setMappingFieldText(XmlUtil.build(table.getXmlTemplateAsDocument(XmlUtil.build(table.getDefaultXmlTemplate(null)), null)));
mappingField.endAtomicEdit();
mappingField.grabFocus();
} catch (Exception e) {
@@ -299,13 +418,18 @@ public class ColumnMapperDialog extends javax.swing.JDialog {
mappingField.setCaretPosition(0);
}
// Variables declaration - do not modify//GEN-BEGIN:variables
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton cancelButton;
private javax.swing.JButton formatButton;
private javax.swing.JLabel jLabel1;
private javax.swing.JLabel jLabel2;
private javax.swing.JLabel jLabel3;
private javax.swing.JPanel jPanel1;
private javax.swing.JPanel jPanel2;
private javax.swing.JPanel jPanel3;
private javax.swing.JPanel jPanel4;
private javax.swing.JPanel jPanel5;
private javax.swing.JSplitPane jSplitPane1;
private javax.swing.JButton okButton;
private javax.swing.JPanel paramPanel;
private javax.swing.JButton resetButton;
@@ -326,6 +450,20 @@ public class ColumnMapperDialog extends javax.swing.JDialog {
private static final long serialVersionUID = -5437578641818236294L;
}
// TODO
// TODO parameter panel:
// TODO docu? grundsaetzlich, as link to docu?
// TODO
// TODO doku: "tutorial"/"preparation": too(ooooo) old!
// TODO
// TODO H2, Demo DB, somtimes tables get empty- (H2-Bug?)
// TODO !!! 2.3.230 !!!
// TODO find work-around
// TODO symptom: all tables are empty but still exists
// TODO f.e.: copy demo-db before connecting. Check if demo-db is valid ("select count(*) from Employee" > 0, same with sakila)
// TODO
// TODO no timer. "auto update" checkbox + "update" button in dialog. + stale-indication. initially check checkbox iff template is small (heuristically, maybe if size < 10000 char?)
// TODO was: show sketch. use timer for preventing lags bcof expensive sketch creation (1000+ column templates f.e.)

View File

@@ -891,7 +891,7 @@ public class DbConnectionDialog extends javax.swing.JDialog {
ConnectionInfo ci = new ConnectionInfo(executionContext);
ci.alias = "Demo Scott";
ci.driverClass = "org.h2.Driver";
ci.jar1 = "lib" + File.separator + "h2-2.2.224.jar";
ci.jar1 = "lib" + File.separator + "h2-2.3.230.jar";
ci.url = "jdbc:h2:" + Environment.newFile("demo-scott-h2").getAbsolutePath();
ci.user = "sa";
ci.password = "";
@@ -901,7 +901,7 @@ public class DbConnectionDialog extends javax.swing.JDialog {
ci = new ConnectionInfo(executionContext);
ci.alias = "Demo Sakila";
ci.driverClass = "org.h2.Driver";
ci.jar1 = "lib" + File.separator + "h2-2.2.224.jar";
ci.jar1 = "lib" + File.separator + "h2-2.3.230.jar";
ci.url = "jdbc:h2:" + Environment.newFile("demo-sakila-h2").getAbsolutePath();
ci.user = "sa";
ci.password = "";

View File

@@ -593,7 +593,7 @@
<Container class="javax.swing.JPanel" name="jPanel16">
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
<GridBagConstraints gridX="1" gridY="7" gridWidth="4" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="4" insetsLeft="0" insetsBottom="4" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
<GridBagConstraints gridX="1" gridY="7" gridWidth="4" gridHeight="1" fill="2" ipadX="0" ipadY="0" insetsTop="4" insetsLeft="0" insetsBottom="6" insetsRight="0" anchor="10" weightX="0.0" weightY="0.0"/>
</Constraint>
</Constraints>

View File

@@ -48,6 +48,7 @@ import java.io.PrintWriter;
import java.sql.SQLException;
import java.util.ArrayDeque;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
@@ -71,8 +72,6 @@ import javax.swing.DefaultListCellRenderer;
import javax.swing.Icon;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JCheckBoxMenuItem;
import javax.swing.JComboBox;
import javax.swing.JComponent;
import javax.swing.JDialog;
@@ -112,12 +111,6 @@ import javax.swing.tree.TreeNode;
import javax.swing.tree.TreePath;
import javax.swing.tree.TreeSelectionModel;
import org.apache.commons.lang3.stream.Streams;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
import org.fife.ui.rsyntaxtextarea.SyntaxConstants;
import com.fasterxml.jackson.annotation.JsonTypeInfo.None;
import net.sf.jailer.ExecutionContext;
import net.sf.jailer.database.BasicDataSource;
import net.sf.jailer.database.Session;
@@ -146,7 +139,6 @@ import net.sf.jailer.ui.graphical_view.GraphicalDataModelView;
import net.sf.jailer.ui.scrollmenu.JScrollPopupMenu;
import net.sf.jailer.ui.syntaxtextarea.DataModelBasedSQLCompletionProvider;
import net.sf.jailer.ui.syntaxtextarea.RSyntaxTextAreaWithSQLSyntaxStyle;
import net.sf.jailer.ui.syntaxtextarea.RSyntaxTextAreaWithTheme;
import net.sf.jailer.ui.syntaxtextarea.SQLCompletionProvider;
import net.sf.jailer.ui.undo.CompensationAction;
import net.sf.jailer.ui.undo.UndoManager;
@@ -300,7 +292,7 @@ public class ExtractionModelEditor extends javax.swing.JPanel implements PlafAwa
return dataModel.getParameters(condition.getText(), extractionModel.additionalSubjects);
}
};
columnMapperDialog = new ColumnMapperDialog(extractionModelFrame, parametersGetter);
columnMapperDialog = new ColumnMapperDialog(extractionModelFrame, parametersGetter, executionContext);
boolean isNew;
if (extractionModelFile == null || !new File(extractionModelFile).exists()) {
needsSave = extractionModelFile != null;
@@ -945,7 +937,7 @@ public class ExtractionModelEditor extends javax.swing.JPanel implements PlafAwa
}
DefaultComboBoxModel formatComboBoxModel = new DefaultComboBoxModel();
Streams.of(ScriptFormat.values()).forEach(sf -> {
Arrays.stream(ScriptFormat.values()).forEach(sf -> {
formatComboBoxModel.addElement(sf);
if (sf.separatorFollowed) {
formatComboBoxModel.addElement(null);
@@ -1459,14 +1451,38 @@ public class ExtractionModelEditor extends javax.swing.JPanel implements PlafAwa
((GridLayout) editorPanel.getLayout()).setVgap(1);
((GridLayout) editorPanel.getLayout()).setColumns(1);
if (false && scriptFormat.isObjectNotation()) { // TODO
gridBagConstraints = new java.awt.GridBagConstraints();
JPanel sketchPanel = new JPanel();
sketchPanel.setLayout(new java.awt.GridBagLayout());
jLabel12.setFont(jLabel12.getFont().deriveFont(jLabel12.getFont().getStyle() | java.awt.Font.BOLD));
jLabel12.setText(" " + scriptFormat + " Sketches");
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 0;
gridBagConstraints.gridwidth = 5;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.insets = new java.awt.Insets(8, 0, 4, 0);
sketchPanel.add(jLabel12, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 1;
gridBagConstraints.gridy = 11;
gridBagConstraints.gridwidth = 2;
gridBagConstraints.fill = java.awt.GridBagConstraints.BOTH;
gridBagConstraints.weightx = 1.0;
gridBagConstraints.weighty = 1.0;
gridBagConstraints.insets = new java.awt.Insets(0, 8, 0, 0);
sketchPanel.add(sketchTabbedPane, gridBagConstraints);
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 0;
gridBagConstraints.gridy = 3;
gridBagConstraints.weightx = 1;
gridBagConstraints.weighty = 0.6;
gridBagConstraints.fill = GridBagConstraints.BOTH;
gridBagConstraints.insets = new Insets(0, 0, 0, 0);
panel2.add(xmlMappingPanel, gridBagConstraints);
panel2.add(sketchPanel, gridBagConstraints);
// editorPanel.add(xmlMappingPanel);
((GridLayout) editorPanel.getLayout()).setRows(1);
} else {
@@ -1559,7 +1575,7 @@ public class ExtractionModelEditor extends javax.swing.JPanel implements PlafAwa
jPanel8 = new javax.swing.JPanel();
jLabel7 = new javax.swing.JLabel();
jPanel10 = new javax.swing.JPanel();
exportFormat = new javax.swing.JComboBox();
exportFormat = new JComboBox2();
exportButton = new javax.swing.JButton();
openXmlSettings = new javax.swing.JButton();
jLabel10 = new javax.swing.JLabel();
@@ -1581,7 +1597,7 @@ public class ExtractionModelEditor extends javax.swing.JPanel implements PlafAwa
jLabel1 = new javax.swing.JLabel();
jLabel2 = new javax.swing.JLabel();
jLabel3 = new javax.swing.JLabel();
aggregationCombobox = new javax.swing.JComboBox();
aggregationCombobox = new JComboBox2();
tagField = new javax.swing.JTextField();
jPanel5 = new javax.swing.JPanel();
xmlTagApply = new javax.swing.JButton();
@@ -1714,7 +1730,7 @@ public class ExtractionModelEditor extends javax.swing.JPanel implements PlafAwa
layeredPane.setLayer(focusPanel, javax.swing.JLayeredPane.PALETTE_LAYER);
layeredPane.add(focusPanel);
focusPanel.setBounds(0, 0, 359, 32);
focusPanel.setBounds(0, 0, 345, 32);
rightBorderPanel.setOpaque(false);
rightBorderPanel.setLayout(new java.awt.GridBagLayout());
@@ -1851,11 +1867,7 @@ public class ExtractionModelEditor extends javax.swing.JPanel implements PlafAwa
exportFormat.setModel(new javax.swing.DefaultComboBoxModel(new String[] { "Item 1", "Item 2", "Item 3", "Item 4" }));
exportFormat.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
if (exportFormat.getSelectedItem() == null) {
UIUtil.invokeLater(() -> exportFormat.setSelectedItem(scriptFormat));
} else {
onExportModusChanged(evt);
}
onExportModusChanged(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
@@ -1960,7 +1972,7 @@ public class ExtractionModelEditor extends javax.swing.JPanel implements PlafAwa
gridBagConstraints.gridy = 7;
gridBagConstraints.gridwidth = 4;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.insets = new java.awt.Insets(4, 0, 4, 0);
gridBagConstraints.insets = new java.awt.Insets(4, 0, 6, 0);
jPanel3.add(jPanel16, gridBagConstraints);
jPanel17.setLayout(new java.awt.FlowLayout(java.awt.FlowLayout.CENTER, 5, 8));
@@ -2976,46 +2988,23 @@ public class ExtractionModelEditor extends javax.swing.JPanel implements PlafAwa
* Updates the XML sketch component.
*/
private void updateSketch() {
try {
sketchTabbedPane.removeAll();
if (currentAssociation != null) {
addSketchTab(currentAssociation.source);
if (currentAssociation.source != currentAssociation.destination) {
addSketchTab(currentAssociation.destination);
}
sketchTabbedPane.setSelectedIndex(0);
} else {
if (root != null) {
addSketchTab(root);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* Adds a tab to the sketch-tabbedpane for a given table.
*
* @param table the table
*/
private void addSketchTab(Table table) throws Exception {
JScrollPane tab = new JScrollPane();
RSyntaxTextArea xmlSketch = new RSyntaxTextAreaWithTheme();
xmlSketch.setEditable(false);
tab.setViewportView(xmlSketch);
xmlSketch.setSyntaxEditingStyle(SyntaxConstants.SYNTAX_STYLE_XML);
xmlSketch.setCodeFoldingEnabled(true);
String tabName = null;
String sketch = "";
tabName = dataModel.getDisplayName(table);
sketch = XmlSketchBuilder.buildSketch(table, 1);
xmlSketch.setText(sketch);
xmlSketch.setCaretPosition(0);
sketchTabbedPane.addTab(tabName, tab);
// try {
// sketchTabbedPane.removeAll();
//
// if (currentAssociation != null) {
// addSketchTab(currentAssociation.source);
// if (currentAssociation.source != currentAssociation.destination) {
// addSketchTab(currentAssociation.destination);
// }
// sketchTabbedPane.setSelectedIndex(0);
// } else {
// if (root != null) {
// addSketchTab(root);
// }
// }
// } catch (Exception e) {
// e.printStackTrace();
// }
}
/**
@@ -3925,7 +3914,7 @@ public class ExtractionModelEditor extends javax.swing.JPanel implements PlafAwa
public void openColumnMapper(Table table) {
String old = table.getXmlTemplate();
columnMapperDialog.setTitle(scriptFormat + " Column Mapping");
if (columnMapperDialog.edit(dataModel, table)) {
if (columnMapperDialog.edit(dataModel, table, scriptFormat)) {
String template = table.getXmlTemplate();
table.setXmlTemplate(old);
changeXmlTemplate(table, template);
@@ -4161,7 +4150,7 @@ public class ExtractionModelEditor extends javax.swing.JPanel implements PlafAwa
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton activateDesictionPendingButton;
private javax.swing.JButton additionalSubjectsButton;
private javax.swing.JComboBox aggregationCombobox;
private JComboBox2 aggregationCombobox;
private javax.swing.JLabel assocStatsLabel;
private javax.swing.JLabel associatedWith;
javax.swing.JTextField condition;
@@ -4169,7 +4158,7 @@ public class ExtractionModelEditor extends javax.swing.JPanel implements PlafAwa
private javax.swing.JLabel dependsOn;
private javax.swing.JPanel editorPanel;
public javax.swing.JButton exportButton;
private javax.swing.JComboBox exportFormat;
private JComboBox2 exportFormat;
private javax.swing.JPanel focusLabelPanel;
javax.swing.JPanel focusPanel;
private javax.swing.JPanel graphContainer;

View File

@@ -152,6 +152,7 @@ import net.sf.jailer.datamodel.DataModel;
import net.sf.jailer.datamodel.Table;
import net.sf.jailer.ddl.DDLCreator;
import net.sf.jailer.progress.ProgressListener;
import net.sf.jailer.subsetting.ObjectNotationOutputException;
import net.sf.jailer.subsetting.RowLimitExceededException;
import net.sf.jailer.ui.databrowser.DetailsView;
import net.sf.jailer.ui.databrowser.Row;
@@ -864,7 +865,7 @@ public class UIUtil {
if (t instanceof DataModel.NoPrimaryKeyException || t instanceof CycleFinder.CycleFoundException) {
context = EXCEPTION_CONTEXT_USER_ERROR;
}
if (t instanceof RowLimitExceededException) {
if (t instanceof RowLimitExceededException || t instanceof ObjectNotationOutputException) {
context = EXCEPTION_CONTEXT_USER_WARNING;
}
if (t instanceof SqlException) {

View File

@@ -147,13 +147,14 @@
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JCheckBox" name="multipleRoots">
<Component class="javax.swing.JCheckBox" name="singleRoot">
<Properties>
<Property name="text" type="java.lang.String" value="Single Object"/>
<Property name="toolTipText" type="java.lang.String" value="&lt;html&gt;Writes a single root/subject object with all its aggregated sub-objects. &lt;br&gt;The export process fails if more than one such object exists.&lt;/html&gt;"/>
</Properties>
<Events>
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="multipleRootsItemStateChanged"/>
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="singleRootItemStateChanged"/>
<EventHandler event="actionPerformed" listener="java.awt.event.ActionListener" parameters="java.awt.event.ActionEvent" handler="singleRootActionPerformed"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">
@@ -208,13 +209,13 @@
</Constraint>
</Constraints>
</Component>
<Component class="javax.swing.JCheckBox" name="singleRoot">
<Component class="javax.swing.JCheckBox" name="multipleRoots">
<Properties>
<Property name="text" type="java.lang.String" value="Multiple Objects (Array)"/>
<Property name="toolTipText" type="java.lang.String" value="&lt;html&gt;Writes an array/collection of all root/subject objects with all their aggregated sub-objects.&lt;/html&gt;"/>
</Properties>
<Events>
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="singleRootItemStateChanged"/>
<EventHandler event="itemStateChanged" listener="java.awt.event.ItemListener" parameters="java.awt.event.ItemEvent" handler="multipleRootsItemStateChanged"/>
</Events>
<Constraints>
<Constraint layoutClass="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout" value="org.netbeans.modules.form.compat2.layouts.DesignGridBagLayout$GridBagConstraintsDescription">

View File

@@ -42,8 +42,8 @@ public class XmlSettingsDialog extends javax.swing.JDialog {
setModal(true);
ButtonGroup buttonGroup = new ButtonGroup();
buttonGroup.add(singleRoot);
buttonGroup.add(multipleRoots);
buttonGroup.add(singleRoot);
buttonGroup = new ButtonGroup();
buttonGroup.add(include);
@@ -91,8 +91,8 @@ public class XmlSettingsDialog extends javax.swing.JDialog {
rootTag.setVisible(scriptFormat == ScriptFormat.XML);
xmlRootTagLabel.setVisible(scriptFormat == ScriptFormat.XML);
multipleRoots.setSelected(!xmlSettings.singleRoot);
singleRoot.setSelected(xmlSettings.singleRoot);
multipleRoots.setSelected(!xmlSettings.singleRoot);
ignore.setSelected(xmlSettings.ignoreNonAggregated);
include.setSelected(xmlSettings.includeNonAggregated);
disallow.setSelected(xmlSettings.disallowNonAggregated);
@@ -226,12 +226,12 @@ public class XmlSettingsDialog extends javax.swing.JDialog {
rootTag = new javax.swing.JTextField();
dateExample = new javax.swing.JLabel();
timestampExample = new javax.swing.JLabel();
multipleRoots = new javax.swing.JCheckBox();
singleRoot = new javax.swing.JCheckBox();
jPanel2 = new javax.swing.JPanel();
Ok = new javax.swing.JButton();
cancelButton = new javax.swing.JButton();
xmlRootTagLabel1 = new javax.swing.JLabel();
singleRoot = new javax.swing.JCheckBox();
multipleRoots = new javax.swing.JCheckBox();
include = new javax.swing.JCheckBox();
xmlRootTagLabel2 = new javax.swing.JLabel();
xmlRootTagLabel3 = new javax.swing.JLabel();
@@ -343,11 +343,16 @@ public class XmlSettingsDialog extends javax.swing.JDialog {
gridBagConstraints.insets = new java.awt.Insets(0, 8, 0, 8);
jPanel3.add(timestampExample, gridBagConstraints);
multipleRoots.setText("Single Object");
multipleRoots.setToolTipText("<html>Writes a single root/subject object with all its aggregated sub-objects. <br>The export process fails if more than one such object exists.</html>");
multipleRoots.addItemListener(new java.awt.event.ItemListener() {
singleRoot.setText("Single Object");
singleRoot.setToolTipText("<html>Writes a single root/subject object with all its aggregated sub-objects. <br>The export process fails if more than one such object exists.</html>");
singleRoot.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
multipleRootsItemStateChanged(evt);
singleRootItemStateChanged(evt);
}
});
singleRoot.addActionListener(new java.awt.event.ActionListener() {
public void actionPerformed(java.awt.event.ActionEvent evt) {
singleRootActionPerformed(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
@@ -355,7 +360,7 @@ public class XmlSettingsDialog extends javax.swing.JDialog {
gridBagConstraints.gridy = 20;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
gridBagConstraints.insets = new java.awt.Insets(8, 0, 0, 0);
jPanel3.add(multipleRoots, gridBagConstraints);
jPanel3.add(singleRoot, gridBagConstraints);
jPanel2.setLayout(new java.awt.GridBagLayout());
@@ -403,18 +408,18 @@ public class XmlSettingsDialog extends javax.swing.JDialog {
gridBagConstraints.insets = new java.awt.Insets(8, 0, 0, 0);
jPanel3.add(xmlRootTagLabel1, gridBagConstraints);
singleRoot.setText("Multiple Objects (Array)");
singleRoot.setToolTipText("<html>Writes an array/collection of all root/subject objects with all their aggregated sub-objects.</html>");
singleRoot.addItemListener(new java.awt.event.ItemListener() {
multipleRoots.setText("Multiple Objects (Array)");
multipleRoots.setToolTipText("<html>Writes an array/collection of all root/subject objects with all their aggregated sub-objects.</html>");
multipleRoots.addItemListener(new java.awt.event.ItemListener() {
public void itemStateChanged(java.awt.event.ItemEvent evt) {
singleRootItemStateChanged(evt);
multipleRootsItemStateChanged(evt);
}
});
gridBagConstraints = new java.awt.GridBagConstraints();
gridBagConstraints.gridx = 10;
gridBagConstraints.gridy = 22;
gridBagConstraints.fill = java.awt.GridBagConstraints.HORIZONTAL;
jPanel3.add(singleRoot, gridBagConstraints);
jPanel3.add(multipleRoots, gridBagConstraints);
include.setText("Include");
include.setToolTipText("Write out all objects that are not aggregated in any other object at root level.");
@@ -508,14 +513,14 @@ public class XmlSettingsDialog extends javax.swing.JDialog {
dispose();
}//GEN-LAST:event_cancelButtonActionPerformed
private void multipleRootsItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_multipleRootsItemStateChanged
rootTag.setEditable(!multipleRoots.isSelected());
}//GEN-LAST:event_multipleRootsItemStateChanged
private void singleRootItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_singleRootItemStateChanged
// TODO add your handling code here:
rootTag.setEditable(!multipleRoots.isSelected());
}//GEN-LAST:event_singleRootItemStateChanged
private void multipleRootsItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_multipleRootsItemStateChanged
rootTag.setEditable(!multipleRoots.isSelected());
}//GEN-LAST:event_multipleRootsItemStateChanged
private void includeItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_includeItemStateChanged
// TODO add your handling code here:
}//GEN-LAST:event_includeItemStateChanged
@@ -527,6 +532,10 @@ public class XmlSettingsDialog extends javax.swing.JDialog {
private void disallowItemStateChanged(java.awt.event.ItemEvent evt) {//GEN-FIRST:event_disallowItemStateChanged
// TODO add your handling code here:
}//GEN-LAST:event_disallowItemStateChanged
private void singleRootActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_singleRootActionPerformed
// TODO add your handling code here:
}//GEN-LAST:event_singleRootActionPerformed
// Variables declaration - do not modify//GEN-BEGIN:variables
private javax.swing.JButton Ok;

View File

@@ -15,7 +15,11 @@
*/
package net.sf.jailer.ui;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
@@ -31,11 +35,15 @@ import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import org.xml.sax.SAXException;
import net.sf.jailer.ExecutionContext;
import net.sf.jailer.datamodel.AggregationSchema;
import net.sf.jailer.datamodel.Association;
import net.sf.jailer.datamodel.Cardinality;
import net.sf.jailer.datamodel.Table;
import net.sf.jailer.subsetting.ScriptFormat;
import net.sf.jailer.xml.XmlRowWriter;
import net.sf.jailer.xml.XmlUtil;
import net.sf.jailer.xml.XmlUtil.ObjectNotationTransformerHandler;
/**
* Builds XML sketches.
@@ -50,19 +58,53 @@ public class XmlSketchBuilder {
* @param table the table
* @return xml sketch for table
*/
public static String buildSketch(Table table, int depth) throws Exception {
public static String buildSketch(Table table, int depth, ScriptFormat scriptFormat, ExecutionContext executionContext) throws Exception {
if (table == null) {
return "";
}
Document sketch = table.getXmlTemplateAsDocument(null);
if (sketch.getChildNodes().getLength() > 0 && sketch.getChildNodes().item(0) instanceof Element) {
insertAssociationSketch(sketch.getChildNodes().item(0), table, sketch, depth);
insertAssociationSketch(sketch.getChildNodes().item(0), table, sketch, scriptFormat, depth);
}
return XmlUtil.buildOmitDeclaration(sketch);
String result = XmlUtil.buildOmitDeclaration(sketch);
if (scriptFormat != ScriptFormat.XML) {
OutputStream out = new ByteArrayOutputStream();
ObjectNotationTransformerHandler th = XmlUtil.createObjectNotationTransformerHandler("", "", new OutputStreamWriter(out, Charset.defaultCharset()), true, scriptFormat, executionContext);
XmlRowWriter xmlRowWriter = new XmlRowWriter(out, null, null, null, null, scriptFormat, Charset.defaultCharset(), th, executionContext);
XmlUtil.visitDocumentNodes(XmlUtil.parse(result), xmlRowWriter.new XmlWritingNodeVisitor(null, null, table, null, null) {
@Override
protected Object toContent(String text, boolean returnNull) {
return "...";
}
@Override
public void visitAssociationElement(String associationName, String name) {
if (name != null) {
table.associations.stream().filter(a -> associationName.equals(a.getName())).findAny()
.ifPresent(a -> {
th.associationSketch(a, associationName, name);
});
}
}
});
th.endDocument();
result = out.toString();
}
return result;
}
private static void insertAssociationSketch(Node node, Table table, Document doc, int depth) throws DOMException, ParserConfigurationException, SAXException, IOException {
private static void insertAssociationSketch(Node node, Table table, Document doc, ScriptFormat scriptFormat, int depth) throws DOMException, ParserConfigurationException, SAXException, IOException {
NodeList children = node.getChildNodes();
if (node instanceof Element) {
Node a0 = ((Element) node).getAttributes().item(0);
if (a0 != null && a0.getNodeName() != null && a0.getNodeName().startsWith("j:")) {
((Element) node).removeAttribute(a0.getNodeName());
}
Node ch = ((Element) node).getFirstChild();
if (ch != null && ch.getTextContent().trim().startsWith("SQL:")) {
((Element) node).removeChild(ch);
((Element) node).appendChild(doc.createTextNode("..."));
}
}
int i = 0;
while (i < children.getLength()) {
if (children.item(i) instanceof Element) {
@@ -77,17 +119,22 @@ public class XmlSketchBuilder {
}
}
}
if (association != null && depth < 3) {
Node[] ae = insertAssociationSketch(association, doc, depth + 1);
if (association != null && depth < 5) {
Node[] ae = insertAssociationSketch(association, doc, scriptFormat, depth + 1);
if (ae != null) {
for (Node n: ae) {
node.insertBefore(doc.importNode(n, true), e);
++i;
}
}
}
node.removeChild(e);
}
if (scriptFormat == ScriptFormat.XML) {
node.removeChild(e);
} else {
++i;
}
} else {
insertAssociationSketch(e, table, doc, scriptFormat, depth + 1);
++i;
}
} else {
@@ -96,37 +143,39 @@ public class XmlSketchBuilder {
}
}
private static Node[] insertAssociationSketch(Association association, Document doc, int depth) throws ParserConfigurationException, SAXException, IOException {
if (association.getAggregationSchema() == AggregationSchema.EXPLICIT_LIST) {
Element e1 = doc.createElement(association.getAggregationTagName());
Element e2 = doc.createElement(association.destination.getUnqualifiedName().toLowerCase(Locale.ENGLISH));
e1.appendChild(e2);
if (association.getCardinality() != Cardinality.MANY_TO_ONE && association.getCardinality() != Cardinality.ONE_TO_ONE) {
e1.appendChild(doc.createComment("..."));
private static Node[] insertAssociationSketch(Association association, Document doc, ScriptFormat scriptFormat, int depth) throws ParserConfigurationException, SAXException, IOException {
if (scriptFormat == ScriptFormat.XML) {
if (association.getAggregationSchema() == AggregationSchema.EXPLICIT_LIST) {
Element e1 = doc.createElement(association.getAggregationTagName());
Element e2 = doc.createElement(association.destination.getUnqualifiedName().toLowerCase(Locale.ENGLISH));
e1.appendChild(e2);
// if (association.getCardinality() != Cardinality.MANY_TO_ONE && association.getCardinality() != Cardinality.ONE_TO_ONE) {
e1.appendChild(doc.createTextNode("..."));
// }
return new Node[] { e1 };
}
return new Node[] { e1 };
}
else if (association.getAggregationSchema() == AggregationSchema.IMPLICIT_LIST) {
Element e1 = doc.createElement(association.getAggregationTagName());
if (association.getCardinality() != Cardinality.MANY_TO_ONE && association.getCardinality() != Cardinality.ONE_TO_ONE) {
Node c = doc.createComment("...");
return new Node[] { e1, c };
else if (association.getAggregationSchema() == AggregationSchema.IMPLICIT_LIST) {
Element e1 = doc.createElement(association.getAggregationTagName());
// if (association.getCardinality() != Cardinality.MANY_TO_ONE && association.getCardinality() != Cardinality.ONE_TO_ONE) {
e1.appendChild(doc.createTextNode("..."));
return new Node[] { e1 };
// }
// return new Node[] { e1 };
} else if (association.getAggregationSchema() == AggregationSchema.FLAT) {
Document sketch = association.destination.getXmlTemplateAsDocument(null);
List<Node> nodes = new ArrayList<Node>();
if (sketch.getChildNodes().getLength() > 0 && sketch.getChildNodes().item(0) instanceof Element) {
insertAssociationSketch(sketch.getChildNodes().item(0), association.destination, sketch, scriptFormat, depth + 1);
}
NodeList children = sketch.getChildNodes().item(0).getChildNodes();
for (int i = 0; i < children.getLength(); ++i) {
nodes.add(children.item(i));
}
// if (association.getCardinality() != Cardinality.MANY_TO_ONE && association.getCardinality() != Cardinality.ONE_TO_ONE) {
// nodes.add(sketch.createTextNode("..."));
// }
return nodes.toArray(new Node[nodes.size()]);
}
return new Node[] { e1 };
} else if (association.getAggregationSchema() == AggregationSchema.FLAT) {
Document sketch = association.destination.getXmlTemplateAsDocument(null);
List<Node> nodes = new ArrayList<Node>();
if (sketch.getChildNodes().getLength() > 0 && sketch.getChildNodes().item(0) instanceof Element) {
insertAssociationSketch(sketch.getChildNodes().item(0), association.destination, sketch, depth + 1);
}
NodeList children = sketch.getChildNodes().item(0).getChildNodes();
for (int i = 0; i < children.getLength(); ++i) {
nodes.add(children.item(i));
}
if (association.getCardinality() != Cardinality.MANY_TO_ONE && association.getCardinality() != Cardinality.ONE_TO_ONE) {
nodes.add(sketch.createComment("..."));
}
return nodes.toArray(new Node[nodes.size()]);
}
return null;
}