diff --git a/README.md b/README.md index 7a9e1e6..273ee06 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,30 @@ G-9013 | Exceptions should start with 'e_'. G-9014 | Constants should start with 'co_'. G-9015 | Subtypes should end with 'type'. +These pre-/suffixes can be customized by using a TrivadisGuidelines3Plus.properties file. This file should be placed in the `users home` directory. +If an entry is omitted it will fall back to the default value (see table above). +The file has the following structure: + +``` +PREFIX_GLOBAL_VARIABLE_NAME = g_ +PREFIX_LOCAL_VARIABLE_NAME = l_ +PREFIX_CURSOR_NAME = c_ +PREFIX_RECORD_NAME = r_ +PREFIX_ARRAY_NAME = t_ +PREFIX_OBJECT_NAME = o_ +PREFIX_CURSOR_PARAMETER_NAME = p_ +PREFIX_IN_PARAMETER_NAME = in_ +PREFIX_OUT_PARAMETER_NAME = out_ +PREFIX_IN_OUT_PARAMETER_NAME = io_ +PREFIX_RECORD_TYPE_NAME = r_ +SUFFIX_RECORD_TYPE_NAME = _type +PREFIX_ARRAY_TYPE_NAME = t_ +SUFFIX_ARRAY_TYPE_NAME = _type +PREFIX_EXCEPTION_NAME = e_ +PREFIX_CONSTANT_NAME = co_ +SUFFIX_SUBTYPE_NAME = _type +``` + This validator is an [extension](https://github.com/Trivadis/cop-validators/blob/master/src/main/java/com/trivadis/tvdcc/validators/TrivadisGuidelines3Plus.xtend#L38) to the Trivadis PL/SQL & SQL Coding Guidelines. This means that the all guidelines defined in chapter [4. Language Usage are checked](https://trivadis.github.io/plsql-and-sql-coding-guidelines/4-language-usage/1-general/g-1010/) as well. ### GLP diff --git a/src/main/java/com/trivadis/tvdcc/validators/TrivadisGuidelines3Plus.xtend b/src/main/java/com/trivadis/tvdcc/validators/TrivadisGuidelines3Plus.xtend index 45e4826..3694157 100644 --- a/src/main/java/com/trivadis/tvdcc/validators/TrivadisGuidelines3Plus.xtend +++ b/src/main/java/com/trivadis/tvdcc/validators/TrivadisGuidelines3Plus.xtend @@ -34,9 +34,16 @@ import java.util.HashMap import org.eclipse.emf.ecore.EObject import org.eclipse.xtext.EcoreUtil2 import org.eclipse.xtext.validation.Check +import java.util.Properties +import java.io.File +import java.io.FileInputStream +import java.io.FileNotFoundException class TrivadisGuidelines3Plus extends TrivadisGuidelines3 implements PLSQLCopValidator { HashMap guidelines + FileInputStream input + Properties prop + public static int ISSUE_GLOBAL_VARIABLE_NAME = 9001 public static int ISSUE_LOCAL_VARIABLE_NAME = 9002 @@ -72,6 +79,42 @@ class TrivadisGuidelines3Plus extends TrivadisGuidelines3 implements PLSQLCopVal public static String PREFIX_CONSTANT_NAME = "co_" public static String SUFFIX_SUBTYPE_NAME = "_type" + new(){ + super() + readProperties + } + + def readProperties() { + try{ + input = new FileInputStream(System.getProperty("user.home") + File.separator + "TrivadisGuidelines3Plus.properties") + prop = new Properties() + + prop.load(input) + + PREFIX_GLOBAL_VARIABLE_NAME = prop.getProperty("PREFIX_GLOBAL_VARIABLE_NAME" , PREFIX_GLOBAL_VARIABLE_NAME) + PREFIX_LOCAL_VARIABLE_NAME = prop.getProperty("PREFIX_LOCAL_VARIABLE_NAME" , PREFIX_LOCAL_VARIABLE_NAME) + PREFIX_CURSOR_NAME = prop.getProperty("PREFIX_CURSOR_NAME" , PREFIX_CURSOR_NAME) + PREFIX_RECORD_NAME = prop.getProperty("PREFIX_RECORD_NAME" , PREFIX_RECORD_NAME) + PREFIX_ARRAY_NAME = prop.getProperty("PREFIX_ARRAY_NAME" , PREFIX_ARRAY_NAME) + PREFIX_OBJECT_NAME = prop.getProperty("PREFIX_OBJECT_NAME" , PREFIX_OBJECT_NAME) + PREFIX_CURSOR_PARAMETER_NAME = prop.getProperty("PREFIX_CURSOR_PARAMETER_NAME", PREFIX_CURSOR_PARAMETER_NAME) + PREFIX_IN_PARAMETER_NAME = prop.getProperty("PREFIX_IN_PARAMETER_NAME" , PREFIX_IN_PARAMETER_NAME) + PREFIX_OUT_PARAMETER_NAME = prop.getProperty("PREFIX_OUT_PARAMETER_NAME" , PREFIX_OUT_PARAMETER_NAME) + PREFIX_IN_OUT_PARAMETER_NAME = prop.getProperty("PREFIX_IN_OUT_PARAMETER_NAME", PREFIX_IN_OUT_PARAMETER_NAME) + PREFIX_RECORD_TYPE_NAME = prop.getProperty("PREFIX_RECORD_TYPE_NAME" , PREFIX_RECORD_TYPE_NAME) + SUFFIX_RECORD_TYPE_NAME = prop.getProperty("SUFFIX_RECORD_TYPE_NAME" , SUFFIX_RECORD_TYPE_NAME) + PREFIX_ARRAY_TYPE_NAME = prop.getProperty("PREFIX_ARRAY_TYPE_NAME" , PREFIX_ARRAY_TYPE_NAME) + SUFFIX_ARRAY_TYPE_NAME = prop.getProperty("SUFFIX_ARRAY_TYPE_NAME" , SUFFIX_ARRAY_TYPE_NAME) + PREFIX_EXCEPTION_NAME = prop.getProperty("PREFIX_EXCEPTION_NAME" , PREFIX_EXCEPTION_NAME) + PREFIX_CONSTANT_NAME = prop.getProperty("PREFIX_CONSTANT_NAME" , PREFIX_CONSTANT_NAME) + SUFFIX_SUBTYPE_NAME = prop.getProperty("SUFFIX_SUBTYPE_NAME" , SUFFIX_SUBTYPE_NAME) + + input.close() + } catch(FileNotFoundException e) { + //no special behaviour without Properties [https://github.com/Trivadis/plsql-cop-validators/issues/13] + } + } + override getGuidelines() { if (guidelines === null) { guidelines = new HashMap() diff --git a/src/test/java/com/trivadis/tvdcc/validators/tests/TrivadisGuidelines3PlusPropertyFileTest.xtend b/src/test/java/com/trivadis/tvdcc/validators/tests/TrivadisGuidelines3PlusPropertyFileTest.xtend new file mode 100644 index 0000000..5c66aa2 --- /dev/null +++ b/src/test/java/com/trivadis/tvdcc/validators/tests/TrivadisGuidelines3PlusPropertyFileTest.xtend @@ -0,0 +1,126 @@ +package com.trivadis.tvdcc.validators.tests + +import com.trivadis.oracle.plsql.validation.PLSQLValidatorPreferences +import com.trivadis.tvdcc.validators.TrivadisGuidelines3Plus +import org.junit.Assert +import org.junit.BeforeClass +import org.junit.Test +import java.nio.file.Files +import java.nio.file.Paths +import java.io.File +import org.junit.AfterClass +import java.io.FileWriter +import java.io.BufferedWriter + +// To ensure that everything works correctly run TrivadisGuidelines3PlusTest before running TrivadisGuidelines3PlusPropertyFileTest. +class TrivadisGuidelines3PlusPropertyFileTest extends AbstractValidatorTest { + + static File file + + static FileWriter fileWriter + + static BufferedWriter bufferedWriter + + static String backupFileSuffix = ".backup" + + static String propertyPathString = System.getProperty("user.home") + File.separator + "TrivadisGuidelines3Plus.properties" + static String backupPropertyPathString = propertyPathString + backupFileSuffix + + @BeforeClass + static def void setupValidator() { + PLSQLValidatorPreferences.INSTANCE.validatorClass = TrivadisGuidelines3Plus + } + + //save the users properties + @BeforeClass + static def void stashPropertiesFile() { + if(Files.exists(Paths.get(propertyPathString))){ + Files.copy(Paths.get(propertyPathString), Paths.get(backupPropertyPathString)) + Files.delete(Paths.get(propertyPathString)) + } + } + + //create a simple property-file to test with + @BeforeClass + static def void createTestPropertyFile() { + file = new File(propertyPathString) + fileWriter = new FileWriter(file, true) + bufferedWriter = new BufferedWriter(fileWriter) + bufferedWriter.write("PREFIX_LOCAL_VARIABLE_NAME = loc_") + bufferedWriter.newLine() + bufferedWriter.close() + fileWriter.close() + + } + + //check that old prefix is now not accepted + @Test + def void LocalVariableNok() { + val stmt = ''' + CREATE OR REPLACE PACKAGE BODY example AS + PROCEDURE a IS + l_some_name INTEGER; + BEGIN + NULL; + END a; + END example; + ''' + val issues = stmt.issues + Assert.assertEquals(1, issues.filter[it.code == "G-9002"].size) + } + + //check that new prefix from file is accepted + @Test + def void LocalVariableOk() { + val stmt = ''' + CREATE OR REPLACE PACKAGE BODY example AS + PROCEDURE a IS + loc_some_name INTEGER; + BEGIN + NULL; + END a; + END example; + ''' + val issues = stmt.issues + Assert.assertEquals(0, issues.filter[it.code == "G-9002"].size) + } + + //check that defaults are used if not specified in the properties-file + @Test + def void GlobalVariableNok() { + val stmt = ''' + CREATE OR REPLACE PACKAGE example AS + some_name INTEGER; + END example; + / + ''' + val issues = stmt.issues + Assert.assertEquals(1, issues.filter[it.code == "G-9001"].size) + } + + //check that defaults are used if not specified in the properties-file + @Test + def void GlobalVariableOk() { + val stmt = ''' + CREATE OR REPLACE PACKAGE example AS + g_some_name INTEGER; + END example; + ''' + val issues = stmt.issues + Assert.assertEquals(0, issues.filter[it.code == "G-9001"].size) + + } + + @AfterClass + static def void restorePropertiesFile() { + //delete the test property-file + if(Files.exists(Paths.get(propertyPathString))){ + Files.delete(Paths.get(propertyPathString)) + } + //restore the users properties after the test + if(Files.exists(Paths.get(backupPropertyPathString))){ + Files.copy(Paths.get(backupPropertyPathString),Paths.get(propertyPathString)) + Files.delete(Paths.get(backupPropertyPathString)) + } + } +} \ No newline at end of file diff --git a/src/test/java/com/trivadis/tvdcc/validators/tests/TrivadisGuidelines3PlusTest.xtend b/src/test/java/com/trivadis/tvdcc/validators/tests/TrivadisGuidelines3PlusTest.xtend index d199d1d..0f7a381 100644 --- a/src/test/java/com/trivadis/tvdcc/validators/tests/TrivadisGuidelines3PlusTest.xtend +++ b/src/test/java/com/trivadis/tvdcc/validators/tests/TrivadisGuidelines3PlusTest.xtend @@ -20,13 +20,30 @@ import com.trivadis.tvdcc.validators.TrivadisGuidelines3Plus import org.junit.Assert import org.junit.BeforeClass import org.junit.Test +import java.nio.file.Files +import java.nio.file.Paths +import java.io.File +import org.junit.AfterClass class TrivadisGuidelines3PlusTest extends AbstractValidatorTest { + static String backupFileSuffix = ".backup" + + static String propertyPathString = System.getProperty("user.home") + File.separator + "TrivadisGuidelines3Plus.properties" + static String backupPropertyPathString = propertyPathString + backupFileSuffix + @BeforeClass static def setupValidator() { PLSQLValidatorPreferences.INSTANCE.validatorClass = TrivadisGuidelines3Plus } + + @BeforeClass + static def void stashPropertiesFile() { + if(Files.exists(Paths.get(propertyPathString))){ + Files.copy(Paths.get(propertyPathString), Paths.get(backupPropertyPathString)); + Files.delete(Paths.get(propertyPathString)) + } + } @Test def void globalVariableNok() { @@ -489,4 +506,12 @@ class TrivadisGuidelines3PlusTest extends AbstractValidatorTest { val issues = stmt.issues Assert.assertEquals(0, issues.filter[it.code == "G-9015"].size) } + + @AfterClass + static def void restorePropertiesFile() { + if(Files.exists(Paths.get(backupPropertyPathString))){ + Files.copy(Paths.get(backupPropertyPathString),Paths.get(propertyPathString)) + Files.delete(Paths.get(backupPropertyPathString)) + } + } }