// Path: src/main/java/org/javiermf/features/models/Feature.java
// @Entity
// public class Feature {
// 
//     @Id
//     @GeneratedValue
//     Long id;
// 
//     @Column(nullable = false)
//     String name;
// 
//     @Column
//     String description;
// 
//     @JsonIgnore
//     @ManyToOne
//     Product product;
// 
//     @JsonIgnore
//     @ManyToMany(mappedBy = "activedFeatures")
//     Set<ProductConfiguration> inConfigurations;
// 
//     public static Feature withName(Product product, String featureName) {
//         Feature feature = new Feature();
//         feature.name = featureName;
//         feature.product = product;
//         return feature;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public String getDescription() {
//         return description;
//     }
// 
//     public void setDescription(String description) {
//         this.description = description;
//     }
// 
//     public Product getProduct() {
//         return product;
//     }
// 
//     public void setProduct(Product product) {
//         this.product = product;
//     }
// 
//     public Long getId() {
//         return id;
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (!(o instanceof Feature)) return false;
// 
//         Feature feature = (Feature) o;
// 
//         if (!name.equals(feature.name)) return false;
//         return product.equals(feature.product);
// 
//     }
// 
//     @Override
//     public int hashCode() {
//         int result = name.hashCode();
//         result = 31 * result + product.hashCode();
//         return result;
//     }
// }
// 
// Path: src/main/java/org/javiermf/features/models/ProductConfiguration.java
// @Entity
// public class ProductConfiguration {
// 
//     @Id
//     @GeneratedValue
//     Long id;
// 
//     @Column(nullable = false)
//     String name;
// 
//     @Column
//     Boolean valid = true;
// 
//     @JsonIgnore
//     @ManyToOne
//     Product product;
// 
//     @ManyToMany(fetch = FetchType.EAGER)
//     Set<Feature> activedFeatures = new HashSet<Feature>();
// 
//     public Set<Feature> getActivedFeatures() {
//         return activedFeatures;
//     }
// 
//     public Set<String> availableFeatures() {
//         return collectFeatureNames(product.getProductFeatures());
//     }
// 
//     private Set<String> collectFeatureNames(Set<Feature> featuresSet) {
//         Set<String> features = new HashSet<String>();
//         for (Feature feature : featuresSet) {
//             features.add(feature.name);
//         }
// 
//         return features;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public Product getProduct() {
//         return product;
//     }
// 
//     public void setProduct(Product product) {
//         this.product = product;
//     }
// 
//     public Set<String> activedFeatures() {
//         return collectFeatureNames(activedFeatures);
//     }
// 
//     public Boolean isValid() {
//         return valid;
//     }
// 
//     public void setValid(Boolean valid) {
//         this.valid = valid;
//     }
// 
//     public void active(Feature feature) {
//         activedFeatures.add(feature);
// 
//     }
// 
//     public void deactive(Feature feature) {
//         activedFeatures.remove(feature);
//     }
// 
//     public void active(String featureName) {
//         Feature feature = product.findProductFeatureByName(featureName);
//         active(feature);
//     }
// 
//     public void deactive(String featureName) {
//         Feature feature = product.findProductFeatureByName(featureName);
//         deactive(feature);
//     }
// 
//     public boolean hasActiveFeature(String featureName) {
//         return activedFeatures().contains(featureName);
//     }
// }


import com.mysema.query.jpa.impl.JPAQuery;
import org.javiermf.features.models.Feature;
import org.javiermf.features.models.ProductConfiguration;
import org.javiermf.features.models.QProduct;
import org.javiermf.features.models.QProductConfiguration;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;
package org.javiermf.features.daos;



@Repository
public class ProductsConfigurationsDAO {

    @PersistenceContext
    private EntityManager entityManager;

    QProductConfiguration qProductConfiguration = QProductConfiguration.productConfiguration;
    QProduct qProduct = QProduct.product;

    public List<ProductConfiguration> findByProductName(String productName) {


        JPAQuery query = new JPAQuery(entityManager);
        query.from(qProductConfiguration)
                .innerJoin(qProductConfiguration.product, qProduct)
                .where(qProduct.name.eq(productName));
        return query.list(qProductConfiguration);
    }

