My question has to do with implementing the FlatApply class that I have created previously into this class called FilteringFlatApplyFunction. I cannot seem to implement the apply correctly because the static class continues to tell me it needs to be abstract and the #Override is not working the way it is supposed to. The end goal I am looking for is a way to use inheritance to borrow most of the functionality from the FlatApply class and implement the filter class. I have tried many different things but still can't get it, the predicate "pred" checks if the given predicate is true and if so, indicates to return the element, I thought that would implement FlatApply,I have been getting this error what seems like forever now. Thanks
Error:
FilteringFlatApplyFunction is not abstract and does not override abstract method apply(T) in FlatApplyFunction
where T is a type-variable:
T extends Object declared in class FilteringFlatApplyFunction
package iterators;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import iterators.Apply;
// Iterator that uses a Predicate to filter out elements from the input
public class Filter<T> extends FlatApply<T,T> {
public Filter(Predicate<T> p, Iterator<T> input) {
super(new FilteringFlatApplyFunction<T>(p),input);
}
// uses a Predicate to decide whether the input element is output or not
private static class FilteringFlatApplyFunction<T> implements FlatApplyFunction<T,T> {
private final Predicate pred;
public FilteringFlatApplyFunction(Predicate<T> p) {
this.pred = p;
}
#Override
public T apply(Iterator T) {
T result = null;
if((!T.hasNext())) throw new IllegalStateException();
if (pred.check(T.next()) == true){
result = (T) T.next();
}
else{
return (T) T;
}
}
Here is the FlatApply
package iterators;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.Queue;
public class FlatApply<InT,OutT> implements Iterator<OutT> {
private final Iterator<InT> input;
private final FlatApplyFunction<InT,OutT> f;
private final Queue<OutT> q;
public FlatApply(FlatApplyFunction<InT,OutT> f, Iterator<InT> input) {
this.input = input;
this.f = f;
this.q = new LinkedList<OutT>();
}
#Override
public boolean hasNext() {
if (!q.isEmpty()) {
return true;
}
else {
while(q.isEmpty() && input.hasNext()) {
List<OutT> result = f.apply(input.next());
q.addAll(result);
}
if(q.isEmpty()) return false;
else return true;
}
}
#Override
public OutT next() {
if((!hasNext())) throw new IllegalStateException();
return q.poll();
}
}
Here is the FlatApplyFunction
package iterators;
import java.util.List;
public interface FlatApplyFunction<InT, OutT> {
public List<OutT> apply(InT x);
}
Here is the apply class
package iterators;
import java.util.Iterator;
public class Apply<InT,OutT> implements Iterator<OutT> {
// The function that will be applied to each input element to make an output element
private final ApplyFunction<InT,OutT> f;
// The Iterator that this Apply object will get its input from
private final Iterator<InT> input;
public Apply(ApplyFunction<InT, OutT> f, Iterator<InT> input) {
this.input = input;
this.f = f;
}
#Override
public boolean hasNext() {
return input.hasNext();
}
#Override
public OutT next() {
if((!hasNext())) throw new IllegalStateException();
OutT result = f.apply(input.next());
return result;
}
}
The FlatApplyFunction interface says this:
public List<OutT> apply(InT x);
But the FilteringFlatApplyFunction implementation of that interface says this:
public T apply(Iterator T) {
The interface requires a List to be returned, by you're just returning T. Also, the parameter is required to be a T, but you have it as an Iterator.
Make those match, and this compiler error should go away.
Related
I have a problem that I cannot understand. First of all, I want to denote my structure:
I have a class named ClassMetadata. It is metadata about class values:
public class ClassMetadata<T extends Object> {
private int serviceId;
private int typeId;
private int revisionId;
#SuppressWarnings("rawtypes")
private Class clazz;
private ClassAttribute[] classAttributeArray;
private ClassMetadata() {
}
public ClassMetadata(int serviceId, Class<T> clazz) {
this();
this.serviceId = serviceId;
this.clazz = clazz;
}
#SuppressWarnings("unchecked")
public Class<T> getClazz() {
return clazz;
}
// getters and setters
}
Argument is a class that responsible from conveying class argument to a function:
public class Argument<T> {
private ClassMetadata<T> classMetadata;
private T sample;
public Argument(ClassMetadata<T> classMetadata, T sample) {
super();
this.classMetadata = classMetadata;
this.sample = sample;
}
// getters and setters
#SuppressWarnings({ "rawtypes", "unchecked" })
public boolean isAssignableFrom (Class classInstance) {
if (classInstance == null || this.classMetadata == null)
return false;
Class localClassValue = this.classMetadata.getClazz();
if (localClassValue == null)
return false;
return localClassValue.isAssignableFrom(classInstance);
}
}
I have an IRepositoryEntityFramework interface that manages database interactions of a project:
package authority.core.dataaccess.entityframework;
import java.util.List;
import javax.persistence.PersistenceException;
public interface IRepositoryEntityFramework<T> extends AutoCloseable {
void add(T value) throws PersistenceException;
void update(T value) throws PersistenceException;
void delete(T value) throws PersistenceException;
//commit
void save() throws PersistenceException ;
List<T> readList(SQL sqlClause) throws IllegalStateException, PersistenceException;
}
I have a IAuthorityDetailRepository that responsible specifically AuthorityDetail entity's database operations:
package authority.repository.conceptual;
import authority.core.dataaccess.entityframework.IRepositoryEntityFramework;
import authority.entities.concrete.AuthorityDetail;
public interface IAuthorityDetailRepository extends IRepositoryEntityFramework<AuthorityDetail> {
}
When I call the clauses below, isAssignableFrom returns false:
IAuthorityDetailRepository authorityDetailRepository = DependencyResolver.getSample().resolve(IAuthorityDetailRepository.class);
ClassMetadata<IAuthorityDetailRepository> authorityDetailRepositoryMetadata = new ClassMetadata(3,IAuthorityDetailRepository.class );
Argument<IAuthorityDetailRepository> authorityDetailRepositoryArgument = new Argument<IAuthorityDetailRepository>(authorityDetailRepositoryMetadata, authorityDetailRepository);
authorityDetailRepositoryArgument.isAssignableFrom(IRepositoryEntityFramework.class);
However, the clauses below return true;
#SuppressWarnings("rawtypes")
Class localClassValue = IAuthorityDetailRepository.class;
#SuppressWarnings("rawtypes")
Class argumentClassValue = IRepositoryEntityFramework.class;
localClassValue.isAssignableFrom( argumentClassValue);
What am I missing?
Thanks in advance.
Update-1
As Mr. Sergey Kalinichenko pointed out that Argument was missing, which implements the failing isAssignableFrom method.
As java.lang.Class#isAssignableFrom JavaDoc says:
Determines if the class or interface represented by this Class object is either the same as, or is a superclass or superinterface of, the class or interface represented by the specified Class parameter. It returns true if so; otherwise it returns false.
So, it returns true when called next way:
Base.class.isAssignableFrom(Child.class); // true
In your case, you're calling
IAuthorityDetailRepository.class.isAssignableFrom(IRepositoryEntityFramework.class)
Since IAuthorityDetailRepository is a child of IRepositoryEntityFramework, method returns false. If you intended different behaviour, just swap localClassValue and classInstance.
return classInstance.isAssignableFrom(localClassValue);
I am wrapping legacy code with some REST/jackson capabilities. In particular let's say I have an interface called LegacyObject
interface LegacyObject {
Integer getAge(); //could throw UnsupportedOperationException
String getDesc();
String getName(); //May throw RuntimeException
//about 200+ other methods.
}
The implementation is a legacy class and assume cannot be changed. My REST service has an endpoint which converts LegacyObject to JSON. The only problem being that this conversion fails fully whenever one of the getters throws an exception. What I need is a json like the below (assuming getAge(), getDesc() worked okay but getName() threw runtimeexception)
{"age": 40, "desc": "some description", "unsupportedFields": ["name"]}
Basically a way to capture all fields that failed serialization and then report at the end.
An interceptor like thing might work for me but if anyone has some code examples that would be great!
Since there are 200+ methods in the interface, below a solution with Proxies.
This code does not guarantee that the "getUnsupportedFields" method is called last (and thus still some exceptions may occur after)
public interface LegacyObject {
Integer getAge(); //could throw UnsupportedOperationException
String getDesc();
String getName(); //May throw RuntimeException
//about 200+ other methods.
}
import java.util.List;
public interface ExtendedLegacyObject extends LegacyObject {
List<String> getUnsupportedFields();
}
public class ExceptionLegacyObject implements LegacyObject {
#Override
public Integer getAge() {
return 40;
}
#Override
public String getDesc() {
return "some description";
}
#Override
public String getName() {
throw new RuntimeException();
}
}
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import org.apache.log4j.Logger;
public class LegacyObjectHandler implements InvocationHandler {
private static final Logger LOG = Logger.getLogger(LegacyObjectHandler.class);
private final List<String> unsupportedFields = new ArrayList<>();
private final LegacyObject legacyObject;
public LegacyObjectHandler(LegacyObject legacyObject) {
this.legacyObject = legacyObject;
}
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
if ("getUnsupportedFields".equals(method.getName())) {
return unsupportedFields;
} else {
try {
return method.invoke(legacyObject, args);
} catch (InvocationTargetException e) {
Throwable cause = e.getCause();
LOG.error(cause.getMessage(), cause);
unsupportedFields.add(method.getName());
Class<?> returnType = method.getReturnType();
if (returnType.isPrimitive()) {
if (returnType.isAssignableFrom(boolean.class)) {
return false;
} else if (returnType.isAssignableFrom(byte.class)) {
return (byte) 0;
} else if (returnType.isAssignableFrom(short.class)) {
return (short) 0;
} else if (returnType.isAssignableFrom(int.class)) {
return 0;
} else if (returnType.isAssignableFrom(long.class)) {
return 0L;
} else if (returnType.isAssignableFrom(float.class)) {
return 0F;
} else if (returnType.isAssignableFrom(double.class)) {
return 0D;
} else if (returnType.isAssignableFrom(char.class)) {
return (char) 0;
} else {
return null;
}
} else {
return null;
}
}
}
}
}
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import java.lang.reflect.Proxy;
public class JacksonTest {
public static void main(String[] args) throws JsonProcessingException {
ObjectMapper mapper = new ObjectMapper();
ExceptionLegacyObject exceptionLegacyObject = new ExceptionLegacyObject();
ExtendedLegacyObject proxy = (ExtendedLegacyObject) Proxy.newProxyInstance(
LegacyObject.class.getClassLoader(),
new Class[] { ExtendedLegacyObject.class },
new LegacyObjectHandler(exceptionLegacyObject)
);
System.out.println(mapper.writeValueAsString(proxy));
}
}
I used a variation of what #toongeorges suggested above. Here is a utility class which will do a "exception safe" convert to JSON. There will be an extra element in the returned JSON called "exceptionMessages" which contains the properties that failed json serialisation (or the method name if it is NOT a Java bean property). This can be changed to return a Pair of JsonNode one for the object and one for exceptionMessages if that style suits you better
import static java.util.stream.Collectors.toMap;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.stream.Stream;
import org.apache.commons.lang3.exception.ExceptionUtils;
public abstract class JsonUtils {
private static ObjectMapper mapper = new ObjectMapper();
/**
* This is only useful in the context of converting a object whose methods could throw exceptions
* into JSON. By default a "getName" method that throws an exception will fail the whole
* serialization however with this method such exceptions will be swallowed and there will be a
* "exceptionMessages" element in the returned JSON which contains all failures
*
* To be used only when working with legacy code.
*/
#SuppressWarnings("unchecked")
public static <U> ObjectNode exceptionSafeWrite(Class<U> sourceClazz, U obj, boolean prettyPrint) {
GuardedInvocationHandler handler = new GuardedInvocationHandler(obj);
U proxiedObject = (U) Proxy
.newProxyInstance(sourceClazz.getClassLoader(), new Class<?>[]{sourceClazz}, handler);
ObjectNode originalNode = mapper.convertValue(proxiedObject, ObjectNode.class);
ObjectNode exceptionMessages = mapper.convertValue(handler.getExceptionMessagesForJson(), ObjectNode.class);
originalNode.put("exceptionMessages", exceptionMessages);
return originalNode;
}
private static class GuardedInvocationHandler implements InvocationHandler {
private final Object target;
private Map<Method, Throwable> exceptionMap = new LinkedHashMap<>();
private Map<Method, String> methodToPropertyNameMap;
private GuardedInvocationHandler(Object target) {
this.target = target;
this.methodToPropertyNameMap = methodToPropertyNameMap(target.getClass());
}
private static Map<Method, String> methodToPropertyNameMap(Class<?> clazz) {
try {
return Stream.of(Introspector.getBeanInfo(clazz).getPropertyDescriptors())
.collect(toMap(d -> d.getReadMethod(), d -> d.getName()));
} catch (IntrospectionException e) {
throw new RuntimeException(e);
}
}
#Override
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
try {
return method.invoke(target, args);
} catch (InvocationTargetException e) {
exceptionMap.put(method, e.getTargetException());
return null;
} catch (Exception e) {
exceptionMap.put(method, e);
return null;
}
}
public Map<String, String> getExceptionMessagesForJson() {
return exceptionMap.entrySet().stream().collect(
toMap(e -> methodToPropertyNameMap.getOrDefault(e.getKey(), e.getKey().getName()),
e -> ExceptionUtils.getMessage(e.getValue())));
}
}
}
I need to create immutable copy of an object in runtime with Java. I made use of org.springframework.cglib.beans.ImmutableBean, which can create immutable copy of an object using CGLIB.
But the problem is that it provides "first-level" immutability: it disallows change of an input object's properties, but it allows to change inner objects (e.g. get collection and add an element to it or get inner object and modify it's parameters etc.)
So the question is: what's the correct way of creating deep (recursive) immutable copy of an object so that one can't change inner objects also (at any level of nesting)?
You may traverse the object tree and use CGLIB to make each object immutable by using interceptor which skips required methods. The tough part though is to determine all methods which modify the object's state - for each object in the tree.
package ut.test;
import static org.junit.Assert.assertEquals;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
import org.junit.Test;
import com.google.common.collect.Lists;
import net.sf.cglib.proxy.Enhancer;
import net.sf.cglib.proxy.MethodInterceptor;
import net.sf.cglib.proxy.MethodProxy;
public class MyTest {
public static class Inner {
private String data = "hello";
public Inner() {}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
}
#Override
public String toString() {
return data;
}
}
public static class Outer {
private List<Inner> list = Lists.newArrayList(new Inner());
public Outer() {}
public List<Inner> getList() {
return list;
}
public void setList(List<Inner> list) {
this.list = list;
}
}
public static class GetOnlyDelegatingMethodInterceptor implements MethodInterceptor {
private Object delegate;
public GetOnlyDelegatingMethodInterceptor(Object delegate) {
this.delegate = delegate;
}
#Override
public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {
if (method.getName().startsWith("get")) {
return makeImmutable(proxy.invoke(delegate, args));
}
if (method.getName().equals("toString")) {
return proxy.invoke(delegate, args);
}
if (method.getDeclaringClass().equals(Object.class)) {
return proxy.invoke(delegate, args);
}
// you may check for other methods here
// skip all others
return null;
}
}
private static Object makeImmutable(Object obj) {
if (obj == null) {
return obj;
}
Enhancer e = new Enhancer();
e.setSuperclass(obj.getClass());
e.setCallback(new GetOnlyDelegatingMethodInterceptor(obj));
return e.create();
}
#Test
public void testImmutable() {
Outer outerImmutable = (Outer) makeImmutable(new Outer());
// this is initial state
assertEquals(outerImmutable.getList().toString(), "[hello]");
// trying to set empty list
outerImmutable.setList(new ArrayList<>());
// but it's still the same
assertEquals(outerImmutable.getList().toString(), "[hello]");
// going deeper
outerImmutable.getList().get(0).setData("bye!");
// but still no changes
assertEquals(outerImmutable.getList().toString(), "[hello]");
}
}
You can use ImmutableProxy of the reflection-util library.
Example:
public class Inner
{
private String data = "hello";
// getters and setters
}
public class Outer
{
private List<Inner> list = Arrays.asList(new Inner());
// getters and setters
}
Outer outerImmutable = ImmutableProxy.create(new Outer());
Inner firstElement = outerImmutable.getList().get(0)
// this is initial state
assertThat(firstElement.getData()).isEqualTo("hello");
// throws UnsupportedOperationException
outerImmutable.setList(…);
// throws UnsupportedOperationException
firstElement.setData("bye!");
I am new to Java and I am trying to learn about the implementation of Iterable & Iterator.
import java.util.Iterator;
import java.util.LinkedList;
import java.util.NoSuchElementException;
public class ClassMates implements Iterable{
private String className;
private LinkedList<String> nameList;
public ClassMates(String className){
this.className = className;
this.nameList = new LinkedList<String>();
}
public void addName(String name){
nameList.add(name);
}
public LinkedList<String> getNameList() {
return nameList;
}
#Override
public Iterator<String> iterator() {
return new IteratorClass();
}
// Inner Class
private class IteratorClass implements Iterator<String>{
private int index;
public IteratorClass(){
this.index = 0;
}
#Override
public boolean hasNext() {
return index < nameList.size();
}
#Override
public String next() {
if(hasNext()){
int i = index;
index++;
System.out.println("This is "+ i);
return nameList.get(i);
}
throw new NoSuchElementException();
}
#Override
public void remove() {
throw new UnsupportedOperationException();
}
}
}
My question is: when I finish the implementation and try to apply the for-each to the "iterable" object, the compiler said types are not match.
Here is the main() execution for apply for-each:
public class Main {
public static void main(String[] args) {
ClassMates classMates = new ClassMates("03-01");
classMates.addName("Classmate 1");
classMates.addName("Classmate 2");
classMates.addName("Classmate 3");
classMates.addName("Classmate 4");
for(String name : classMates){
//HERE! the compiler report "String" is not match the return type of "classMates"
System.out.println(name);
}
}
Anyone can point me out the problem?
Thank you!!!
As your class will iterate through strings, you should specify the template type:
public class ClassMates implements Iterable<String>
I've looked through these forums to give me insight on how to create a ParallelIterator, but no luck. I want one Collection to be on one Thread and the another Collection to be on another Thread, but I wish to use a ThreadPool to do the job so that it can split up into parts equal to the amount of cores you have using Runtime.getRuntime().availableProcessors(). I also want to return an Actor rather than a Collection of Actors but the next() method is stopping me from doing so. Here is my code so far:
package com.atem.util;
public class ParallelIterator<Collection<Actor>> implements Iterator<Collection<Actor>> {
private Iterator<Actor> firstActorIterator;
private Iterator<Actor> secondActorIterator;
public ParallelIterator(final Collection<Actor> firstCollection, final Collection<Actor> secondCollection) {
this.firstActorIterator = firstCollection.iterator();
this.secondActorIterator = secondCollection.iterator();
}
#Override
public boolean hasNext() {
return this.getFirstActorIterator().hasNext() && this.getSecondActorIterator().hasNext();
}
#Override
public Collection<Actor> next() {
return new ParallelCollection(this.getFirstActorIterator().next(), this.getSecondActorIterator().next());
}
#Override
public void remove() {
this.getFirstActorIterator().remove();
this.getSecondActorIterator().remove();
}
public Iterator<Actor> getFirstIterator() {
return this.firstIterator;
}
public Iterator<Actor> getSecondIterator() {
return this.secondIterator;
}
public ParallelCollection<Actor> getParallelActorCollection() {
return this.parallelActorCollection;
}
}
I could change the next() method to return an Actor but then the ParallelCollection would get in the way. If there's anything else you wish to know, please let me know. Help is very much appreciated. Also, I'm somewhat of a beginner so if you could explain it in simple terms that would be great. Thanks!
I agree with Louis's comment that you shouldn't try to write something like this on your own, but I wrote something that might help you get started.
WARNING: This code was not thoroughly tested:
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
public class Parallel {
//modify the arg for the number of threads you want to use
final static ExecutorService service = Executors.newFixedThreadPool(2);
public static interface Operation<R, E> {
public R perform(E input);
}
public static <R, E> List<R> forEach(final Iterable<E> inputs,
final Operation<R,E> operation) {
final List<Future<R>> futures = Collections.synchronizedList(new ArrayList<Future<R>>());
for (final E input : inputs) {
final Callable<R> callable = new Callable<R>() {
public R call() throws Exception {
return operation.perform(input);
}
};
futures.add(service.submit(callable));
}
final List<R> outputs = new ArrayList<>();
try {
for (final Future<R> future : futures) {
outputs.add(future.get());
}
}
catch (Exception e) {
e.printStackTrace();
}
return outputs;
}
}