package ma.glasnost.orika.test.interceptor;

import java.math.BigDecimal;

import ma.glasnost.orika.CustomFilter;
import ma.glasnost.orika.MapperFacade;
import ma.glasnost.orika.MapperFactory;
import ma.glasnost.orika.MappingContext;
import ma.glasnost.orika.metadata.Type;
import ma.glasnost.orika.test.MappingUtil;

import org.junit.Assert;
import org.junit.Test;

public class FilterTestCase {
    
    @Test
    public void testFiltering() {
        
        MapperFactory factory = MappingUtil.getMapperFactory();
        factory.classMap(Source.class, Destination.class).byDefault().register();
        factory.registerFilter(new SecurityFilter());
        
        MapperFacade mapper = factory.getMapperFacade();
        
        Source source = new Source();
        source.name = new SourceName();
        source.name.first = "Joe";
        source.name.last = "Smith";
        source.id = 2L;
        source.age = 35;
        source.cost = 12.34d;
        source.creditCardNumber = "5432109876543210";
        
        Destination dest = mapper.map(source, Destination.class);
        
        Assert.assertEquals(source.name.first, dest.name.first);
        Assert.assertEquals(source.name.last, dest.name.last);
        Assert.assertNull(dest.age);
        Assert.assertEquals("************3210", dest.creditCardNumber);
        
    }
    
   
    public static class SecurityFilter extends CustomFilter<Object, Object> {

        private final String MASK = "*************";
        
        public boolean filtersSource() {
            return false;
        }

        public boolean filtersDestination() {
            return true;
        }

        public boolean shouldMap(Type<?> sourceType, String sourceName, Type<?> destType, String destName, MappingContext mappingContext) {
            if ("age".equals(sourceName)) {
                return false;
            }
            return true;
        }

        public <D> D filterDestination(D destinationValue, Type<?> sourceType, String sourceName, Type<D> destType, String destName,
                MappingContext mappingContext) {
            if ("creditCardNumber".equals(sourceName)) {
                String cardMask = (String)destinationValue;
                destinationValue = (D) (MASK.substring(0, cardMask.length()-4) + cardMask.substring(cardMask.length() - 4));
            }
            return destinationValue;
            
        }

        public <S> S filterSource(S sourceValue, Type<S> sourceType, String sourceName, Type<?> destType, String destName,
                MappingContext mappingContext) {
            return sourceValue;
        }
    }
    
    public static class Source {
        public SourceName name;
        public Long id;
        public int age;
        public double cost;
        public String creditCardNumber;
    }
    
    public static class SourceName {
        public String first;
        public String last;
    }
    
    public static class Destination {
        public DestinationName name;
        public Long id;
        public Integer age;
        public BigDecimal cost;
        public String creditCardNumber;
    }
    
    public static class DestinationName {
        public String first;
        public String last;
    }
}

@@ -28,19 +28,15 @@
 est.
-interceptor
+filters
 ;%0A%0Ai
@@ -1342,20 +1342,16 @@
  %7D%0A    %0A
-   %0A
     publ
@@ -1420,16 +1420,24 @@
 ject%3E %7B%0A
+        
 %0A       
@@ -1560,32 +1560,40 @@
 alse;%0A        %7D%0A
+        
 %0A        public 
@@ -1650,32 +1650,40 @@
 true;%0A        %7D%0A
+        
 %0A        public 
@@ -1700,16 +1700,22 @@
 ouldMap(
+final 
 Type%3C?%3E 
@@ -1717,32 +1717,38 @@
 e%3C?%3E sourceType,
+ final
  String sourceNa
@@ -1742,32 +1742,38 @@
 ring sourceName,
+ final
  Type%3C?%3E destTyp
@@ -1766,32 +1766,38 @@
 ype%3C?%3E destType,
+ final
  String destName
@@ -1797,16 +1797,38 @@
 estName,
+%0A                final
  Mapping
@@ -1968,32 +1968,40 @@
 true;%0A        %7D%0A
+        
 %0A        public 
@@ -2039,24 +2039,30 @@
 nationValue,
+ final
  Type%3C?%3E sou
@@ -2061,32 +2061,38 @@
 e%3C?%3E sourceType,
+ final
  String sourceNa
@@ -2090,24 +2090,30 @@
  sourceName,
+ final
  Type%3CD%3E des
@@ -2110,32 +2110,54 @@
 ype%3CD%3E destType,
+%0A                final
  String destName
@@ -2157,32 +2157,22 @@
 estName,
-%0A               
+ final
  Mapping
@@ -2296,16 +2296,17 @@
 (String)
+ 
 destinat
@@ -2390,17 +2390,19 @@
 length()
--
+ - 
 4) + car
@@ -2516,16 +2516,24 @@
       %7D%0A
+        
 %0A       
@@ -2559,16 +2559,22 @@
 rSource(
+final 
 S source
@@ -2579,16 +2579,22 @@
 ceValue,
+ final
  Type%3CS%3E
@@ -2601,24 +2601,30 @@
  sourceType,
+ final
  String sour
@@ -2630,16 +2630,22 @@
 rceName,
+ final
  Type%3C?%3E
@@ -2654,16 +2654,38 @@
 estType,
+%0A                final
  String 
@@ -2693,32 +2693,22 @@
 estName,
-%0A               
+ final
  Mapping

Fix package of FilterTestCase