// Path: src/main/java/org/javiermf/features/models/constraints/FeatureConstraint.java
// @Entity
// @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
// public abstract class FeatureConstraint {
// 
//     @Id
//     @GeneratedValue(strategy = GenerationType.SEQUENCE)
//     Long id;
// 
//     @ManyToOne
//     Product forProduct;
// 
//     public abstract String getType();
// 
//     public abstract EvaluationResult evaluateConfiguration(EvaluationResult currentResult, ProductConfiguration configuration);
// 
//     public Long getId() {
//         return id;
//     }
// 
//     public void setId(Long id) {
//         this.id = id;
//     }
// 
//     public void setForProduct(Product forProduct) {
//         this.forProduct = forProduct;
//     }
// }
// 
// Path: src/main/java/org/javiermf/features/services/ProductsService.java
// @Service
// public class ProductsService {
// 
//     @Autowired
//     ProductsDAO productsDAO;
// 
//     @Autowired
//     ProductsConfigurationsDAO productsConfigurationsDAO;
// 
// 
//     public List<String> getAllProductNames() {
//         List<String> allProducts = new ArrayList<String>();
// 
//         for (Product product : productsDAO.findAll()) {
//             allProducts.add(product.getName());
//         }
// 
//         return allProducts;
//     }
// 
//     public Product findByName(String productName) {
//         return productsDAO.findByName(productName);
//     }
// 
//     public void deleteByName(String productName) {
//         productsConfigurationsDAO.deleteConfigurationsForProduct(productName);
//         productsDAO.deleteConstraintsForProduct(productName);
//         productsDAO.deleteByName(productName);
//     }
// 
//     public void add(String productName) {
//         Product product = new Product();
//         product.setName(productName);
//         productsDAO.insert(product);
//     }
// 
//     public Set<Feature> getFeaturesForProduct(String productName) {
//         Product product = findByName(productName);
//         return product.getProductFeatures();
//     }
// 
//     public void addFeatureToProduct(String productName, String featureName, String featureDescription) {
//         Product product = findByName(productName);
//         if (product.hasFeatureNamed(featureName)) {
//             throw new DuplicatedObjectException(featureName);
//         }
//         Feature feature = Feature.withName(product, featureName);
//         feature.setDescription(featureDescription);
//         productsDAO.insertFeature(feature);
//     }
// 
//     @Transactional
//     public Feature updateFeatureOfProduct(String productName, String featureName, String featureDescription) {
//         Product product = productsDAO.findByName(productName);
//         Feature feature = product.findProductFeatureByName(featureName);
//         feature.setDescription(featureDescription);
//         return feature;
//     }
// 
//     @Transactional
//     public void deleteFeatureOfProduct(String productName, String featureName) {
//         Product product = productsDAO.findByName(productName);
//         Feature feature = product.findProductFeatureByName(featureName);
// 
//         for (ProductConfiguration productConfiguration : productsConfigurationsDAO.findConfigurationsWithFeatureActive(feature)) {
//             productConfiguration.getActivedFeatures().remove(feature);
//         }
// 
//         productsDAO.deleteFeature(feature);
//     }
// 
//     public FeatureConstraint addRequiresConstraintToProduct(String productName, String sourceFeatureName, String requiredFeatureName) {
//         Product product = productsDAO.findByName(productName);
// 
//         ConstraintRequires constraintRequires = new ConstraintRequires(sourceFeatureName, requiredFeatureName);
//         constraintRequires.setForProduct(product);
//         productsDAO.insertConstraint(constraintRequires);
// 
//         return constraintRequires;
//     }
// 
//     public void deleteConstraintFromProduct(String productName, Long constraintId) {
//         productsDAO.deleteConstraintForProduct(productName, constraintId);
//     }
// 
//     public FeatureConstraint addExcludesConstraintToProduct(String productName, String sourceFeatureName, String excludedFeatureName) {
//         Product product = productsDAO.findByName(productName);
// 
//         ConstraintExcludes constraintExcludes = new ConstraintExcludes(sourceFeatureName, excludedFeatureName);
//         constraintExcludes.setForProduct(product);
//         productsDAO.insertConstraint(constraintExcludes);
// 
//         return constraintExcludes;
//     }
// }


import org.javiermf.features.models.constraints.FeatureConstraint;
import org.javiermf.features.services.ProductsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
import java.net.URI;
import java.net.URISyntaxException;
package org.javiermf.features.services.rest;



@Component
@Produces("application/json")
public class ProductsConstraintsResource {

    @Autowired
    ProductsService productsService;

