All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.cflint.plugins.core.PackageCaseChecker Maven / Gradle / Ivy

Go to download

A static code analysis tool for ColdFusion (in the spirit of FindBugs and Lint). With CFLint, you are able to analyze your ColdFusion code base for code violations.

There is a newer version: 1.5.0
Show newest version
package com.cflint.plugins.core;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import com.cflint.BugList;
import com.cflint.CFLint;
import com.cflint.plugins.CFLintScannerAdapter;
import com.cflint.plugins.CFLintSet;
import com.cflint.plugins.Context;
import com.cflint.plugins.Context.ContextMessage;

import cfml.parsing.cfscript.CFExpression;
import cfml.parsing.cfscript.CFFunctionExpression;
import cfml.parsing.cfscript.CFNewExpression;
import ro.fortsoft.pf4j.Extension;

@Extension
public class PackageCaseChecker extends CFLintScannerAdapter implements CFLintSet {
   
	final Map> componentRegister = new HashMap>();
	final Map> expressionCheckRegister = new HashMap>();
	private CFLint cflintRef;
   
    @Override
    public void expression(final CFExpression expression, final Context context, final BugList bugs) {
		if (expression instanceof CFFunctionExpression) {
			final CFFunctionExpression funcExpr = (CFFunctionExpression) expression;
			if (isCreateObject(funcExpr)) {
				final String componentPath = funcExpr.getArgs().get(1).Decompile(0).replace("'", "");
				final String componentName = componentPath.replaceAll("^.+[.]", "");
				checkComponentRegister(context, componentPath, componentName);
			}
		} else if (expression instanceof CFNewExpression) {
			final CFNewExpression newExpr = (CFNewExpression) expression;
			final String componentPath = newExpr.getComponentPath().Decompile(0);
			final List exprs = newExpr.getComponentPath().decomposeExpression();
			final String componentName = exprs.size()==0?"":exprs.get(exprs.size() - 1).toString();
			checkComponentRegister(context, componentPath, componentName);
		}
    }

	private boolean checkComponentRegister(final Context context, final String componentPath, final String componentName) {
		if(componentRegister.containsKey(componentName.toLowerCase())){
			List filePathOfComponents = componentRegister.get(componentName.toLowerCase());
			for(String filePathOfComponent:filePathOfComponents){
				if(filePathOfComponent.toLowerCase().endsWith(componentPath.toLowerCase())){
					if(!filePathOfComponent.endsWith(componentPath)){
						final String expectedPath = filePathOfComponent.substring(filePathOfComponent.length()-componentPath.length());
						context.addMessage("PACKAGE_CASE_MISMATCH", expectedPath);
					}
					return true;
				}
			}
		}
		//otherwise remember the component use for when component is first registered.
		final String key = componentName.toLowerCase();
		if(!expressionCheckRegister.containsKey(key)){
			expressionCheckRegister.put(key, new ArrayList());
		}
		expressionCheckRegister.get(key).add(new PackageCaseCheckerEntry(context,componentPath,componentName));
		return false;
	}

	@Override
	public void startComponent(Context context, BugList bugs) {
		final String key = context.getComponentName().toLowerCase();
		if(!componentRegister.containsKey(key)){
			componentRegister.put(key, new ArrayList());
		}
		componentRegister.get(key).add(normalize(context.getFilename()));
		
		//if an expression already referenced this component, check it here:
		boolean matched = false;
		if(expressionCheckRegister.containsKey(key)){
			List clonedList = new ArrayList();
			clonedList.addAll(expressionCheckRegister.get(key));
			for(final PackageCaseCheckerEntry expressionEntry : clonedList){
				if(checkComponentRegister(expressionEntry.context,expressionEntry.componentPath,expressionEntry.componentName)){
					matched = true;
					for(ContextMessage message: expressionEntry.context.getMessages()){
						cflintRef.reportRule(expressionEntry.context.getElement(), null, expressionEntry.context, this, message);
					}
					expressionEntry.context.getMessages().clear();
				}
			}
		}
		//If component matched, remove the remembered expression.  (Efficiency)
		if(matched){
			expressionCheckRegister.remove(key);
		}
	}

	private String normalize(String filename) {
		return filename.replaceAll(".[cC][fF][cC]$", "").replace("\\",".").replace("/",".");
	}

	private boolean isCreateObject(CFFunctionExpression funcExpr) {
		return "createobject".equalsIgnoreCase(funcExpr.getFunctionName()) && funcExpr.getArgs().size() > 1
				&& "'component'".equalsIgnoreCase(funcExpr.getArgs().get(0).Decompile(0));
	}

	final static class PackageCaseCheckerEntry{
		
		final Context context;
		final String componentPath;
		final String componentName;
		
		public PackageCaseCheckerEntry(Context context, String componentPath,final String componentName) {
			this.context = context;
			this.componentPath = componentPath;
			this.componentName=componentName;
		}
	}

	@Override
	public void setCFLint(CFLint cflint) {
		this.cflintRef = cflint;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy