Author: cbrisson
Date: Thu Apr 18 15:20:59 2019
New Revision: 1857762
URL: http://svn.apache.org/viewvc?rev=1857762&view=rev
Log:
[tools/model] Add tests
Added:
velocity/tools/branches/model/velocity-tools-model/src/test/java/org/apache/velocity/tools/model/BaseBookshelfTests.java
velocity/tools/branches/model/velocity-tools-model/src/test/java/org/apache/velocity/tools/model/BasicModelToolTests.java
velocity/tools/branches/model/velocity-tools-model/src/test/resources/
velocity/tools/branches/model/velocity-tools-model/src/test/resources/blank_model.xml
velocity/tools/branches/model/velocity-tools-model/src/test/resources/blank_model_tools.xml
velocity/tools/branches/model/velocity-tools-model/src/test/resources/bookshelf.sql
velocity/tools/branches/model/velocity-tools-model/src/test/resources/test_action.xml
velocity/tools/branches/model/velocity-tools-model/src/test/resources/test_init_model.xml
velocity/tools/branches/model/velocity-tools-model/src/test/resources/test_mapping.properties
velocity/tools/branches/model/velocity-tools-model/src/test/resources/test_minimal_model.xml
Removed:
velocity/tools/branches/model/velocity-tools-model/dependency-reduced-pom.xml
Modified:
velocity/tools/branches/model/velocity-tools-model/pom.xml
Modified: velocity/tools/branches/model/velocity-tools-model/pom.xml
URL:
http://svn.apache.org/viewvc/velocity/tools/branches/model/velocity-tools-model/pom.xml?rev=1857762&r1=1857761&r2=1857762&view=diff
==============================================================================
--- velocity/tools/branches/model/velocity-tools-model/pom.xml (original)
+++ velocity/tools/branches/model/velocity-tools-model/pom.xml Thu Apr 18
15:20:59 2019
@@ -106,6 +106,11 @@
<version>${project.version}</version>
</dependency>
<dependency>
+ <groupId>org.atteo</groupId>
+ <artifactId>evo-inflector</artifactId>
+ <version>1.2.2</version>
+ </dependency>
+ <dependency>
<groupId>commons-codec</groupId>
<artifactId>commons-codec</artifactId>
<version>1.12</version>
@@ -120,5 +125,28 @@
<artifactId>slf4j-simple</artifactId>
<scope>test</scope>
</dependency>
+ <dependency>
+ <groupId>org.apache.commons</groupId>
+ <artifactId>commons-dbcp2</artifactId>
+ <version>2.6.0</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.hsqldb</groupId>
+ <artifactId>hsqldb</artifactId>
+ <version>2.4.1</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>commons-io</groupId>
+ <artifactId>commons-io</artifactId>
+ <version>2.6</version>
+ <scope>test</scope>
+ </dependency>
+ <dependency>
+ <groupId>org.easymock</groupId>
+ <artifactId>easymock</artifactId>
+ <scope>test</scope>
+ </dependency>
</dependencies>
</project>
Added:
velocity/tools/branches/model/velocity-tools-model/src/test/java/org/apache/velocity/tools/model/BaseBookshelfTests.java
URL:
http://svn.apache.org/viewvc/velocity/tools/branches/model/velocity-tools-model/src/test/java/org/apache/velocity/tools/model/BaseBookshelfTests.java?rev=1857762&view=auto
==============================================================================
---
velocity/tools/branches/model/velocity-tools-model/src/test/java/org/apache/velocity/tools/model/BaseBookshelfTests.java
(added)
+++
velocity/tools/branches/model/velocity-tools-model/src/test/java/org/apache/velocity/tools/model/BaseBookshelfTests.java
Thu Apr 18 15:20:59 2019
@@ -0,0 +1,135 @@
+package org.apache.velocity.tools.model;
+
+import org.apache.commons.dbcp2.BasicDataSource;
+import org.apache.commons.io.IOUtils;
+import org.apache.velocity.app.VelocityEngine;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.naming.spi.InitialContextFactory;
+import javax.sql.DataSource;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.sql.Connection;
+import java.sql.Statement;
+import java.util.Hashtable;
+import java.util.Properties;
+
+public class BaseBookshelfTests
+{
+ protected VelocityEngine createVelocityEngine(String propertiesFile)
+ {
+ VelocityEngine engine = propertiesFile == null ? new VelocityEngine()
: new VelocityEngine(propertiesFile);
+ engine.init();
+ return engine;
+ }
+
+ protected VelocityEngine createVelocityEngine(Properties properties)
+ {
+ VelocityEngine engine = properties == null ? new VelocityEngine() :
new VelocityEngine(properties);
+ engine.init();
+ return engine;
+ }
+
+
+ protected static DataSource initDataSource() throws Exception
+ {
+ BasicDataSource ds = new BasicDataSource();
+ ds.setUrl("jdbc:hsqldb:.;hsqldb.sqllog=3");
+ ds.setUsername("sa");
+ ds.setPassword("");
+ return ds;
+ }
+
+ private static boolean dataSourcePopulated = false;
+
+ protected static synchronized void populateDataSource() throws Exception
+ {
+ if (dataSourcePopulated)
+ {
+ return;
+ }
+ DataSource ds = initDataSource();
+ Connection connection = ds.getConnection();
+ Statement statement = connection.createStatement();
+ String sql = IOUtils.toString(getResourceReader("bookshelf.sql"));
+ for (String command : sql.split(";"))
+ {
+ if (command.trim().length() == 0) continue;
+ // System.err.println("Running ["+command+"]");
+ statement.executeUpdate(command);
+ // System.err.println("Done.");
+ }
+ statement.close();
+ connection.close();
+ dataSourcePopulated = true;
+ }
+
+ protected static URL getResource(String name)
+ {
+ return BasicModelToolTests.class.getClassLoader().getResource(name);
+ }
+
+ protected static Reader getResourceReader(String name)
+ {
+ return new
InputStreamReader(BasicModelToolTests.class.getClassLoader().getResourceAsStream(name),
StandardCharsets.UTF_8);
+ }
+
+ public static class TestJNDIContext extends InitialContext
+ {
+ public TestJNDIContext() throws NamingException
+ {}
+
+ @Override
+ public Object lookup(String name) throws NamingException
+ {
+ try
+ {
+ // System.err.println("@@@ looking for " + name);
+ switch (name)
+ {
+ case "java:comp/env": return this;
+ case "jdbc/test-data-source": return initDataSource();
+ default: return null;
+ }
+ }
+ catch(Exception e)
+ {
+ e.printStackTrace();
+ }
+ return null;
+ }
+ }
+
+ /*
+ * A dummy jndi mechanism
+ */
+
+ static TestJNDIContext jndiContext;
+ static
+ {
+ try
+ {
+ // define system property after singleton creation to avoid
infinite loop
+ jndiContext = new TestJNDIContext();
+ System.setProperty("java.naming.factory.initial",
JNDIContextFactory.class.getName());
+ }
+ catch (NamingException ne)
+ {
+ ne.printStackTrace();
+ }
+ }
+
+ public static class JNDIContextFactory implements InitialContextFactory
+ {
+ @Override
+ public javax.naming.Context getInitialContext(Hashtable<?, ?>
environment) throws NamingException
+ {
+ return jndiContext;
+ }
+ }
+
+
+}
Added:
velocity/tools/branches/model/velocity-tools-model/src/test/java/org/apache/velocity/tools/model/BasicModelToolTests.java
URL:
http://svn.apache.org/viewvc/velocity/tools/branches/model/velocity-tools-model/src/test/java/org/apache/velocity/tools/model/BasicModelToolTests.java?rev=1857762&view=auto
==============================================================================
---
velocity/tools/branches/model/velocity-tools-model/src/test/java/org/apache/velocity/tools/model/BasicModelToolTests.java
(added)
+++
velocity/tools/branches/model/velocity-tools-model/src/test/java/org/apache/velocity/tools/model/BasicModelToolTests.java
Thu Apr 18 15:20:59 2019
@@ -0,0 +1,519 @@
+package org.apache.velocity.tools.model;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+import org.apache.commons.dbcp2.BasicDataSource;
+import org.apache.commons.io.IOUtils;
+import org.apache.velocity.VelocityContext;
+import org.apache.velocity.app.VelocityEngine;
+import org.apache.velocity.context.Context;
+import org.apache.velocity.tools.ToolManager;
+import org.apache.velocity.tools.Toolbox;
+import org.apache.velocity.tools.ToolboxFactory;
+import org.apache.velocity.tools.config.ConfigurationException;
+import org.apache.velocity.tools.config.ConfigurationUtils;
+import org.apache.velocity.tools.config.FactoryConfiguration;
+import org.apache.velocity.tools.config.XmlFactoryConfiguration;
+import org.apache.velocity.tools.model.filter.Filter;
+import org.junit.BeforeClass;
+import org.junit.Test;
+
+import javax.naming.InitialContext;
+import javax.naming.NamingException;
+import javax.naming.spi.InitialContextFactory;
+import javax.sql.DataSource;
+import java.io.InputStreamReader;
+import java.io.Reader;
+import java.io.StringWriter;
+import java.net.URL;
+import java.nio.charset.StandardCharsets;
+import java.sql.Connection;
+import java.sql.Date;
+import java.sql.SQLException;
+import java.sql.Statement;
+import java.text.DateFormat;
+import java.text.SimpleDateFormat;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.GregorianCalendar;
+import java.util.HashMap;
+import java.util.Hashtable;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.stream.Collectors;
+
+import static
org.apache.velocity.tools.config.ConfigurationUtils.MODEL_DEFAULTS_PATH;
+import static org.junit.Assert.*;
+
+/**
+ * <p>Basic model tests</p>
+ *
+ * @author Claude Brisson
+ * @since VelocityTools 3.1
+ * @version $Id$
+ */
+public class BasicModelToolTests extends BaseBookshelfTests
+{
+ private static final String BLANK_MODEL = "blank_model.xml";
+ private static final String BLANK_MODEL_TOOLS = "blank_model_tools.xml";
+
+ public @Test void instanciateToolbox() throws Exception
+ {
+ XmlFactoryConfiguration config = new XmlFactoryConfiguration();
+ config.read(MODEL_DEFAULTS_PATH, true);
+ config.setProperty("datasource", initDataSource());
+ ToolboxFactory factory = config.createFactory();
+ Toolbox toolbox = factory.createToolbox("application");
+ Object obj = toolbox.get("model");
+ assertNotNull(obj);
+ assertTrue(obj instanceof ModelTool);
+ }
+
+ public @Test void loadToolbox() throws Exception
+ {
+ ToolManager manager = new ToolManager();
+ manager.setVelocityEngine(createVelocityEngine((String)null));
+ FactoryConfiguration config =
ConfigurationUtils.find("org/apache/velocity/tools/model/tools.xml");
+ FactoryConfiguration modelConfig =
ConfigurationUtils.find("blank_model_tools.xml");
+ config.addConfiguration(modelConfig);
+ manager.configure(config);
+ Context context = manager.createContext();
+ Object obj = context.get("model");
+ assertNotNull(obj);
+ assertTrue(obj instanceof ModelTool);
+ }
+
+ public @Test void testModelInit() throws Exception
+ {
+ // test model
+ Model model = new Model();
+ model.setDataSource(initDataSource());
+ model.initialize(getResource("test_init_model.xml"));
+ assertEquals(Model.WriteAccess.JAVA, model.getWriteAccess());
+
+ // test entities
+ Entity book = model.getEntity("book");
+ assertNotNull(book);
+ Entity author = model.getEntity("author");
+ assertNotNull(author);
+
+ // test attributes
+ Attribute countAuthors = book.getAttribute("count_authors");
+ assertNotNull(countAuthors);
+ assertTrue(countAuthors instanceof ScalarAttribute);
+ Attribute countBooks = model.getAttribute("count_books");
+ assertNotNull(countBooks);
+ assertTrue(countBooks instanceof ScalarAttribute);
+ Attribute authors = book.getAttribute("authors");
+ assertNotNull(author);
+ assertTrue(authors instanceof RowsetAttribute);
+ }
+
+ public @Test void testRealData() throws Exception
+ {
+ DataSource dataSource = initDataSource();
+ Model model = new Model();
+ model.setDataSource(dataSource);
+ model.initialize(getResourceReader("test_init_model.xml"));
+ ScalarAttribute countBooks =
(ScalarAttribute)model.getAttribute("count_books");
+ long books = countBooks.getLong();
+ assertEquals(books, 1);
+ }
+
+ public @Test void testReverseColumns() throws Exception
+ {
+ DataSource dataSource = initDataSource();
+ Model model = new Model();
+ model.setDataSource(dataSource);
+ model.setReverseMode(Model.ReverseMode.COLUMNS);
+ model.initialize(getResourceReader("test_init_model.xml"));
+ Entity book = model.getEntity("book");
+ Collection<Entity.Column> columns = book.getColumns();
+ assertNotNull(columns);
+ String allCols = columns.stream().map(c ->
c.name).collect(Collectors.joining(","));
+ assertEquals("book_id,title,published,publisher_id", allCols);
+ List<Entity.Column> pk = book.getPrimaryKey();
+ assertNotNull(pk);
+ assertEquals(1, pk.size());
+ assertEquals("book_id", pk.get(0).name);
+ }
+
+ public @Test void testBasicFetch() throws Exception
+ {
+ Map identMapping = new HashMap();
+ identMapping.put("*", "lowercase");
+ identMapping.put("*.*", "lowercase");
+ DataSource dataSource = initDataSource();
+ Model model = new Model();
+ model.setDataSource(dataSource);
+ model.setReverseMode(Model.ReverseMode.COLUMNS);
+ model.getIdentifiers().setMapping(identMapping);
+ model.initialize(getResourceReader("test_init_model.xml"));
+ Entity book = model.getEntity("book");
+ assertNotNull(book);
+ Instance oneBook = book.fetch(1);
+ assertNotNull(oneBook);
+ String title = oneBook.getString("title");
+ assertEquals("The Astonishing Life of Duncan Moonwalker", title);
+ Instance otherBook = book.fetch(1);
+ assertEquals(oneBook, otherBook);
+ }
+
+ public @Test void testCount() throws Exception
+ {
+ DataSource dataSource = initDataSource();
+ Model model = new Model();
+ model.setDataSource(dataSource);
+ model.setReverseMode(Model.ReverseMode.COLUMNS);
+ model.initialize(getResourceReader("test_init_model.xml"));
+ Entity authors = model.getEntity("author");
+ assertNotNull(authors);
+ long count = authors.getCount();
+ assertEquals(2l, count);
+ }
+
+ public @Test void testReverseJoins() throws Exception
+ {
+ DataSource dataSource = initDataSource();
+ Model model = new Model();
+ model.setDataSource(dataSource);
+ model.setReverseMode(Model.ReverseMode.JOINS);
+ model.getIdentifiers().setInflector("org.atteo.evo.inflector.English");
+ model.getIdentifiers().setMapping("lowercase");
+ model.initialize(getResourceReader("test_minimal_model.xml"));
+
+ // test upstream attribute
+ Entity bookEntity = model.getEntity("book");
+ assertNotNull(bookEntity);
+ Attribute bookPublisher = bookEntity.getAttribute("publisher");
+ assertNotNull(bookPublisher);
+ assertTrue(bookPublisher instanceof RowAttribute);
+ Instance book = bookEntity.fetch(1);
+ assertNotNull(book);
+ Instance publisher = book.retrieve("publisher");
+ assertNotNull(publisher);
+ assertEquals("Green Penguin Books", publisher.getString("name"));
+
+ // test downstream attribute
+ Entity publisherEntity = model.getEntity("publisher");
+ assertNotNull(publisherEntity);
+ Instance firstPublisher = publisherEntity.fetch(1);
+ assertNotNull(firstPublisher);
+ Iterator<Instance> books = firstPublisher.query("books");
+ assertNotNull(books);
+ assertTrue(books.hasNext());
+ assertNotNull(books.next());
+ }
+
+ public @Test void testAction() throws Exception
+ {
+ DataSource dataSource = initDataSource();
+ Model model = new Model();
+ model.setDataSource(dataSource);
+ model.setReverseMode(Model.ReverseMode.COLUMNS);
+ model.initialize(getResourceReader("test_action.xml"));
+ Entity book = model.getEntity("book");
+ assertNotNull(book);
+ Instance oneBook = book.fetch(1);
+ assertNotNull(oneBook);
+ String title = oneBook.getString("title");
+ assertEquals("The Astonishing Life of Duncan Moonwalker", title);
+ Action censor = (Action)book.getAttribute("censor");
+ assertNotNull(censor);
+ int changed = censor.perform(oneBook);
+ assertEquals(1, changed);
+ oneBook = book.fetch(1);
+ assertNotNull(oneBook);
+ String censored = oneBook.getString("title");
+ assertEquals("** censored **", censored);
+ oneBook.perform("rename", title);
+ oneBook = book.fetch(1);
+ assertNotNull(oneBook);
+ assertEquals(title, oneBook.getString("title"));
+ }
+
+ public @Test void testUberspector() throws Exception
+ {
+ DataSource dataSource = initDataSource();
+ Properties velProps = new Properties();
+ velProps.put("introspector.uberspect.class",
"org.apache.velocity.tools.model.ModelUberspector,
org.apache.velocity.util.introspection.UberspectImpl");
+ VelocityEngine engine = createVelocityEngine(velProps);
+ ModelTool model = new ModelTool();
+ Map<String, Object> props = new HashMap<>();
+ props.put("datasource", dataSource);
+ props.put("reverse", "full");
+ props.put("definition", "blank_model.xml");
+ props.put("identifiers.inflector", "org.atteo.evo.inflector.English");
+ props.put("identifiers.mapping", "lowercase");
+ model.configure(props);
+ Context context = new VelocityContext();
+ context.put("model", model);
+ StringWriter out = new StringWriter();
+ assertTrue(engine.evaluate(context, out, "test",
"$model.book.fetch(1).publisher.name"));
+ assertEquals("Green Penguin Books", out.toString());
+ out = new StringWriter();
+ assertTrue(engine.evaluate(context, out, "test", "#foreach(
$book_author in $model.book.fetch(1).book_authors
)$book_author.author.author_id#end"));
+ assertEquals("12", out.toString());
+ }
+
+ public @Test void testExtended() throws Exception
+ {
+ DataSource dataSource = initDataSource();
+ Properties velProps = new Properties();
+ velProps.put("introspector.uberspect.class",
"org.apache.velocity.tools.model.ModelUberspector,org.apache.velocity.util.introspection.UberspectImpl");
+ velProps.put("model.datasource", dataSource);
+ velProps.put("model.reverse", "extended");
+ velProps.put("model.identifiers.mapping", "lowercase");
+ velProps.put("model.identifiers.mapping.pub*.*_id", "/^.*_id/id/");
+ velProps.put("model.identifiers.mapping.author.*_id", "/^.*_id/id/");
+ velProps.put("model.identifiers.inflector",
"org.atteo.evo.inflector.English");
+ VelocityEngine engine = createVelocityEngine(velProps);
+
+ Map params = new HashMap();
+ params.put("velocityEngine", engine);
+ ModelTool model = new ModelTool();
+ model.configure(params);
+
+ Context context = new VelocityContext();
+ context.put("model", model);
+ StringWriter out = new StringWriter();
+ assertTrue(engine.evaluate(context, out, "test",
"$model.book.fetch(1).publisher.id"));
+ assertEquals("1", out.toString());
+ out = new StringWriter();
+ assertTrue(engine.evaluate(context, out, "test", "#foreach( $author in
$model.book.fetch(1).authors )$author.id#end"));
+ assertEquals("12", out.toString());
+ }
+
+ public @Test void testCollision() throws Exception
+ {
+ DataSource dataSource = initDataSource();
+ Properties velProps = new Properties();
+ velProps.put("introspector.uberspect.class",
"org.apache.velocity.tools.model.ModelUberspector,org.apache.velocity.util.introspection.UberspectImpl");
+ velProps.put("model.datasource", dataSource);
+ velProps.put("model.reverse", "extended");
+ velProps.put("model.identifiers.mapping", "lowercase");
+ velProps.put("model.identifiers.mapping.*.*_id", "/^.*_id/id/");
+ velProps.put("model.identifiers.inflector",
"org.atteo.evo.inflector.English");
+ VelocityEngine engine = createVelocityEngine(velProps);
+
+ Map params = new HashMap();
+ params.put("velocityEngine", engine);
+ Model model = new Model().configure(params);
+ try
+ {
+ model.initialize();
+ fail("initialization should throw");
+ }
+ catch (ConfigurationException e)
+ {
+ assertEquals("column name collision: book.id mapped on
BOOK.BOOK_ID and on BOOK.PUBLISHER_ID", e.getMessage());
+ }
+ }
+
+ public @Test void testWithoutInputFilter() throws Exception
+ {
+ DataSource dataSource = initDataSource();
+ Properties props = new Properties();
+ props.put("datasource", dataSource);
+ props.put("reverse", "tables");
+ props.put("identifiers.inflector", "org.atteo.evo.inflector.English");
+ props.put("identifiers.mapping", "lowercase");
+
+ Model model = new Model().configure(props).initialize();
+ Instance book = model.getEntity("book").fetch(1);
+ Date date = (Date)book.get("published");
+ assertNotNull(date);
+ DateFormat ymd = new SimpleDateFormat("yyyy-MM-dd");
+ assertEquals("2018-05-09", ymd.format(date));
+ Calendar cal = GregorianCalendar.getInstance();
+ cal.set(2008, 8, 8);
+ book.put("published", cal);
+ try
+ {
+ book.update();
+ fail("should throw when hsqldb receives a Calendar");
+ }
+ catch (SQLException sqle)
+ {
+ assertEquals("incompatible data type in conversion",
sqle.getMessage());
+ }
+ }
+
+ public @Test void testInputFilter() throws Exception
+ {
+ DataSource dataSource = initDataSource();
+ Properties props = new Properties();
+ props.put("datasource", dataSource);
+ props.put("reverse", "tables");
+ props.put("identifiers.inflector", "org.atteo.evo.inflector.English");
+ props.put("identifiers.mapping", "lowercase");
+ Filter calendar_to_time = x -> ((Calendar)x).getTime();
+ props.put("filters.write.java.util.Calendar", calendar_to_time);
+
+ Model model = new Model().configure(props).initialize();
+ Instance book = model.getEntity("book").fetch(1);
+ Date date = (Date)book.get("published");
+ assertNotNull(date);
+ DateFormat ymd = new SimpleDateFormat("yyyy-MM-dd");
+ assertEquals("2018-05-09", ymd.format(date));
+ Calendar cal = GregorianCalendar.getInstance();
+ cal.set(2008, 8, 8);
+ book.put("published", cal);
+ book.update();
+ book.refresh();
+ assertEquals("2008-09-08", ymd.format(book.get("published")));
+ book.put("published", date);
+ book.update();
+ book.refresh();
+ assertEquals("2018-05-09", ymd.format(book.get("published")));
+ }
+
+ public @Test void testJdbc() throws Exception
+ {
+ Model model = new Model().setDatabaseURL("jdbc:hsqldb:.");
+ model.getCredentials().setUser("sa");
+ model.getCredentials().setPassword("");
+ model.initialize();
+ }
+
+ public @Test void testObfuscation() throws Exception
+ {
+ Properties velProps = new Properties();
+
velProps.load(BasicModelToolTests.class.getClassLoader().getResourceAsStream("org/apache/velocity/tools/model/velocity.properties"));
+ VelocityEngine engine = createVelocityEngine(velProps);
+
+ Properties props = new Properties();
+ props.put("reverse", "extended");
+ props.put("credentials.user", "sa");
+ props.put("credentials.password", "");
+ props.put("database", "jdbc:hsqldb:.");
+ props.put("identifiers.mapping.*", "lowercase");
+ props.put("identifiers.mapping.*.*_id", "snake_to_camel");
+ props.put("filters.read.book.book_id", "obfuscate");
+ props.put("filters.write.book.book_id", "deobfuscate_strings");
+ props.put("filters.read.author.author_id", "obfuscate");
+ props.put("filters.write.author.author_id", "deobfuscate");
+ props.put("velocityEngine", engine);
+ Model model = new Model().configure(props).initialize();
+ Instance book = model.getEntity("book").fetch(1);
+ assertNotNull(book);
+ Object bookId = book.get("bookId");
+ assertNotNull(bookId);
+ assertTrue(bookId instanceof String && ((String)bookId).length() > 5);
+ Iterator<Instance> authors = book.query("authors");
+ assertNotNull(authors);
+ Instance author1 = authors.next();
+ Instance author2 = authors.next();
+ assertFalse(authors.hasNext());
+ assertNotNull(author1);
+ assertNotNull(author2);
+ Object authorId = author1.get("authorId");
+ assertNotNull(authorId);
+ assertTrue(authorId instanceof String && ((String)authorId).length() >
5);
+ Instance again = author1.query("books").next();
+ assertNotNull(again);
+ assertEquals(book.get("bookId"), again.get("bookId"));
+ try
+ {
+ Instance author = model.getEntity("author").fetch(1);
+ fail("SQLException expected");
+ }
+ catch (SQLException sqle)
+ {
+ assertEquals("data exception: invalid character value for cast",
sqle.getMessage());
+ }
+ }
+
+ public static class MyBook
+ {
+ public void setISBN(String isbn) { this.isbn = isbn.toUpperCase(); }
+ public String getISBN() { return isbn; }
+ private String isbn = null;
+ }
+
+ public static class MyPub extends Instance
+ {
+ public MyPub(Entity entity) { super(entity); }
+
+ public String getAddress()
+ {
+ return "some address";
+ }
+ }
+
+ public static class MyAuthor
+ {
+ }
+
+ public static class MyFactory
+ {
+ public static MyAuthor createAuthor()
+ {
+ return new MyAuthor();
+ }
+ }
+
+ public @Test void testBean() throws Exception
+ {
+ Properties velProps = new Properties();
+
velProps.load(BasicModelToolTests.class.getClassLoader().getResourceAsStream("org/apache/velocity/tools/model/velocity.properties"));
+ VelocityEngine engine = createVelocityEngine(velProps);
+
+ Properties props = new Properties();
+ props.put("reverse", "extended");
+ props.put("credentials.user", "sa");
+ props.put("credentials.password", "");
+ props.put("database", "jdbc:hsqldb:.");
+ props.put("identifiers.mapping", "lowercase");
+ props.put("velocityEngine", engine);
+ props.put("instances.classes.book", MyBook.class);
+ props.put("instances.classes.publisher", MyPub.class);
+ props.put("instances.factory", MyFactory.class);
+ Model model = new Model().configure(props).initialize();
+ Instance book = model.getEntity("book").fetch(1);
+ assertNotNull(book);
+ Object bookId = book.get("book_id");
+ assertNotNull(bookId);
+ assertEquals(1, bookId);
+ assertTrue(book instanceof WrappingInstance);
+ assertNull(book.put("ISBN", "lowercase characters"));
+ assertEquals("LOWERCASE CHARACTERS", book.get("ISBN"));
+ Instance publisher = book.retrieve("publisher");
+ assertTrue(publisher instanceof MyPub);
+ String address = ((MyPub)publisher).getAddress();
+ assertNotNull(address);
+ assertEquals("some address", address);
+ Instance author = model.getEntity("author").fetch(1);
+ assertNotNull(author);
+ assertTrue(author instanceof WrappingInstance);
+ Object wrapped = ((WrappingInstance)author).unwrap(MyAuthor.class);
+ assertNotNull(wrapped);
+ }
+
+ @BeforeClass
+ public static void populateDataSource() throws Exception
+ {
+ BaseBookshelfTests.populateDataSource();
+ }
+
+}
Added:
velocity/tools/branches/model/velocity-tools-model/src/test/resources/blank_model.xml
URL:
http://svn.apache.org/viewvc/velocity/tools/branches/model/velocity-tools-model/src/test/resources/blank_model.xml?rev=1857762&view=auto
==============================================================================
---
velocity/tools/branches/model/velocity-tools-model/src/test/resources/blank_model.xml
(added)
+++
velocity/tools/branches/model/velocity-tools-model/src/test/resources/blank_model.xml
Thu Apr 18 15:20:59 2019
@@ -0,0 +1,3 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<model>
+</model>
Added:
velocity/tools/branches/model/velocity-tools-model/src/test/resources/blank_model_tools.xml
URL:
http://svn.apache.org/viewvc/velocity/tools/branches/model/velocity-tools-model/src/test/resources/blank_model_tools.xml?rev=1857762&view=auto
==============================================================================
---
velocity/tools/branches/model/velocity-tools-model/src/test/resources/blank_model_tools.xml
(added)
+++
velocity/tools/branches/model/velocity-tools-model/src/test/resources/blank_model_tools.xml
Thu Apr 18 15:20:59 2019
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<tools>
+ <toolbox scope="application">
+ <tool key="model" definition="blank_model.xml"
datasource="jdbc/test-data-source"/>
+ </toolbox>
+</tools>
Added:
velocity/tools/branches/model/velocity-tools-model/src/test/resources/bookshelf.sql
URL:
http://svn.apache.org/viewvc/velocity/tools/branches/model/velocity-tools-model/src/test/resources/bookshelf.sql?rev=1857762&view=auto
==============================================================================
---
velocity/tools/branches/model/velocity-tools-model/src/test/resources/bookshelf.sql
(added)
+++
velocity/tools/branches/model/velocity-tools-model/src/test/resources/bookshelf.sql
Thu Apr 18 15:20:59 2019
@@ -0,0 +1,55 @@
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements. See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership. The ASF licenses this file
+-- to you under the Apache License, Version 2.0 (the
+-- "License"). you may not use this file except in compliance
+-- with the License. You may obtain a copy of the License at
+--
+-- http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing,
+-- software distributed under the License is distributed on an
+-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+-- KIND, either express or implied. See the License for the
+-- specific language governing permissions and limitations
+-- under the License.
+
+create table publisher
+(
+ publisher_id int not null,
+ name varchar(200) not null,
+ primary key (publisher_id)
+);
+
+create table author
+(
+ author_id int not null,
+ name varchar(200) not null,
+ primary key (author_id)
+);
+
+create table book
+(
+ book_id int not null,
+ title varchar(200) not null,
+ published date not null,
+ publisher_id int not null,
+ primary key (book_id),
+ foreign key (publisher_id) references publisher (publisher_id)
+);
+
+create table book_author
+(
+ book_id int not null,
+ author_id int not null,
+ primary key (book_id, author_id),
+ foreign key (book_id) references book (book_id),
+ foreign key (author_id) references author (author_id)
+);
+
+insert into publisher values (1, 'Green Penguin Books');
+insert into book values (1, 'The Astonishing Life of Duncan Moonwalker',
'2018-05-09', 1);
+insert into author values (1, 'Graham Brigovicz');
+insert into author values (2, 'Robert Willhelm');
+insert into book_author values (1, 1), (1, 2);
Added:
velocity/tools/branches/model/velocity-tools-model/src/test/resources/test_action.xml
URL:
http://svn.apache.org/viewvc/velocity/tools/branches/model/velocity-tools-model/src/test/resources/test_action.xml?rev=1857762&view=auto
==============================================================================
---
velocity/tools/branches/model/velocity-tools-model/src/test/resources/test_action.xml
(added)
+++
velocity/tools/branches/model/velocity-tools-model/src/test/resources/test_action.xml
Thu Apr 18 15:20:59 2019
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<model write="java" identifiers.mapping="lowercase">
+ <book>
+ <action name="censor">
+ update book set title = '** censored **' where book_id = <book_id/>
+ </action>
+ <action name="rename">
+ update book set title = <new_title/> where book_id = <book_id/>
+ </action>
+ </book>
+</model>
Added:
velocity/tools/branches/model/velocity-tools-model/src/test/resources/test_init_model.xml
URL:
http://svn.apache.org/viewvc/velocity/tools/branches/model/velocity-tools-model/src/test/resources/test_init_model.xml?rev=1857762&view=auto
==============================================================================
---
velocity/tools/branches/model/velocity-tools-model/src/test/resources/test_init_model.xml
(added)
+++
velocity/tools/branches/model/velocity-tools-model/src/test/resources/test_init_model.xml
Thu Apr 18 15:20:59 2019
@@ -0,0 +1,9 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<model write="java" identifiers.mapping="lowercase">
+ <book>
+ <scalar name="count_authors">select count(*) from book_author where
book_id = <book_id/></scalar>
+ <rowset name="authors" result="author">select * from author where
book_id = <book_id/></rowset>
+ </book>
+ <author/>
+ <scalar name="count_books">select count(*) from book</scalar>
+</model>
Added:
velocity/tools/branches/model/velocity-tools-model/src/test/resources/test_mapping.properties
URL:
http://svn.apache.org/viewvc/velocity/tools/branches/model/velocity-tools-model/src/test/resources/test_mapping.properties?rev=1857762&view=auto
==============================================================================
---
velocity/tools/branches/model/velocity-tools-model/src/test/resources/test_mapping.properties
(added)
+++
velocity/tools/branches/model/velocity-tools-model/src/test/resources/test_mapping.properties
Thu Apr 18 15:20:59 2019
@@ -0,0 +1,2 @@
+identifiers.mapping.*.*_id = /^.*_id/id/
+identifiers.inflector =
\ No newline at end of file
Added:
velocity/tools/branches/model/velocity-tools-model/src/test/resources/test_minimal_model.xml
URL:
http://svn.apache.org/viewvc/velocity/tools/branches/model/velocity-tools-model/src/test/resources/test_minimal_model.xml?rev=1857762&view=auto
==============================================================================
---
velocity/tools/branches/model/velocity-tools-model/src/test/resources/test_minimal_model.xml
(added)
+++
velocity/tools/branches/model/velocity-tools-model/src/test/resources/test_minimal_model.xml
Thu Apr 18 15:20:59 2019
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" ?>
+<model write="java">
+ <book/>
+ <author/>
+ <publisher/>
+</model>