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

org.kuali.common.util.metainf.service.DefaultMetaInfService Maven / Gradle / Ivy

package org.kuali.common.util.metainf.service;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Properties;

import org.apache.commons.io.FileUtils;
import org.apache.commons.lang3.StringUtils;
import org.kuali.common.util.Assert;
import org.kuali.common.util.CollectionUtils;
import org.kuali.common.util.FileSystemUtils;
import org.kuali.common.util.LocationUtils;
import org.kuali.common.util.PropertyUtils;
import org.kuali.common.util.SimpleScanner;
import org.kuali.common.util.file.CanonicalFile;
import org.kuali.common.util.log.LoggerUtils;
import org.kuali.common.util.metainf.model.MetaInfContext;
import org.kuali.common.util.metainf.model.MetaInfResource;
import org.kuali.common.util.metainf.model.ScanResult;
import org.kuali.common.util.metainf.model.WriteLines;
import org.kuali.common.util.metainf.model.WriteProperties;
import org.kuali.common.util.metainf.model.WriteRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class DefaultMetaInfService implements MetaInfService {

	private static final Logger logger = LoggerFactory.getLogger(DefaultMetaInfService.class);

	protected static final String PROPERTIES = "properties";
	protected static final String SIZE = "size";
	protected static final String LINES = "lines";

	@Override
	public ScanResult scan(MetaInfContext context) {
		List files = scanFileSystem(context);
		List resources = getResources(context, files);
		return new ScanResult(context, resources);
	}

	@Override
	public List scan(List contexts) {
		List results = new ArrayList();
		for (MetaInfContext context : contexts) {
			ScanResult result = scan(context);
			results.add(result);
		}
		return results;
	}

	@Override
	public void write(ScanResult result) {
		write(Arrays.asList(result));
	}

	protected WriteLines getWriteLines(ScanResult result) {
		List resources = result.getResources();
		List locations = new ArrayList();
		for (MetaInfResource resource : resources) {
			locations.add(resource.getLocation());
		}
		MetaInfContext context = result.getContext();
		File outputFile = context.getOutputFile();
		String encoding = context.getEncoding();
		File relativeDir = context.getRelativeDir();
		WriteRequest request = new WriteRequest(outputFile, encoding, relativeDir);
		return new WriteLines(request, locations);
	}

	@Override
	public void write(List results) {
		List lines = getWriteLines(results);
		List properties = getWriteProperties(results);
		for (WriteLines element : CollectionUtils.toEmptyList(lines)) {
			WriteRequest request = element.getRequest();
			String relativePath = FileSystemUtils.getRelativePathQuietly(request.getRelativeDir(), request.getOutputFile());
			logger.info("Creating [{}] - {} resources", relativePath, element.getLines().size());
			write(request, element.getLines());
		}
		for (WriteProperties element : CollectionUtils.toEmptyList(properties)) {
			WriteRequest request = element.getRequest();
			PropertyUtils.store(element.getProperties(), request.getOutputFile(), request.getEncoding());
		}
	}

	protected void write(WriteRequest request, List lines) {
		try {
			FileUtils.writeLines(request.getOutputFile(), request.getEncoding(), lines);
		} catch (IOException e) {
			throw new IllegalArgumentException("Unexpected IO error", e);
		}
	}

	protected List getWriteProperties(List results) {
		List requests = new ArrayList();
		for (ScanResult result : results) {
			MetaInfContext context = result.getContext();
			if (context.isIncludePropertiesFile()) {
				WriteProperties request = getWriteProperties(result);
				requests.add(request);
			}
		}
		return requests;
	}

	protected WriteProperties getWriteProperties(ScanResult result) {
		List resources = result.getResources();
		Properties properties = new Properties();
		for (MetaInfResource resource : resources) {
			String key = getPropertyKey(resource.getLocation());
			String sizeKey = key + "." + SIZE;
			String linesKey = key + "." + LINES;
			properties.setProperty(sizeKey, Long.toString(resource.getSize()));
			properties.setProperty(linesKey, Long.toString(resource.getLineCount()));
		}
		MetaInfContext context = result.getContext();
		File canonical = new CanonicalFile(context.getOutputFile());
		File outputFile = new File(canonical.getPath() + "." + PROPERTIES);
		String encoding = context.getEncoding();
		File relativeDir = context.getRelativeDir();
		WriteRequest request = new WriteRequest(outputFile, encoding, relativeDir);
		return new WriteProperties(request, properties);
	}

	protected List getWriteLines(List results) {
		List requests = new ArrayList();
		for (ScanResult result : results) {
			WriteLines request = getWriteLines(result);
			requests.add(request);
		}
		return requests;
	}

	protected List scanFileSystem(MetaInfContext context) {
		File dir = context.getScanDir();
		Assert.isExistingDir(dir);
		logger.debug("Examining [" + LocationUtils.getCanonicalPath(dir) + "]");
		List includes = context.getIncludes();
		List excludes = context.getExcludes();
		logger.debug("Patterns - {}", LoggerUtils.getLogMsg(includes, excludes));
		SimpleScanner scanner = new SimpleScanner(dir, includes, excludes);
		return scanner.getFiles();
	}

	protected List getResources(MetaInfContext context, List files) {
		List resources = new ArrayList();
		for (File file : files) {
			MetaInfResource resource = getResource(file, context);
			resources.add(resource);
		}
		if (context.isSort()) {
			if (context.getComparator().isPresent()) {
				Comparator comparator = context.getComparator().get();
				Collections.sort(resources, comparator);
			} else {
				Collections.sort(resources);
			}
		}
		return resources;
	}

	protected MetaInfResource getResource(File resourceFile, MetaInfContext context) {
		String location = getLocationURL(new CanonicalFile(resourceFile), context);

		long lineCount = MetaInfResource.UNKNOWN_LINECOUNT;

		// Only read through the file if we've been explicitly configured to do so
		if (context.isIncludeLineCounts()) {

			// Make sure an encoding has been supplied
			Assert.noBlanks(context.getEncoding());

			// Read through the entire file keeping track of how many lines of text we encounter
			lineCount = LocationUtils.getLineCount(resourceFile, context.getEncoding());
		}

		// Create a resource object from the information we've collected
		return new MetaInfResource(location, resourceFile.length(), lineCount);
	}

	protected String getLocationURL(CanonicalFile resourceFile, MetaInfContext context) {
		if (!context.isRelativePaths()) {
			return LocationUtils.getCanonicalURLString(resourceFile);
		} else {
			return getRelativeLocationURL(resourceFile, context);
		}
	}

	/**
	 * Get a URL string that can be used to address file. This is usually a Spring pseudo-url classpath location, eg - [classpath:foo/bar.txt]
	 * 
	 * @param resourceFile
	 *            The file to get a location url for. eg - [/x/y/z/src/main/resources/foo/bar.txt]
	 * @param context
	 *            Context information for generating a relative location url. eg - [/x/y/z/src/main/resources] and [classpath:].
	 * 
	 * @return A string representing a fully qualified location URL for file. eg - [classpath:foo/bar.txt]
	 */
	protected String getRelativeLocationURL(CanonicalFile resourceFile, MetaInfContext context) {

		// Extract the parent directory
		CanonicalFile parent = new CanonicalFile(context.getRelativeDir());

		// Make sure it is an existing directory
		Assert.isExistingDir(parent);

		// Get a string representing the path to the parent dir
		String parentPath = parent.getPath();

		// Get a string representing the path to the resource file
		String resourcePath = resourceFile.getPath();

		// Make sure the resource file resides underneath the parent dir
		Assert.isTrue(StringUtils.contains(resourcePath, parentPath), "[" + resourcePath + "] does not contain [" + parentPath + "]");

		// Extract the portion of the path to the resource file that is relative to the parent dir
		int relativePos = parentPath.length() + 1;
		String relativePath = StringUtils.substring(resourcePath, relativePos);

		// Prepend the prefix and return
		return context.getUrlPrefix() + relativePath;
	}

	protected String getPropertyKey(String location) {
		location = StringUtils.replace(location, ":", ".");
		location = StringUtils.replace(location, "/", ".");
		return location;
	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy