diff --git a/src/main/java/com/cflint/CFLint.java b/src/main/java/com/cflint/CFLint.java index ec4b4d2e0..1a34f02e4 100644 --- a/src/main/java/com/cflint/CFLint.java +++ b/src/main/java/com/cflint/CFLint.java @@ -63,6 +63,7 @@ import com.cflint.listeners.ProgressMonitorListener; import com.cflint.listeners.ScanProgressListener; import com.cflint.plugins.CFLintScanner; +import com.cflint.plugins.CFLintStructureListener; import com.cflint.plugins.Context; import com.cflint.plugins.Context.ContextMessage; import com.cflint.plugins.exceptions.CFLintExceptionListener; @@ -376,14 +377,36 @@ else if (elem.getName().equalsIgnoreCase("cffunction")) { if (elem.getName().equalsIgnoreCase("cffunction")) { inFunction = true; handler.push("function"); + + for (final CFLintStructureListener structurePlugin : getStructureListeners(extensions)) { + try{ + structurePlugin.startFunction(context); + }catch(Exception e){} + } processStack(elem.getChildElements(), space + " ", context); + for (final CFLintStructureListener structurePlugin : getStructureListeners(extensions)) { + try{ + structurePlugin.endFunction(context); + }catch(Exception e){} + } inFunction = false; handler.pop(); } else if (elem.getName().equalsIgnoreCase("cfcomponent")) { inComponent = true; handler.push("component"); + for (final CFLintStructureListener structurePlugin : getStructureListeners(extensions)) { + try{ + structurePlugin.startComponent(context); + }catch(Exception e){} + } context.setInComponent(true); processStack(elem.getChildElements(), space + " ", context); + for (final CFLintStructureListener structurePlugin : getStructureListeners(extensions)) { + try{ + structurePlugin.endComponent(context); + }catch(Exception e){} + } + inComponent = false; handler.pop(); } else if (elem.getName().equalsIgnoreCase("cfquery")) { @@ -403,6 +426,14 @@ else if (elem.getName().equalsIgnoreCase("cffunction")) { } } + private List getStructureListeners(final List extensions) { + final List retval = new ArrayList(); + for(CFLintScanner plugin: extensions) + if(plugin instanceof CFLintStructureListener){ + retval.add((CFLintStructureListener) plugin); + } + return retval; + } private String shortSource(final Source source, final int line) { final String retval = source == null ? "" : source.toString().trim(); if (retval.length() < 300) { @@ -459,7 +490,21 @@ private void process(final CFScriptStatement expression, final String filename, process(((CFExpressionStatement) expression).getExpression(), filename, elem, functionName); } else if (expression instanceof CFCompDeclStatement) { inComponent = true; + //do startComponent notifications + for (final CFLintStructureListener structurePlugin : getStructureListeners(extensions)) { + try{ + structurePlugin.startComponent(context); + }catch(Exception e){} + } + //process the component declaration process(((CFCompDeclStatement) expression).getBody(), filename, elem, functionName); + //do endComponent notifications + for (final CFLintStructureListener structurePlugin : getStructureListeners(extensions)) { + try{ + structurePlugin.endComponent(context); + }catch(Exception e){} + } + inComponent = false; } else if (expression instanceof CFForStatement) { process(((CFForStatement) expression).getInit(), filename, elem, functionName); @@ -503,7 +548,18 @@ private void process(final CFScriptStatement expression, final String filename, for (final CFFunctionParameter param : function.getFormals()) { handler.addArgument(param.getName()); } + for (final CFLintStructureListener structurePlugin : getStructureListeners(extensions)) { + try{ + structurePlugin.startFunction(context); + }catch(Exception e){} + } + process(function.getBody(), filename, elem, function.getName()); + for (final CFLintStructureListener structurePlugin : getStructureListeners(extensions)) { + try{ + structurePlugin.endFunction(context); + }catch(Exception e){} + } inFunction = false; handler.pop(); } else { @@ -767,12 +823,22 @@ public void addScanProgressListener(final ScanProgressListener scanProgressListe protected void fireStartedProcessing(final String srcidentifier) { currentFile = srcidentifier; + for (final CFLintStructureListener structurePlugin : getStructureListeners(extensions)) { + try{ + structurePlugin.startFile(srcidentifier); + }catch(Exception e){} + } for (final ScanProgressListener p : scanProgressListeners) { p.startedProcessing(srcidentifier); } } protected void fireFinishedProcessing(final String srcidentifier) { + for (final CFLintStructureListener structurePlugin : getStructureListeners(extensions)) { + try{ + structurePlugin.endFile(srcidentifier); + }catch(Exception e){} + } for (final ScanProgressListener p : scanProgressListeners) { p.finishedProcessing(srcidentifier); } diff --git a/src/main/java/com/cflint/plugins/CFLintScannerAdapter.java b/src/main/java/com/cflint/plugins/CFLintScannerAdapter.java index f2159d0fe..580be1521 100644 --- a/src/main/java/com/cflint/plugins/CFLintScannerAdapter.java +++ b/src/main/java/com/cflint/plugins/CFLintScannerAdapter.java @@ -11,11 +11,12 @@ /** * Lint Rule Plugins can extend this adapter instead of implementing all the methods of CFLintScanner + * (and CFLintStructureListener) * * @author eberlyrh * */ -public class CFLintScannerAdapter implements CFLintScanner { +public class CFLintScannerAdapter implements CFLintScanner,CFLintStructureListener { Map params = new HashMap(); public CFLintScannerAdapter() { @@ -49,4 +50,40 @@ public int currentLine(final CFExpression expression, final Context context) { public Map getParams() { return params; } + + /** + * Default implementation does nothing + */ + @Override + public void startFile(String fileName) {} + + /** + * Default implementation does nothing + */ + @Override + public void endFile(String fileName) {} + + /** + * Default implementation does nothing + */ + @Override + public void startComponent(Context context) {} + + /** + * Default implementation does nothing + */ + @Override + public void endComponent(Context context) {} + + /** + * Default implementation does nothing + */ + @Override + public void startFunction(Context context) {} + + /** + * Default implementation does nothing + */ + @Override + public void endFunction(Context context) {} } diff --git a/src/main/java/com/cflint/plugins/CFLintStructureListener.java b/src/main/java/com/cflint/plugins/CFLintStructureListener.java new file mode 100644 index 000000000..4beb0377d --- /dev/null +++ b/src/main/java/com/cflint/plugins/CFLintStructureListener.java @@ -0,0 +1,45 @@ +package com.cflint.plugins; + +/** + * This interface supports plugins recieving structure notifications (file start/end, component start/end, function start/end) + * + * Normally it is used for initialization or summarization types of behaviours + * @author eberlyrh + * + */ +public interface CFLintStructureListener { + + /** + * Called when processing of a new file has started + * @param context + */ + public void startFile(String fileName); + /** + * Called when processing of current file has ended + * @param context + */ + public void endFile(String fileName); + + /** + * Called when processing a new component has started + * @param context + */ + public void startComponent(Context context); + /** + * Called when processing of current component has ended + * @param context + */ + public void endComponent(Context context); + + /** + * Called when processing of a new function has started + * @param context + */ + public void startFunction(Context context); + /** + * Called when processing of current function has ended + * @param context + */ + public void endFunction(Context context); + +}