View Javadoc
1   /*
2    * (c) Copyright 2006-2020 by rapiddweller GmbH & Volker Bergmann. All rights reserved.
3    *
4    * Redistribution and use in source and binary forms, with or without
5    * modification, is permitted under the terms of the
6    * GNU General Public License.
7    *
8    * For redistributing this software or a derivative work under a license other
9    * than the GPL-compatible Free Software License as defined by the Free
10   * Software Foundation or approved by OSI, you must first obtain a commercial
11   * license to this software product from rapiddweller GmbH & Volker Bergmann.
12   *
13   * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
14   * WITHOUT A WARRANTY OF ANY KIND. ALL EXPRESS OR IMPLIED CONDITIONS,
15   * REPRESENTATIONS AND WARRANTIES, INCLUDING ANY IMPLIED WARRANTY OF
16   * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT, ARE
17   * HEREBY EXCLUDED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
18   * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
19   * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
20   * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
21   * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
22   * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
23   * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
24   * POSSIBILITY OF SUCH DAMAGE.
25   */
26  
27  package com.rapiddweller.benerator.engine.parser.xml;
28  
29  import com.rapiddweller.benerator.engine.BeneratorContext;
30  import com.rapiddweller.benerator.engine.BeneratorRootStatement;
31  import com.rapiddweller.benerator.engine.Statement;
32  import com.rapiddweller.benerator.engine.statement.DefineDatabaseStatement;
33  import com.rapiddweller.benerator.engine.statement.IfStatement;
34  import com.rapiddweller.common.CollectionUtil;
35  import com.rapiddweller.common.ConfigurationError;
36  import com.rapiddweller.common.Context;
37  import com.rapiddweller.common.ConversionException;
38  import com.rapiddweller.script.Expression;
39  import com.rapiddweller.script.expression.DynamicExpression;
40  import com.rapiddweller.script.expression.FallbackExpression;
41  import org.w3c.dom.Element;
42  
43  import java.util.Set;
44  
45  import static com.rapiddweller.benerator.engine.DescriptorConstants.ATT_ACC_UNK_COL_TYPES;
46  import static com.rapiddweller.benerator.engine.DescriptorConstants.ATT_BATCH;
47  import static com.rapiddweller.benerator.engine.DescriptorConstants.ATT_CATALOG;
48  import static com.rapiddweller.benerator.engine.DescriptorConstants.ATT_DRIVER;
49  import static com.rapiddweller.benerator.engine.DescriptorConstants.ATT_ENVIRONMENT;
50  import static com.rapiddweller.benerator.engine.DescriptorConstants.ATT_EXCL_TABLES;
51  import static com.rapiddweller.benerator.engine.DescriptorConstants.ATT_FETCH_SIZE;
52  import static com.rapiddweller.benerator.engine.DescriptorConstants.ATT_ID;
53  import static com.rapiddweller.benerator.engine.DescriptorConstants.ATT_INCL_TABLES;
54  import static com.rapiddweller.benerator.engine.DescriptorConstants.ATT_LAZY;
55  import static com.rapiddweller.benerator.engine.DescriptorConstants.ATT_META_CACHE;
56  import static com.rapiddweller.benerator.engine.DescriptorConstants.ATT_PASSWORD;
57  import static com.rapiddweller.benerator.engine.DescriptorConstants.ATT_READ_ONLY;
58  import static com.rapiddweller.benerator.engine.DescriptorConstants.ATT_SCHEMA;
59  import static com.rapiddweller.benerator.engine.DescriptorConstants.ATT_TABLE_FILTER;
60  import static com.rapiddweller.benerator.engine.DescriptorConstants.ATT_URL;
61  import static com.rapiddweller.benerator.engine.DescriptorConstants.ATT_USER;
62  import static com.rapiddweller.benerator.engine.DescriptorConstants.EL_DATABASE;
63  import static com.rapiddweller.benerator.engine.parser.xml.DescriptorParserUtil.parseAttribute;
64  import static com.rapiddweller.benerator.engine.parser.xml.DescriptorParserUtil.parseBooleanExpressionAttribute;
65  import static com.rapiddweller.benerator.engine.parser.xml.DescriptorParserUtil.parseIntAttribute;
66  import static com.rapiddweller.benerator.engine.parser.xml.DescriptorParserUtil.parseScriptableStringAttribute;
67  
68  /**
69   * Parses a &lt;database&gt; element in a Benerator descriptor file.<br/><br/>
70   * Created: 25.10.2009 00:40:56
71   *
72   * @author Volker Bergmann
73   * @since 0.6.0
74   */
75  public class DatabaseParser extends AbstractBeneratorDescriptorParser {
76  
77    private static final Set<String> REQUIRED_ATTRIBUTES = CollectionUtil.toSet(ATT_ID);
78  
79    private static final Set<String> OPTIONAL_ATTRIBUTES = CollectionUtil.toSet(
80        ATT_ENVIRONMENT, ATT_URL, ATT_DRIVER, ATT_USER, ATT_PASSWORD, ATT_CATALOG, ATT_SCHEMA,
81        ATT_TABLE_FILTER, ATT_INCL_TABLES, ATT_EXCL_TABLES, ATT_META_CACHE, ATT_BATCH, ATT_FETCH_SIZE,
82        ATT_READ_ONLY, ATT_LAZY, ATT_ACC_UNK_COL_TYPES);
83  
84  
85    // TODO v1.0 define parser extension mechanism and move DatabaseParser and DefineDatabaseStatement to DB package?
86  
87    /**
88     * Instantiates a new Database parser.
89     */
90    public DatabaseParser() {
91      super(EL_DATABASE, REQUIRED_ATTRIBUTES, OPTIONAL_ATTRIBUTES,
92          BeneratorRootStatement.class, IfStatement.class);
93    }
94  
95    @Override
96    public DefineDatabaseStatement doParse(Element element, Statement[] parentPath, BeneratorParseContext context) {
97      // check preconditions
98      assertAtLeastOneAttributeIsSet(element, ATT_ENVIRONMENT, ATT_DRIVER);
99      assertAtLeastOneAttributeIsSet(element, ATT_ENVIRONMENT, ATT_URL);
100 
101     // parse
102     try {
103       Expression<String> id = parseAttribute(ATT_ID, element);
104       Expression<String> environment = parseScriptableStringAttribute(ATT_ENVIRONMENT, element);
105       Expression<String> url = parseScriptableStringAttribute(ATT_URL, element);
106       Expression<String> driver = parseScriptableStringAttribute(ATT_DRIVER, element);
107       Expression<String> user = parseScriptableStringAttribute(ATT_USER, element);
108       Expression<String> password = parseScriptableStringAttribute(ATT_PASSWORD, element);
109       Expression<String> catalog = parseScriptableStringAttribute(ATT_CATALOG, element);
110       Expression<String> schema = parseScriptableStringAttribute(ATT_SCHEMA, element);
111       Expression<String> tableFilter = parseScriptableStringAttribute(ATT_TABLE_FILTER, element);
112       Expression<String> includeTables = parseScriptableStringAttribute(ATT_INCL_TABLES, element);
113       Expression<String> excludeTables = parseScriptableStringAttribute(ATT_EXCL_TABLES, element);
114       Expression<Boolean> metaCache = parseBooleanExpressionAttribute(ATT_META_CACHE, element, false);
115       Expression<Boolean> batch = parseBooleanExpressionAttribute(ATT_BATCH, element, false);
116       Expression<Integer> fetchSize = parseIntAttribute(ATT_FETCH_SIZE, element, 100);
117       Expression<Boolean> readOnly = parseBooleanExpressionAttribute(ATT_READ_ONLY, element, false);
118       Expression<Boolean> lazy = parseBooleanExpressionAttribute(ATT_LAZY, element, true);
119       Expression<Boolean> acceptUnknownColumnTypes = new FallbackExpression<>(
120           parseBooleanExpressionAttribute(ATT_ACC_UNK_COL_TYPES, element),
121           new GlobalAcceptUnknownSimpleTypeExpression());
122       return createDatabaseStatement(id, environment, url, driver, user,
123           password, catalog, schema, tableFilter, includeTables,
124           excludeTables, metaCache, batch, fetchSize, readOnly, lazy,
125           acceptUnknownColumnTypes, context);
126     } catch (ConversionException e) {
127       throw new ConfigurationError(e);
128     }
129   }
130 
131   /**
132    * Create database statement define database statement.
133    *
134    * @param id                       the id
135    * @param environment              the environment
136    * @param url                      the url
137    * @param driver                   the driver
138    * @param user                     the user
139    * @param password                 the password
140    * @param catalog                  the catalog
141    * @param schema                   the schema
142    * @param tableFilter              the table filter
143    * @param includeTables            the include tables
144    * @param excludeTables            the exclude tables
145    * @param metaCache                the meta cache
146    * @param batch                    the batch
147    * @param fetchSize                the fetch size
148    * @param readOnly                 the read only
149    * @param lazy                     the lazy
150    * @param acceptUnknownColumnTypes the accept unknown column types
151    * @param context                  the context
152    * @return the define database statement
153    */
154   protected DefineDatabaseStatement createDatabaseStatement(
155       Expression<String> id, Expression<String> environment,
156       Expression<String> url, Expression<String> driver,
157       Expression<String> user, Expression<String> password,
158       Expression<String> catalog, Expression<String> schema,
159       Expression<String> tableFilter, Expression<String> includeTables,
160       Expression<String> excludeTables, Expression<Boolean> metaCache,
161       Expression<Boolean> batch, Expression<Integer> fetchSize,
162       Expression<Boolean> readOnly, Expression<Boolean> lazy,
163       Expression<Boolean> acceptUnknownColumnTypes,
164       BeneratorParseContext context) {
165     return new DefineDatabaseStatement(id, environment, url, driver, user, password, catalog, schema,
166         metaCache, tableFilter, includeTables, excludeTables,
167         batch, fetchSize, readOnly, lazy, acceptUnknownColumnTypes, context.getResourceManager());
168   }
169 
170   /**
171    * The type Global accept unknown simple type expression.
172    */
173   static class GlobalAcceptUnknownSimpleTypeExpression extends DynamicExpression<Boolean> {
174     @Override
175     public Boolean evaluate(Context context) {
176       return ((BeneratorContext) context).isAcceptUnknownSimpleTypes();
177     }
178   }
179 
180 }