view src/org/tmatesoft/hg/util/Path.java @ 217:e39cf474ef94

Experimental support to mix-in start and end events for inspectors. Additionally, Lifecycle may serve as iteration control
author Artem Tikhomirov <tikhomirov.artem@gmail.com>
date Tue, 17 May 2011 03:40:52 +0200
parents 1a7a9a20e1f9
children 1ec6b327a6ac
line wrap: on
line source
/*
 * Copyright (c) 2011 TMate Software Ltd
 *  
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; version 2 of the License.
 *
 * This program 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 General Public License for more details.
 *
 * For information on how to redistribute this software under
 * the terms of a license other than GNU General Public License
 * contact TMate Software at support@hg4j.com
 */
package org.tmatesoft.hg.util;

/**
 * Identify repository files (not String nor io.File). Convenient for pattern matching. Memory-friendly.
 * 
 * @author Artem Tikhomirov
 * @author TMate Software Ltd.
 */
public final class Path implements CharSequence, Comparable<Path>/*Cloneable? - although clone for paths make no sense*/{
//	private String[] segments;
//	private int flags; // dir, unparsed
	private String path;
	
	/*package-local*/Path(String p) {
		path = p;
	}

	/**
	 * Check if this is directory's path. 
	 * Note, this method doesn't perform any file system operation.
	 * 
	 * @return true when this path points to a directory 
	 */
	public boolean isDirectory() {
		// XXX simple logic for now. Later we may decide to have an explicit factory method to create directory paths
		return path.charAt(path.length() - 1) == '/';
	}

	public int length() {
		return path.length();
	}

	public char charAt(int index) {
		return path.charAt(index);
	}

	public CharSequence subSequence(int start, int end) {
		// new Path if start-end matches boundaries of any subpath
		return path.substring(start, end);
	}
	
	@Override
	public String toString() {
		return path; // CharSequence demands toString() impl
	}

	public int compareTo(Path o) {
		return path.compareTo(o.path);
	}
	
	@Override
	public boolean equals(Object obj) {
		if (obj != null && getClass() == obj.getClass()) {
			return this == obj || path.equals(((Path) obj).path);
		}
		return false;
	}
	@Override
	public int hashCode() {
		return path.hashCode();
	}

	public static Path create(String path) {
		if (path == null) {
			throw new IllegalArgumentException();
		}
		if (path.indexOf('\\') != -1) {
			throw new IllegalArgumentException();
		}
		Path rv = new Path(path);
		return rv;
	}

	/**
	 * Path filter.
	 */
	public interface Matcher {
		boolean accept(Path path);
	}

	/**
	 * Factory for paths
	 */
	public interface Source {
		Path path(String p);
	}

	/**
	 * Straightforward {@link Source} implementation that creates new Path instance for each supplied string
	 */
	public static class SimpleSource implements Source {
		private final PathRewrite normalizer;

		public SimpleSource(PathRewrite pathRewrite) {
			if (pathRewrite == null) {
				throw new IllegalArgumentException();
			}
			normalizer = pathRewrite;
		}

		public Path path(String p) {
			return Path.create(normalizer.rewrite(p));
		}
	}
}