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

io.dstream.function.DStreamToStreamAdapterFunction Maven / Gradle / Ivy

The newest version!
/**
 * 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.
 */
package io.dstream.function;

import java.lang.reflect.Method;
import java.util.Comparator;
import java.util.Map;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import io.dstream.DStream;
import io.dstream.Ops;
import io.dstream.SerializableStreamAssets.SerFunction;
import io.dstream.SerializableStreamAssets.SerPredicate;
import io.dstream.utils.Assert;
import io.dstream.utils.ReflectionUtils;

/**
 * An implementation of {@link SerFunction} which will translate Stream-like
 * invocations on the {@link DStream} to {@link Stream} operations.
 * It is created for each invocation of operations that match operations defined on {@link Stream}.
 * At the time of writing this javadoc these operations are - map, flatMap and filter.
 */
public class DStreamToStreamAdapterFunction implements SerFunction, Stream>{
	private static final long serialVersionUID = 6836233233261184905L;
	
	private static final Map supportedOperations = buildSupportedOperations(Stream.of(
			Ops.flatMap, 
			Ops.map, 
			Ops.filter, 
			Ops.distinct,
			Ops.min,
			Ops.max,
			Ops.sorted));
	
	private final String streamOperationName;
	
	private final Object streamOperation;
	
	/**
	 * Constructs this function.
	 * 
	 * @param streamOperationName the name of the target operation.
	 * @param streamOperation target operation. The reason why it's an Object is because it could be 
	 * 		{@link SerFunction} or {@link SerPredicate}.
	 */
	public DStreamToStreamAdapterFunction(String streamOperationName, Object streamOperation){
		Assert.notEmpty(streamOperationName, "'streamOperationName' must not be null or empty");

		if (!supportedOperations.containsKey(Ops.valueOf(streamOperationName))){
			throw new IllegalArgumentException("Operation '" + streamOperationName + "' is not supported");
		}
		
		this.streamOperation = streamOperation;
		this.streamOperationName = streamOperationName;
	}

	/**
	 * 
	 */
	@Override
	public Stream apply(Stream streamIn) {
		try {
			Method m = supportedOperations.get(Ops.valueOf(this.streamOperationName));
			Stream result;
			if (m.getName().equals(Ops.distinct.name())){
				result = ((Stream) m.invoke(streamIn));
			}
			else {
				Object tRes = m.invoke(streamIn, this.streamOperation);
				// min/max will have Optional result
				result = tRes instanceof Optional ? Stream.of(((Optional)tRes).get()) : (Stream) tRes;
			}
			return result;
		} 
		catch (Exception e) {
			throw new IllegalStateException("Operation '" + this.streamOperationName + "' is not supported.", e);
		}
	}
	
	/**
	 * 
	 */
	private static Map buildSupportedOperations(Stream operationsStream){
		return operationsStream
				.collect(Collectors.toMap(op -> op, op -> {
					if (op.equals(Ops.sorted)){
						return ReflectionUtils.findMethod(Ops.sorted.name(), Stream.class, Stream.class, Comparator.class);
					}
					else {
						return ReflectionUtils.findSingleMethod(op.name(), Stream.class);
					}
				} ));
	}
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy