From 685a2924e26cadae9fdfd4fe091db9815ed7f5ec Mon Sep 17 00:00:00 2001 From: lukaseder Date: Mon, 12 Feb 2018 15:39:27 +0100 Subject: [PATCH] [#7163] Add Settings.parseWithMetaLookups --- .../org/jooq/conf/ParseWithMetaLookups.java | 47 +++++++ .../src/main/java/org/jooq/conf/Settings.java | 32 +++++ .../java/org/jooq/impl/CatalogMetaImpl.java | 116 ++++++++++++++++++ .../org/jooq/impl/CatalogMetaProvider.java | 65 ++++++++++ .../java/org/jooq/impl/DefaultDSLContext.java | 6 +- .../impl/InformationSchemaMetaProvider.java | 65 ++++++++++ .../main/java/org/jooq/impl/ParserImpl.java | 10 +- .../java/org/jooq/impl/SchemaMetaImpl.java | 116 ++++++++++++++++++ .../org/jooq/impl/SchemaMetaProvider.java | 65 ++++++++++ .../java/org/jooq/impl/TableMetaImpl.java | 112 +++++++++++++++++ .../java/org/jooq/impl/TableMetaProvider.java | 65 ++++++++++ .../resources/xsd/jooq-runtime-3.11.0.xsd | 18 +++ 12 files changed, 713 insertions(+), 4 deletions(-) create mode 100644 jOOQ/src/main/java/org/jooq/conf/ParseWithMetaLookups.java create mode 100644 jOOQ/src/main/java/org/jooq/impl/CatalogMetaImpl.java create mode 100644 jOOQ/src/main/java/org/jooq/impl/CatalogMetaProvider.java create mode 100644 jOOQ/src/main/java/org/jooq/impl/InformationSchemaMetaProvider.java create mode 100644 jOOQ/src/main/java/org/jooq/impl/SchemaMetaImpl.java create mode 100644 jOOQ/src/main/java/org/jooq/impl/SchemaMetaProvider.java create mode 100644 jOOQ/src/main/java/org/jooq/impl/TableMetaImpl.java create mode 100644 jOOQ/src/main/java/org/jooq/impl/TableMetaProvider.java diff --git a/jOOQ/src/main/java/org/jooq/conf/ParseWithMetaLookups.java b/jOOQ/src/main/java/org/jooq/conf/ParseWithMetaLookups.java new file mode 100644 index 0000000000..52c5671fcd --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/conf/ParseWithMetaLookups.java @@ -0,0 +1,47 @@ + + + + + + + + +package org.jooq.conf; + +import javax.xml.bind.annotation.XmlEnum; +import javax.xml.bind.annotation.XmlType; + + +/** + *

Java class for ParseWithMetaLookups. + * + *

The following schema fragment specifies the expected content contained within this class. + *

+ *

+ * <simpleType name="ParseWithMetaLookups">
+ *   <restriction base="{http://www.w3.org/2001/XMLSchema}string">
+ *     <enumeration value="OFF"/>
+ *     <enumeration value="IGNORE_ON_FAILURE"/>
+ *     <enumeration value="THROW_ON_FAILURE"/>
+ *   </restriction>
+ * </simpleType>
+ * 
+ * + */ +@XmlType(name = "ParseWithMetaLookups") +@XmlEnum +public enum ParseWithMetaLookups { + + OFF, + IGNORE_ON_FAILURE, + THROW_ON_FAILURE; + + public String value() { + return name(); + } + + public static ParseWithMetaLookups fromValue(String v) { + return valueOf(v); + } + +} diff --git a/jOOQ/src/main/java/org/jooq/conf/Settings.java b/jOOQ/src/main/java/org/jooq/conf/Settings.java index 262fc8be49..205822b81d 100644 --- a/jOOQ/src/main/java/org/jooq/conf/Settings.java +++ b/jOOQ/src/main/java/org/jooq/conf/Settings.java @@ -112,6 +112,9 @@ public class Settings @XmlElement(defaultValue = "LOG_DEBUG") @XmlSchemaType(name = "string") protected ExecuteWithoutWhere executeDeleteWithoutWhere = ExecuteWithoutWhere.LOG_DEBUG; + @XmlElement(defaultValue = "IGNORE_ON_FAILURE") + @XmlSchemaType(name = "string") + protected ParseWithMetaLookups parseWithMetaLookups = ParseWithMetaLookups.IGNORE_ON_FAILURE; /** * Whether any catalog name should be rendered at all. @@ -992,6 +995,30 @@ public class Settings this.executeDeleteWithoutWhere = value; } + /** + * [#7163] Whether the parser should perform meta lookups in the Configuration's MetaProvider. + * + * @return + * possible object is + * {@link ParseWithMetaLookups } + * + */ + public ParseWithMetaLookups getParseWithMetaLookups() { + return parseWithMetaLookups; + } + + /** + * Sets the value of the parseWithMetaLookups property. + * + * @param value + * allowed object is + * {@link ParseWithMetaLookups } + * + */ + public void setParseWithMetaLookups(ParseWithMetaLookups value) { + this.parseWithMetaLookups = value; + } + public Settings withRenderCatalog(Boolean value) { setRenderCatalog(value); return this; @@ -1167,4 +1194,9 @@ public class Settings return this; } + public Settings withParseWithMetaLookups(ParseWithMetaLookups value) { + setParseWithMetaLookups(value); + return this; + } + } diff --git a/jOOQ/src/main/java/org/jooq/impl/CatalogMetaImpl.java b/jOOQ/src/main/java/org/jooq/impl/CatalogMetaImpl.java new file mode 100644 index 0000000000..9ffbb8c828 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/impl/CatalogMetaImpl.java @@ -0,0 +1,116 @@ +/* + * 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.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +import org.jooq.Catalog; +import org.jooq.Configuration; +import org.jooq.Meta; +import org.jooq.Schema; +import org.jooq.Sequence; +import org.jooq.Table; +import org.jooq.UniqueKey; + +/** + * @author Lukas Eder + */ +final class CatalogMetaImpl implements Meta { + + @SuppressWarnings("unused") + private final Configuration configuration; + private final Catalog[] catalogs; + + CatalogMetaImpl(Configuration configuration, Catalog[] catalogs) { + this.configuration = configuration; + this.catalogs = catalogs; + } + + @Override + public final List getCatalogs() { + return Collections.unmodifiableList(Arrays.asList(catalogs)); + } + + @Override + public final List getSchemas() { + List result = new ArrayList(); + + for (Catalog catalog : catalogs) + result.addAll(catalog.getSchemas()); + + return result; + } + + @Override + public final List> getTables() { + List> result = new ArrayList>(); + + for (Catalog catalog : catalogs) + for (Schema schema : catalog.getSchemas()) + result.addAll(schema.getTables()); + + return result; + } + + @Override + public final List> getSequences() { + List> result = new ArrayList>(); + + for (Catalog catalog : catalogs) + for (Schema schema : catalog.getSchemas()) + result.addAll(schema.getSequences()); + + return result; + } + + @Override + public final List> getPrimaryKeys() { + List> result = new ArrayList>(); + + for (Catalog catalog : catalogs) + for (Schema schema : catalog.getSchemas()) + for (Table table : schema.getTables()) + if (table.getPrimaryKey() != null) + result.add(table.getPrimaryKey()); + + return result; + } +} diff --git a/jOOQ/src/main/java/org/jooq/impl/CatalogMetaProvider.java b/jOOQ/src/main/java/org/jooq/impl/CatalogMetaProvider.java new file mode 100644 index 0000000000..103fc49c77 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/impl/CatalogMetaProvider.java @@ -0,0 +1,65 @@ +/* + * 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.impl; + +import org.jooq.Catalog; +import org.jooq.Configuration; +import org.jooq.Meta; +import org.jooq.MetaProvider; + +/** + * A {@link MetaProvider} that provides its meta data based on (possibly + * generated) catalogs. + * + * @author Lukas Eder + */ +public class CatalogMetaProvider implements MetaProvider { + + private final Configuration configuration; + private final Catalog[] catalogs; + + public CatalogMetaProvider(Configuration configuration, Catalog... catalogs) { + this.configuration = configuration; + this.catalogs = catalogs; + } + + @Override + public Meta provide() { + return new CatalogMetaImpl(configuration, catalogs); + } +} diff --git a/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java b/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java index 584691148a..24bb28a72b 100644 --- a/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java +++ b/jOOQ/src/main/java/org/jooq/impl/DefaultDSLContext.java @@ -410,17 +410,17 @@ public class DefaultDSLContext extends AbstractScope implements DSLContext, Seri @Override public Meta meta(Catalog... catalogs) { - return null; + return new CatalogMetaImpl(configuration(), catalogs); } @Override public Meta meta(Schema... schemas) { - return null; + return new SchemaMetaImpl(configuration(), schemas); } @Override public Meta meta(Table... tables) { - return null; + return new TableMetaImpl(configuration(), tables); } @Override diff --git a/jOOQ/src/main/java/org/jooq/impl/InformationSchemaMetaProvider.java b/jOOQ/src/main/java/org/jooq/impl/InformationSchemaMetaProvider.java new file mode 100644 index 0000000000..411d97ec38 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/impl/InformationSchemaMetaProvider.java @@ -0,0 +1,65 @@ +/* + * 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.impl; + +import org.jooq.Configuration; +import org.jooq.Meta; +import org.jooq.MetaProvider; +import org.jooq.util.xml.jaxb.InformationSchema; + +/** + * A {@link MetaProvider} that provides its meta data based on JAXB-annotated + * {@link InformationSchema} meta information. + * + * @author Lukas Eder + */ +public class InformationSchemaMetaProvider implements MetaProvider { + + private final Configuration configuration; + private final InformationSchema schema; + + public InformationSchemaMetaProvider(Configuration configuration, InformationSchema schema) { + this.configuration = configuration; + this.schema = schema; + } + + @Override + public Meta provide() { + return new InformationSchemaMetaImpl(configuration, schema); + } +} diff --git a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java index 7ffd26e323..caf963bc6e 100644 --- a/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java +++ b/jOOQ/src/main/java/org/jooq/impl/ParserImpl.java @@ -39,6 +39,8 @@ package org.jooq.impl; import static java.util.Collections.emptyList; import static java.util.Collections.singletonList; +import static org.jooq.conf.ParseWithMetaLookups.IGNORE_ON_FAILURE; +import static org.jooq.conf.ParseWithMetaLookups.THROW_ON_FAILURE; import static org.jooq.impl.DSL.abs; import static org.jooq.impl.DSL.acos; import static org.jooq.impl.DSL.arrayAgg; @@ -316,6 +318,7 @@ import org.jooq.MergeFinalStep; import org.jooq.MergeMatchedStep; import org.jooq.MergeNotMatchedStep; import org.jooq.MergeUsingStep; +import org.jooq.Meta; import org.jooq.Name; import org.jooq.OrderedAggregateFunction; import org.jooq.OrderedAggregateFunctionOfDeferredType; @@ -365,6 +368,7 @@ import org.jooq.WindowSpecification; import org.jooq.WindowSpecificationOrderByStep; import org.jooq.WindowSpecificationRowsAndStep; import org.jooq.WindowSpecificationRowsStep; +import org.jooq.conf.ParseWithMetaLookups; import org.jooq.tools.reflect.Reflect; /** @@ -373,10 +377,14 @@ import org.jooq.tools.reflect.Reflect; @SuppressWarnings({ "rawtypes", "unchecked" }) final class ParserImpl implements Parser { - private final DSLContext dsl; + private final DSLContext dsl; + private final ParseWithMetaLookups metaLookups; + private final Meta meta; ParserImpl(Configuration configuration) { this.dsl = DSL.using(configuration); + this.metaLookups = configuration.settings().getParseWithMetaLookups(); + this.meta = metaLookups == IGNORE_ON_FAILURE || metaLookups == THROW_ON_FAILURE ? dsl.meta() : null; } // ----------------------------------------------------------------------------------------------------------------- diff --git a/jOOQ/src/main/java/org/jooq/impl/SchemaMetaImpl.java b/jOOQ/src/main/java/org/jooq/impl/SchemaMetaImpl.java new file mode 100644 index 0000000000..c6765e193c --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/impl/SchemaMetaImpl.java @@ -0,0 +1,116 @@ +/* + * 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.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import org.jooq.Catalog; +import org.jooq.Configuration; +import org.jooq.Meta; +import org.jooq.Schema; +import org.jooq.Sequence; +import org.jooq.Table; +import org.jooq.UniqueKey; + +/** + * @author Lukas Eder + */ +final class SchemaMetaImpl implements Meta { + + @SuppressWarnings("unused") + private final Configuration configuration; + private final Schema[] schemas; + + SchemaMetaImpl(Configuration configuration, Schema[] schemas) { + this.configuration = configuration; + this.schemas = schemas; + } + + @Override + public final List getCatalogs() { + Set result = new LinkedHashSet(); + + for (Schema schema : schemas) + if (schema.getCatalog() != null) + result.add(schema.getCatalog()); + + return new ArrayList(result); + } + + @Override + public final List getSchemas() { + return Collections.unmodifiableList(Arrays.asList(schemas)); + } + + @Override + public final List> getTables() { + List> result = new ArrayList>(); + + for (Schema schema : schemas) + result.addAll(schema.getTables()); + + return result; + } + + @Override + public final List> getSequences() { + List> result = new ArrayList>(); + + for (Schema schema : schemas) + result.addAll(schema.getSequences()); + + return result; + } + + @Override + public final List> getPrimaryKeys() { + List> result = new ArrayList>(); + + for (Schema schema : schemas) + for (Table table : schema.getTables()) + if (table.getPrimaryKey() != null) + result.add(table.getPrimaryKey()); + + return result; + } +} diff --git a/jOOQ/src/main/java/org/jooq/impl/SchemaMetaProvider.java b/jOOQ/src/main/java/org/jooq/impl/SchemaMetaProvider.java new file mode 100644 index 0000000000..bc8f2ff161 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/impl/SchemaMetaProvider.java @@ -0,0 +1,65 @@ +/* + * 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.impl; + +import org.jooq.Configuration; +import org.jooq.Meta; +import org.jooq.MetaProvider; +import org.jooq.Schema; + +/** + * A {@link MetaProvider} that provides its meta data based on (possibly + * generated) schemas. + * + * @author Lukas Eder + */ +public class SchemaMetaProvider implements MetaProvider { + + private final Configuration configuration; + private final Schema[] schemas; + + public SchemaMetaProvider(Configuration configuration, Schema... schemas) { + this.configuration = configuration; + this.schemas = schemas; + } + + @Override + public Meta provide() { + return new SchemaMetaImpl(configuration, schemas); + } +} diff --git a/jOOQ/src/main/java/org/jooq/impl/TableMetaImpl.java b/jOOQ/src/main/java/org/jooq/impl/TableMetaImpl.java new file mode 100644 index 0000000000..e9d0c071a0 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/impl/TableMetaImpl.java @@ -0,0 +1,112 @@ +/* + * 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.impl; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Set; + +import org.jooq.Catalog; +import org.jooq.Configuration; +import org.jooq.Meta; +import org.jooq.Schema; +import org.jooq.Sequence; +import org.jooq.Table; +import org.jooq.UniqueKey; + +/** + * @author Lukas Eder + */ +final class TableMetaImpl implements Meta { + + @SuppressWarnings("unused") + private final Configuration configuration; + private final Table[] tables; + + TableMetaImpl(Configuration configuration, Table[] tables) { + this.configuration = configuration; + this.tables = tables; + } + + @Override + public final List getCatalogs() { + Set result = new LinkedHashSet(); + + for (Table table : tables) + if (table.getSchema() != null) + if (table.getSchema().getCatalog() != null) + result.add(table.getSchema().getCatalog()); + + return new ArrayList(result); + } + + @Override + public final List getSchemas() { + Set result = new LinkedHashSet(); + + for (Table table : tables) + if (table.getSchema() != null) + result.add(table.getSchema()); + + return new ArrayList(result); + } + + @Override + public final List> getTables() { + return Collections.unmodifiableList(Arrays.asList(tables)); + } + + @Override + public final List> getSequences() { + return Collections.emptyList(); + } + + @Override + public final List> getPrimaryKeys() { + List> result = new ArrayList>(); + + for (Table table : tables) + if (table.getPrimaryKey() != null) + result.add(table.getPrimaryKey()); + + return result; + } +} diff --git a/jOOQ/src/main/java/org/jooq/impl/TableMetaProvider.java b/jOOQ/src/main/java/org/jooq/impl/TableMetaProvider.java new file mode 100644 index 0000000000..e81bf3d9e8 --- /dev/null +++ b/jOOQ/src/main/java/org/jooq/impl/TableMetaProvider.java @@ -0,0 +1,65 @@ +/* + * 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.impl; + +import org.jooq.Configuration; +import org.jooq.Meta; +import org.jooq.MetaProvider; +import org.jooq.Table; + +/** + * A {@link MetaProvider} that provides its meta data based on (possibly + * generated) schemas. + * + * @author Lukas Eder + */ +public class TableMetaProvider implements MetaProvider { + + private final Configuration configuration; + private final Table[] tables; + + public TableMetaProvider(Configuration configuration, Table... tables) { + this.configuration = configuration; + this.tables = tables; + } + + @Override + public Meta provide() { + return new TableMetaImpl(configuration, tables); + } +} diff --git a/jOOQ/src/main/resources/xsd/jooq-runtime-3.11.0.xsd b/jOOQ/src/main/resources/xsd/jooq-runtime-3.11.0.xsd index 694a0ac7ce..06b68a755c 100644 --- a/jOOQ/src/main/resources/xsd/jooq-runtime-3.11.0.xsd +++ b/jOOQ/src/main/resources/xsd/jooq-runtime-3.11.0.xsd @@ -190,6 +190,10 @@ jOOQ queries, for which no specific fetchSize value was specified.]]> + + + + @@ -448,4 +452,18 @@ Either <input/> or <inputExpression/> must be provided]]> + + + + + + + + + + + + + + \ No newline at end of file