    public ProductConfiguration findByNameAndProductName(String productName, String configurationName) {
        QProduct qProduct = QProduct.product;


        JPAQuery query = new JPAQuery(entityManager);
        query.from(qProductConfiguration)
                .innerJoin(qProductConfiguration.product, qProduct)
                .where(qProduct.name.eq(productName)
// Path: src/main/java/org/javiermf/features/models/Feature.java
// @Entity
// public class Feature {
// 
//     @Id
//     @GeneratedValue
//     Long id;
// 
//     @Column(nullable = false)
//     String name;
// 
//     @Column
//     String description;
// 
//     @JsonIgnore
//     @ManyToOne
//     Product product;
// 
//     @JsonIgnore
//     @ManyToMany(mappedBy = "activedFeatures")
//     Set<ProductConfiguration> inConfigurations;
// 
//     public static Feature withName(Product product, String featureName) {
//         Feature feature = new Feature();
//         feature.name = featureName;
//         feature.product = product;
//         return feature;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public String getDescription() {
//         return description;
//     }
// 
//     public void setDescription(String description) {
//         this.description = description;
//     }
// 
//     public Product getProduct() {
//         return product;
//     }
// 
//     public void setProduct(Product product) {
//         this.product = product;
//     }
// 
//     public Long getId() {
//         return id;
//     }
// 
//     @Override
//     public boolean equals(Object o) {
//         if (this == o) return true;
//         if (!(o instanceof Feature)) return false;
// 
//         Feature feature = (Feature) o;
// 
//         if (!name.equals(feature.name)) return false;
//         return product.equals(feature.product);
// 
//     }
// 
//     @Override
//     public int hashCode() {
//         int result = name.hashCode();
//         result = 31 * result + product.hashCode();
//         return result;
//     }
// }
// 
// Path: src/main/java/org/javiermf/features/models/ProductConfiguration.java
// @Entity
// public class ProductConfiguration {
// 
//     @Id
//     @GeneratedValue
//     Long id;
// 
//     @Column(nullable = false)
//     String name;
// 
//     @Column
//     Boolean valid = true;
// 
//     @JsonIgnore
//     @ManyToOne
//     Product product;
// 
//     @ManyToMany(fetch = FetchType.EAGER)
//     Set<Feature> activedFeatures = new HashSet<Feature>();
// 
//     public Set<Feature> getActivedFeatures() {
//         return activedFeatures;
//     }
// 
//     public Set<String> availableFeatures() {
//         return collectFeatureNames(product.getProductFeatures());
//     }
// 
//     private Set<String> collectFeatureNames(Set<Feature> featuresSet) {
//         Set<String> features = new HashSet<String>();
//         for (Feature feature : featuresSet) {
//             features.add(feature.name);
//         }
// 
//         return features;
//     }
// 
//     public String getName() {
//         return name;
//     }
// 
//     public void setName(String name) {
//         this.name = name;
//     }
// 
//     public Product getProduct() {
//         return product;
//     }
// 
//     public void setProduct(Product product) {
//         this.product = product;
//     }
// 
//     public Set<String> activedFeatures() {
//         return collectFeatureNames(activedFeatures);
//     }
// 
//     public Boolean isValid() {
//         return valid;
//     }
// 
//     public void setValid(Boolean valid) {
//         this.valid = valid;
//     }
// 
//     public void active(Feature feature) {
//         activedFeatures.add(feature);
// 
//     }
// 
//     public void deactive(Feature feature) {
//         activedFeatures.remove(feature);
//     }
// 
//     public void active(String featureName) {
//         Feature feature = product.findProductFeatureByName(featureName);
//         active(feature);
//     }
// 
//     public void deactive(String featureName) {
//         Feature feature = product.findProductFeatureByName(featureName);
//         deactive(feature);
//     }
// 
//     public boolean hasActiveFeature(String featureName) {
//         return activedFeatures().contains(featureName);
//     }
// }


// Path: src/main/java/org/javiermf/features/daos/ProductsConfigurationsDAO.java
import com.mysema.query.jpa.impl.JPAQuery;
import org.javiermf.features.models.Feature;
import org.javiermf.features.models.ProductConfiguration;
import org.javiermf.features.models.QProduct;
import org.javiermf.features.models.QProductConfiguration;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import java.util.List;

package org.javiermf.features.daos;



@Repository
public class ProductsConfigurationsDAO {

    @PersistenceContext
    private EntityManager entityManager;

    QProductConfiguration qProductConfiguration = QProductConfiguration.productConfiguration;
    QProduct qProduct = QProduct.product;

    public List<ProductConfiguration> findByProductName(String productName) {


        JPAQuery query = new JPAQuery(entityManager);
        query.from(qProductConfiguration)
                .innerJoin(qProductConfiguration.product, qProduct)
                .where(qProduct.name.eq(productName));
        return query.list(qProductConfiguration);
    }

    public ProductConfiguration findByNameAndProductName(String productName, String configurationName) {
        QProduct qProduct = QProduct.product;


        JPAQuery query = new JPAQuery(entityManager);
        query.from(qProductConfiguration)
                .innerJoin(qProductConfiguration.product, qProduct)
                .where(qProduct.name.eq(productName)
                        .and(qProductConfiguration.name.eq(configurationName)));