소스 검색

new: PrintRules#skip
new: PrintRules#match(name)

Mariusz Czarnowski 4 년 전
부모
커밋
bbe844463f

+ 13 - 0
assira.core/src/main/java/net/ranides/assira/collection/iterators/IterableUtils.java

@@ -12,6 +12,7 @@ import net.ranides.assira.generic.CompareUtils;
 
 import java.util.*;
 import java.util.function.BiPredicate;
+import java.util.function.Consumer;
 import java.util.function.Function;
 import java.util.function.Predicate;
 import java.util.stream.Stream;
@@ -107,4 +108,16 @@ public final class IterableUtils {
         return () -> IteratorUtils.finite(generator);
     }
 
+    public static <T> Iterable<T> safe(Iterable<T> values) {
+        return safe(values, Exception.class, e -> {});
+    }
+
+    public static <T, E extends Throwable> Iterable<T> safe(Iterable<T> values, Class<E> type) {
+        return safe(values, type, e -> {});
+    }
+
+    public static <T, E extends Throwable> Iterable<T> safe(Iterable<T> values, Class<E> type, Consumer<E> handler) {
+        return () -> IteratorUtils.safe(values.iterator(), type, handler);
+    }
+
 }

+ 76 - 0
assira.core/src/main/java/net/ranides/assira/collection/iterators/IteratorUtils.java

@@ -15,6 +15,8 @@ import net.ranides.assira.functional.Functions.EachFunction;
 import net.ranides.assira.functional.Predicates.EachPredicate;
 import net.ranides.assira.functional.checked.CheckedSupplier;
 import net.ranides.assira.generic.CompareUtils;
