/* * This library is part of OpenCms - * the Open Source Content Management System * * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com) * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. * * For further information about Alkacon Software GmbH, please see the * company website: http://www.alkacon.com * * For further information about OpenCms, please see the * project website: http://www.opencms.org * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ package org.opencms.db; import org.opencms.test.OpenCmsTestCase; import java.io.File; import java.io.FileInputStream; import java.io.InputStreamReader; import java.io.LineNumberReader; import java.nio.charset.Charset; import java.text.ParseException; import java.util.StringTokenizer; import junit.framework.Test; import junit.framework.TestSuite; /** * Unit tests that checks the "query.properties" files used by the various drivers for correct * format. * <p> * * This is no code functionality test but a configuration validation that was inspired by a 1 hour * debug session caused by a query.properties file with a trailing tab after the "escape linebreak" * backslash. * <p> * * Currently the following checks are made: * <ul> * <li> <b>Invalid linebreak escape</b><br> * If a linebreak is escaped by a backslash there must not follow any character in that line. </li> * <li> <b>Invalid comment line</b><br> * If a comment character is found it has to be the first character of the line or * <ul> * <li> The characters before it have to be fully "trimmable" (Unicode General Category Separator, * Space [Zs]). </li> * <li> The characters before it are a valid key - value pair in properties notation. </li> * </ul> * </li> * </ul> * <p> */ public class TestQueryProperties extends OpenCmsTestCase { /** * Default JUnit constructor. * <p> * * @param arg0 JUnit parameters */ public TestQueryProperties(String arg0) { super(arg0); } /** * Test suite for this test class. * <p> * * @return the test suite */ public static Test suite() { TestSuite suite = new TestSuite(); suite.setName(TestQueryProperties.class.getName()); suite.addTest(new TestQueryProperties("testQueryPropertiesGeneric")); suite.addTest(new TestQueryProperties("testQueryPropertiesMssql")); suite.addTest(new TestQueryProperties("testQueryPropertiesMysql")); suite.addTest(new TestQueryProperties("testQueryPropertiesOracle")); suite.addTest(new TestQueryProperties("testQueryPropertiesPostgresql")); return suite; } /** * Test the generic query.properties file within the workspace for format errors.<p> * * @throws Exception if something goes wrong */ public void testQueryPropertiesGeneric() throws Exception { // generic File queries = new File(ClassLoader.getSystemResource("./org/opencms/db/generic/query.properties").getPath()); parseQueryProperties(queries); } /** * Test the mssql query.properties file within the workspace for format errors.<p> * * @throws Exception if something goes wrong */ public void testQueryPropertiesMssql() throws Exception { // mssql File queries = new File(ClassLoader.getSystemResource("./org/opencms/db/mssql/query.properties").getPath()); parseQueryProperties(queries); } /** * Test the mysql query.properties file within the workspace for format errors.<p> * * @throws Exception if something goes wrong */ public void testQueryPropertiesMysql() throws Exception { // mysql File queries = new File(ClassLoader.getSystemResource("./org/opencms/db/mysql/query.properties").getPath()); parseQueryProperties(queries); } /** * Test the oracle query.properties file within the workspace for format errors.<p> * * @throws Exception if something goes wrong */ public void testQueryPropertiesOracle() throws Exception { // oracle8 File queries = new File(ClassLoader.getSystemResource("./org/opencms/db/oracle/query.properties").getPath()); parseQueryProperties(queries); } /** * Test the postgresql query.properties file within the workspace for format errors.<p> * * @throws Exception if something goes wrong */ public void testQueryPropertiesPostgresql() throws Exception { // postgresql File queries = new File(ClassLoader.getSystemResource("./org/opencms/db/postgresql/query.properties").getPath()); parseQueryProperties(queries); } private void parseKeyValue(String keyValue) throws ParseException { StringTokenizer tokenizer = new StringTokenizer(keyValue, "=: ", false); if (tokenizer.countTokens() != 2) { throw new ParseException("Illegal key value pair " + keyValue, 0); } } /** * Implementation of the checks to perform.<p> * * @param f the query.properties file to parse * * @throws Exception if something goes wrong */ private void parseQueryProperties(File f) throws Exception { LineNumberReader reader = new LineNumberReader(new InputStreamReader( new FileInputStream(f), Charset.forName("ISO-8859-1"))); String read; int len; int count = 0; int lastEscape = 0; while ((read = reader.readLine()) != null) { len = read.length(); count++; lastEscape = read.lastIndexOf('\\'); if (read.trim().length() > 0) { // filter comments int firstSharp = read.indexOf('#'); if (firstSharp > -1) { String prefix = read.substring(0, firstSharp).trim(); if (prefix.length() > 0) { // check 1: invalid key value pair before comment char try { parseKeyValue(prefix); } catch (ParseException pe) { throw new ParseException("Bad format in file " + f.getAbsolutePath() + ", line " + count + ": " + pe.getMessage(), count); } } else { // valid comment - only line continue; } } else { // no omment line } } // check 2: invalid attempt to escape a line break, something follows if (lastEscape != -1) { if (lastEscape != len - 1) { throw new ParseException("Bad format in file " + f.getAbsolutePath() + ", line " + count + ": Line termination escape '\\' is followed by further characters.", count); } } // further checks if desired } reader.close(); } }