    @POST
    @Path("requires")
    public Response addRequiresConstraintToProduct(@PathParam("productName") String productName,
                                                   @FormParam("sourceFeature") String sourceFeatureName,
                                                   @FormParam("requiredFeature") String requiredFeatureName
    ) throws URISyntaxException {
// Path: src/main/java/org/javiermf/features/models/constraints/FeatureConstraint.java
// @Entity
// @Inheritance(strategy = InheritanceType.TABLE_PER_CLASS)
// public abstract class FeatureConstraint {
// 
//     @Id
//     @GeneratedValue(strategy = GenerationType.SEQUENCE)
//     Long id;
// 
//     @ManyToOne
//     Product forProduct;
// 
//     public abstract String getType();
// 
//     public abstract EvaluationResult evaluateConfiguration(EvaluationResult currentResult, ProductConfiguration configuration);
// 
//     public Long getId() {
//         return id;
//     }
// 
//     public void setId(Long id) {
//         this.id = id;
//     }
// 
//     public void setForProduct(Product forProduct) {
//         this.forProduct = forProduct;
//     }
// }
// 
// Path: src/main/java/org/javiermf/features/services/ProductsService.java
// @Service
// public class ProductsService {
// 
//     @Autowired
//     ProductsDAO productsDAO;
// 
//     @Autowired
//     ProductsConfigurationsDAO productsConfigurationsDAO;
// 
// 
//     public List<String> getAllProductNames() {
//         List<String> allProducts = new ArrayList<String>();
// 
//         for (Product product : productsDAO.findAll()) {
//             allProducts.add(product.getName());
//         }
// 
//         return allProducts;
//     }
// 
//     public Product findByName(String productName) {
//         return productsDAO.findByName(productName);
//     }
// 
//     public void deleteByName(String productName) {
//         productsConfigurationsDAO.deleteConfigurationsForProduct(productName);
//         productsDAO.deleteConstraintsForProduct(productName);
//         productsDAO.deleteByName(productName);
//     }
// 
//     public void add(String productName) {
//         Product product = new Product();
//         product.setName(productName);
//         productsDAO.insert(product);
//     }
// 
//     public Set<Feature> getFeaturesForProduct(String productName) {
//         Product product = findByName(productName);
//         return product.getProductFeatures();
//     }
// 
//     public void addFeatureToProduct(String productName, String featureName, String featureDescription) {
//         Product product = findByName(productName);
//         if (product.hasFeatureNamed(featureName)) {
//             throw new DuplicatedObjectException(featureName);
//         }
//         Feature feature = Feature.withName(product, featureName);
//         feature.setDescription(featureDescription);
//         productsDAO.insertFeature(feature);
//     }
// 
//     @Transactional
//     public Feature updateFeatureOfProduct(String productName, String featureName, String featureDescription) {
//         Product product = productsDAO.findByName(productName);
//         Feature feature = product.findProductFeatureByName(featureName);
//         feature.setDescription(featureDescription);
//         return feature;
//     }
// 
//     @Transactional
//     public void deleteFeatureOfProduct(String productName, String featureName) {
//         Product product = productsDAO.findByName(productName);
//         Feature feature = product.findProductFeatureByName(featureName);
// 
//         for (ProductConfiguration productConfiguration : productsConfigurationsDAO.findConfigurationsWithFeatureActive(feature)) {
//             productConfiguration.getActivedFeatures().remove(feature);
//         }
// 
//         productsDAO.deleteFeature(feature);
//     }
// 
//     public FeatureConstraint addRequiresConstraintToProduct(String productName, String sourceFeatureName, String requiredFeatureName) {
//         Product product = productsDAO.findByName(productName);
// 
//         ConstraintRequires constraintRequires = new ConstraintRequires(sourceFeatureName, requiredFeatureName);
//         constraintRequires.setForProduct(product);
//         productsDAO.insertConstraint(constraintRequires);
// 
//         return constraintRequires;
//     }
// 
//     public void deleteConstraintFromProduct(String productName, Long constraintId) {
//         productsDAO.deleteConstraintForProduct(productName, constraintId);
//     }
// 
//     public FeatureConstraint addExcludesConstraintToProduct(String productName, String sourceFeatureName, String excludedFeatureName) {
//         Product product = productsDAO.findByName(productName);
// 
//         ConstraintExcludes constraintExcludes = new ConstraintExcludes(sourceFeatureName, excludedFeatureName);
//         constraintExcludes.setForProduct(product);
//         productsDAO.insertConstraint(constraintExcludes);
// 
//         return constraintExcludes;
//     }
// }


// Path: src/main/java/org/javiermf/features/services/rest/ProductsConstraintsResource.java
import org.javiermf.features.models.constraints.FeatureConstraint;
import org.javiermf.features.services.ProductsService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import javax.ws.rs.*;
import javax.ws.rs.core.Response;
import java.net.URI;
import java.net.URISyntaxException;

package org.javiermf.features.services.rest;



@Component
@Produces("application/json")
public class ProductsConstraintsResource {

    @Autowired
    ProductsService productsService;

    @POST
    @Path("requires")
    public Response addRequiresConstraintToProduct(@PathParam("productName") String productName,
                                                   @FormParam("sourceFeature") String sourceFeatureName,
                                                   @FormParam("requiredFeature") String requiredFeatureName
    ) throws URISyntaxException {
        FeatureConstraint newConstraint = productsService.addRequiresConstraintToProduct(productName, sourceFeatureName, requiredFeatureName);