+import net.ranides.assira.generic.Wrapper;
+import net.ranides.assira.trace.ExceptionUtils;
 
 /**
  *
@@ -255,6 +257,18 @@ public final class IteratorUtils {
         };
     }
 
+    public static <T> Iterator<T> safe(Iterator<T> iterator) {
+        return safe(iterator, Exception.class, e -> {});
+    }
+
+    public static <T, E extends Throwable> Iterator<T> safe(Iterator<T> iterator, Class<E> type) {
+        return safe(iterator, type, e -> {});
+    }
+
+    public static <T, E extends Throwable> Iterator<T> safe(Iterator<T> iterator, Class<E> type, Consumer<E> handler) {
+        return new SafeIterator<>(iterator, type, handler);
+    }
+
     public static <T> Iterator<T> singletonIterator(T value) {
 	    return new SingleIterator<>(value);
     }
@@ -831,4 +845,66 @@ public final class IteratorUtils {
                     Spliterator.DISTINCT | Spliterator.ORDERED;
         }
     }
+
+    private static class SafeIterator<T, E extends Throwable> implements Iterator<T> {
+
+        private final Iterator<? extends T> iterator;
+        private final Class<E> type;
+        private final Consumer<E> handler;
+        private final Wrapper <T> last;
+
+        public SafeIterator(Iterator<? extends T> iterator, Class<E> type, Consumer<E> handler) {
+            this.iterator = iterator;
+            this.type = type;
+            this.handler = handler;
+            this.last = Wrapper.of(null);
+        }
+
+        @Override
+        public boolean hasNext() {
+            if (last.isPresent()) {
+                return true;
+            }
+            if (!iterator.hasNext()) {
+                return false;
+            }
+            while(last.isEmpty() && iterator.hasNext()) {
+                try {
+                    last.set(iterator.next());
+                    return true;
+                } catch (Throwable e) {
+                    if (type.isInstance(e)) {
+                        e.printStackTrace();
+                        handler.accept(type.cast(e));
+                    } else {
+                        throw ExceptionUtils.rethrow(e);
+                    }
+                }
+            }
+            return false;
+        }
+
+        @Override
+        public T next() {
+            if (last.isPresent()) {
+                return last.replace(null);
+            } else {
+                throw new NoSuchElementException();
+            }
+        }
+
+        @Override
+        public void remove() {
+            try {
+                iterator.remove();
+            } catch (Throwable e) {
+                if(type.isInstance(e)) {
+                    handler.accept(type.cast(e));
+                } else {
+                    throw ExceptionUtils.rethrow(e);
+                }
+            }
+        }
+
+    }
 }

+ 13 - 12
assira.core/src/main/java/net/ranides/assira/collection/query/CQuery.java

@@ -36,15 +36,15 @@ public interface CQuery<T> extends Iterable<T> {
     }
 
     @SuppressWarnings("unchecked")
-    static <T> CQueryAbstract.Wrapper<T> from() {
-        return Wrapper.INSTANCE;
+    static <T> WrapBuilder<T> from() {
+        return WrapBuilder.INSTANCE;
     }
 
-    static  <T,E extends Exception> CQuery<T> from(CheckedSupplier<Stream<T>,E> source) throws E {
+    static  <T> CQuery<T> from(CheckedSupplier<Stream<T>,?> source) {
         return from().stream(source);
     }
 
-    static  <T,E extends Exception> CQuery<T> from(Collection<T> source) throws E {
+    static  <T> CQuery<T> from(Collection<T> source) {
         return from().collection(source);
     }
 
@@ -176,9 +176,10 @@ public interface CQuery<T> extends Iterable<T> {
 
     <R> R apply(Function<CQuery<? extends T>, R> function);
 
-    class Wrapper<F> {
+    class WrapBuilder<F> {
 
-        protected static final Wrapper INSTANCE = new Wrapper();
+        @SuppressWarnings({"rawtypes"})
+        protected static final WrapBuilder INSTANCE = new WrapBuilder();
 
         @SuppressWarnings({"rawtypes", "unchecked"})
         protected static final CQuery EMPTY = new CQueryAbstract.CQCollection(Collections.emptyList());
@@ -205,23 +206,23 @@ public interface CQuery<T> extends Iterable<T> {
             return new CQueryAbstract.CQIterable<>(source);
         }
 
-        public final <T extends F> CQuery<T> iterable(Supplier<Iterable<T>> source) {
-            return new CQueryAbstract.CQIterable<>(source);
+        public final <T extends F> CQuery<T> iterable(CheckedSupplier<Iterable<T>, ?> source) {
+            return new CQueryAbstract.CQIterable<>(source::$get);
         }
 
-        public final <T extends F,P> CQuery<T> iterable(P param, Function<? super P, Iterable<T>> source) {
+        public final <T extends F,P> CQuery<T> iterable(P param, CheckedFunction<? super P, Iterable<T>, ?> source) {
             return iterable(() -> source.apply(param));
         }
 
-        public final <T extends F,E extends Exception> CQuery<T> spliterator(CheckedSupplier<Spliterator<T>,E> source) throws E {
+        public final <T extends F> CQuery<T> spliterator(CheckedSupplier<Spliterator<T>,?> source) {
             return stream(() -> StreamSupport.stream(source.$get(), false));
         }
 
-        public final <T extends F,E extends Exception> CQuery<T> stream(CheckedSupplier<Stream<T>,E> source) throws E {
+        public final <T extends F> CQuery<T> stream(CheckedSupplier<Stream<T>,?> source) {
             return new CQueryAbstract.CQIterable<>(() -> source.$get().iterator());
         }
 
-        public final <T extends F,P,E extends Exception> CQuery<T> stream(P param, CheckedFunction<? super P, Stream<T>,E> source) throws E {
+        public final <T extends F,P> CQuery<T> stream(P param, CheckedFunction<? super P, Stream<T>,?> source) {
             return iterable(() -> source.$apply(param).iterator());
         }
 

+ 53 - 7
assira.core/src/main/java/net/ranides/assira/generic/Wrapper.java

@@ -7,18 +7,20 @@
 package net.ranides.assira.generic;
 
 import java.io.Serializable;
+import java.util.concurrent.atomic.AtomicReference;
+
 import net.ranides.assira.reflection.IClass;
 
 public interface Wrapper<T> {
 
-    static <Q> Wrapper<Q> wrap(Q value) {
-        class CWrapper<R> implements Wrapper<R>, Serializable {
+    static <Q> Wrapper<Q> of(Q value) {
+        class SimpleWrapper<R> implements Wrapper<R>, Serializable {
 
             private static final long serialVersionUID = 3L;
 
             private R value;
 
-            public CWrapper(R value) {
+            public SimpleWrapper(R value) {
                 this.value = value;
             }
 
@@ -39,9 +41,47 @@ public interface Wrapper<T> {
 
         }
         
-        return new CWrapper<>(value);
+        return new SimpleWrapper<>(value);
+    }
+
+    static <Q> Wrapper<Q> atomic(Q value) {
+        class AtomicWrapper<R> implements Wrapper<R>, Serializable {
+
+            private static final long serialVersionUID = 3L;
+
+            private final AtomicReference<R> ref;
+
+            public AtomicWrapper(R value) {
+                this.ref = new AtomicReference<>(value);
+            }
+
+            @Override
+            public R get() {
+                return ref.get();
+            }
+
+            @Override
+            public void set(R value) {
+                ref.set(value);
+            }
+
+            @Override
+            public R replace(R value) {
+                return ref.getAndSet(value);
+            }
+
+            @Override
+            public IClass<?> type() {
+                return IClass.typefor(ref);
+            }
+
+        }
+
+        return new AtomicWrapper<>(value);
     }
 
+    IClass<?> type();
+
     T get();
 
     void set(T value);
@@ -51,9 +91,15 @@ public interface Wrapper<T> {
         set(value);
         return prv;
     }
-    
-    IClass<?> type();
-    
+
+    default boolean isEmpty() {
+        return get() == null;
+    }
+
+    default boolean isPresent() {
+        return !isEmpty();
+    }
+
     @SuppressWarnings("unchecked")
     default <R> Wrapper<R> cast(Class<R> type) {
         if( !type().isEquivalent(IClass.typeinfo(type))) {

+ 31 - 11
assira.core/src/main/java/net/ranides/assira/io/PathUtils.java

@@ -6,15 +6,21 @@
  */
 package net.ranides.assira.io;
 
