| package org.apache.maven.surefire.booter; |
| |
| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| import java.util.Collections; |
| import java.util.Iterator; |
| |
| import org.apache.maven.surefire.api.booter.MasterProcessChannelEncoder; |
| import org.apache.maven.surefire.api.provider.SurefireProvider; |
| import org.apache.maven.surefire.api.util.CloseableIterator; |
| import org.apache.maven.surefire.api.util.TestsToRun; |
| |
| import static org.apache.maven.surefire.api.util.ReflectionUtils.loadClass; |
| |
| /** |
| * A variant of TestsToRun that is provided with test class names |
| * from an {@code System.in}. |
| * The method {@link #iterator()} returns an Iterator that blocks on calls to |
| * {@link Iterator#hasNext()} or {@link Iterator#next()} until new classes are available, or no more |
| * classes will be available or the internal stream is closed. |
| * The iterator can be used only in one Thread and it is the thread which executes |
| * {@link SurefireProvider provider implementation}. |
| * |
| * @author Andreas Gudian |
| * @author Tibor Digana |
| */ |
| final class LazyTestsToRun |
| extends TestsToRun |
| { |
| private final MasterProcessChannelEncoder eventChannel; |
| private final CommandReader commandReader; |
| |
| /** |
| * C'tor |
| * |
| * @param eventChannel the output stream to use when requesting new new tests |
| */ |
| LazyTestsToRun( MasterProcessChannelEncoder eventChannel, CommandReader commandReader ) |
| { |
| super( Collections.<Class<?>>emptySet() ); |
| this.eventChannel = eventChannel; |
| this.commandReader = commandReader; |
| } |
| |
| private final class BlockingIterator |
| implements Iterator<Class<?>> |
| { |
| private final Iterator<String> it = commandReader.getIterableClasses( eventChannel ).iterator(); |
| |
| @Override |
| public boolean hasNext() |
| { |
| return it.hasNext(); |
| } |
| |
| @Override |
| public Class<?> next() |
| { |
| return findClass( it.next() ); |
| } |
| |
| @Override |
| public void remove() |
| { |
| throw new UnsupportedOperationException(); |
| } |
| } |
| |
| /** |
| * @return test classes which have been retrieved by {@link LazyTestsToRun#iterator()}. |
| */ |
| @Override |
| public Iterator<Class<?>> iterated() |
| { |
| return newWeakIterator(); |
| } |
| |
| /** |
| * The iterator can be used only in one Thread. |
| * {@inheritDoc} |
| * @see TestsToRun#iterator() |
| * */ |
| @Override |
| public Iterator<Class<?>> iterator() |
| { |
| return new BlockingIterator(); |
| } |
| |
| /* (non-Javadoc) |
| * {@inheritDoc} |
| * @see org.apache.maven.surefire.util.TestsToRun#toString() |
| */ |
| @Override |
| public String toString() |
| { |
| return "LazyTestsToRun"; |
| } |
| |
| /* (non-Javadoc) |
| * {@inheritDoc} |
| * @see org.apache.maven.surefire.util.TestsToRun#allowEagerReading() |
| */ |
| @Override |
| public boolean allowEagerReading() |
| { |
| return false; |
| } |
| |
| private static Class<?> findClass( String clazz ) |
| { |
| return loadClass( Thread.currentThread().getContextClassLoader(), clazz ); |
| } |
| |
| /** |
| * @return snapshot of tests upon constructs of {@link CommandReader#iterated() iterator}. |
| * Therefore weakly consistent while {@link LazyTestsToRun#iterator()} is being iterated. |
| */ |
| private Iterator<Class<?>> newWeakIterator() |
| { |
| final Iterator<String> it = commandReader.iterated(); |
| return new CloseableIterator<Class<?>>() |
| { |
| @Override |
| protected boolean isClosed() |
| { |
| return LazyTestsToRun.this.isFinished(); |
| } |
| |
| @Override |
| protected boolean doHasNext() |
| { |
| return it.hasNext(); |
| } |
| |
| @Override |
| protected Class<?> doNext() |
| { |
| return findClass( it.next() ); |
| } |
| |
| @Override |
| protected void doRemove() |
| { |
| } |
| |
| @Override |
| public void remove() |
| { |
| throw new UnsupportedOperationException( "unsupported remove" ); |
| } |
| }; |
| } |
| } |