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

org.walkmod.licenseapplier.visitors.LicenseApplier Maven / Gradle / Ivy

There is a newer version: 2.2
Show newest version
/* 
  Copyright (C) 2013 Raquel Pau and Albert Coroleu.
 
 Walkmod is free software: you can redistribute it and/or modify
 it under the terms of the GNU Lesser General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.
 
 Walkmod is distributed in the hope that it will be useful,
 but WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU Lesser General Public License for more details.
 
 You should have received a copy of the GNU Lesser General Public License
 along with Walkmod.  If not, see .*/

package org.walkmod.licenseapplier.visitors;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import org.walkmod.exceptions.WalkModException;
import org.walkmod.javalang.ast.BlockComment;
import org.walkmod.javalang.ast.Comment;
import org.walkmod.javalang.ast.CompilationUnit;
import org.walkmod.javalang.ast.Node;
import org.walkmod.javalang.visitors.VoidVisitorAdapter;
import org.walkmod.walkers.VisitorContext;

public class LicenseApplier extends VoidVisitorAdapter {

	/**
	 * File with the license text
	 */
	private File licenseFile;

	/**
	 * Different words without blank characters
	 */
	private String[] licenseWords;

	/**
	 * license content with resolved variables
	 */
	private String licenseContent;

	/**
	 * property values to replace in the license
	 */
	private Map propertyValues = new HashMap();

	private String action = REFORMAT_ACTION;

	/**
	 * update existing header with a new one
	 */
	public static final String UPDATE_ACTION = "update";

	/**
	 * check if header is missing in some source file
	 */
	public static final String CHECK_ACTION = "check";

	/**
	 * can remove existing header
	 */
	public static final String REMOVE_ACTION = "remove";

	/**
	 * add headers if missing
	 */
	public static final String REFORMAT_ACTION = "reformat";

	public boolean firstExecution = true;

	public void setAction(String action) {
		if (action != null) {
			if (UPDATE_ACTION.equalsIgnoreCase(action)) {
				this.action = UPDATE_ACTION;
			} else if (CHECK_ACTION.equalsIgnoreCase(action)) {
				this.action = CHECK_ACTION;
			} else if (REMOVE_ACTION.equalsIgnoreCase(action)) {
				this.action = REMOVE_ACTION;
			} else if (REFORMAT_ACTION.equalsIgnoreCase(action)) {
				this.action = REFORMAT_ACTION;
			}
		}
	}

	private boolean isVariable(String word) {
		return word.startsWith("${") && word.endsWith("}");
	}

	private boolean matchesWithLicense(String content) {
		int matchingIndex = 0;
		boolean containsLicense = false;
		if (content != null && licenseWords != null) {
			String[] words = content.split("\\s");
			if (words != null) {
				for (int i = 0; i < words.length && !containsLicense; i++) {
					String word = words[i].trim();
					if (!"".equals(word)) {
						if (isVariable(licenseWords[matchingIndex]) || word.equals(licenseWords[matchingIndex])) {
							matchingIndex++;
						} else {
							matchingIndex = 0;
						}
						containsLicense = matchingIndex == licenseWords.length - 1;
					}
				}
			}
		}
		return containsLicense;
	}