+import net.ranides.assira.collection.iterators.IterableUtils;
 import net.ranides.assira.collection.query.CQuery;
+import net.ranides.assira.functional.checked.CheckedSupplier;
 import net.ranides.assira.text.Wildcard;
 
 import java.io.File;
 import java.io.IOException;
 import java.net.URISyntaxException;
 import java.net.URL;
-import java.nio.file.*;
-import java.util.*;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Locale;
 
 /**
  *
@@ -22,6 +28,8 @@ import java.util.*;
  */
 public final class PathUtils {
 
+    private static final boolean WALKER_JDK7 = true;
+
     private static final boolean CASE_SENSITIVE_FILES = !new File( "a" ).equals( new File( "A" ) );
     
     private PathUtils() {
@@ -105,23 +113,35 @@ public final class PathUtils {
     }
 
     public static CQuery<Path> list(Path dir) {
-        try {
-            return CQuery.from().stream(() -> Files.list(dir));
-        } catch (IOException e) {
-            return CQuery.empty();
+        if(WALKER_JDK7) {
+            return listJDK7(dir);
+        } else {
+            return listJDK8(dir);
         }
     }
 
+    public static CQuery<Path> listJDK7(Path dir) {
+        return CQuery.from().iterable(() -> {
+            try {
+                return IterableUtils.safe(Files.newDirectoryStream(dir));
+            } catch (IOException e) {
+                return Collections.emptyList();
+            }
+        });
+    }
+
+    public static CQuery<Path> listJDK8(Path dir) {
+        return CQuery.from().stream(() -> Files.list(dir));
+    }
+
     public static CQuery<Path> list(Path dir, String wildcard) {
         return PathUtils.list(dir).filter(Wildcard.compile(wildcard).asPathFilter());
     }
 
     public static CQuery<Path> walk(Path dir) {
-        try {
-            return CQuery.from().stream(() -> Files.walk(dir, FileVisitOption.FOLLOW_LINKS));
-        } catch (IOException e) {
-            return CQuery.empty();
-        }
+        return list(dir).unfoldIf(Files::isDirectory, file -> {
+            return CQuery.builder().with(file).withQuery(PathUtils.walk(file)).build();
+        });
     }
 
     public static CQuery<Path> walk(Path dir, String wildcard) {

+ 5 - 5
assira.core/src/test/java/net/ranides/assira/generic/WrapperTest.java

@@ -18,7 +18,7 @@ public class WrapperTest {
     
     @Test
     public void testWrapper() {
-        Wrapper<String> wrapper = Wrapper.wrap("hello");
+        Wrapper<String> wrapper = Wrapper.of("hello");
         assertEquals("hello", wrapper.get());
         wrapper.set("world");
         assertEquals("world", wrapper.get());
@@ -26,10 +26,10 @@ public class WrapperTest {
     
     @Test
     public void testType() {
-        Wrapper<Number> w1 = Wrapper.wrap(14.1);
-        Wrapper<Number> w2 = Wrapper.wrap((Number)14.1);
-        Wrapper<String> w3 = Wrapper.wrap("Hello");
-        Wrapper<String> w4 = Wrapper.wrap(null);
+        Wrapper<Number> w1 = Wrapper.of(14.1);
+        Wrapper<Number> w2 = Wrapper.of((Number)14.1);
+        Wrapper<String> w3 = Wrapper.of("Hello");
+        Wrapper<String> w4 = Wrapper.of(null);
         
         assertEquals(IClass.typeinfo(Double.class), w1.type());
         assertEquals(IClass.typeinfo(Double.class), w2.type());

+ 12 - 0
assira.core/src/test/java/net/ranides/assira/io/PathUtilsTest.java

@@ -11,12 +11,16 @@ import static org.junit.Assert.assertEquals;
 
 import java.io.File;
 import java.net.MalformedURLException;
+import java.net.URI;
 import java.net.URL;
 import java.nio.file.FileSystemNotFoundException;
+import java.nio.file.Files;
 import java.nio.file.Path;
 import java.nio.file.Paths;
 import java.util.Arrays;
+import java.util.List;
 
+import net.ranides.assira.collection.query.CQuery;
 import org.junit.Assume;
 import org.junit.Test;
 
@@ -254,4 +258,12 @@ public class PathUtilsTest {
         return PathUtils.changeExtension(Paths.get(path), ext);
     }
 
+    @Test
+    public void walk() {
+        CQuery<Path> found = PathUtils.walk(Paths.get(".\\src")).fetch();
+
+        assertTrue(found.filter(Files::isDirectory).size() > 20);
+        assertTrue(found.discard(Files::isDirectory).size() > 200);
+        assertTrue(found.discard(Files::isDirectory).discard(p -> p.toString().endsWith(".java")).size() > 30);
+    }
 }

+ 36 - 25
assira.jdk11/pom.xml

@@ -1,5 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
     <modelVersion>4.0.0</modelVersion>
     <parent>
         <groupId>net.ranides</groupId>
@@ -12,7 +13,7 @@
 
     <name>${project.groupId}:${project.artifactId}</name>
     <description>assira: general purpose java library: release for JDK11</description>
-    
+
     <build>
         <plugins>
             <plugin>
@@ -34,32 +35,42 @@
                     </execution>
                 </executions>
             </plugin>
-            <plugin>
-                <groupId>org.codehaus.mojo</groupId>
-                <artifactId>build-helper-maven-plugin</artifactId>
-                <version>3.2.0</version>
-                <executions>
-                    <execution>
-                        <id>attach-artifacts</id>
-                        <phase>package</phase>
-                        <goals>
-                            <goal>attach-artifact</goal>
-                        </goals>
-                        <configuration>
-                            <artifacts>
-                                <artifact>
-                                    <file>../assira.core11/target/assira.core11-${project.version}-javadoc.jar</file>
-                                    <type>jar</type>
-                                    <classifier>javadoc</classifier>
-                                </artifact>
-                            </artifacts>
-                        </configuration>
-                    </execution>
-                </executions>
-            </plugin>
         </plugins>
     </build>
 
+    <profiles>
+        <profile>
+            <id>release</id>
+            <build>
+                <plugins>
+                    <plugin>
+                        <groupId>org.codehaus.mojo</groupId>
+                        <artifactId>build-helper-maven-plugin</artifactId>
+                        <version>3.2.0</version>
+                        <executions>
+                            <execution>
+                                <id>attach-artifacts</id>
+                                <phase>package</phase>
+                                <goals>
+                                    <goal>attach-artifact</goal>
+                                </goals>
+                                <configuration>
+                                    <artifacts>
+                                        <artifact>
+                                            <file>../assira.core11/target/assira.core11-${project.version}-javadoc.jar</file>
+                                            <type>jar</type>
+                                            <classifier>javadoc</classifier>
+                                        </artifact>
+                                    </artifacts>
+                                </configuration>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
+            </build>
+        </profile>
+    </profiles>
+
     <dependencies>
         <dependency>
             <groupId>${project.groupId}</groupId>