diff --git a/symmetric-core/src/main/java/org/jumpmind/symmetric/model/Extension.java b/symmetric-core/src/main/java/org/jumpmind/symmetric/model/Extension.java index bbb94b5d31..8ea86b4114 100644 --- a/symmetric-core/src/main/java/org/jumpmind/symmetric/model/Extension.java +++ b/symmetric-core/src/main/java/org/jumpmind/symmetric/model/Extension.java @@ -41,7 +41,7 @@ public class Extension implements Serializable { private boolean enabled; - private int extensionOrder; + private int extensionOrder = 1; private String extensionText; diff --git a/symmetric-core/src/main/java/org/jumpmind/symmetric/service/IExtensionService.java b/symmetric-core/src/main/java/org/jumpmind/symmetric/service/IExtensionService.java index d7bf7a77ba..db3a34fa42 100644 --- a/symmetric-core/src/main/java/org/jumpmind/symmetric/service/IExtensionService.java +++ b/symmetric-core/src/main/java/org/jumpmind/symmetric/service/IExtensionService.java @@ -25,6 +25,7 @@ import org.jumpmind.extension.IExtensionPoint; import org.jumpmind.symmetric.ext.ExtensionPointMetaData; +import org.jumpmind.symmetric.model.Extension; public interface IExtensionService { @@ -44,4 +45,10 @@ public interface IExtensionService { public void removeExtensionPoint(IExtensionPoint extension); + public List getExtensions(); + + public void saveExtension(Extension extension); + + public void deleteExtension(String extensionId); + } diff --git a/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/ExtensionService.java b/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/ExtensionService.java index e0a1ca39e0..59fe0a6a9e 100644 --- a/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/ExtensionService.java +++ b/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/ExtensionService.java @@ -75,7 +75,7 @@ public ExtensionService(ISymmetricEngine engine) { setSqlMap(new ExtensionServiceSqlMap(symmetricDialect.getPlatform(), createSqlReplacementTokens())); } - public void refresh() { + public synchronized void refresh() { extensionsByClassByName = new HashMap>(); extensionMetaData = new ArrayList(); @@ -90,35 +90,39 @@ public void refresh() { String prefix = parameterService.getString(ParameterConstants.RUNTIME_CONFIG_TABLE_PREFIX); if (platform.getTableFromCache(TableConstants.getTableName(prefix, TableConstants.SYM_EXTENSION), false) != null) { - List extensionList = sqlTemplate.query(getSql("selectAll"), new ExtensionRowMapper(), parameterService.getNodeGroupId()); + List extensionList = sqlTemplate.query(getSql("selectEnabled"), new ExtensionRowMapper(), parameterService.getNodeGroupId()); log.info("Found {} extension points from the database that will be registered", extensionList.size()); for (Extension extension : extensionList) { - if (extension.getExtensionType().equalsIgnoreCase(Extension.EXTENSION_TYPE_JAVA)) { - try { - Object ext = SimpleClassCompiler.getInstance().getCompiledClass(extension.getExtensionText()); - registerExtension(extension.getExtensionId(), (IExtensionPoint) ext); - } catch (Exception e) { - log.error("Error while compiling Java extension " + extension.getExtensionId(), e); - } - } else if (extension.getExtensionType().equalsIgnoreCase(Extension.EXTENSION_TYPE_BSH)) { - try { - Interpreter interpreter = new Interpreter(); - interpreter.eval(extension.getExtensionText()); - Object ext = interpreter.getInterface(Class.forName(extension.getInterfaceName())); - registerExtension(extension.getExtensionId(), (IExtensionPoint) ext); - } catch (EvalError e) { - log.error("Error while parsing BSH extension " + extension.getExtensionId(), e); - } catch (ClassNotFoundException e) { - log.error("Interface class not found for BSH extension " + extension.getExtensionId(), e); - } - } else { - log.error("Skipping extension " + extension.getExtensionId() + ", unknown extension type " + extension.getExtensionType()); - } + registerExtension(extension); } } } + protected void registerExtension(Extension extension) { + if (extension.getExtensionType().equalsIgnoreCase(Extension.EXTENSION_TYPE_JAVA)) { + try { + Object ext = SimpleClassCompiler.getInstance().getCompiledClass(extension.getExtensionText()); + registerExtension(extension.getExtensionId(), (IExtensionPoint) ext); + } catch (Exception e) { + log.error("Error while compiling Java extension " + extension.getExtensionId(), e); + } + } else if (extension.getExtensionType().equalsIgnoreCase(Extension.EXTENSION_TYPE_BSH)) { + try { + Interpreter interpreter = new Interpreter(); + interpreter.eval(extension.getExtensionText()); + Object ext = interpreter.getInterface(Class.forName(extension.getInterfaceName())); + registerExtension(extension.getExtensionId(), (IExtensionPoint) ext); + } catch (EvalError e) { + log.error("Error while parsing BSH extension " + extension.getExtensionId(), e); + } catch (ClassNotFoundException e) { + log.error("Interface class not found for BSH extension " + extension.getExtensionId(), e); + } + } else { + log.error("Skipping extension " + extension.getExtensionId() + ", unknown extension type " + extension.getExtensionType()); + } + } + protected boolean registerExtension(String name, IExtensionPoint ext) { if (! (ext instanceof IExtensionPoint)) { log.error("Missing IExtensionPoint interface for extension " + name); @@ -196,7 +200,7 @@ protected List getExtensionClassList(IExtensionPoint ext) { return classList; } - public List getExtensionPointMetaData() { + public synchronized List getExtensionPointMetaData() { return new ArrayList(extensionMetaData); } @@ -207,36 +211,36 @@ protected void addExtensionPointMetaData(IExtensionPoint extensionPoint, String } } - public T getExtensionPoint(Class extensionClass) { + public synchronized T getExtensionPoint(Class extensionClass) { for (T extension : getExtensionPointList(extensionClass)) { return extension; } return null; } - public List getExtensionPointList(Class extensionClass) { + public synchronized List getExtensionPointList(Class extensionClass) { return new ArrayList(getExtensionPointMap(extensionClass).values()); } - public Map getExtensionPointMap(Class extensionClass) { + public synchronized Map getExtensionPointMap(Class extensionClass) { return (Map) getExtensionsByNameMap(extensionClass); } - public void addExtensionPoint(IExtensionPoint extension) { + public synchronized void addExtensionPoint(IExtensionPoint extension) { for (Class extensionClass : getExtensionClassList(extension)) { getStaticExtensionsByNameMap(extensionClass).put(extension.getClass().getCanonicalName(), extension); } registerExtension(extension.getClass().getCanonicalName(), extension, false); } - public void addExtensionPoint(String name, IExtensionPoint extension) { + public synchronized void addExtensionPoint(String name, IExtensionPoint extension) { for (Class extensionClass : getExtensionClassList(extension)) { getStaticExtensionsByNameMap(extensionClass).put(name, extension); } registerExtension(name, extension, false); } - public void removeExtensionPoint(IExtensionPoint extension) { + public synchronized void removeExtensionPoint(IExtensionPoint extension) { for (Class extensionClass : getExtensionClassList(extension)) { getStaticExtensionsByNameMap(extensionClass).remove(extension.getClass().getCanonicalName()); } @@ -261,6 +265,29 @@ protected Map getExtensionsByNameMap(Map getExtensions() { + return sqlTemplate.query(getSql("selectAll"), new ExtensionRowMapper()); + } + + public void saveExtension(Extension extension) { + Object[] args = { extension.getExtensionType(), extension.getInterfaceName(), extension.getNodeGroupId(), + extension.isEnabled() ? 1 : 0, extension.getExtensionOrder(), extension.getExtensionText(), extension.getLastUpdateBy(), + extension.getExtensionId() }; + if (sqlTemplate.update(getSql("updateExtensionSql"), args) == 0) { + sqlTemplate.update(getSql("insertExtensionSql"), args); + if (extension.isEnabled()) { + registerExtension(extension); + } + } else { + refresh(); + } + } + + public void deleteExtension(String extensionId) { + sqlTemplate.update(getSql("deleteExtensionSql"), extensionId); + refresh(); + } + class ExtensionRowMapper implements ISqlRowMapper { @Override public Extension mapRow(Row row) { diff --git a/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/ExtensionServiceSqlMap.java b/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/ExtensionServiceSqlMap.java index 34fe3bef1d..e9bd5817a5 100644 --- a/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/ExtensionServiceSqlMap.java +++ b/symmetric-core/src/main/java/org/jumpmind/symmetric/service/impl/ExtensionServiceSqlMap.java @@ -29,10 +29,22 @@ public class ExtensionServiceSqlMap extends AbstractSqlMap { public ExtensionServiceSqlMap(IDatabasePlatform platform, Map replacementTokens) { super(platform, replacementTokens); - putSql("selectAll", "select extension_id, extension_type, interface_name, node_group_id, enabled, extension_order, " + + putSql("selectEnabled", "select extension_id, extension_type, interface_name, node_group_id, enabled, extension_order, " + "extension_text, create_time, last_update_by, last_update_time from $(extension) " + "where enabled = 1 and node_group_id = ? order by extension_order"); + + putSql("selectAll", "select extension_id, extension_type, interface_name, node_group_id, enabled, extension_order, " + + "extension_text, create_time, last_update_by, last_update_time from $(extension)"); + + putSql("insertExtensionSql", "insert into $(extension) (extension_type, interface_name, node_group_id, enabled, " + + "extension_order, extension_text, create_time, last_update_by, last_update_time, extension_id) " + + "values (?, ?, ?, ?, ?, ?, current_timestamp, ?, current_timestamp, ?)"); + + putSql("updateExtensionSql", "update $(extension) set extension_type = ?, interface_name = ?, " + + "node_group_id = ?, enabled = ?, extension_order = ?, extension_text = ?, last_update_by = ?, " + + "last_update_time = current_timestamp where extension_id = ?"); + putSql("deleteExtensionSql", "delete from $(extension) where extension_id = ?"); } }