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

org.walkmod.writers.AbstractFileWriter Maven / Gradle / Ivy

There is a newer version: 3.0.5
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.writers;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.FileReader;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.StringReader;
import java.io.Writer;

import org.apache.commons.io.FilenameUtils;
import org.apache.log4j.Logger;
import org.walkmod.ChainWriter;
import org.walkmod.exceptions.WalkModException;
import org.walkmod.walkers.AbstractWalker;
import org.walkmod.walkers.VisitorContext;

public abstract class AbstractFileWriter implements ChainWriter {

	private String[] excludes;

	private String[] includes;

	private File outputDirectory;

	private String normalizedOutputDirectory;

	private String encoding = "UTF-8";

	private String platform = null;

	private static final String UNIX = "unix";
	private static final String MAC = "mac";
	private static final String WINDOWS = "windows";

	private static Logger log = Logger.getLogger(AbstractFileWriter.class);

	public void setOutputDirectory(String outputDirectory) {
		this.outputDirectory = new File(outputDirectory);
		if (!this.outputDirectory.exists()) {
			this.outputDirectory.mkdir();
		}
		normalizedOutputDirectory = FilenameUtils.normalize(this.outputDirectory.getAbsolutePath(), true);
	}

	public File getOutputDirectory() {
		return this.outputDirectory;
	}

	public abstract File createOutputDirectory(Object o);

	public void write(Object n, VisitorContext vc) throws Exception {

		File out = null;
		boolean createdEmptyFile = false;
		if (vc != null) {
			out = (File) vc.get(AbstractWalker.ORIGINAL_FILE_KEY);
		}
		if (out == null) {
			log.debug("Creating the target source file. This is not the original source file.");
			out = createOutputDirectory(n);
			createdEmptyFile = true;
		} else {
			log.debug("The system will overwrite the original source file.");
		}
		boolean write = true;
		if (out != null) {
			log.debug("Analyzing exclude and include rules");
			String aux = FilenameUtils.normalize(out.getCanonicalPath(), true);
			if (excludes != null) {
				for (int i = 0; i < excludes.length && write; i++) {
					if (!excludes[i].startsWith(normalizedOutputDirectory)) {
						excludes[i] = normalizedOutputDirectory + "/" + excludes[i];
						if (excludes[i].endsWith("\\*\\*")) {
							excludes[i] = excludes[i].substring(0, excludes[i].length() - 2);
						}
					}
					write = !(excludes[i].startsWith(aux) || FilenameUtils.wildcardMatch(aux, excludes[i]));
				}
			}
			if (includes != null && write) {
				write = false;
				for (int i = 0; i < includes.length && !write; i++) {
					if (!includes[i].startsWith(normalizedOutputDirectory)) {
						includes[i] = normalizedOutputDirectory + "/" + includes[i];
						if (includes[i].endsWith("\\*\\*")) {
							includes[i] = includes[i].substring(0, includes[i].length() - 2);
						}
					}

					write = includes[i].startsWith(aux) || FilenameUtils.wildcardMatch(aux, includes[i]);
				}
			}
			if (write) {
				Writer writer = null;

				try {
					vc.put("outFile", out);
					String content = getContent(n, vc);
					vc.remove("outFile");
					if (content != null && !"".equals(content)) {
						char endLineChar = getEndLineChar(out);

						writer = new BufferedWriter(new OutputStreamWriter(new FileOutputStream(out), getEncoding()));

						if (vc.get("append") == null) {
							write(content, writer, endLineChar);
						} else {
							if (Boolean.TRUE.equals(vc.get("append"))) {
								append(content, writer, endLineChar);
							} else {
								write(content, writer, endLineChar);
							}
						}
						Summary.getInstance().addFile(out);
						log.debug(out.getPath() + " written ");
					}
				} finally {
					if (writer != null) {
						writer.close();

					}
				}
			} else {
				if (createdEmptyFile && out != null && out.isFile()) {
					out.delete();
				}
				log.debug("skipping " + out.getParent());
			}
		} else {
			log.debug("There is no place where to write.");
		}
	}

	public void write(String content, Writer writer, char endLineChar) throws IOException {
		char[] buffer = content.toCharArray();

		String endLine = "\n";
		if (endLineChar == '\r') {
			endLine = "\r\n";
		}
		if (platform != null) {
			if (platform.equals(UNIX)) {
				endLine = "\n";
			} else if (platform.equals(WINDOWS)) {
				endLine = "\r\n";
			} else if (platform.equals(MAC)) {
				endLine = "\r";
			}
		}
		for (int i = 0; i < buffer.length; i++) {
			if (buffer[i] == '\n') {
				writer.write(endLine);
			} else if (buffer[i] == '\r') {
				writer.write(endLine);
				if (i + 1 < buffer.length && buffer[i + 1] == '\n') {
					i++;
				}
			} else {
				writer.write(buffer[i]);
			}
		}

	}

	public void append(String content, Writer writer, char endLineChar) throws IOException {
		BufferedReader reader = new BufferedReader(new StringReader(content));
		String line = reader.readLine();
		String endLine = "\n";
		if (endLineChar == '\r') {
			endLine = "\r\n";
		}
		while (line != null) {
			writer.append(line + endLine);
			line = reader.readLine();
		}
	}

	public char getEndLineChar(File file) throws IOException {
		char endLineChar = '\n';
		if (file.exists()) {
			FileReader reader = new FileReader(file);
			try {
				char[] buffer = new char[150];
				boolean detected = false;
				int bytes = reader.read(buffer);
				char previousChar = '\0';
				while (bytes > 0 && !detected) {
					for (int i = 0; i < bytes && !detected; i++) {
						if (buffer[i] == '\r') {
							endLineChar = '\r';
							detected = true;
						}
						detected = detected || (previousChar == '\n' && buffer[i] != '\r');
						previousChar = buffer[i];

					}
					if (!detected) {
						bytes = reader.read(buffer);
					}
				}
			} finally {
				reader.close();
			}
		} else {
			String os = System.getProperty("os.name");
			if (os.toLowerCase().startsWith("windows")) {
				endLineChar = '\r';
			}
		}
		return endLineChar;
	}

	public abstract String getContent(Object n, VisitorContext vc);

	@Override
	public void close() throws IOException {
	}

	@Override
	public void flush() throws IOException {
	}

	public void setPath(String path) {
		setOutputDirectory(path);
	}

	public String getPath() {
		return this.outputDirectory.getPath();
	}

	@Override
	public void setExcludes(String[] excludes) {
		if (excludes != null && System.getProperty("os.name").toLowerCase().contains("windows")) {
			for (int i = 0; i < excludes.length; i++) {
				excludes[i] = FilenameUtils.normalize(excludes[i], true);
			}
		}
		this.excludes = excludes;
	}

	@Override
	public String[] getExcludes() {
		return excludes;
	}

	@Override
	public void setIncludes(String[] includes) {
		if (includes != null && System.getProperty("os.name").toLowerCase().contains("windows")) {
			for (int i = 0; i < includes.length; i++) {
				includes[i] = FilenameUtils.normalize(includes[i], true);
			}
		}
		this.includes = includes;
	}

	@Override
	public String[] getIncludes() {
		return includes;
	}

	public String getEncoding() {
		return encoding;
	}

	public void setEncoding(String encoding) {
		this.encoding = encoding;
		log.debug("[encoding]:" + encoding);
	}

	public void setPlatform(String platform) {
		this.platform = platform;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy