/**
 *
 * Copyright (c) 2006-2015, Speedment, Inc. All Rights Reserved.
 *
 * Licensed 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 com.speedment.internal.core.field.trait;

import com.speedment.internal.core.field.predicate.impl.string.ContainsPredicate;
import com.speedment.internal.core.field.predicate.impl.string.EndsWithPredicate;
import com.speedment.internal.core.field.predicate.impl.string.EqualIgnoreCasePredicate;
import com.speedment.internal.core.field.predicate.impl.string.IsEmptyPredicate;
import com.speedment.internal.core.field.predicate.impl.string.IsNotEmptyPredicate;
import com.speedment.internal.core.field.predicate.impl.string.NotEqualIgnoreCasePredicate;
import com.speedment.internal.core.field.predicate.impl.string.StartsWithPredicate;
import com.speedment.field.trait.StringFieldTrait;
import com.speedment.field.predicate.StringSpeedmentPredicate;
import com.speedment.field.trait.FieldTrait;
import com.speedment.field.trait.ReferenceFieldTrait;
import com.speedment.internal.core.field.predicate.impl.string.AlwaysFalseStringPredicate;
import com.speedment.internal.core.field.predicate.impl.string.AlwaysTrueStringPredicate;
import com.speedment.internal.core.field.predicate.impl.string.IsNotNullStringPredicate;
import com.speedment.internal.core.field.predicate.impl.string.IsNullStringPredicate;

/**
 * @param <ENTITY> the entity type
 * @author pemi
 */
public class StringFieldTraitImpl<ENTITY> implements StringFieldTrait<ENTITY> {

    private final FieldTrait field;
    private final ReferenceFieldTrait<ENTITY, String> referenceField;
    private final StringSpeedmentPredicate<ENTITY> alwaysFalsePredicate;
    private final StringSpeedmentPredicate<ENTITY> isNullPredicate;
    private final StringSpeedmentPredicate<ENTITY> isNotNullPredicate;

    public StringFieldTraitImpl(FieldTrait field, ReferenceFieldTrait<ENTITY, String> referenceField) {
        this.field = field;
        this.referenceField = referenceField;
        this.alwaysFalsePredicate = new AlwaysFalseStringPredicate<>(field, referenceField);
        this.isNullPredicate = new IsNullStringPredicate<>(field, referenceField);
        this.isNotNullPredicate = new IsNotNullStringPredicate<>(field, referenceField);
    }

    @Override
    public StringSpeedmentPredicate<ENTITY> equalIgnoreCase(String value) {
        if (value == null) {
            return isNullPredicate;
        }
        return new EqualIgnoreCasePredicate<>(field, referenceField, value);
    }

    @Override
    public StringSpeedmentPredicate<ENTITY> notEqualIgnoreCase(String value) {
        if (value == null) {
            return isNotNullPredicate;
        }
        return new NotEqualIgnoreCasePredicate<>(field, referenceField, value);
    }

    @Override
    public StringSpeedmentPredicate<ENTITY> startsWith(String value) {
        if (value == null) {
            return alwaysFalsePredicate;
        }
        return new StartsWithPredicate<>(field, referenceField, value);
    }

    @Override
    public StringSpeedmentPredicate<ENTITY> endsWith(String value) {
        if (value == null) {
            return alwaysFalsePredicate;
        }
        return new EndsWithPredicate<>(field, referenceField, value);
    }

    @Override
    public StringSpeedmentPredicate<ENTITY> contains(String value) {
        if (value == null) {
            return alwaysFalsePredicate;
        }
        return new ContainsPredicate<>(field, referenceField, value);
    }

    @Override
    public StringSpeedmentPredicate<ENTITY> isEmpty() {
        return new IsEmptyPredicate<>(field, referenceField);
    }

    @Override
    public StringSpeedmentPredicate<ENTITY> isNotEmpty() {
        return new IsNotEmptyPredicate<>(field, referenceField);
    }

    private StringSpeedmentPredicate<ENTITY> newAlwaysFalsePredicate() {
        return new AlwaysFalseStringPredicate<>(field, referenceField);
    }

    private StringSpeedmentPredicate<ENTITY> newAlwaysTruePredicate() {
        return new AlwaysTrueStringPredicate<>(field, referenceField);
    }

    private StringSpeedmentPredicate<ENTITY> newIsNullPredicate() {
        return new IsNullStringPredicate<>(field, referenceField);
    }

    private StringSpeedmentPredicate<ENTITY> newIsNotNullPredicate() {
        return new IsNotNullStringPredicate<>(field, referenceField);
    }

}

@@ -2088,662 +2088,185 @@
 ld;%0A
-    private final StringSpeedmentPredicate%3CENTITY%3E alwaysFalsePredicate;%0A    private final StringSpeedmentPredicate%3CENTITY%3E isNullPredicate;%0A    private final StringSpeedmentPredicate%3CENTITY%3E isNotNullPredicate;%0A%0A    public StringFieldTraitImpl(FieldTrait field, ReferenceFieldTrait%3CENTITY, String%3E referenceField) %7B%0A        this.field = field;%0A        this.referenceField = referenceField;%0A        this.alwaysFalsePredicate = new AlwaysFalseStringPredicate%3C%3E(field, referenceField);%0A        this.isNullPredicate = new IsNullStringPredicate%3C%3E(field, referenceField);%0A        this.isNotNullPredicate = new IsNotNullStringPredicate%3C%3E(field, referenceField)
+%0A    public StringFieldTraitImpl(FieldTrait field, ReferenceFieldTrait%3CENTITY, String%3E referenceField) %7B%0A        this.field = field;%0A        this.referenceField = referenceField
 ;%0A  
@@ -2408,17 +2408,20 @@
  return 
-i
+newI
 sNullPre
@@ -2418,32 +2418,34 @@
 wIsNullPredicate
+()
 ;%0A        %7D%0A    
@@ -2665,17 +2665,20 @@
  return 
-i
+newI
 sNotNull
@@ -2678,32 +2678,34 @@
 NotNullPredicate
+()
 ;%0A        %7D%0A    
@@ -2912,33 +2912,36 @@
          return 
-a
+newA
 lwaysFalsePredic
@@ -2935,32 +2935,34 @@
 ysFalsePredicate
+()
 ;%0A        %7D%0A    
@@ -3159,33 +3159,36 @@
          return 
-a
+newA
 lwaysFalsePredic
@@ -3182,32 +3182,34 @@
 ysFalsePredicate
+()
 ;%0A        %7D%0A    
@@ -3412,17 +3412,20 @@
  return 
-a
+newA
 lwaysFal
@@ -3435,16 +3435,18 @@
 redicate
+()
 ;%0A      

Fix static predicate bug