/** @author <a href="mailto:[email protected]">Trygve Laugstøl</a> */ public class FileAttributes { public final Option<String> user; public final Option<String> group; public final Option<UnixFileMode> mode; public final List<String> tags; public static final Show<FileAttributes> singleLineShow = Show.anyShow(); /** A file object with all none fields. Use this when creating template objects. */ public static final FileAttributes EMPTY = new FileAttributes( Option.<String>none(), Option.<String>none(), Option.<UnixFileMode>none(), List.<String>nil()); public FileAttributes(Option<String> user, Option<String> group, Option<UnixFileMode> mode) { this(user, group, mode, List.<String>nil()); } public FileAttributes( Option<String> user, Option<String> group, Option<UnixFileMode> mode, List<String> tags) { validateNotNull(user, group, mode, tags); this.user = user; this.group = group; this.mode = mode; this.tags = tags; } public FileAttributes user(String user) { return new FileAttributes(fromNull(user), group, mode, tags); } public FileAttributes user(Option<String> user) { return new FileAttributes(user, group, mode, tags); } public FileAttributes group(String group) { return new FileAttributes(user, fromNull(group), mode, tags); } public FileAttributes group(Option<String> group) { return new FileAttributes(user, group, mode, tags); } public FileAttributes mode(UnixFileMode mode) { return new FileAttributes(user, group, fromNull(mode), tags); } public FileAttributes mode(Option<UnixFileMode> mode) { return new FileAttributes(user, group, mode, tags); } public FileAttributes addTag(String tag) { return new FileAttributes(user, group, mode, tags.append(single(tag))); } public FileAttributes tags(List<String> tags) { return new FileAttributes(user, group, mode, this.tags.append(tags)); } // ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- public FileAttributes useAsDefaultsFor(FileAttributes other) { return new FileAttributes( other.user.orElse(user), other.group.orElse(group), other.mode.orElse(mode), other.tags); } // ----------------------------------------------------------------------- // // ----------------------------------------------------------------------- public static final F2<FileAttributes, FileAttributes, FileAttributes> useAsDefaultsFor = new F2<FileAttributes, FileAttributes, FileAttributes>() { public FileAttributes f(FileAttributes defaults, FileAttributes other) { return defaults.useAsDefaultsFor(other); } }; public static final F<FileAttributes, Option<String>> userF = new F<FileAttributes, Option<String>>() { public Option<String> f(FileAttributes attributes) { return attributes.user; } }; public static final F<FileAttributes, Option<String>> groupF = new F<FileAttributes, Option<String>>() { public Option<String> f(FileAttributes attributes) { return attributes.group; } }; public static final F<FileAttributes, Option<UnixFileMode>> modeF = new F<FileAttributes, Option<UnixFileMode>>() { public Option<UnixFileMode> f(FileAttributes attributes) { return attributes.mode; } }; public static final F<FileAttributes, List<String>> tagsF = new F<FileAttributes, List<String>>() { public List<String> f(FileAttributes attributes) { return attributes.tags; } }; // ----------------------------------------------------------------------- // Object Overrides // ----------------------------------------------------------------------- public boolean equals(Object o) { if (this == o) { return true; } if (o == null || getClass() != o.getClass()) { return false; } FileAttributes that = (FileAttributes) o; return optionEquals(user, that.user) && optionEquals(group, that.group) && optionEquals(mode, that.mode); } public String toString() { return "user="******"<not set>") + ", " + "group=" + group.orSome("<not set>") + ", " + "mode=" + mode.map(showLong).orSome("<not set>"); } }
public FileAttributes(Option<String> user, Option<String> group, Option<UnixFileMode> mode) { this(user, group, mode, List.<String>nil()); }
/** * Binds the given function across each element of this list with a final join. * * @param f The function to apply to each element of this list. * @return A new list after performing the map, then final join. */ public <B> NonEmptyList<B> bind(final F<A, NonEmptyList<B>> f) { final List.Buffer<B> b = new List.Buffer<B>(); final NonEmptyList<B> p = f.f(head); b.snoc(p.head); b.append(p.tail); tail.foreachDoEffect( new Effect1<A>() { public void f(final A a) { final NonEmptyList<B> p = f.f(a); b.snoc(p.head); b.append(p.tail); } }); final List<B> bb = b.toList(); return nel(bb.head(), bb.tail()); }
public FileAttributes addTag(String tag) { return new FileAttributes(user, group, mode, tags.append(single(tag))); }
/** * Maps the given function across this list. * * @param f The function to map across this list. * @return A new list after the given function has been applied to each element. */ public <B> NonEmptyList<B> map(final F<A, B> f) { return nel(f.f(head), tail.map(f)); }
/** * The length of this list. * * @return The length of this list. */ public int length() { return 1 + tail.length(); }
/** * Appends (snoc) the given element to this non empty list to produce a new non empty list. O(n). * * @param a The element to append to this non empty list. * @return A new non empty list with the given element appended. */ public NonEmptyList<A> snoc(final A a) { return nel(head, tail.snoc(a)); }
/** * Prepend the given value to this list. * * @param a The value to prepend. * @return A non-empty list with an extra element. */ public NonEmptyList<A> cons(final A a) { return nel(a, tail.cons(head)); }
/** * Returns a potential non-empty list from the given list. A non-value is returned if the given * list is empty. * * @param as The list to construct a potential non-empty list with. * @return A potential non-empty list from the given list. */ public static <A> Option<NonEmptyList<A>> fromList(final List<A> as) { return as.isEmpty() ? Option.<NonEmptyList<A>>none() : some(nel(as.head(), as.tail())); }
/** * Constructs a non empty list from the given elements. * * @param head The first in the non-empty list. * @param tail The elements to construct a list's tail with. * @return A non-empty list with the given elements. */ @SafeVarargs public static <A> NonEmptyList<A> nel(final A head, final A... tail) { return nel(head, List.list(tail)); }
/** * Returns a <code>List</code> projection of this list. * * @return A <code>List</code> projection of this list. */ public List<A> toList() { return tail.cons(head); }
/** * Transforms a non empty list of pairs into a non empty list of first components and a non empty * list of second components. * * @param xs The non empty list of pairs to transform. * @return A non empty list of first components and a non empty list of second components. */ public static <A, B> P2<NonEmptyList<A>, NonEmptyList<B>> unzip(final NonEmptyList<P2<A, B>> xs) { final P2<List<A>, List<B>> p = List.unzip(xs.toList()); return P.p(nel(p._1().head(), p._1().tail()), nel(p._2().head(), p._2().tail())); }
/** * Zips this non empty list with the given non empty list using the given function to produce a * new list. If this list and the given list have different lengths, then the longer list is * normalised so this function never fails. * * @param bs The non empty list to zip this non empty list with. * @param f The function to zip this non empty list and the given non empty list with. * @return A new non empty list with a length the same as the shortest of this list and the given * list. */ public <B, C> NonEmptyList<C> zipWith(final List<B> bs, final F2<A, B, C> f) { final List<C> list = toList().zipWith(bs, f); return nel(list.head(), list.tail()); }
/** * Sorts this non empty list using the given order over elements using a <em>merge sort</em> * algorithm. * * @param o The order over the elements of this non empty list. * @return A sorted non empty list according to the given order. */ public NonEmptyList<A> sort(final Ord<A> o) { final List<A> list = toList().sort(o); return nel(list.head(), list.tail()); }
/** * Reverse this non empty list in constant stack space. * * @return A new non empty list with the elements in reverse order. */ public NonEmptyList<A> reverse() { final List<A> list = toList().reverse(); return nel(list.head(), list.tail()); }
/** * Intersperses the given argument between each element of this non empty list. * * @param a The separator to intersperse in this non empty list. * @return A non empty list with the given separator interspersed. */ public NonEmptyList<A> intersperse(final A a) { final List<A> list = toList().intersperse(a); return nel(list.head(), list.tail()); }