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

jsclassloader.dependency.DependencyParser Maven / Gradle / Ivy

package jsclassloader.dependency;

import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import java.util.regex.Pattern;

import jsclassloader.Config;
import jsclassloader.classes.ClassFileSet;
import jsclassloader.classes.ClassNameCharTree;
import jsclassloader.classes.LetterNode;

public class DependencyParser {

	private LetterNode root;
	private StringBuffer sinceStartOfLine;
	private List possibleMatches;
	
	private Pattern extendRegex;
	private Pattern implementRegex;
	private Pattern forceLoadRegex;

	private Pattern startOfWholeLineForceLoadRegex;
	private Pattern wholeLineForceLoadRegex;
	
	private static String jsdocLinkRegex = ".*\\{ *@link.*";
	
	private int readAheadLimit = 1000;
	

	public DependencyParser(Config config) {
		this.extendRegex = Pattern.compile(config.getProperty(Config.PROP_EXTEND));
		this.implementRegex = Pattern.compile(config.getProperty(Config.PROP_IMPLEMENT));
		this.forceLoadRegex = Pattern.compile(config.getProperty(Config.PROP_FORCE));
		this.startOfWholeLineForceLoadRegex = Pattern.compile(config.getProperty(Config.PROP_START_FORCE));
		this.wholeLineForceLoadRegex = Pattern.compile(config.getProperty(Config.PROP_WHOLE_FORCE));
	}
	
	public void setClassFileSet(ClassFileSet fileSet) {
		root = new ClassNameCharTree(fileSet).getRootNode();
	}
	
	public List parse(InputStream in) throws IOException {
		sinceStartOfLine = new StringBuffer();
		possibleMatches = new ArrayList();

		int latest;
		List results = new ArrayList();
		while((latest = in.read()) !=  -1)
		{
			Match matched = next((char)latest);
			if(matched != null){
				if (matched.isReadAheadRequired()) {
					in.mark(readAheadLimit);
					StringBuffer restOfLine = new StringBuffer();
					int nextAhead = in.read();
					while(nextAhead != -1 && nextAhead != 10 && nextAhead != 13) {
						restOfLine.append((char)nextAhead);
						nextAhead = in.read();
					}
					in.reset();
					checkWholeLineForceLoad(sinceStartOfLine + restOfLine.toString(), matched);
				}
				results.add(matched);
			}
		}
		return results;
	}	
	
	private Match next(char latest) {
		if(latest == '\n'){
			sinceStartOfLine.setLength(0);
		}else{
			sinceStartOfLine.append(latest);
		}
		Match result = null;
		LetterNode rootFound = root.find(latest);
		List toRemove = new ArrayList();
		
		for (Match match : possibleMatches) {
			LetterNode found = match.node.find(latest);
			if (found == null) {
				toRemove.add(match);
				if(match.lastPartial != null){
					if(!isJsDocLink()){
						detectStatic(match);
						result =  match;
					}
				}
			} else {
				match.buffer.append(latest);
				match.node = found;
				if (found.isLeaf()) {
					if(!isJsDocLink()){
						detectStatic(match);
						result = match;
					}
					toRemove.add(match);
				}else {
					if (found.isClassEnd()){
						match.lastPartial = match.buffer.toString();
					}
				}
			}
		}

		if (rootFound != null) {
			possibleMatches.add(new Match(latest, rootFound));
		}
		possibleMatches.removeAll(toRemove);
		return result;
	}
	
	public void checkWholeLineForceLoad(String line, Match match) {
		if (wholeLineForceLoadRegex.matcher(line).find()) {
			match.setStaticDependency(true);
		}
		
	}

	private boolean isJsDocLink() {
		 String line = sinceStartOfLine.toString();
		 boolean result =  line.matches(jsdocLinkRegex);
		 return result;
	}

	private void detectStatic(Match match) {
		
		String line = sinceStartOfLine.toString();
		
		if(startOfWholeLineForceLoadRegex.matcher(line).find()) {
			match.setReadAheadRequired(true);
		}
		else if(implementRegex.matcher(line).find()){
			match.setStaticDependency(true);
		}
		else if(extendRegex.matcher(line).find()){
			match.setStaticDependency(true);
		}
		else if (forceLoadRegex.matcher(line).find()) {
			match.setStaticDependency(true);
		}
	}

	public class Match {
		private StringBuffer buffer = new StringBuffer();
		private LetterNode node;
		private String lastPartial;
		private boolean staticDependency = false;
		private boolean readAheadRequired = false;

		private Match(char first, LetterNode root) {
			buffer.append(first);
			node = root;
		}
		
		public String getClassname(){
			return buffer.toString();
		}

		public void setStaticDependency(boolean staticDependency) {
			this.staticDependency = staticDependency;
		}

		public boolean isStaticDependency() {
			return staticDependency;
		}
		
		public void setReadAheadRequired(boolean readAheadRequired) {
			this.readAheadRequired = readAheadRequired;
		}
		
		public boolean isReadAheadRequired() {
			return readAheadRequired;
		}
		
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy