velocity-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cbris...@apache.org
Subject svn commit: r1857762 - in /velocity/tools/branches/model/velocity-tools-model: ./ src/test/java/org/apache/velocity/tools/model/ src/test/resources/
Date Thu, 18 Apr 2019 15:20:59 GMT
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>



Mime
View raw message