	@Override
	public void visit(CompilationUnit cu, VisitorContext ctx) {

		if (licenseFile == null && !REMOVE_ACTION.equals(action)) {
			throw new WalkModException("Missing license file");
		}

		if (firstExecution) {
			updateLicenseContent();
			firstExecution = false;
		}
		boolean licenseFound = false;
		List comments = cu.getComments();
		Comment comment = null;
		boolean referenceIsPackage = false;
		Node reference = cu.getPackage();
		if (reference == null) {
			if (cu.getImports() != null && !cu.getImports().isEmpty()) {
				reference = cu.getImports().get(0);
			} else if (cu.getTypes() != null && !cu.getTypes().isEmpty()) {
				reference = cu.getTypes().get(0);
			}
		} else {
			referenceIsPackage = true;
		}
		if (comments != null) {
			Iterator it = comments.iterator();
			while (it.hasNext() && !licenseFound) {
				comment = it.next();
				if (reference == null || comment.isPreviousThan(reference)) {
					licenseFound = matchesWithLicense(comment.getContent());
				} else {
					break;
				}
			}
		}
		if (!licenseFound) {
			if (REFORMAT_ACTION.equals(action)) {
				boolean add = false;
				if (comments == null || comments.isEmpty()) {
					comments = new LinkedList();
					cu.setComments(comments);
					add = true;
				} else {
					Comment firstComment = comments.get(0);
					add = !(firstComment.getBeginLine() <= cu.getBeginLine());
				}

				if (add) {
					BlockComment licenseComment = new BlockComment(licenseContent);
					comments.add(0, licenseComment);
					ctx.addTransformationMessage("Missing license as block comment. License file added");
				}
			} else if (CHECK_ACTION.equals(action)) {
				ctx.addTransformationMessage("Missing license as block comment. License file added");
			}
		}
		if (REMOVE_ACTION.equals(action)) {
			if (comments != null) {
				Iterator it = comments.iterator();
				while (it.hasNext()) {
					comment = it.next();
					if (referenceIsPackage || comment instanceof BlockComment) {
						if (reference == null || comment.isPreviousThan(reference)) {
							it.remove();
						} else {
							break;
						}
					}
				}
				if (comments.isEmpty()) {
					cu.setComments(null);
				}
			}
			ctx.addTransformationMessage("License removed");
		}
		if (UPDATE_ACTION.equals(action)) {
			if (comments != null) {
				Iterator it = comments.iterator();
				while (it.hasNext()) {
					comment = it.next();
					if (referenceIsPackage || comment instanceof BlockComment) {
						if (reference == null || comment.isPreviousThan(reference)) {
							it.remove();
						} else {
							break;
						}
					}
				}
			} else {
				comments = new LinkedList();
				cu.setComments(comments);
			}
			BlockComment licenseComment = new BlockComment(licenseContent);
			comments.add(0, licenseComment);
			ctx.addTransformationMessage("Updating license");
		}
	}

	public void setLicenseFile(String path) throws FileNotFoundException {
		setLicense(new File(path));
	}

	private void updateLicenseContent() {
		if (licenseFile != null) {
			StringBuffer sb = new StringBuffer();
			FileReader fr = null;
			try {
				fr = new FileReader(licenseFile);
				BufferedReader reader = new BufferedReader(fr);
				try {
					String line = reader.readLine();
					List wordLines = new LinkedList();
					int wordsSize = 0;
					while (line != null) {
						sb.append(' ');
						String[] words = line.split("\\s");
						for (int i = 0; i < words.length; i++) {
							String trimmed = words[i].trim();

							if (isVariable(trimmed)) {
								String variable = trimmed.substring(2, trimmed.length() - 1);
								if (propertyValues.containsKey(variable)) {
									sb.append(propertyValues.get(variable));
								} else {
									sb.append(words[i]);
								}
							} else {
								sb.append(words[i]);
							}
							if (i + 1 < words.length) {
								sb.append(' ');
							}
							words[i] = trimmed;
							if (!"".equals(trimmed)) {
								wordsSize += 1;
							}
						}

						wordLines.add(words);
						line = reader.readLine();
						if (line != null) {
							sb.append('\n');
						}
					}
					licenseWords = new String[wordsSize];
					int i = 0;
					for (String[] words : wordLines) {
						for (int j = 0; j < words.length; j++) {
							if (!"".equals(words[j])) {
								licenseWords[i] = words[j];
								i++;
							}
						}
					}
				} finally {
					if (reader != null) {
						reader.close();
					}
				}
			} catch (IOException e) {
				throw new WalkModException("License file read", e);
			} finally {
				if (fr != null) {
					try {
						fr.close();
					} catch (IOException e) {
						throw new WalkModException("License file cannot be closed", e);
					}
				}
			}
			licenseContent = new String(sb);
		}
	}

	public void setLicense(File licenseFile) throws FileNotFoundException {
		this.licenseFile = licenseFile;
		if (licenseFile == null) {
			throw new WalkModException("Missing license file");
		}
		if (!licenseFile.exists()) {
			throw new WalkModException("License file does not exists");
		}
		if (!licenseFile.canRead()) {
			throw new WalkModException("License file cannot be read");
		}

	}

	public void setPropertyValues(Map propertyValues) {
		this.propertyValues = propertyValues;
	}
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy