diff --git a/.gitignore b/.gitignore
index 764c55c..79fd5aa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@
/.settings
/.classpath
/.project
+/target/
diff --git a/pom.xml b/pom.xml
index cd40846..f7d07f9 100644
--- a/pom.xml
+++ b/pom.xml
@@ -2,8 +2,8 @@
4.0.0
org.sitenv.vocabulary
- codevalidator-api
- 1.0.10
+ cerner-codevalidator-api
+ 1.0.10-SNAPSHOT
Code Validator API
http://www.sitenv.org
@@ -12,6 +12,16 @@
+
+ com.ximpleware
+ vtd-xml
+ 2.13
+
+
+ commons-io
+ commons-io
+ 2.4
+
junit
junit
@@ -111,11 +121,35 @@
apache-log4j-extras
1.2.17
+
+ junit
+ junit
+ 4.11
+
+
+ org.springframework
+ spring-test
+ 4.1.6.RELEASE
+
+
+
+
+ com.ximpleware
+ vtd-xml
+ 2.13
+
+
+
+ org.apache.directory.studio
+ org.apache.commons.io
+ 2.4
+
- codevalidator
+
+ cerner-codevalidator-${version}
org.apache.maven.plugins
diff --git a/src/main/java/org/sitenv/vocabularies/configuration/CodeValidatorApiConfiguration.java b/src/main/java/org/sitenv/vocabularies/configuration/CodeValidatorApiConfiguration.java
index 9c7b998..b5c5ca8 100644
--- a/src/main/java/org/sitenv/vocabularies/configuration/CodeValidatorApiConfiguration.java
+++ b/src/main/java/org/sitenv/vocabularies/configuration/CodeValidatorApiConfiguration.java
@@ -1,162 +1,321 @@
package org.sitenv.vocabularies.configuration;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
+import java.util.concurrent.Executor;
+
+import javax.persistence.EntityManagerFactory;
+import javax.sql.DataSource;
+import javax.xml.parsers.DocumentBuilderFactory;
+import javax.xml.parsers.ParserConfigurationException;
+import javax.xml.xpath.XPathFactory;
+
+import org.apache.commons.dbcp2.BasicDataSource;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.log4j.BasicConfigurator;
+import org.apache.log4j.Logger;
import org.sitenv.vocabularies.loader.VocabularyLoadRunner;
import org.sitenv.vocabularies.loader.VocabularyLoaderFactory;
import org.sitenv.vocabularies.validation.NodeValidatorFactory;
+import org.springframework.aop.interceptor.AsyncUncaughtExceptionHandler;
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
import org.springframework.beans.factory.config.ServiceLocatorFactoryBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
+import org.springframework.context.annotation.PropertySource;
import org.springframework.context.support.PropertySourcesPlaceholderConfigurer;
import org.springframework.core.env.Environment;
+import org.springframework.core.io.Resource;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
-import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
-import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
+import org.springframework.jdbc.datasource.init.DataSourceInitializer;
+import org.springframework.jdbc.datasource.init.DatabasePopulator;
+import org.springframework.jdbc.datasource.init.ResourceDatabasePopulator;
import org.springframework.orm.hibernate4.HibernateExceptionTranslator;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter;
import org.springframework.oxm.jaxb.Jaxb2Marshaller;
+import org.springframework.scheduling.annotation.AsyncConfigurer;
+import org.springframework.scheduling.annotation.EnableAsync;
+import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.transaction.PlatformTransactionManager;
-import javax.persistence.EntityManagerFactory;
-import javax.sql.DataSource;
-import javax.xml.parsers.DocumentBuilder;
-import javax.xml.parsers.DocumentBuilderFactory;
-import javax.xml.parsers.ParserConfigurationException;
-import javax.xml.xpath.XPathFactory;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-
/**
* Created by Brian on 2/5/2016.
*/
@Configuration
+@EnableAsync
@ComponentScan("org.sitenv.vocabularies")
@EnableJpaRepositories("org.sitenv.vocabularies.validation.repositories")
-public class CodeValidatorApiConfiguration {
-
- @Bean
- public EntityManagerFactory entityManagerFactory() {
- HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
- vendorAdapter.setGenerateDdl(false);
- vendorAdapter.setShowSql(true);
- LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
- factory.setJpaVendorAdapter(vendorAdapter);
- factory.setPackagesToScan("org.sitenv.vocabularies.validation.entities");
- Properties jpaProperties = new Properties();
- jpaProperties.put("hibernate.hbm2ddl.auto", "none");
- jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.HSQLDialect");
- jpaProperties.put("hibernate.format_sql", "true");
- jpaProperties.put("hibernate.show_sql", "false");
- factory.setDataSource(dataSource());
- factory.setJpaProperties(jpaProperties);
- factory.afterPropertiesSet();
- return factory.getObject();
- }
-
- @Bean
- public PlatformTransactionManager transactionManager() {
- JpaTransactionManager txManager = new JpaTransactionManager();
- txManager.setEntityManagerFactory(entityManagerFactory());
- return txManager;
- }
-
- @Bean
- public HibernateExceptionTranslator hibernateExceptionTranslator() {
- return new HibernateExceptionTranslator();
- }
-
- @Bean
- public DataSource dataSource() {
- return new EmbeddedDatabaseBuilder()
- .setType(EmbeddedDatabaseType.HSQL)
- .addScript("classpath:schema.sql")
- .build();
- }
-
- @Bean
- public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
- PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
- propertySourcesPlaceholderConfigurer.setLocalOverride(true);
- return propertySourcesPlaceholderConfigurer;
- }
-
- @Bean
- public ServiceLocatorFactoryBean vocabularyLoaderFactoryServiceLocatorFactoryBean() {
- ServiceLocatorFactoryBean bean = new ServiceLocatorFactoryBean();
- bean.setServiceLocatorInterface(VocabularyLoaderFactory.class);
- return bean;
- }
-
- @Bean
- public VocabularyLoaderFactory vocabularyLoaderFactory() {
- return (VocabularyLoaderFactory) vocabularyLoaderFactoryServiceLocatorFactoryBean().getObject();
- }
-
- @Bean
- public ServiceLocatorFactoryBean vocabularyValidatorFactoryServiceLocatorFactoryBean() {
- ServiceLocatorFactoryBean bean = new ServiceLocatorFactoryBean();
- bean.setServiceLocatorInterface(NodeValidatorFactory.class);
- return bean;
- }
-
- @Bean
- public NodeValidatorFactory vocabularyValidatorFactory() {
- return (NodeValidatorFactory) vocabularyValidatorFactoryServiceLocatorFactoryBean().getObject();
- }
-
- @Autowired
- @Bean
- VocabularyLoadRunner vocabularyLoadRunner(final Environment environment, final VocabularyLoaderFactory vocabularyLoaderFactory, final DataSource dataSource){
- VocabularyLoadRunner vocabularyLoadRunner = null;
- String localCodeRepositoryDir = environment.getProperty("vocabulary.localCodeRepositoryDir");
- String localValueSetRepositoryDir = environment.getProperty("vocabulary.localValueSetRepositoryDir");
- vocabularyLoadRunner = new VocabularyLoadRunner();
- System.out.println("LOADING VOCABULARY DATABASES FROM THE FOLLOWING RESOURCES: VALUESETS - " + localValueSetRepositoryDir + " CODES - " + localCodeRepositoryDir);
- vocabularyLoadRunner.setCodeDirectory(localCodeRepositoryDir);
- vocabularyLoadRunner.setValueSetDirectory(localValueSetRepositoryDir);
- vocabularyLoadRunner.setDataSource(dataSource);
- vocabularyLoadRunner.setVocabularyLoaderFactory(vocabularyLoaderFactory);
- return vocabularyLoadRunner;
- }
-
- @Bean
- public List vocabularyValidationConfigurations(ValidationConfigurationLoader configurationLoader){
- return configurationLoader.getConfigurations().getExpressions();
- }
-
- @Bean
- public DocumentBuilder documentBuilder() throws ParserConfigurationException {
- DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
- domFactory.setNamespaceAware(true);
- return domFactory.newDocumentBuilder();
- }
-
- @Bean
- public XPathFactory xPathFactory(){
- return XPathFactory.newInstance();
- }
-
- @Autowired
- @Bean
- public ValidationConfigurationLoader validationConfigurationLoader(final Environment environment){
- ValidationConfigurationLoader validationConfigurationLoader = new ValidationConfigurationLoader();
- validationConfigurationLoader.setValidationConfigurationFilePath(environment.getProperty("referenceccda.configFile"));
- validationConfigurationLoader.setUnmarshaller(castorMarshaller());
- return validationConfigurationLoader;
- }
-
- @Bean
- public Jaxb2Marshaller castorMarshaller() {
- Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
- jaxb2Marshaller.setPackagesToScan("org.sitenv.vocabularies.configuration");
- Map map = new HashMap<>();
- map.put("jaxb.formatted.output", true);
- jaxb2Marshaller.setMarshallerProperties(map);
- return jaxb2Marshaller;
- }
+@PropertySource("classpath:CodeValidator.properties")
+public class CodeValidatorApiConfiguration implements AsyncConfigurer {
+ private static final Logger logger = Logger.getLogger(CodeValidatorApiConfiguration.class);
+ private static final String HSQL_JDBC_URL_TEMPLATE = "jdbc:h2:mem:inmemdb;DB_CLOSE_DELAY=-1;MULTI_THREADED=1;CACHE_SIZE=1048576";
+
+
+ @Value("classpath:schema.sql")
+ private Resource HSQL_SCHEMA_SCRIPT;
+
+ @Autowired
+ private Environment environment;
+
+ @Value("${executor.maxPoolSize}")
+ private int maxPoolSize;
+
+ @Value("${executor.corePoolSize}")
+ private int corePoolSize;
+
+ @Value("${executor.queueCapacity}")
+ private int queueCapacity;
+
+ @Bean(name = "taskExecutor")
+ public Executor getAsyncExecutor() {
+ ThreadPoolTaskExecutor e = new ThreadPoolTaskExecutor();
+ e.setThreadGroupName("Spring-group-");
+ e.setThreadNamePrefix("Spring-thread-");
+ e.setMaxPoolSize(maxPoolSize);
+ e.setCorePoolSize(corePoolSize);
+ e.setQueueCapacity(queueCapacity);
+ e.initialize();
+ return e;
+ }
+
+ @Override
+ public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
+ // TODO Auto-generated method stub
+ return null;
+ }
+
+ @Bean
+ public ServiceLocatorFactoryBean vocabularyValidatorFactoryServiceLocatorFactoryBean() {
+ ServiceLocatorFactoryBean bean = new ServiceLocatorFactoryBean();
+ bean.setServiceLocatorInterface(NodeValidatorFactory.class);
+ return bean;
+ }
+
+ @Bean
+ public NodeValidatorFactory vocabularyValidatorFactory() {
+ return (NodeValidatorFactory) vocabularyValidatorFactoryServiceLocatorFactoryBean().getObject();
+ }
+
+ @Bean
+ public EntityManagerFactory entityManagerFactory() {
+ HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter();
+ vendorAdapter.setGenerateDdl(false);
+ vendorAdapter.setShowSql(true);
+ LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean();
+ factory.setJpaVendorAdapter(vendorAdapter);
+ factory.setPackagesToScan("org.sitenv.vocabularies.validation.entities");
+ Properties jpaProperties = new Properties();
+ jpaProperties.put("hibernate.hbm2ddl.auto", "none");
+ jpaProperties.put("hibernate.dialect", "org.hibernate.dialect.H2Dialect");
+ jpaProperties.put("hibernate.format_sql", "true");
+ jpaProperties.put("hibernate.show_sql", "false");
+ jpaProperties.put("hibernate.connection.pool_size", "80");
+ factory.setDataSource(dataSource());
+ factory.setJpaProperties(jpaProperties);
+ factory.afterPropertiesSet();
+ return factory.getObject();
+ }
+
+ @Bean
+ public PlatformTransactionManager transactionManager() {
+ JpaTransactionManager txManager = new JpaTransactionManager();
+ txManager.setEntityManagerFactory(entityManagerFactory());
+ return txManager;
+ }
+
+ @Bean
+ public HibernateExceptionTranslator hibernateExceptionTranslator() {
+ return new HibernateExceptionTranslator();
+ }
+
+ @Autowired
+ @Bean
+ public DataSourceInitializer dataSourceInitializer(final DataSource dataSource) {
+ final DataSourceInitializer initializer = new DataSourceInitializer();
+ initializer.setDataSource(dataSource);
+ initializer.setDatabasePopulator(databasePopulator());
+ return initializer;
+ }
+
+ private DatabasePopulator databasePopulator() {
+ final ResourceDatabasePopulator populator = new ResourceDatabasePopulator();
+ populator.addScript(HSQL_SCHEMA_SCRIPT);
+ return populator;
+ }
+
+ @Value("${dataSource.initialSize}")
+ private int initialSize;
+
+ @Value("${dataSource.minIdle}")
+ private int minIdle;
+
+ @Value("${dataSource.maxActive}")
+ private int maxActive;
+
+ @Bean
+ public DataSource dataSource() {
+ BasicDataSource ds = new BasicDataSource();
+ ds.setUrl(HSQL_JDBC_URL_TEMPLATE);
+ ds.setUsername("sa");
+ ds.setPassword("");
+ ds.setInitialSize(initialSize);
+ ds.setMinIdle(minIdle);
+ ds.setMaxTotal(maxActive); // DBCP2 maxTotal: The maximum number of active connections that can be allocated from this pool at the same time, or negative for no limit.
+ ds.setDriverClassName("org.h2.Driver");
+ return ds;
+ }
+
+ @Bean
+ public static PropertySourcesPlaceholderConfigurer propertyPlaceholderConfigurer() {
+ PropertySourcesPlaceholderConfigurer propertySourcesPlaceholderConfigurer = new PropertySourcesPlaceholderConfigurer();
+ propertySourcesPlaceholderConfigurer.setLocalOverride(true);
+ return propertySourcesPlaceholderConfigurer;
+ }
+
+ @Bean
+ public ServiceLocatorFactoryBean vocabularyLoaderFactoryServiceLocatorFactoryBean() {
+ ServiceLocatorFactoryBean bean = new ServiceLocatorFactoryBean();
+ bean.setServiceLocatorInterface(VocabularyLoaderFactory.class);
+ return bean;
+ }
+
+ @Bean
+ public VocabularyLoaderFactory vocabularyLoaderFactory() {
+ return (VocabularyLoaderFactory) vocabularyLoaderFactoryServiceLocatorFactoryBean().getObject();
+ }
+
+ @Autowired
+ @Bean
+ VocabularyLoadRunner vocabularyLoadRunner(final Environment environment,
+ final VocabularyLoaderFactory vocabularyLoaderFactory, final DataSourceInitializer dataSourceInitializer,
+ final DataSource dataSource) {
+ // VocabularyLoadRunner vocabularyLoadRunner(final Environment
+ // environment, final VocabularyLoaderFactory vocabularyLoaderFactory,
+ // final DataSourceInitializer dataSourceInitializer, final DataSource
+ // dataSource){
+ VocabularyLoadRunner vocabularyLoadRunner = null;
+ String localCodeRepositoryDir = environment.getProperty("vocabulary.localCodeRepositoryDir");
+ String localValueSetRepositoryDir = environment.getProperty("vocabulary.localValueSetRepositoryDir");
+ vocabularyLoadRunner = new VocabularyLoadRunner();
+ logger.info("LOADING VOCABULARY DATABASES FROM THE FOLLOWING RESOURCES: VALUESETS - "
+ + localValueSetRepositoryDir + " CODES - " + localCodeRepositoryDir);
+ vocabularyLoadRunner.setCodeDirectory(localCodeRepositoryDir);
+ vocabularyLoadRunner.setValueSetDirectory(localValueSetRepositoryDir);
+ vocabularyLoadRunner.setDataSource(dataSource);
+ vocabularyLoadRunner.setVocabularyLoaderFactory(vocabularyLoaderFactory);
+
+ BasicConfigurator.configure();
+
+ return vocabularyLoadRunner;
+ }
+
+ /*
+ * Following open source method is commented and re-factored it to support
+ * MU2 document validation.
+ */
+
+ // ------------------------- INTERNAL CODE CHANGE START --------------------------
+ /*
+ * @Bean public List
+ * vocabularyValidationConfigurations(ValidationConfigurationLoader
+ * configurationLoader){ return
+ * configurationLoader.getConfigurations().getExpressions(); }
+ */
+ // ------------------------- INTERNAL CODE CHANGE END --------------------------
+
+ // ------------------------- INTERNAL CODE CHANGE START --------------------------
+ // @Bean
+ // public DocumentBuilder documentBuilder() throws
+ // ParserConfigurationException {
+ // DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
+ // domFactory.setNamespaceAware(true);
+ // return domFactory.newDocumentBuilder();
+ // }
+
+ @Bean
+ public DocumentBuilderFactory documentBuilderFactory() throws ParserConfigurationException {
+ DocumentBuilderFactory domFactory = DocumentBuilderFactory.newInstance();
+ domFactory.setNamespaceAware(true);
+ return domFactory;
+ }
+
+ // ------------------------- INTERNAL CODE CHANGE END ------------------
+
+ @Bean
+ public XPathFactory xPathFactory() {
+ return XPathFactory.newInstance();
+ }
+
+ @Autowired
+ @Bean
+ public ValidationConfigurationLoader validationConfigurationLoader(final Environment environment) {
+ ValidationConfigurationLoader validationConfigurationLoader = new ValidationConfigurationLoader();
+ validationConfigurationLoader
+ .setValidationConfigurationFilePath(environment.getProperty("referenceccda.configFile"));
+ validationConfigurationLoader.setUnmarshaller(castorMarshaller());
+ return validationConfigurationLoader;
+ }
+
+ @Bean
+ public Jaxb2Marshaller castorMarshaller() {
+ Jaxb2Marshaller jaxb2Marshaller = new Jaxb2Marshaller();
+ jaxb2Marshaller.setPackagesToScan("org.sitenv.vocabularies.configuration");
+ Map map = new HashMap<>();
+ map.put("jaxb.formatted.output", true);
+ jaxb2Marshaller.setMarshallerProperties(map);
+ return jaxb2Marshaller;
+ }
+
+ /*
+ * Following set of code is added for enhancing open source code base to
+ * support MU2 document validation.
+ */
+ // ------------------------- INTERNAL CODE CHANGE START --------------------------
+
+ @Bean
+ public List vocabularyValidationConfigurations(
+ ValidationConfigurationLoader configurationLoader) {
+
+ List mu3Expressions = new ArrayList();
+ List expressions = configurationLoader.getConfigurations().getExpressions();
+ for (ConfiguredExpression configuredExpression : expressions) {
+ List configuredValidators = configuredExpression.getConfiguredValidators();
+ for (ConfiguredValidator configuredValidator : configuredValidators) {
+ if (StringUtils.isEmpty(configuredValidator.getScope())) {
+ mu3Expressions.add(configuredExpression);
+ break;
+ }
+ }
+ }
+ logger.info("Number of MU3 expressions:" + mu3Expressions.size());
+ return mu3Expressions;
+ }
+
+ @Bean
+ public List vocabularyValidationConfigurationsForMu2(
+ ValidationConfigurationLoader configurationLoader) {
+
+ List mu2Expressions = new ArrayList();
+ List expressions = configurationLoader.getConfigurations().getExpressions();
+ for (ConfiguredExpression configuredExpression : expressions) {
+ List configuredValidators = configuredExpression.getConfiguredValidators();
+ for (ConfiguredValidator configuredValidator : configuredValidators) {
+ if (configuredValidator.getScope() != null && configuredValidator.getScope().equals("1.1")) {
+ mu2Expressions.add(configuredExpression);
+ break;
+ }
+ }
+ }
+ logger.info("Number of MU2 expressions:" + mu2Expressions.size());
+ return mu2Expressions;
+ }
+
+ // ------------------------- INTERNAL CODE CHANGE END --------------------------
}
diff --git a/src/main/java/org/sitenv/vocabularies/configuration/ConfiguredExpression.java b/src/main/java/org/sitenv/vocabularies/configuration/ConfiguredExpression.java
index c27c342..391b96b 100644
--- a/src/main/java/org/sitenv/vocabularies/configuration/ConfiguredExpression.java
+++ b/src/main/java/org/sitenv/vocabularies/configuration/ConfiguredExpression.java
@@ -1,7 +1,17 @@
package org.sitenv.vocabularies.configuration;
-import javax.xml.bind.annotation.*;
+import java.util.HashMap;
import java.util.List;
+import java.util.Map;
+
+import javax.xml.bind.annotation.XmlAccessType;
+import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
+import javax.xml.bind.annotation.XmlElement;
+import javax.xml.bind.annotation.XmlRootElement;
+
+import com.ximpleware.AutoPilot;
+import com.ximpleware.XPathParseException;
/**
* Created by Brian on 2/10/2016.
@@ -13,11 +23,11 @@ public class ConfiguredExpression {
String configuredXpathExpression;
@XmlElement(name = "validator")
List configuredValidators = null;
-
+
public String getConfiguredXpathExpression() {
return configuredXpathExpression;
}
-
+
public void setConfiguredXpathExpression(String configuredXpathExpression) {
this.configuredXpathExpression = configuredXpathExpression;
}
diff --git a/src/main/java/org/sitenv/vocabularies/configuration/ConfiguredValidator.java b/src/main/java/org/sitenv/vocabularies/configuration/ConfiguredValidator.java
index 6cf4c36..400e350 100644
--- a/src/main/java/org/sitenv/vocabularies/configuration/ConfiguredValidator.java
+++ b/src/main/java/org/sitenv/vocabularies/configuration/ConfiguredValidator.java
@@ -2,6 +2,7 @@
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
+import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
@@ -11,7 +12,17 @@
@XmlRootElement(name = "validator")
@XmlAccessorType(XmlAccessType.FIELD)
public class ConfiguredValidator {
- @XmlElement(name = "name")
+ /*
+ * Following XML attribute 'scope' is added to support MU2 document validation.
+ * Xpath configuration validator having scope attribute set to '1.1' are targeted for
+ * CCDA R 1.1 CCDA document validation.
+ */
+ //------------------------- INTERNAL CODE CHAGNE START --------------------------
+ @XmlAttribute(name = "scope")
+ String scope;
+ //------------------------- INTERNAL CODE CHAGNE END --------------------------
+
+ @XmlElement(name = "name")
String name;
@XmlElement(name = "nodeType")
String nodeType;
@@ -21,7 +32,9 @@ public class ConfiguredValidator {
String allowedValuesetOids;
@XmlElement(name = "allowedCodesystemNames")
String allowedCodesystemNames;
-
+ @XmlAttribute(name = "id")
+ String id;
+
public String getName() {
return name;
}
@@ -61,5 +74,27 @@ public String getAllowedCodesystemNames() {
public void setAllowedCodesystemNames(String allowedCodesystemNames) {
this.allowedCodesystemNames = allowedCodesystemNames;
}
+
+ /*
+ * setter and getter methods for 'scope' attribute to support MU2 document validation.
+ * scope attribute set to '1.1' are targeted for CCDA R 1.1 CCDA document validation.
+ */
+ //------------------------- INTERNAL CODE CHAGNE START --------------------------
+ public String getScope() {
+ return scope;
+ }
+
+ public void setScope(String scope) {
+ this.scope = scope;
+ }
+
+ public String getId() {
+ return id;
+ }
+
+ public void setId(String id) {
+ this.id = id;
+ }
+ //------------------------- INTERNAL CODE CHAGNE END --------------------------
}
diff --git a/src/main/java/org/sitenv/vocabularies/configuration/ValidationConfigurationLoader.java b/src/main/java/org/sitenv/vocabularies/configuration/ValidationConfigurationLoader.java
index 0aca331..eaf60f7 100644
--- a/src/main/java/org/sitenv/vocabularies/configuration/ValidationConfigurationLoader.java
+++ b/src/main/java/org/sitenv/vocabularies/configuration/ValidationConfigurationLoader.java
@@ -1,16 +1,20 @@
package org.sitenv.vocabularies.configuration;
-import org.springframework.beans.factory.InitializingBean;
-import org.springframework.oxm.Unmarshaller;
-
-import javax.xml.transform.stream.StreamSource;
import java.io.FileInputStream;
import java.io.IOException;
+import javax.xml.transform.stream.StreamSource;
+
+import org.apache.log4j.Logger;
+import org.sitenv.vocabularies.validation.pool.AutoPilotObjectPoolInitializer;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.oxm.Unmarshaller;
+
/**
* Created by Brian on 2/10/2016.
*/
public class ValidationConfigurationLoader implements InitializingBean {
+ private static Logger logger = Logger.getLogger(ValidationConfigurationLoader.class);
private Unmarshaller unmarshaller;
private String validationConfigurationFilePath;
private Configurations configurations;
@@ -32,7 +36,9 @@ public Object xmlToObject(String fileName) throws IOException {
FileInputStream fis = null;
try {
fis = new FileInputStream(fileName);
- return configurations = (Configurations) unmarshaller.unmarshal(new StreamSource(fis));
+ configurations = (Configurations) unmarshaller.unmarshal(new StreamSource(fis));
+ logger.info("Loading expressions from: " + fileName + ". # Expressions:" + configurations.getExpressions().size());
+ return configurations;
} finally {
fis.close();
}
@@ -41,5 +47,9 @@ public Object xmlToObject(String fileName) throws IOException {
@Override
public void afterPropertiesSet() throws Exception {
xmlToObject(validationConfigurationFilePath);
+ // ------------------------- INTERNAL CODE CHANGE START --------------------------
+ AutoPilotObjectPoolInitializer initializer = new AutoPilotObjectPoolInitializer();
+ initializer.initFromExpressions(configurations.getExpressions());
+ // ------------------------- INTERNAL CODE CHANGE END --------------------------
}
}
\ No newline at end of file
diff --git a/src/main/java/org/sitenv/vocabularies/constants/VocabularyConstants.java b/src/main/java/org/sitenv/vocabularies/constants/VocabularyConstants.java
index b760030..ac29fd3 100644
--- a/src/main/java/org/sitenv/vocabularies/constants/VocabularyConstants.java
+++ b/src/main/java/org/sitenv/vocabularies/constants/VocabularyConstants.java
@@ -1,5 +1,6 @@
package org.sitenv.vocabularies.constants;
+import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;
diff --git a/src/main/java/org/sitenv/vocabularies/loader/BaseVocabularyLoader.java b/src/main/java/org/sitenv/vocabularies/loader/BaseVocabularyLoader.java
new file mode 100644
index 0000000..e69de29
diff --git a/src/main/java/org/sitenv/vocabularies/loader/VocabularyLoadRunner.java b/src/main/java/org/sitenv/vocabularies/loader/VocabularyLoadRunner.java
index ae0ba98..8db1f34 100644
--- a/src/main/java/org/sitenv/vocabularies/loader/VocabularyLoadRunner.java
+++ b/src/main/java/org/sitenv/vocabularies/loader/VocabularyLoadRunner.java
@@ -1,19 +1,29 @@
package org.sitenv.vocabularies.loader;
-import org.apache.log4j.Logger;
-import org.springframework.beans.factory.DisposableBean;
-import org.springframework.beans.factory.InitializingBean;
-
-import javax.sql.DataSource;
import java.io.File;
import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.Arrays;
+import javax.persistence.EntityManager;
+import javax.persistence.EntityManagerFactory;
+import javax.persistence.EntityTransaction;
+import javax.sql.DataSource;
+
+import org.apache.log4j.Logger;
+import org.sitenv.vocabularies.validation.dao.CodeSystemCodeDAO;
+import org.sitenv.vocabularies.validation.dao.ValueSetDAO;
+import org.springframework.beans.factory.DisposableBean;
+import org.springframework.beans.factory.InitializingBean;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Value;
+import org.springframework.context.annotation.PropertySource;
+
/**
* Created by Brian on 2/6/2016.
*/
+@PropertySource("classpath:CodeValidator.properties")
public class VocabularyLoadRunner implements InitializingBean, DisposableBean {
private VocabularyLoaderFactory vocabularyLoaderFactory;
private static Logger logger = Logger.getLogger(VocabularyLoadRunner.class);
@@ -22,19 +32,30 @@ public class VocabularyLoadRunner implements InitializingBean, DisposableBean {
private boolean recursive = true;
private DataSource dataSource;
- public void loadDirectory(String directory, Connection connection) throws IOException {
+ @Value("${cleanUpDatabaseAfterLoadingHashSets}")
+ private boolean cleanUpDatabaseAfterLoadingHashSets;
+
+ @Autowired
+ ValueSetDAO vsdao;
+
+ @Autowired
+ CodeSystemCodeDAO csdao;
+
+
+ public void loadDirectory(String directory, DataSource datasource) throws IOException {
File dir = new File(directory);
if (dir.isFile()) {
throw new IOException("Directory to Load is a file and not a directory");
} else {
File[] list = dir.listFiles();
for (File file : list) {
- load(file, connection);
+ load(file, datasource);
}
}
}
+
- private void load(File directory, Connection connection) throws IOException {
+ private void load(File directory, DataSource datasource) throws IOException {
if (directory.isDirectory() && !directory.isHidden()) {
File[] filesToLoad = directory.listFiles();
logger.debug("Building Loader for directory: " + directory.getName() + "...");
@@ -42,13 +63,14 @@ private void load(File directory, Connection connection) throws IOException {
if (loader != null && filesToLoad != null) {
logger.debug("Loader built...");
logger.info("Loading files in : " + directory.getName() + "...");
- loader.load(Arrays.asList(filesToLoad), connection);
- logger.debug("File loaded...");
+ long n = loader.load(Arrays.asList(filesToLoad), datasource);
+ logger.info("File loaded...(" + n + ") entries.");
} else {
logger.debug("Building of Loader Failed.");
}
}
}
+
public String getCodeDirectory() {
return codeDirectory;
@@ -90,24 +112,60 @@ public void afterPropertiesSet() throws Exception {
connection.setAutoCommit(false);
if (codeDirectory != null && !codeDirectory.trim().equals("")) {
logger.info("Loading vocabularies at: " + codeDirectory + "...");
- loadDirectory(codeDirectory, connection);
+ loadDirectory(codeDirectory, dataSource);
logger.info("Vocabularies loaded...");
}
connection.commit();
if (valueSetDirectory != null && !valueSetDirectory.trim().equals("")) {
logger.info("Loading value sets at: " + valueSetDirectory + "...");
- loadDirectory(valueSetDirectory, connection);
+ loadDirectory(valueSetDirectory, dataSource);
logger.info("Value Sets loaded...");
}
connection.commit();
logger.info("!!!!*********** VOCABULARY DATABASE HAS FINISHED LOADING - SERVER WILL CONTINUE AND SHOULD BE DONE SHORTLY. ***********!!!!");
+
+ vsdao.loadValueSets(dataSource);
+ connection.commit();
+ csdao.loadCodes(dataSource);
+ connection.commit();
+
+ logger.info("!!!!*********** INITIALIZED HASH SETS. ***********!!!!");
+
} catch (Exception e) {
logger.error("Failed to load configured vocabulary directory.", e);
}finally {
try {
- if(connection != null || !(connection.isClosed())) {
+ logger.info("!!!!*********** cleanUpDatabaseAfterLoadingHashSets falg set as : "
+ + cleanUpDatabaseAfterLoadingHashSets);
+ /*
+ * If the 'cleanUpDatabaseAfterLoadingHashSets' defined in
+ * CodeValidator.properties is set to true, then all the records
+ * from (Codes and ValueSets tables) the DB are deleted.
+ *
+ * Note: If there are any methods that are defined in the
+ * Repository classes (CodeRepository, VsacValuesSetRepository
+ * etc.,) are not implemented in the DAO classes (ValueSetDAO,
+ * CodeSystemDAO) and the same methods are being used by the
+ * consumer/caller then the flag
+ * cleanUpDatabaseAfterLoadingHashSets should be set to false.
+ * Otherwise if this flag was set to true and when these methods
+ * are invoked, no records will be returned. Ex., In the current
+ * versionm, these three methods findByCodeAndCodeSystemIn;
+ * findByValuesetOidIn, findByCodeAndValuesetOidIn defined in
+ * CodeRepository and ValueSetRepository are not implemented in
+ * ValueSetDAO & CodeSystemDAO classes. Hence, if any
+ * client/consumer wants to leverage these helper methods,
+ * should set the flag to false.
+ *
+ */
+
+ if(cleanUpDatabaseAfterLoadingHashSets) {
+ perfromDBCleanup(connection);
+ logger.info("!!!!*********** DB Cleanup completed **************!!!!");
+ }
+ if(connection != null && !(connection.isClosed())) {
connection.close();
}
} catch (SQLException e) {
@@ -116,6 +174,14 @@ public void afterPropertiesSet() throws Exception {
}
}
+ private void perfromDBCleanup(Connection connection) throws SQLException {
+ csdao.cleanupDBAfterLoadingToHashSets(dataSource);
+ connection.commit();
+
+ vsdao.cleanupDBAfterLoadingToHashSets(dataSource);
+ connection.commit();
+ }
+
@Override
public void destroy() throws Exception {
logger.info("Destroying Loader Bean. Loading is done.");
diff --git a/src/main/java/org/sitenv/vocabularies/loader/VocabularyLoader.java b/src/main/java/org/sitenv/vocabularies/loader/VocabularyLoader.java
index 1d1610d..e0876de 100644
--- a/src/main/java/org/sitenv/vocabularies/loader/VocabularyLoader.java
+++ b/src/main/java/org/sitenv/vocabularies/loader/VocabularyLoader.java
@@ -4,9 +4,11 @@
import java.sql.Connection;
import java.util.List;
+import javax.sql.DataSource;
+
/**
* Created by Brian on 2/7/2016.
*/
public interface VocabularyLoader {
- void load(List file, Connection connection);
+ long load(List file, DataSource ds);
}
diff --git a/src/main/java/org/sitenv/vocabularies/loader/code/CdtLoader.java b/src/main/java/org/sitenv/vocabularies/loader/code/CdtLoader.java
index 28f0cbd..1444d7a 100644
--- a/src/main/java/org/sitenv/vocabularies/loader/code/CdtLoader.java
+++ b/src/main/java/org/sitenv/vocabularies/loader/code/CdtLoader.java
@@ -1,5 +1,13 @@
package org.sitenv.vocabularies.loader.code;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import javax.sql.DataSource;
+
import org.apache.commons.lang3.text.StrBuilder;
import org.apache.log4j.Logger;
import org.apache.poi.ss.usermodel.Cell;
@@ -8,24 +16,18 @@
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.sitenv.vocabularies.loader.BaseCodeLoader;
+import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.List;
-
@Component(value = "CDT")
- public class CdtLoader extends BaseCodeLoader {
+public class CdtLoader extends BaseCodeLoader {
private static Logger logger = Logger.getLogger(CdtLoader.class);
- @Override
- public void load(List filesToLoad, Connection connection) {
+ public long load(List filesToLoad, DataSource ds) {
+ long n = 0;
StrBuilder insertQueryBuilder = null;
String insertQueryPrefix = codeTableInsertSQLPrefix;
+ JdbcTemplate t = new JdbcTemplate(ds);
for (File file : filesToLoad) {
if (file.isFile() && !file.isHidden()) {
String codeSystem = file.getParentFile().getName();
@@ -54,15 +56,17 @@ public void load(List filesToLoad, Connection connection) {
code = codeCell.getStringCellValue();
displayName = descriptionCell.getStringCellValue();
- buildCodeInsertQueryString(insertQueryBuilder, code, displayName, codeSystem, CodeSystemOIDs.CDT.codesystemOID());
+ n++;
+ buildCodeInsertQueryString(insertQueryBuilder, code.toUpperCase(), displayName.toUpperCase(), codeSystem, CodeSystemOIDs.CDT.codesystemOID());
+ t.update(insertQueryPrefix.toString());
+ insertQueryBuilder.clear();
+ insertQueryBuilder.append(codeTableInsertSQLPrefix);
+
}
}
- insertCode(insertQueryBuilder.toString(), connection);
}
} catch (IOException e) {
logger.error(e);
- } catch (SQLException e) {
- e.printStackTrace();
} finally {
try {
if(workBook != null) {
@@ -77,6 +81,7 @@ public void load(List filesToLoad, Connection connection) {
}
}
}
+ return n;
}
public static boolean isRowEmpty(Row row) {
diff --git a/src/main/java/org/sitenv/vocabularies/loader/code/CodeSystemOIDs.java b/src/main/java/org/sitenv/vocabularies/loader/code/CodeSystemOIDs.java
index 1c3ae19..943e773 100644
--- a/src/main/java/org/sitenv/vocabularies/loader/code/CodeSystemOIDs.java
+++ b/src/main/java/org/sitenv/vocabularies/loader/code/CodeSystemOIDs.java
@@ -4,9 +4,9 @@
* Created by Brian on 8/9/2016.
*/
public enum CodeSystemOIDs {
- SNOMEDCT("2.16.840.1.113883.6.96"),
- RXNORM("2.16.840.1.113883.6.88"),
- LOINC("2.16.840.1.113883.6.1"),
+ SNOMEDCT("2.16.840.1.113883.6.96"),
+ RXNORM("2.16.840.1.113883.6.88"),
+ LOINC("2.16.840.1.113883.6.1"),
ICD10CM("2.16.840.1.113883.6.90"),
ICD10PCS("2.16.840.1.113883.6.4"),
CPT4("2.16.840.1.113883.6.12"),
diff --git a/src/main/java/org/sitenv/vocabularies/loader/code/CptLoader.java b/src/main/java/org/sitenv/vocabularies/loader/code/CptLoader.java
index d4b8715..627d2bd 100644
--- a/src/main/java/org/sitenv/vocabularies/loader/code/CptLoader.java
+++ b/src/main/java/org/sitenv/vocabularies/loader/code/CptLoader.java
@@ -1,18 +1,19 @@
package org.sitenv.vocabularies.loader.code;
-import org.apache.commons.lang3.text.StrBuilder;
-import org.apache.log4j.Logger;
-import org.sitenv.vocabularies.loader.BaseCodeLoader;
-import org.springframework.stereotype.Component;
-
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
-import java.sql.Connection;
-import java.sql.SQLException;
import java.util.List;
+import javax.sql.DataSource;
+
+import org.apache.commons.lang3.text.StrBuilder;
+import org.apache.log4j.Logger;
+import org.sitenv.vocabularies.loader.BaseCodeLoader;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.stereotype.Component;
+
/**
* Created by Brian on 2/7/2016.
*/
@@ -26,13 +27,13 @@ public CptLoader() {
}
@Override
- public void load(List filesToLoad, Connection connection) {
+ public long load(List filesToLoad, DataSource ds) {
+ long n = 0;
BufferedReader br = null;
FileReader fileReader = null;
try {
StrBuilder insertQueryBuilder = new StrBuilder(codeTableInsertSQLPrefix);
- int totalCount = 0, pendingCount = 0;
-
+ JdbcTemplate t = new JdbcTemplate(ds);
for (File file : filesToLoad) {
if (file.isFile() && !file.isHidden()) {
logger.debug("Loading CPT File: " + file.getName());
@@ -46,24 +47,17 @@ public void load(List filesToLoad, Connection connection) {
String displayName = line.substring(line.indexOf(" "));
buildCodeInsertQueryString(insertQueryBuilder, code, displayName, codeSystem, oid);
- if ((++totalCount % BATCH_SIZE) == 0) {
- insertCode(insertQueryBuilder.toString(), connection);
- insertQueryBuilder.clear();
- insertQueryBuilder.append(codeTableInsertSQLPrefix);
- pendingCount = 0;
- }
+ n++;
+ t.update(codeTableInsertSQLPrefix,code.toUpperCase().trim(),displayName.toUpperCase().trim(),codeSystem,CodeSystemOIDs.CDT.codesystemOID());
+
}
}
}
}
- if (pendingCount > 0) {
- insertCode(insertQueryBuilder.toString(), connection);
- }
} catch (IOException e) {
logger.error(e);
- } catch (SQLException e) {
- e.printStackTrace();
- } finally {
+ }
+ finally {
if (br != null) {
try {
fileReader.close();
@@ -73,5 +67,7 @@ public void load(List filesToLoad, Connection connection) {
}
}
}
+
+ return n;
}
}
diff --git a/src/main/java/org/sitenv/vocabularies/loader/code/Icd10BaseLoader.java b/src/main/java/org/sitenv/vocabularies/loader/code/Icd10BaseLoader.java
index 7084299..1efbcc5 100644
--- a/src/main/java/org/sitenv/vocabularies/loader/code/Icd10BaseLoader.java
+++ b/src/main/java/org/sitenv/vocabularies/loader/code/Icd10BaseLoader.java
@@ -1,8 +1,5 @@
package org.sitenv.vocabularies.loader.code;
-import org.apache.commons.lang3.text.StrBuilder;
-import org.apache.log4j.Logger;
-
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
@@ -11,6 +8,13 @@
import java.sql.SQLException;
import java.util.List;
+import javax.sql.DataSource;
+
+import org.apache.commons.lang3.text.StrBuilder;
+import org.apache.log4j.Logger;
+import org.sitenv.vocabularies.loader.VocabularyLoader;
+import org.springframework.jdbc.core.JdbcTemplate;
+
/**
* Created by Brian on 2/7/2016.
*/
@@ -18,8 +22,9 @@ public abstract class Icd10BaseLoader extends IcdLoader {
private static Logger logger = Logger.getLogger(Icd10BaseLoader.class);
protected String oid;
- @Override
- public void load(List filesToLoad, Connection connection) {
+ public long load(List filesToLoad, DataSource datasource) {
+ long n = 0;
+ JdbcTemplate t = new JdbcTemplate(datasource);
BufferedReader br = null;
FileReader fileReader = null;
try {
@@ -38,26 +43,24 @@ public void load(List filesToLoad, Connection connection) {
String shortDisplayName = available.substring(16, 77);
String longDisplayName = available.substring(77);
+ n++;
+
buildCodeInsertQueryString(insertQueryBuilder, code, shortDisplayName, codeSystem, oid);
+ t.update(insertQueryBuilder.toString());
+ insertQueryBuilder.clear();
+ insertQueryBuilder.append(codeTableInsertSQLPrefix);
+
buildCodeInsertQueryString(insertQueryBuilder, code, longDisplayName, codeSystem, oid);
-
- if ((++totalCount % BATCH_SIZE) == 0) {
- insertCode(insertQueryBuilder.toString(), connection);
- insertQueryBuilder.clear();
- insertQueryBuilder.append(codeTableInsertSQLPrefix);
- pendingCount = 0;
- }
+ t.update(insertQueryBuilder.toString());
+ insertQueryBuilder.clear();
+ insertQueryBuilder.append(codeTableInsertSQLPrefix);
+
}
}
}
- if (pendingCount > 0) {
- insertCode(insertQueryBuilder.toString(), connection);
- }
} catch (IOException e) {
logger.error(e);
- } catch (SQLException e) {
- e.printStackTrace();
} finally {
if (br != null) {
try {
@@ -68,5 +71,6 @@ public void load(List filesToLoad, Connection connection) {
}
}
}
+ return n;
}
}
diff --git a/src/main/java/org/sitenv/vocabularies/loader/code/Icd9BaseLoader.java b/src/main/java/org/sitenv/vocabularies/loader/code/Icd9BaseLoader.java
index be5554e..9278982 100644
--- a/src/main/java/org/sitenv/vocabularies/loader/code/Icd9BaseLoader.java
+++ b/src/main/java/org/sitenv/vocabularies/loader/code/Icd9BaseLoader.java
@@ -1,18 +1,19 @@
package org.sitenv.vocabularies.loader.code;
-import org.apache.commons.lang3.text.StrBuilder;
-import org.apache.log4j.Logger;
-import org.sitenv.vocabularies.loader.BaseCodeLoader;
+import static org.sitenv.vocabularies.loader.code.IcdLoader.buildDelimitedIcdCode;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
-import java.sql.Connection;
-import java.sql.SQLException;
import java.util.List;
-import static org.sitenv.vocabularies.loader.code.IcdLoader.buildDelimitedIcdCode;
+import javax.sql.DataSource;
+
+import org.apache.commons.lang3.text.StrBuilder;
+import org.apache.log4j.Logger;
+import org.sitenv.vocabularies.loader.BaseCodeLoader;
+import org.springframework.jdbc.core.JdbcTemplate;
/**
* Created by Brian on 2/7/2016.
@@ -22,12 +23,13 @@ public abstract class Icd9BaseLoader extends BaseCodeLoader {
protected String oid;
@Override
- public void load(List filesToLoad, Connection connection) {
+ public long load(List filesToLoad, DataSource datasource) {
+ long n = 0;
BufferedReader br = null;
FileReader fileReader = null;
+ JdbcTemplate t = new JdbcTemplate(datasource);
try {
StrBuilder insertQueryBuilder = new StrBuilder(codeTableInsertSQLPrefix);
- int totalCount = 0, pendingCount = 0;
for (File file : filesToLoad) {
if (file.isFile() && !file.isHidden()) {
@@ -41,24 +43,17 @@ public void load(List filesToLoad, Connection connection) {
String code = buildDelimitedIcdCode(line.substring(0, 5));
String displayName = line.substring(6);
buildCodeInsertQueryString(insertQueryBuilder, code, displayName, codeSystem, oid);
+ n++;
+ t.update(insertQueryBuilder.toString());
+ insertQueryBuilder.clear();
+ insertQueryBuilder.append(codeTableInsertSQLPrefix);
- if ((++totalCount % BATCH_SIZE) == 0) {
- insertCode(insertQueryBuilder.toString(), connection);
- insertQueryBuilder.clear();
- insertQueryBuilder.append(codeTableInsertSQLPrefix);
- pendingCount = 0;
- }
}
}
}
}
- if (pendingCount > 0) {
- insertCode(insertQueryBuilder.toString(), connection);
- }
} catch (IOException e) {
logger.error(e);
- } catch (SQLException e) {
- e.printStackTrace();
} finally {
if (br != null) {
try {
@@ -69,5 +64,6 @@ public void load(List filesToLoad, Connection connection) {
}
}
}
+ return n;
}
}
diff --git a/src/main/java/org/sitenv/vocabularies/loader/code/Icd9CmDxLoader.java b/src/main/java/org/sitenv/vocabularies/loader/code/Icd9CmDxLoader.java
index 8704c6a..3a26492 100644
--- a/src/main/java/org/sitenv/vocabularies/loader/code/Icd9CmDxLoader.java
+++ b/src/main/java/org/sitenv/vocabularies/loader/code/Icd9CmDxLoader.java
@@ -11,5 +11,4 @@ public class Icd9CmDxLoader extends Icd9BaseLoader {
public Icd9CmDxLoader() {
this.oid = CodeSystemOIDs.ICD9CMDX.codesystemOID();
}
-
}
diff --git a/src/main/java/org/sitenv/vocabularies/loader/code/LoincLoader.java b/src/main/java/org/sitenv/vocabularies/loader/code/LoincLoader.java
index 2a3900e..9d0273c 100644
--- a/src/main/java/org/sitenv/vocabularies/loader/code/LoincLoader.java
+++ b/src/main/java/org/sitenv/vocabularies/loader/code/LoincLoader.java
@@ -1,20 +1,21 @@
package org.sitenv.vocabularies.loader.code;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.List;
+
+import javax.sql.DataSource;
+
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.text.StrBuilder;
import org.apache.log4j.Logger;
import org.sitenv.vocabularies.loader.BaseCodeLoader;
import org.sitenv.vocabularies.loader.VocabularyLoader;
+import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.List;
-
/**
* Created by Brian on 2/7/2016.
*/
@@ -22,13 +23,13 @@
public class LoincLoader extends BaseCodeLoader implements VocabularyLoader {
private static Logger logger = Logger.getLogger(LoincLoader.class);
- @Override
- public void load(List filesToLoad, Connection connection) {
+ public long load(List filesToLoad, DataSource datasource) {
+ long n = 0;
+ JdbcTemplate t = new JdbcTemplate(datasource);
BufferedReader br = null;
FileReader fileReader = null;
try {
StrBuilder insertQueryBuilder = new StrBuilder(codeTableInsertSQLPrefix);
- int totalCount = 0, pendingCount = 0;
for (File file : filesToLoad) {
if (file.isFile() && !file.isHidden()) {
@@ -49,28 +50,29 @@ public void load(List filesToLoad, Connection connection) {
String longCommonName = StringUtils.strip(line[29], "\"");
String componentName = StringUtils.strip(line[1], "\"");
String shortName = StringUtils.strip(line[23], "\"");
+ n++;
+
+ buildCodeInsertQueryString(insertQueryBuilder, code, longCommonName.toUpperCase(), codeSystem, oid);
+ t.update(insertQueryBuilder.toString());
+ insertQueryBuilder.clear();
+ insertQueryBuilder.append(codeTableInsertSQLPrefix);
+
+ buildCodeInsertQueryString(insertQueryBuilder, code, componentName.toUpperCase(), codeSystem, oid);
+ t.update(insertQueryBuilder.toString());
+ insertQueryBuilder.clear();
+ insertQueryBuilder.append(codeTableInsertSQLPrefix);
- buildCodeInsertQueryString(insertQueryBuilder, code, longCommonName, codeSystem, oid);
- buildCodeInsertQueryString(insertQueryBuilder, code, componentName, codeSystem, oid);
- buildCodeInsertQueryString(insertQueryBuilder, code, shortName, codeSystem, oid);
-
- if ((++totalCount % BATCH_SIZE) == 0) {
- insertCode(insertQueryBuilder.toString(), connection);
- insertQueryBuilder.clear();
- insertQueryBuilder.append(codeTableInsertSQLPrefix);
- pendingCount = 0;
- }
+
+ buildCodeInsertQueryString(insertQueryBuilder, code, shortName.toUpperCase(), codeSystem, oid);
+ t.update(insertQueryBuilder.toString());
+ insertQueryBuilder.clear();
+ insertQueryBuilder.append(codeTableInsertSQLPrefix);
}
}
}
}
- if (pendingCount > 0) {
- insertCode(insertQueryBuilder.toString(), connection);
- }
} catch (IOException e) {
logger.error(e);
- } catch (SQLException e) {
- e.printStackTrace();
} finally {
if (br != null) {
try {
@@ -81,6 +83,6 @@ public void load(List filesToLoad, Connection connection) {
}
}
}
+ return n;
}
-
}
diff --git a/src/main/java/org/sitenv/vocabularies/loader/code/RxNormLoader.java b/src/main/java/org/sitenv/vocabularies/loader/code/RxNormLoader.java
index 0fc4513..f50ecf7 100644
--- a/src/main/java/org/sitenv/vocabularies/loader/code/RxNormLoader.java
+++ b/src/main/java/org/sitenv/vocabularies/loader/code/RxNormLoader.java
@@ -1,20 +1,21 @@
package org.sitenv.vocabularies.loader.code;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.util.List;
+
+import javax.sql.DataSource;
+
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.text.StrBuilder;
import org.apache.log4j.Logger;
import org.sitenv.vocabularies.loader.BaseCodeLoader;
import org.sitenv.vocabularies.loader.VocabularyLoader;
+import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileReader;
-import java.io.IOException;
-import java.sql.Connection;
-import java.sql.SQLException;
-import java.util.List;
-
/**
* Created by Brian on 2/7/2016.
*/
@@ -22,13 +23,13 @@
public class RxNormLoader extends BaseCodeLoader implements VocabularyLoader {
private static Logger logger = Logger.getLogger(RxNormLoader.class);
- @Override
- public void load(List filesToLoad, Connection connection) {
+ public long load(List filesToLoad, DataSource datasource) {
+ long n = 0;
+ JdbcTemplate t = new JdbcTemplate(datasource);
FileReader fileReader = null;
BufferedReader br = null;
try {
StrBuilder insertQueryBuilder = new StrBuilder(codeTableInsertSQLPrefix);
- int totalCount = 0, pendingCount = 0;
for (File file : filesToLoad) {
if (file.isFile() && !file.isHidden()) {
@@ -42,24 +43,17 @@ public void load(List filesToLoad, Connection connection) {
String code = line[0];
String displayName = line[14];
- buildCodeInsertQueryString(insertQueryBuilder, code, displayName, codeSystem, CodeSystemOIDs.RXNORM.codesystemOID());
-
- if ((++totalCount % BATCH_SIZE) == 0) {
- insertCode(insertQueryBuilder.toString(), connection);
- insertQueryBuilder.clear();
- insertQueryBuilder.append(codeTableInsertSQLPrefix);
- pendingCount = 0;
- }
+ n++;
+ buildCodeInsertQueryString(insertQueryBuilder, code, displayName.toUpperCase(), codeSystem, CodeSystemOIDs.RXNORM.codesystemOID());
+ t.update(insertQueryBuilder.toString());
+ insertQueryBuilder.clear();
+ insertQueryBuilder.append(codeTableInsertSQLPrefix);
+
}
}
}
- if (pendingCount > 0) {
- insertCode(insertQueryBuilder.toString(), connection);
- }
} catch (IOException e) {
logger.error(e);
- } catch (SQLException e) {
- e.printStackTrace();
} finally {
if (br != null) {
try {
@@ -70,5 +64,7 @@ public void load(List filesToLoad, Connection connection) {
}
}
}
+ return n;
}
+
}
diff --git a/src/main/java/org/sitenv/vocabularies/loader/code/SnomedLoader.java b/src/main/java/org/sitenv/vocabularies/loader/code/SnomedLoader.java
index 4cdd33d..64966e8 100644
--- a/src/main/java/org/sitenv/vocabularies/loader/code/SnomedLoader.java
+++ b/src/main/java/org/sitenv/vocabularies/loader/code/SnomedLoader.java
@@ -5,16 +5,17 @@
import org.apache.log4j.Logger;
import org.sitenv.vocabularies.loader.BaseCodeLoader;
import org.sitenv.vocabularies.loader.VocabularyLoader;
+import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
-import java.sql.Connection;
-import java.sql.SQLException;
import java.util.List;
+import javax.sql.DataSource;
+
/**
* Created by Brian on 2/7/2016.
*/
@@ -22,13 +23,13 @@
public class SnomedLoader extends BaseCodeLoader implements VocabularyLoader {
private static Logger logger = Logger.getLogger(SnomedLoader.class);
- @Override
- public void load(List filesToLoad, Connection connection) {
+ public long load(List filesToLoad, DataSource datasource) {
+ long n = 0;
+ JdbcTemplate t = new JdbcTemplate(datasource);
BufferedReader br = null;
FileReader fileReader = null;
try {
StrBuilder insertQueryBuilder = new StrBuilder(codeTableInsertSQLPrefix);
- int totalCount = 0, pendingCount = 0;
for (File file : filesToLoad) {
if (file.isFile() && !file.isHidden()) {
@@ -45,26 +46,17 @@ public void load(List filesToLoad, Connection connection) {
String[] line = StringUtils.splitPreserveAllTokens(available, "\t", 9);
String code = line[4];
String displayName = line[7];
-
- buildCodeInsertQueryString(insertQueryBuilder, code, displayName, codeSystem, CodeSystemOIDs.SNOMEDCT.codesystemOID());
-
- if ((++totalCount % BATCH_SIZE) == 0) {
- insertCode(insertQueryBuilder.toString(), connection);
- insertQueryBuilder.clear();
- insertQueryBuilder.append(codeTableInsertSQLPrefix);
- pendingCount = 0;
- }
+ n++;
+ buildCodeInsertQueryString(insertQueryBuilder, code.toUpperCase(), displayName.toUpperCase(), codeSystem, CodeSystemOIDs.SNOMEDCT.codesystemOID());
+ t.update(insertQueryBuilder.toString());
+ insertQueryBuilder.clear();
+ insertQueryBuilder.append(codeTableInsertSQLPrefix);
}
}
}
}
- if (pendingCount > 0) {
- insertCode(insertQueryBuilder.toString(), connection);
- }
} catch (IOException e) {
logger.error(e);
- } catch (SQLException e) {
- e.printStackTrace();
} finally {
if (br != null) {
try {
@@ -75,5 +67,7 @@ public void load(List filesToLoad, Connection connection) {
}
}
}
+ return n;
}
+
}
diff --git a/src/main/java/org/sitenv/vocabularies/loader/valueset/VsacLoader.java b/src/main/java/org/sitenv/vocabularies/loader/valueset/VsacLoader.java
index f7f716b..85f8494 100644
--- a/src/main/java/org/sitenv/vocabularies/loader/valueset/VsacLoader.java
+++ b/src/main/java/org/sitenv/vocabularies/loader/valueset/VsacLoader.java
@@ -1,40 +1,44 @@
package org.sitenv.vocabularies.loader.valueset;
-import com.monitorjbl.xlsx.StreamingReader;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+
+import javax.sql.DataSource;
+
import org.apache.log4j.Logger;
+import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
+import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;
+import org.apache.poi.ss.usermodel.WorkbookFactory;
import org.sitenv.vocabularies.loader.BaseCodeLoader;
import org.sitenv.vocabularies.loader.VocabularyLoader;
+import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
-import java.sql.Connection;
-import java.sql.PreparedStatement;
-import java.sql.SQLException;
-import java.util.List;
+//import com.monitorjbl.xlsx.StreamingReader;
@Component(value = "VSAC")
public class VsacLoader extends BaseCodeLoader implements VocabularyLoader {
private static Logger logger = Logger.getLogger(VsacLoader.class);
private static final int MIN_EXPECTED_NUMBER_OF_CELLS_IN_ROW = 6;
private static final int CODE_CELL_INDEX_IN_ROW = 0;
- private static final int BATCH_SIZE = 1000;
private static final String HEADER_ROW_FINDER_KEY = "CODE";
- public void load(List filesToLoad, Connection connection) {
- String insertQueryPrefix = "insert into VALUESETS (ID, CODE, DISPLAYNAME, CODESYSTEMNAME, CODESYSTEMVERSION, CODESYSTEM, TTY, VALUESETNAME, VALUESETOID, VALUESETTYPE, VALUESETDEFINITIONVERSION, VALUESETSTEWARD) values (DEFAULT ,?,?,?,?,?,?,?,?,?,?,?)";
+ public long load(List filesToLoad, DataSource datasource) {
+ String insertQueryPrefix = "insert into VALUESETS (CODE, DISPLAYNAME, CODESYSTEMNAME, CODESYSTEMVERSION, CODESYSTEM, TTY, VALUESETNAME, VALUESETOID, VALUESETTYPE, VALUESETDEFINITIONVERSION, VALUESETSTEWARD) values (?,?,?,?,?,?,?,?,?,?,?)";
+ long n = 0;
+ JdbcTemplate templ = new JdbcTemplate(datasource);
for (File file : filesToLoad) {
if (file.isFile() && !file.isHidden()) {
try {
logger.info("Loading Value Set File: " + file.getName());
- PreparedStatement preparedStatement = connection.prepareStatement(insertQueryPrefix);
InputStream inputStream = new FileInputStream(file);
- Workbook workBook = StreamingReader.builder().open(inputStream);
+ Workbook workBook = WorkbookFactory.create(inputStream);
for (int i = 1; i < workBook.getNumberOfSheets(); i++) {
boolean headerRowFound = false;
Sheet sheet = workBook.getSheetAt(i);
@@ -43,46 +47,53 @@ public void load(List filesToLoad, Connection connection) {
String valueSetType = "";
String valueSetVersion = "";
String valueSetSteward = "";
- int valuesetDataRowCount = 0;
for(Row row : sheet){
if(row.getRowNum() < 6) {
if (row.getRowNum() == 1) {
+ row.getCell(1).setCellType(Cell.CELL_TYPE_STRING);
valueSetName = row.getCell(1).getStringCellValue().toUpperCase().trim();
}
if (row.getRowNum() == 2) {
+ row.getCell(1).setCellType(Cell.CELL_TYPE_STRING);
valueSetOid = row.getCell(1).getStringCellValue().toUpperCase().trim();
}
if (row.getRowNum() == 3) {
+ row.getCell(1).setCellType(Cell.CELL_TYPE_STRING);
valueSetType = row.getCell(1).getStringCellValue().toUpperCase().trim();
}
if (row.getRowNum() == 4) {
+ row.getCell(1).setCellType(Cell.CELL_TYPE_STRING);
valueSetVersion = row.getCell(1).getStringCellValue().toUpperCase().trim();
}
if (row.getRowNum() == 5) {
- valueSetSteward = row.getCell(1).getStringCellValue().toUpperCase().trim();
+ row.getCell(1).setCellType(Cell.CELL_TYPE_STRING);
+ valueSetSteward = row.getCell(1).getStringCellValue().replaceAll("'", "''").toUpperCase().trim();
}
}
- if(headerRowFound && canProcessRow(row)){
- preparedStatement.setString(1, row.getCell(0).getStringCellValue().toUpperCase().trim());
- preparedStatement.setString(2, row.getCell(1).getStringCellValue().toUpperCase().trim());
- preparedStatement.setString(3, row.getCell(2).getStringCellValue().toUpperCase().trim());
- preparedStatement.setString(4, row.getCell(3).getStringCellValue().trim());
- preparedStatement.setString(5, row.getCell(4).getStringCellValue().toUpperCase().trim());
- preparedStatement.setString(6, row.getCell(5).getStringCellValue().toUpperCase().trim());
- preparedStatement.setString(7, valueSetName);
- preparedStatement.setString(8, valueSetOid);
- preparedStatement.setString(9, valueSetType);
- preparedStatement.setString(10, valueSetVersion);
- preparedStatement.setString(11, valueSetSteward);
- preparedStatement.addBatch();
- valuesetDataRowCount++;
-
- if(valuesetDataRowCount % BATCH_SIZE == 0){
- preparedStatement.executeBatch();
- connection.commit();
- preparedStatement.clearBatch();
+ if(row.getRowNum() > 10){
+ if(row.getCell(0) != null) {
+ row.getCell(0).setCellType(Cell.CELL_TYPE_STRING);
+ if(headerRowFound && canProcessRow(row)){
+ n++;
+ row.getCell(1).setCellType(Cell.CELL_TYPE_STRING);
+ row.getCell(2).setCellType(Cell.CELL_TYPE_STRING);
+ row.getCell(3).setCellType(Cell.CELL_TYPE_STRING);
+ row.getCell(4).setCellType(Cell.CELL_TYPE_STRING);
+ row.getCell(5).setCellType(Cell.CELL_TYPE_STRING);
+ templ.update(insertQueryPrefix, row.getCell(0).getStringCellValue().toUpperCase().trim(),
+ row.getCell(1).getStringCellValue().toUpperCase().trim(),
+ row.getCell(2).getStringCellValue().toUpperCase().trim(),
+ row.getCell(3).getStringCellValue().trim(),
+ row.getCell(4).getStringCellValue().toUpperCase().trim(),
+ row.getCell(5).getStringCellValue().toUpperCase().trim(),
+ valueSetName,
+ valueSetOid,
+ valueSetType,
+ valueSetVersion,
+ valueSetSteward);
+ }
}
}
@@ -92,19 +103,21 @@ public void load(List filesToLoad, Connection connection) {
}
}
}
-
- preparedStatement.executeBatch();
- connection.commit();
}
workBook.close();
- } catch (IOException | SQLException e) {
+ } catch (InvalidFormatException e) {
+ logger.error("ERROR loading valueset. " + e.getLocalizedMessage());
+ e.printStackTrace();
+ } catch (IOException e) {
logger.error("ERROR loading valueset. " + e.getLocalizedMessage());
e.printStackTrace();
}
}
}
+ return n;
}
+
private boolean canProcessRow(Row row) {
return hasCodevalueInFirstCell(row) && hasExpectedNumberOfCellsInRow(row);
}
diff --git a/src/main/java/org/sitenv/vocabularies/validation/NodeValidation.java b/src/main/java/org/sitenv/vocabularies/validation/NodeValidation.java
index 9de9a44..3cf86bc 100644
--- a/src/main/java/org/sitenv/vocabularies/validation/NodeValidation.java
+++ b/src/main/java/org/sitenv/vocabularies/validation/NodeValidation.java
@@ -1,12 +1,15 @@
package org.sitenv.vocabularies.validation;
+import java.util.List;
+
+import javax.xml.xpath.XPath;
+
import org.sitenv.vocabularies.configuration.ConfiguredValidator;
import org.sitenv.vocabularies.validation.dto.VocabularyValidationResult;
-import org.w3c.dom.Node;
+import org.sitenv.vocabularies.validation.utils.ConfiguredExpressionFilter;
-import javax.xml.xpath.XPath;
-import java.util.List;
+import com.ximpleware.VTDNav;
public interface NodeValidation {
- List validateNode(ConfiguredValidator configuredValidator, XPath xpath, Node node, int nodeIndex);
+ List validateNode(ConfiguredValidator configuredValidator, XPath xpath, VTDNav vn, int nodeIndex, ConfiguredExpressionFilter filter, String xpathExpression);
}
diff --git a/src/main/java/org/sitenv/vocabularies/validation/dao/CodeSystemCodeDAO.java b/src/main/java/org/sitenv/vocabularies/validation/dao/CodeSystemCodeDAO.java
new file mode 100644
index 0000000..3cb05ff
--- /dev/null
+++ b/src/main/java/org/sitenv/vocabularies/validation/dao/CodeSystemCodeDAO.java
@@ -0,0 +1,210 @@
+package org.sitenv.vocabularies.validation.dao;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.sql.DataSource;
+
+import org.apache.log4j.Logger;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.RowCallbackHandler;
+import org.springframework.stereotype.Component;
+
+@Component
+public class CodeSystemCodeDAO {
+
+ private static Logger logger = Logger.getLogger(CodeSystemCodeDAO.class);
+ private static Map> CodeToCodeSystems = new HashMap>();
+ private static Set CodeSystems = new HashSet();
+ private static Map> DisplayNameToCodeSystems = new HashMap>();
+ private static Map> CodeAndDisplayNameToCodeSystems = new HashMap>();
+ private static Map> CodeAndDisplayNameAndCodeSystemOIDToCodeSystems = new HashMap>();
+ private static Map> CodeSystemOIDToCodeSystems = new HashMap>();
+
+ private static boolean done = false;
+ private static boolean hasDBCleanupDone = false;
+
+ private void addRow(String code, String codeSystem, String displayName, String codeSystemOID) {
+ CodeSystems.add(codeSystem);
+
+ if (CodeToCodeSystems.get(code) == null) {
+ CodeToCodeSystems.put(code, new HashSet());
+ }
+
+ CodeToCodeSystems.get(code).add(codeSystem);
+
+ if (DisplayNameToCodeSystems.get(displayName) == null) {
+ DisplayNameToCodeSystems.put(displayName, new HashSet());
+ }
+ DisplayNameToCodeSystems.get(displayName).add(codeSystem);
+
+ String key = "C/" + code + "/D/" + displayName;
+ if (CodeAndDisplayNameToCodeSystems.get(key) == null) {
+ CodeAndDisplayNameToCodeSystems.put(key, new HashSet());
+ }
+ CodeAndDisplayNameToCodeSystems.get(key).add(codeSystem);
+
+ key = "C/" + code + "/D/" + displayName + "/OID/" + codeSystemOID;
+ if (CodeAndDisplayNameAndCodeSystemOIDToCodeSystems.get(key) == null) {
+ CodeAndDisplayNameAndCodeSystemOIDToCodeSystems.put(key, new HashSet());
+ }
+ CodeAndDisplayNameAndCodeSystemOIDToCodeSystems.get(key).add(codeSystem);
+
+ if (CodeSystemOIDToCodeSystems.get(codeSystemOID) == null) {
+ CodeSystemOIDToCodeSystems.put(codeSystemOID, new HashSet());
+ }
+ CodeSystemOIDToCodeSystems.get(codeSystemOID).add(codeSystem);
+ }
+
+ public synchronized void loadCodes(DataSource ds) {
+ if (done) {
+ return;
+ }
+
+ String sql = "SELECT code, displayName,codeSystem, codeSystemOID FROM Codes";
+ JdbcTemplate tmpl = new JdbcTemplate(ds);
+ CodeSetRowHandler handler = new CodeSetRowHandler();
+ tmpl.query(sql, handler);
+
+ done = true;
+ logger.info("Code Maps initialized. Total rows:" + handler.n);
+ }
+
+ public synchronized void cleanupDBAfterLoadingToHashSets(DataSource ds) {
+ if (hasDBCleanupDone) {
+ return;
+ }
+ String deleteCodesQry = "Delete FROM Codes";
+ JdbcTemplate tmpl = new JdbcTemplate(ds);
+ tmpl.update(deleteCodesQry);
+ hasDBCleanupDone = true;
+ logger.info("*********** All Codes deleted from DB *************");
+ }
+
+ public class CodeSetRowHandler implements RowCallbackHandler {
+ public long n = 0;
+ @Override
+ public void processRow(ResultSet arg0) throws SQLException {
+ String code = arg0.getString("code");
+ String codeSystem = arg0.getString("codeSystem");
+ String displayName = arg0.getString("displayName");
+ String codeSystemOID = arg0.getString("codeSystemOID");
+ addRow(code, codeSystem, displayName, codeSystemOID);
+ n++;
+ }
+ }
+
+ // 1
+ // @Query("SELECT CASE WHEN COUNT(c) > 0 THEN true ELSE false END FROM Code
+ // c WHERE c.codeSystem in (:codesystems)")
+ public boolean foundCodesystems(List codesystems) {
+ for (String s : codesystems) {
+ if (CodeSystems.contains(s)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // 2
+ // @Query("SELECT CASE WHEN COUNT(c) > 0 THEN true ELSE false END FROM Code
+ // c WHERE c.code = :code and c.displayName = :displayName and c.codeSystem
+ // in (:codesystems)")
+ public boolean foundCodeAndDisplayNameInCodesystem(String code, String displayName, List codesystems) {
+ String key = "C/" + code + "/D/" + displayName;
+ Set codeSystems = CodeAndDisplayNameToCodeSystems.get(key);
+ if (codeSystems == null) {
+ return false;
+ }
+ for (String s : codesystems) {
+ if (codeSystems.contains(s)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // 3
+ // @Query("SELECT CASE WHEN COUNT(c) > 0 THEN true ELSE false END FROM Code
+ // c WHERE c.code = :code and c.displayName = :displayName and
+ // c.codeSystemOID = :codeSystemOID and c.codeSystem in (:codesystems)")
+ // boolean
+ // foundCodeAndDisplayNameAndCodeSystemOIDInCodesystem(@Param("code")String
+ // code, @Param("displayName")String displayName,
+ // @Param("codeSystemOID")String codeSystemOID,
+ // @Param("codesystems")List codesystems);
+ public boolean foundCodeAndDisplayNameAndCodeSystemOIDInCodesystem(String code, String displayName,
+ String codeSystemOID, List codesystems) {
+ String key = "C/" + code + "/D/" + displayName + "/OID/" + codeSystemOID;
+ Set codeSystems = CodeAndDisplayNameAndCodeSystemOIDToCodeSystems.get(key);
+ if (codeSystems == null) {
+ return false;
+ }
+ for (String s : codesystems) {
+ if (codeSystems.contains(s)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // 4
+ // @Query("SELECT CASE WHEN COUNT(c) > 0 THEN true ELSE false END FROM Code
+ // c WHERE c.code = :code and c.codeSystem in (:codesystems)")
+ public boolean foundCodeInCodesystems(String code, List codesystems) {
+ Set codeSystems = CodeToCodeSystems.get(code);
+ if (codeSystems == null) {
+ return false;
+ }
+
+ for (String s : codesystems) {
+ if (codeSystems.contains(s)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // 5
+ // @Query("SELECT CASE WHEN COUNT(c) > 0 THEN true ELSE false END FROM Code
+ // c WHERE c.displayName = :displayName and c.codeSystem in (:codesystems)")
+ public boolean foundDisplayNameInCodesystems(String displayName, List codesystems) {
+ Set codeSystems = DisplayNameToCodeSystems.get(displayName);
+ if (codeSystems == null) {
+ return false;
+ }
+
+ for (String s : codesystems) {
+ if (codeSystems.contains(s)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // 6
+ // @Query("SELECT CASE WHEN COUNT(c) > 0 THEN true ELSE false END FROM Code
+ // c WHERE c.codeSystemOID = :codeSystemOID and c.codeSystem in
+ // (:codesystems)")
+ // boolean foundCodeSystemOIDInCodesystems(@Param("codeSystemOID")String
+ // codeSystemOID, @Param("codesystems")List codesystems);
+ public boolean foundCodeSystemOIDInCodesystems(String codeSystemOID, List codesystems) {
+ Set codeSystems = CodeSystemOIDToCodeSystems.get(codeSystemOID);
+ if (codeSystems == null) {
+ return false;
+ }
+
+ for (String s : codesystems) {
+ if (codeSystems.contains(s)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/src/main/java/org/sitenv/vocabularies/validation/dao/ValueSetDAO.java b/src/main/java/org/sitenv/vocabularies/validation/dao/ValueSetDAO.java
new file mode 100644
index 0000000..88a0f7f
--- /dev/null
+++ b/src/main/java/org/sitenv/vocabularies/validation/dao/ValueSetDAO.java
@@ -0,0 +1,284 @@
+package org.sitenv.vocabularies.validation.dao;
+
+import java.sql.ResultSet;
+import java.sql.SQLException;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+import javax.sql.DataSource;
+
+import org.apache.log4j.Logger;
+import org.springframework.jdbc.core.JdbcTemplate;
+import org.springframework.jdbc.core.RowCallbackHandler;
+import org.springframework.stereotype.Component;
+
+@Component
+public class ValueSetDAO {
+
+ private static Logger logger = Logger.getLogger(ValueSetDAO.class);
+ private static Map> CodeToValueSetOID = new HashMap>();
+ private static Set ValueSetOIDS = new HashSet();
+ private static Map> CodeAndCodeSystemAndCodeSystemNameAndDisplayNameToValueSetOID = new HashMap>();
+ private static Map> CodeSystemToValueSetOID = new HashMap>();
+ private static Map> CodeAndCodeSystemToValueSetOID = new HashMap>();
+ private static Map> DisplayNameAndCodeAndCodeSystemToValueSetOID = new HashMap>();
+ private static Map> CodeSystemNameAndCodeAndCodeSystemToValueSetOID = new HashMap>();
+ private static Map> CodeSystemNameToValueSetOID = new HashMap>();
+ private static Map> DisplayNameToValueSetOID = new HashMap>();
+
+ private static boolean done = false;
+ private static boolean hasDBCleanupDone = false;
+
+ private void addRow(String code, String codeSystem, String displayName, String codeSystemName,
+ String valueSetOID) {
+ ValueSetOIDS.add(valueSetOID);
+
+ Set codes = CodeToValueSetOID.get(code);
+ if (codes == null) {
+ CodeToValueSetOID.put(code, new HashSet());
+ }
+ CodeToValueSetOID.get(code).add(valueSetOID);
+
+ String key = "C/" + code + "/CS/" + codeSystem + "/CSN/" + codeSystemName + "/DN/" + displayName;
+ Set vsoids = CodeAndCodeSystemAndCodeSystemNameAndDisplayNameToValueSetOID.get(key);
+ if (vsoids == null) {
+ CodeAndCodeSystemAndCodeSystemNameAndDisplayNameToValueSetOID.put(key, new HashSet());
+ }
+ CodeAndCodeSystemAndCodeSystemNameAndDisplayNameToValueSetOID.get(key).add(valueSetOID);
+
+ vsoids = CodeSystemToValueSetOID.get(codeSystem);
+ if (vsoids == null) {
+ CodeSystemToValueSetOID.put(codeSystem, new HashSet());
+ }
+ CodeSystemToValueSetOID.get(codeSystem).add(valueSetOID);
+
+ key = "C/" + code + "/CS/" + codeSystem;
+ vsoids = CodeAndCodeSystemToValueSetOID.get(key);
+ if (vsoids == null) {
+ CodeAndCodeSystemToValueSetOID.put(key, new HashSet());
+ }
+ CodeAndCodeSystemToValueSetOID.get(key).add(valueSetOID);
+
+ key = "D/" + displayName + "/C/" + code + "/CS/" + codeSystem;
+ vsoids = DisplayNameAndCodeAndCodeSystemToValueSetOID.get(key);
+ if (vsoids == null) {
+ DisplayNameAndCodeAndCodeSystemToValueSetOID.put(key, new HashSet());
+ }
+ DisplayNameAndCodeAndCodeSystemToValueSetOID.get(key).add(valueSetOID);
+
+ key = "CSN/" + codeSystemName + "/C/" + code + "/CS/" + codeSystem;
+ vsoids = CodeSystemNameAndCodeAndCodeSystemToValueSetOID.get(key);
+ if (vsoids == null) {
+ CodeSystemNameAndCodeAndCodeSystemToValueSetOID.put(key, new HashSet());
+ }
+ CodeSystemNameAndCodeAndCodeSystemToValueSetOID.get(key).add(valueSetOID);
+
+ if (CodeSystemNameToValueSetOID.get(codeSystemName)==null) {
+ CodeSystemNameToValueSetOID.put(codeSystemName, new HashSet());
+ }
+ CodeSystemNameToValueSetOID.get(codeSystemName).add(valueSetOID);
+
+ if (DisplayNameToValueSetOID.get(displayName)==null) {
+ DisplayNameToValueSetOID.put(displayName, new HashSet());
+ }
+ DisplayNameToValueSetOID.get(displayName).add(valueSetOID);
+ }
+
+ public synchronized void loadValueSets(DataSource ds) {
+ if (done) {
+ return;
+ }
+
+ String sql = "SELECT code, displayName,codeSystem, codeSystemName, valuesetOid FROM ValueSets";
+ JdbcTemplate tmpl = new JdbcTemplate(ds);
+ ValueSetRowHandler handler = new ValueSetRowHandler();
+ tmpl.query(sql, handler);
+ done = true;
+ logger.info("ValueSet Maps initialized. Total rows:" + handler.n);
+ logger.info("ValueSetOIDs:" + ValueSetOIDS.size());
+ }
+
+ public synchronized void cleanupDBAfterLoadingToHashSets(DataSource ds) {
+ if (hasDBCleanupDone) {
+ return;
+ }
+ String deleteValueSetsQry = "Delete FROM ValueSets";
+ JdbcTemplate tmpl = new JdbcTemplate(ds);
+ tmpl.update(deleteValueSetsQry);
+ hasDBCleanupDone = true;
+ logger.info("*********** All ValueSets deleted from DB *************");
+ }
+
+ public class ValueSetRowHandler implements RowCallbackHandler {
+ public long n = 0;
+ @Override
+ public void processRow(ResultSet arg0) throws SQLException {
+ String code = arg0.getString("code");
+ String codeSystem = arg0.getString("codeSystem");
+ String displayName = arg0.getString("displayName");
+ String codeSystemName = arg0.getString("codeSystemName");
+ String valueSetOID = arg0.getString("valuesetOid");
+ addRow(code, codeSystem, displayName, codeSystemName, valueSetOID);
+ n++;
+ }
+ }
+
+ // 1
+ // @Query("SELECT CASE WHEN COUNT(c) > 0 THEN true ELSE false END FROM
+ // VsacValueSet c WHERE c.code = :code and c.codeSystem = :codeSystem and
+ // c.codeSystemName = :codeSystemName and c.displayName = :displayName and
+ // c.valuesetOid in (:valuesetOids)")
+ public boolean existsByCodeAndCodeSystemAndCodeSystemNameAndDisplayNameInValuesetOid(String code, String codeSystem,
+ String codeSystemName, String displayName, List valuesetOids) {
+
+ String key = "C/" + code + "/CS/" + codeSystem + "/CSN/" + codeSystemName + "/DN/" + displayName;
+ Set oids = CodeAndCodeSystemAndCodeSystemNameAndDisplayNameToValueSetOID.get(key);
+ if (oids == null) {
+ return false;
+ }
+ for (String oid : valuesetOids) {
+ if (oids.contains(oid)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // 2
+ // @Query("SELECT CASE WHEN COUNT(c) > 0 THEN true ELSE false END FROM
+ // VsacValueSet c WHERE c.valuesetOid in (:valuesetOids)")
+ public boolean valuesetOidsExists(List valuesetOids) {
+ for (String vsoid : valuesetOids) {
+ if (ValueSetOIDS.contains(vsoid)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // 3
+ // @Query("SELECT CASE WHEN COUNT(c) > 0 THEN true ELSE false END FROM
+ // VsacValueSet c WHERE c.codeSystem = :codeSystem and c.valuesetOid in
+ // (:valuesetOids)")
+ public boolean codeSystemExistsInValueset(String codeSystem, List valuesetOids) {
+ Set oids = CodeSystemToValueSetOID.get(codeSystem);
+ if (oids == null) {
+ return false;
+ }
+ for (String oid : valuesetOids) {
+ if (oids.contains(oid)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // @Query("SELECT CASE WHEN COUNT(c) > 0 THEN true ELSE false END FROM
+ // VsacValueSet c WHERE c.code = :code and c.codeSystem = :codeSystem and
+ // c.valuesetOid in (:valuesetOids)")
+ public boolean codeExistsByCodeSystemInValuesetOid(String code, String codeSystem, List valuesetOids) {
+
+ String key = "C/" + code + "/CS/" + codeSystem;
+ Set oids = CodeAndCodeSystemToValueSetOID.get(key);
+ if (oids == null) {
+ return false;
+ }
+ for (String oid : valuesetOids) {
+ if (oids.contains(oid)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // 4
+ // @Query("SELECT CASE WHEN COUNT(c) > 0 THEN true ELSE false END FROM
+ // VsacValueSet c WHERE c.displayName = :displayName and c.code = :code and
+ // c.codeSystem = :codeSystem and c.valuesetOid in (:valuesetOids)")
+ public boolean displayNameExistsForCodeByCodeSystemInValueset(String displayName, String code, String codeSystem,
+ List valuesetOids) {
+ String key = "D/" + displayName + "/C/" + code + "/CS/" + codeSystem;
+ Set oids = DisplayNameAndCodeAndCodeSystemToValueSetOID.get(key);
+ if (oids == null) {
+ return false;
+ }
+ for (String oid : valuesetOids) {
+ if (oids.contains(oid)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // 5
+ // @Query("SELECT CASE WHEN COUNT(c) > 0 THEN true ELSE false END FROM
+ // VsacValueSet c WHERE c.codeSystemName = :codeSystemName and c.code =
+ // :code and c.codeSystem = :codeSystem and c.valuesetOid in
+ // (:valuesetOids)")
+ public boolean codeSystemNameExistsForCodeByCodeSystemInValueset(String codeSystemName, String code,
+ String codeSystem, List valuesetOids) {
+ String key = "CSN/" + codeSystemName + "/C/" + code + "/CS/" + codeSystem;
+ Set oids = CodeSystemNameAndCodeAndCodeSystemToValueSetOID.get(key);
+ if (oids == null) {
+ return false;
+ }
+ for (String oid : valuesetOids) {
+ if (oids.contains(oid)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // 6
+ // @Query("SELECT CASE WHEN COUNT(c) > 0 THEN true ELSE false END FROM VsacValueSet c WHERE c.displayName = :displayName and c.valuesetOid in (:valuesetOids)")
+ public boolean displayNameExistsInValueset(String displayName, List valueSetOids) {
+ Set codes = DisplayNameToValueSetOID.get(displayName);
+ if (codes == null) {
+ return false;
+ }
+ for (String vsoid : valueSetOids) {
+ if (codes.contains(vsoid)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // 7
+ // @Query("SELECT CASE WHEN COUNT(c) > 0 THEN true ELSE false END FROM VsacValueSet c WHERE c.codeSystemName = :codeSystemName and c.valuesetOid in (:valuesetOids)")
+ public boolean codeSystemNameExistsInValueset(String codeSystemName,
+ List valuesetOids) {
+ Set codes = CodeSystemNameToValueSetOID.get(codeSystemName);
+ if (codes == null) {
+ return false;
+ }
+ for (String vsoid : valuesetOids) {
+ if (codes.contains(vsoid)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ // 8
+ // @Query("SELECT CASE WHEN COUNT(c) > 0 THEN true ELSE false END FROM
+ // VsacValueSet c WHERE c.code = :code and c.valuesetOid in
+ // (:valuesetOids)")
+ public boolean codeExistsInValueset(String code, List valuesetOids) {
+ Set codes = CodeToValueSetOID.get(code);
+ if (codes == null) {
+ return false;
+ }
+ for (String vsoid : valuesetOids) {
+ if (codes.contains(vsoid)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+}
diff --git a/src/main/java/org/sitenv/vocabularies/validation/dto/NodeValidationResult.java b/src/main/java/org/sitenv/vocabularies/validation/dto/NodeValidationResult.java
index a4b3b4e..702cf2f 100644
--- a/src/main/java/org/sitenv/vocabularies/validation/dto/NodeValidationResult.java
+++ b/src/main/java/org/sitenv/vocabularies/validation/dto/NodeValidationResult.java
@@ -6,7 +6,16 @@ public class NodeValidationResult {
private int baseNodeIndex;
private String configuredXpathExpression;
private int nodeIndex;
+ public long getErrorOffset() {
+ return errorOffset;
+ }
+
+ public void setErrorOffset(long errorOffset) {
+ this.errorOffset = errorOffset;
+ }
+ private long errorOffset = 0;
+
private String requestedCode;
private String requestedCodeSystem;
private String requestedCodeSystemName;
@@ -16,6 +25,7 @@ public class NodeValidationResult {
private String requestedText;
private String configuredAllowableValuesetOidsForNode;
private String configuredAllowableCodesystemNamesForNode;
+ private String ruleID;
private boolean nodeCodeSystemOIDFound;
private boolean nodeValuesetsFound;
@@ -183,4 +193,12 @@ public boolean isNodeCodeSystemOIDFound() {
public void setNodeCodeSystemOIDFound(boolean nodeCodeSystemOIDFound) {
this.nodeCodeSystemOIDFound = nodeCodeSystemOIDFound;
}
+
+ public String getRuleID() {
+ return this.ruleID;
+ }
+
+ public void setRuleID(String id) {
+ this.ruleID = id;
+ }
}
diff --git a/src/main/java/org/sitenv/vocabularies/validation/pool/AutoPilotObjectPoolInitializer.java b/src/main/java/org/sitenv/vocabularies/validation/pool/AutoPilotObjectPoolInitializer.java
new file mode 100644
index 0000000..12a6389
--- /dev/null
+++ b/src/main/java/org/sitenv/vocabularies/validation/pool/AutoPilotObjectPoolInitializer.java
@@ -0,0 +1,31 @@
+package org.sitenv.vocabularies.validation.pool;
+
+import java.util.List;
+
+import org.apache.log4j.Logger;
+import org.sitenv.vocabularies.configuration.ConfiguredExpression;
+
+public class AutoPilotObjectPoolInitializer {
+
+ private static Logger logger = Logger.getLogger(AutoPilotObjectPoolInitializer.class);
+ private static boolean done = false;
+
+ private void initPools(List ces) throws Exception {
+ if (done) {
+ return;
+ }
+ long s = System.currentTimeMillis();
+ for (ConfiguredExpression ce : ces) {
+ AutoPilotWrapper apw = AutoPilotPool.newInstance().borrow(ce.getConfiguredXpathExpression());
+ AutoPilotPool.newInstance().returnObject(apw);
+
+ }
+ logger.info("Init AutoPilot ObjectPools in " + (System.currentTimeMillis() - s) + " ms for " + ces.size() + " expressions.");
+ done = true;
+ }
+
+ public void initFromExpressions(List expressions) throws Exception {
+ initPools(expressions);
+ }
+
+}
diff --git a/src/main/java/org/sitenv/vocabularies/validation/pool/AutoPilotPool.java b/src/main/java/org/sitenv/vocabularies/validation/pool/AutoPilotPool.java
new file mode 100644
index 0000000..af65b54
--- /dev/null
+++ b/src/main/java/org/sitenv/vocabularies/validation/pool/AutoPilotPool.java
@@ -0,0 +1,43 @@
+package org.sitenv.vocabularies.validation.pool;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
+
+public class AutoPilotPool {
+
+ private static Map POOLS = new HashMap();
+ private static AutoPilotPool pool = null;
+
+ public static AutoPilotPool newInstance() {
+ if (pool==null) {
+ pool = new AutoPilotPool();
+ }
+ return pool;
+ }
+
+ public AutoPilotWrapper borrow(String xpath) throws Exception {
+ AutoPilotWrapperPool apwpool = POOLS.get(xpath);
+ if (apwpool == null) {
+
+ GenericObjectPoolConfig config = new GenericObjectPoolConfig();
+ config.setMaxIdle(200);
+ config.setMaxTotal(200);
+ config.setMinIdle(100);
+ config.setTestOnBorrow(true);
+ config.setTestOnReturn(true);
+
+ apwpool = new AutoPilotWrapperPool(new AutoPilotWrapperFactory(xpath), config);
+ POOLS.put(xpath, apwpool);
+ }
+ return apwpool.borrowObject();
+ }
+
+ public void returnObject(AutoPilotWrapper apw) {
+ AutoPilotWrapperPool apwpool = POOLS.get(apw.getXPath());
+ if (apwpool!=null) {
+ apwpool.returnObject(apw);
+ }
+ }
+}
diff --git a/src/main/java/org/sitenv/vocabularies/validation/pool/AutoPilotWrapper.java b/src/main/java/org/sitenv/vocabularies/validation/pool/AutoPilotWrapper.java
new file mode 100644
index 0000000..3b29276
--- /dev/null
+++ b/src/main/java/org/sitenv/vocabularies/validation/pool/AutoPilotWrapper.java
@@ -0,0 +1,62 @@
+package org.sitenv.vocabularies.validation.pool;
+
+import java.util.UUID;
+
+import com.ximpleware.AutoPilot;
+
+public class AutoPilotWrapper {
+
+ private AutoPilot autopilot;
+ private String xpath;
+ private boolean ok = false;
+
+ private final UUID objID = UUID.randomUUID();
+
+ /*
+ * Have to implement the equals method, since Spring puts a proxy around the object.
+ * @see java.lang.Object#equals(java.lang.Object)
+ */
+ @Override
+ public boolean equals(Object o) {
+ if (this == o) {
+ return true;
+ }
+ if (!(o instanceof AutoPilotWrapper)) {
+ return false;
+ }
+ AutoPilotWrapper w = (AutoPilotWrapper) o;
+ return (objID == null) ? w.objID==null : objID.equals(w.objID);
+ }
+
+ public AutoPilotWrapper(String xpath) {
+ try {
+ this.xpath = xpath;
+ this.autopilot = new AutoPilot();
+ this.autopilot.declareXPathNameSpace("sdtc", "urn:hl7-org:sdtc");
+ this.autopilot.declareXPathNameSpace("v3", "urn:hl7-org:v3");
+ this.autopilot.declareXPathNameSpace("voc", "urn:hl7-org:v3/voc");
+ this.autopilot.declareXPathNameSpace("", "urn:hl7-org:v3");
+ this.autopilot.selectXPath(this.xpath);
+ ok = true;
+ } catch (Exception e) {
+ e.printStackTrace();
+ }
+ }
+
+ public AutoPilot getAutoPilot() {
+ this.autopilot.resetXPath();
+ return this.autopilot;
+ }
+
+ public String getXPath() {
+ return xpath;
+ }
+
+ public boolean isValid() {
+ return ok;
+ }
+
+ public void reset() {
+ // void
+ }
+}
diff --git a/src/main/java/org/sitenv/vocabularies/validation/pool/AutoPilotWrapperFactory.java b/src/main/java/org/sitenv/vocabularies/validation/pool/AutoPilotWrapperFactory.java
new file mode 100644
index 0000000..5d17d4b
--- /dev/null
+++ b/src/main/java/org/sitenv/vocabularies/validation/pool/AutoPilotWrapperFactory.java
@@ -0,0 +1,36 @@
+package org.sitenv.vocabularies.validation.pool;
+
+import org.apache.commons.pool2.BasePooledObjectFactory;
+import org.apache.commons.pool2.PooledObject;
+import org.apache.commons.pool2.impl.DefaultPooledObject;
+
+public class AutoPilotWrapperFactory extends BasePooledObjectFactory {
+
+ private String xpath;
+
+ public AutoPilotWrapperFactory(String xpath) {
+ super();
+ this.xpath=xpath;
+ }
+
+ @Override
+ public AutoPilotWrapper create() throws Exception {
+ return new AutoPilotWrapper(xpath);
+ }
+
+ @Override
+ public PooledObject wrap(AutoPilotWrapper parser) {
+ return new DefaultPooledObject(parser);
+ }
+
+ @Override
+ public void passivateObject(PooledObject po) throws Exception {
+ po.getObject().reset();
+ }
+
+ @Override
+ public boolean validateObject(PooledObject po) {
+ return po.getObject().isValid();
+ }
+
+}
diff --git a/src/main/java/org/sitenv/vocabularies/validation/pool/AutoPilotWrapperPool.java b/src/main/java/org/sitenv/vocabularies/validation/pool/AutoPilotWrapperPool.java
new file mode 100644
index 0000000..e413f7e
--- /dev/null
+++ b/src/main/java/org/sitenv/vocabularies/validation/pool/AutoPilotWrapperPool.java
@@ -0,0 +1,17 @@
+package org.sitenv.vocabularies.validation.pool;
+
+import org.apache.commons.pool2.PooledObjectFactory;
+import org.apache.commons.pool2.impl.GenericObjectPool;
+import org.apache.commons.pool2.impl.GenericObjectPoolConfig;
+
+public class AutoPilotWrapperPool extends GenericObjectPool {
+
+ public AutoPilotWrapperPool(PooledObjectFactory factory) {
+ super(factory);
+ }
+
+ public AutoPilotWrapperPool(PooledObjectFactory factory, GenericObjectPoolConfig config) {
+ super(factory, config);
+ }
+
+}
diff --git a/src/main/java/org/sitenv/vocabularies/validation/services/ValidateRequest.java b/src/main/java/org/sitenv/vocabularies/validation/services/ValidateRequest.java
new file mode 100644
index 0000000..7ad6a85
--- /dev/null
+++ b/src/main/java/org/sitenv/vocabularies/validation/services/ValidateRequest.java
@@ -0,0 +1,39 @@
+package org.sitenv.vocabularies.validation.services;
+
+import org.apache.log4j.Logger;
+import org.sitenv.vocabularies.configuration.ConfiguredExpression;
+import org.sitenv.vocabularies.validation.utils.ConfiguredExpressionFilter;
+
+import com.ximpleware.VTDNav;
+
+public class ValidateRequest {
+
+ private ConfiguredExpression ce;
+ private ConfiguredExpressionFilter filter;
+ private Logger logger;
+ private VTDNav nv;
+
+ public Logger getLogger() {
+ return this.logger;
+ }
+
+ public ValidateRequest(ConfiguredExpression ce, ConfiguredExpressionFilter filter, Logger lgr, VTDNav vn) {
+ this.ce = ce;
+ this.filter = filter;
+ this.logger = lgr;
+ this.nv = vn;
+ }
+
+ public VTDNav getNav() {
+ return this.nv;
+ }
+
+ public ConfiguredExpressionFilter getFilter() {
+ return this.filter;
+ }
+
+ public ConfiguredExpression getConfiguredExpression() {
+ return this.ce;
+ }
+
+}
diff --git a/src/main/java/org/sitenv/vocabularies/validation/services/ValidateWorker.java b/src/main/java/org/sitenv/vocabularies/validation/services/ValidateWorker.java
new file mode 100644
index 0000000..69c47e6
--- /dev/null
+++ b/src/main/java/org/sitenv/vocabularies/validation/services/ValidateWorker.java
@@ -0,0 +1,125 @@
+package org.sitenv.vocabularies.validation.services;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.Future;
+
+import javax.annotation.Resource;
+import javax.xml.namespace.NamespaceContext;
+import javax.xml.xpath.XPath;
+import javax.xml.xpath.XPathConstants;
+import javax.xml.xpath.XPathExpressionException;
+import javax.xml.xpath.XPathFactory;
+
+import org.sitenv.vocabularies.configuration.ConfiguredExpression;
+import org.sitenv.vocabularies.configuration.ConfiguredValidator;
+import org.sitenv.vocabularies.validation.NodeValidation;
+import org.sitenv.vocabularies.validation.NodeValidatorFactory;
+import org.sitenv.vocabularies.validation.dto.VocabularyValidationResult;
+import org.sitenv.vocabularies.validation.dto.enums.VocabularyValidationResultLevel;
+import org.sitenv.vocabularies.validation.pool.AutoPilotPool;
+import org.sitenv.vocabularies.validation.pool.AutoPilotWrapper;
+import org.sitenv.vocabularies.validation.utils.CCDADocumentNamespaces;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.scheduling.annotation.Async;
+import org.springframework.scheduling.annotation.AsyncResult;
+import org.springframework.stereotype.Component;
+import org.w3c.dom.Document;
+import org.w3c.dom.NodeList;
+
+import com.ximpleware.AutoPilot;
+import com.ximpleware.VTDNav;
+
+@Component
+public class ValidateWorker {
+
+ public ValidateWorker() {
+ XPathFactory.newInstance();
+ }
+
+ @Resource(name = "vocabularyValidationConfigurations")
+ List vocabularyValidationConfigurations;
+
+ @Resource(name = "vocabularyValidationConfigurationsForMu2")
+ List vocabularyValidationConfigurationsForMu2;
+
+ @Autowired
+ NodeValidatorFactory vocabularyValidatorFactory;
+
+ @Async("taskExecutor")
+ public Future