diff --git a/.vscode/settings.json b/.vscode/settings.json
new file mode 100644
index 0000000..c5f3f6b
--- /dev/null
+++ b/.vscode/settings.json
@@ -0,0 +1,3 @@
+{
+ "java.configuration.updateBuildConfiguration": "interactive"
+}
\ No newline at end of file
diff --git a/ANALISIS_CONCURRENCIA.txt b/ANALISIS_CONCURRENCIA.txt
index e69de29..14401a5 100644
--- a/ANALISIS_CONCURRENCIA.txt
+++ b/ANALISIS_CONCURRENCIA.txt
@@ -0,0 +1,6 @@
+La primera condición de carrera es que dos hilos intenten modificar de alguna manera la lista (ya sea adicionando o accediendo a algún elemento) al mismo tiempo
+Esto lo solucionamos modificando el HashMap en InMemoryBlueprintPersistence por un ConcurrentHashMap, el cual limita las modificaciones múltiples.
+
+La segunda condición de carrera, es que se acceda a algún plano, y este se intente modificar o acceder al mismo tiempo que otro está trabajando con dicho plano.
+Por lo cual, en cada uno de los métodos de los servicios (InMemoryBlueprintPersistence), vamos a bloquear el acceso múltiple por medio de syncronized, pero de planos específicos, con el fin
+de no limitar la eficiencia de la aplicación
diff --git a/API REST BLUEPRINTS.pdf b/API REST BLUEPRINTS.pdf
new file mode 100644
index 0000000..dec4fcd
Binary files /dev/null and b/API REST BLUEPRINTS.pdf differ
diff --git a/BlueprintsRestApi.drawio b/BlueprintsRestApi.drawio
new file mode 100644
index 0000000..4fc7e4c
--- /dev/null
+++ b/BlueprintsRestApi.drawio
@@ -0,0 +1 @@
+7Vrdc9o4EP9b7oGZ5sE3WMZAHgPk2tz0bjJNZ9o8ClsGHbbkyOLr/vpb2ZIt2xBICgk3LckM0u56Je3+9kNOOt442XwUOJ3/xUMSd1A33HS8SQchF7k9+FKUbUHxh4OCMBM01EIV4YH+SzSxq6lLGpKsJig5jyVN68SAM0YCWaNhIfi6LhbxuL5qimekRXgIcNymfqOhnBfUIRpU9E+EzuZmZbd/XXASbIT1SbI5DvnaInm3HW8sOJfFKNmMSayMZ+xSPPfHHm65MUGYPOaBp490mvR5/86Letd/Ltbpwv/b0VpWOF7qA3dQPwZ9o6mA0UyNDCVLMVPnkFttnP7TUm1+FPCYi453A0wxm36AbYxhaL6uchVgeSadCCc03hain0i8IpIG2OJnuf8V10XpxmYUiyoO4yLBscVbYUExfMd0huVSKLQ8KxfgdJ/IWrtSMQdwgpwTEymJcOD4AWWz9pNcpHPMtEpU0CTZSAfDjlhBDsBJRFg8ysLcb4rZNUfNOVKAsgj0m5UYKbhrGuZwtpZZcxHWN1bqgrNMFxTUKZ2ZFHxBnHWB4JrcFAeLmeBLFjoNPyLfLVxoD66snYYk4AJLypkj5zRYMJLp7VFGJTX2acpavnxWztpOTS6KOZZN44Q0S2O8NeIxBQbq/kaTlAuJmcaxBqxB9ghQnwrK5Jfbh68393cG6RBEBdjrAWCHBKpFAprLBHY3cYEXCp5+xWJGVFQqCOXGJaGerYhQoI9vCnBMJE9LhYpHNnvj2y2zBqRbwhMixRZEzAOeTjRbk4r0fF3lrV5f0+ZWziqJWOfKWam7Sicw0BnlBdkF7cguDcNBVkzVMOHhUtFG/0C0bU2qHRpCmWN7xxprf7rbb8GWvdAOcxmaIDHgdFWvE7tMqNe75wC0ajHHlBDtrkFdAY+iDBDU9EC56dc7xWs7ZYw6N6Mxh1hhyn4wHe0Evaa0wid7IGJFA5JVOqpImp4gaE4QHl6/ER6DdnjkRavp7+tzRUfvPNHxCsvtx8lPHivu8HgfpYKvoFcNv5CnJRUkvFMVP8KBcpuFdJP/P+Mpie95RlWtA96US8kT1WYtiAzmO8NAcIm1uHN9orjo+fW48Lq74mK/a08eFu71YZsTFt6o5h5mugWwLExC6OC1LBT/OZ9xhuPbitqwKtlQ+V2Nf/f17NFogvFkY4lNtmbC4KjfjZiaPFYa1LR6LJ/VnrsngoKtVD9oxaja9vM+BBPwpQjI4eQuTSp9HthtUPxgoHq9Bpi8BkqKA+in7MtKQ5HfPaCoOGFL0akC32DOAmFZ7cB9Gc0kYeCJJjBVDwse1Z3/pGz71e3CYNLOAqYLTGgY5tDUzfxnEin3eRXliw69nJS38+OiPzYRkCcHPM2XUKhKlW1ya/kj+FXXMYVPf6J6eX/kVnP4VeJCjjkD1ZjmqCM4k2uSyROlGbfhUNROM8NdaaZ/pjSDdpTfF/dBOy7DU7iSwW3RurzAvfOD49j0q+dvI5mFsEvuqHy/5tKyktiVw33Ljgr5l91SFZj7yXsqs9Lb13erule1/kB9t0r6Y62i76nvoOSM5d30owfr+z6k/SBoeoN6FkeDV9b3piLPfeP6frmNvTs8UX5GjZKL3ruz99pvm8uaZ94g/Oqojn7fN2y49707Ku+IFxrvn9jPm6DRee5VJ8u7zbdg6I3zrndEh3ZajLzPRf1wgT4PUJp/BGj59/9SoL3+RRXoiMaxqQ4d5EW++tFVyKIXn1Y9AU4//5wm8/uXVtfbHX1Z1/O/qv0q6Ud2bBdW0c3bvDev6Obl6wVU9CIRnT5R9/b4+qWJ+mDGf3Wihmn13ymFePU/Pt7tfw==
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index d7f6e67..f70c8f7 100644
--- a/pom.xml
+++ b/pom.xml
@@ -25,6 +25,25 @@
+
+ javax.activation
+ activation
+ 1.1
+
+
+
+
+ jakarta.xml.bind
+ jakarta.xml.bind-api
+ 2.3.2
+
+
+
+
+ org.glassfish.jaxb
+ jaxb-runtime
+ 2.3.2
+
org.springframework.boot
spring-boot-starter-web
diff --git a/src/main/java/edu/eci/arsw/blueprints/controllers/BlueprintAPIController.java b/src/main/java/edu/eci/arsw/blueprints/controllers/BlueprintAPIController.java
index 45b140e..0420955 100644
--- a/src/main/java/edu/eci/arsw/blueprints/controllers/BlueprintAPIController.java
+++ b/src/main/java/edu/eci/arsw/blueprints/controllers/BlueprintAPIController.java
@@ -7,20 +7,99 @@
import java.util.LinkedHashSet;
import java.util.Set;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import javax.security.auth.message.callback.PrivateKeyCallback.Request;
+
import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.http.HttpStatus;
+import org.springframework.http.ResponseEntity;
+import org.springframework.stereotype.Controller;
+import org.springframework.web.bind.annotation.GetMapping;
+import org.springframework.web.bind.annotation.PathVariable;
+import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
+import edu.eci.arsw.blueprints.controllers.dao.BlueprintBody;
+import edu.eci.arsw.blueprints.model.Blueprint;
+import edu.eci.arsw.blueprints.model.Point;
+import edu.eci.arsw.blueprints.persistence.BlueprintNotFoundException;
+import edu.eci.arsw.blueprints.persistence.BlueprintPersistenceException;
+import edu.eci.arsw.blueprints.services.BlueprintsServices;
+
/**
*
* @author hcadavid
*/
+@RestController
+@RequestMapping(value = "/blueprints")
public class BlueprintAPIController {
+ @Autowired
+ BlueprintsServices services;
+
+ @RequestMapping(method = RequestMethod.GET)
+ public ResponseEntity> get() {
+ try {
+ //obtener datos que se enviarán a través del API
+ return new ResponseEntity<>(services.getAllBlueprints(),HttpStatus.ACCEPTED);
+ } catch (BlueprintNotFoundException ex) {
+ Logger.getLogger(BlueprintAPIController.class.getName()).log(Level.SEVERE, null, ex);
+ return new ResponseEntity<>("No se ha encontrado",HttpStatus.NOT_FOUND);
+ }
+ }
+
+ @RequestMapping(method = RequestMethod.GET, value = "/{author}")
+ public ResponseEntity> getByAuthor(@PathVariable String author) {
+ try {
+ //obtener datos que se enviarán a través del API
+ return new ResponseEntity<>(services.getBlueprintsByAuthor(author),HttpStatus.ACCEPTED);
+ } catch (BlueprintNotFoundException ex) {
+ Logger.getLogger(BlueprintAPIController.class.getName()).log(Level.SEVERE, null, ex);
+ return new ResponseEntity<>("Error 404 Blueprint not found",HttpStatus.NOT_FOUND);
+ }
+ }
-
-
+ @RequestMapping(method = RequestMethod.GET, value = "/{author}/{bpname}")
+ public ResponseEntity> getByAuthorAndName(@PathVariable String author, @PathVariable String bpname) {
+ try {
+ //obtener datos que se enviarán a través del API
+ return new ResponseEntity<>(services.getBlueprint(author, bpname),HttpStatus.ACCEPTED);
+ } catch (BlueprintNotFoundException ex) {
+ Logger.getLogger(BlueprintAPIController.class.getName()).log(Level.SEVERE, null, ex);
+ return new ResponseEntity<>("Error 404 Blueprint not found",HttpStatus.NOT_FOUND);
+ }
+ }
+
+ @RequestMapping(method = RequestMethod.POST, value = "/create")
+ public ResponseEntity> create(@RequestBody BlueprintBody body) {
+ try {
+ Point[] pts = new Point[]{new Point(body.getX1(),body.getY1()),new Point(body.getX2(), body.getY2())};
+ Blueprint bp = new Blueprint(body.getAuthor(), body.getName(), pts);
+ services.addNewBlueprint(bp);
+
+ return new ResponseEntity<>(HttpStatus.CREATED);
+ } catch (BlueprintPersistenceException ex) {
+ Logger.getLogger(BlueprintAPIController.class.getName()).log(Level.SEVERE, null, ex);
+ return new ResponseEntity<>("Could not create blueprint",HttpStatus.BAD_REQUEST);
+ }
+ }
+
+ @RequestMapping(method = RequestMethod.PUT, value = "/{author}/{bpname}")
+ public ResponseEntity> update(@RequestBody BlueprintBody body, @PathVariable String author, @PathVariable String bpname) {
+ try {
+ services.updateBlueprint(author, bpname, body);
+ return new ResponseEntity<>(HttpStatus.CREATED);
+ } catch (Exception ex) {
+ Logger.getLogger(BlueprintAPIController.class.getName()).log(Level.SEVERE, null, ex);
+ return new ResponseEntity<>("Could not update blueprint",HttpStatus.BAD_REQUEST);
+ }
+ }
+
+
}
diff --git a/src/main/java/edu/eci/arsw/blueprints/controllers/dao/BlueprintBody.java b/src/main/java/edu/eci/arsw/blueprints/controllers/dao/BlueprintBody.java
new file mode 100644
index 0000000..b13b6d7
--- /dev/null
+++ b/src/main/java/edu/eci/arsw/blueprints/controllers/dao/BlueprintBody.java
@@ -0,0 +1,46 @@
+package edu.eci.arsw.blueprints.controllers.dao;
+
+public class BlueprintBody {
+ String author, name;
+ Integer x1, y1, x2, y2;
+
+ public String getAuthor() {
+ return author;
+ }
+ public void setAuthor(String author) {
+ this.author = author;
+ }
+ public String getName() {
+ return name;
+ }
+ public void setName(String name) {
+ this.name = name;
+ }
+ public Integer getX1() {
+ return x1;
+ }
+ public void setX1(Integer x1) {
+ this.x1 = x1;
+ }
+ public Integer getY1() {
+ return y1;
+ }
+ public void setY1(Integer y1) {
+ this.y1 = y1;
+ }
+ public Integer getX2() {
+ return x2;
+ }
+ public void setX2(Integer x2) {
+ this.x2 = x2;
+ }
+ public Integer getY2() {
+ return y2;
+ }
+ public void setY2(Integer y2) {
+ this.y2 = y2;
+ }
+
+
+
+}
diff --git a/src/main/java/edu/eci/arsw/blueprints/filters/Filter.java b/src/main/java/edu/eci/arsw/blueprints/filters/Filter.java
new file mode 100644
index 0000000..e1b66b0
--- /dev/null
+++ b/src/main/java/edu/eci/arsw/blueprints/filters/Filter.java
@@ -0,0 +1,7 @@
+package edu.eci.arsw.blueprints.filters;
+
+import edu.eci.arsw.blueprints.model.Blueprint;
+
+public interface Filter {
+ public void filter(Blueprint bp);
+}
diff --git a/src/main/java/edu/eci/arsw/blueprints/filters/RedundanceFilter.java b/src/main/java/edu/eci/arsw/blueprints/filters/RedundanceFilter.java
new file mode 100644
index 0000000..c06f6ec
--- /dev/null
+++ b/src/main/java/edu/eci/arsw/blueprints/filters/RedundanceFilter.java
@@ -0,0 +1,25 @@
+package edu.eci.arsw.blueprints.filters;
+
+import java.util.*;
+
+import org.springframework.stereotype.Service;
+
+import edu.eci.arsw.blueprints.model.*;
+import org.springframework.stereotype.Component;
+
+@Component("RedundanceFilter")
+public class RedundanceFilter implements Filter{
+
+ @Override
+ public void filter(Blueprint bp) {
+ List pts0 = bp.getPoints();
+ ArrayList ps1 = new ArrayList();
+ for(int i=0;i pts0 = bp.getPoints();
+ int i=0;
+ ArrayList ps1 = new ArrayList();
+ for(Point p:pts0){
+ if(i%2!=0){
+ ps1.add(p);
+ }
+ i++;
+ }
+ bp.setPoints(ps1);
+ }
+}
diff --git a/src/main/java/edu/eci/arsw/blueprints/model/Blueprint.java b/src/main/java/edu/eci/arsw/blueprints/model/Blueprint.java
new file mode 100644
index 0000000..e3407ad
--- /dev/null
+++ b/src/main/java/edu/eci/arsw/blueprints/model/Blueprint.java
@@ -0,0 +1,100 @@
+
+package edu.eci.arsw.blueprints.model;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Objects;
+
+
+public class Blueprint {
+
+ private String author=null;
+
+ private List points=null;
+
+ private String name=null;
+
+ public Blueprint(String author,String name,Point[] pnts){
+ this.author=author;
+ this.name=name;
+ points=Arrays.asList(pnts);
+ }
+
+ public Blueprint(String author, String name){
+ this.name=name;
+ points=new ArrayList<>();
+ }
+
+ public Blueprint() {
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public String getAuthor() {
+ return author;
+ }
+
+ public List getPoints() {
+ return points;
+ }
+
+ public void setPoints(List points) {
+ this.points = points;
+ }
+
+ public void addPoint(Point p){
+ this.points.add(p);
+ }
+
+ @Override
+ public String toString() {
+ return "Blueprint{" + "author=" + author + ", name=" + name + '}';
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final Blueprint other = (Blueprint) obj;
+ if (!Objects.equals(this.author, other.author)) {
+ return false;
+ }
+ if (!Objects.equals(this.name, other.name)) {
+ return false;
+ }
+ if (this.points.size()!=other.points.size()){
+ return false;
+ }
+ for (int i=0;i update) {
+ this.points = update;
+
+ }
+
+
+
+}
diff --git a/src/main/java/edu/eci/arsw/blueprints/model/Point.java b/src/main/java/edu/eci/arsw/blueprints/model/Point.java
new file mode 100644
index 0000000..7281888
--- /dev/null
+++ b/src/main/java/edu/eci/arsw/blueprints/model/Point.java
@@ -0,0 +1,43 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package edu.eci.arsw.blueprints.model;
+
+/**
+ *
+ * @author hcadavid
+ */
+public class Point {
+
+ private int x;
+ private int y;
+
+ public Point(int x, int y) {
+ this.x = x;
+ this.y = y;
+ }
+
+ public Point() {
+ }
+
+ public int getX() {
+ return x;
+ }
+
+ public void setX(int x) {
+ this.x = x;
+ }
+
+ public int getY() {
+ return y;
+ }
+
+ public void setY(int y) {
+ this.y = y;
+ }
+
+
+
+}
diff --git a/src/main/java/edu/eci/arsw/blueprints/persistence/BlueprintNotFoundException.java b/src/main/java/edu/eci/arsw/blueprints/persistence/BlueprintNotFoundException.java
new file mode 100644
index 0000000..51f18a2
--- /dev/null
+++ b/src/main/java/edu/eci/arsw/blueprints/persistence/BlueprintNotFoundException.java
@@ -0,0 +1,22 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package edu.eci.arsw.blueprints.persistence;
+
+/**
+ *
+ * @author hcadavid
+ */
+public class BlueprintNotFoundException extends Exception{
+
+ public BlueprintNotFoundException(String message) {
+ super(message);
+ }
+
+ public BlueprintNotFoundException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
diff --git a/src/main/java/edu/eci/arsw/blueprints/persistence/BlueprintPersistenceException.java b/src/main/java/edu/eci/arsw/blueprints/persistence/BlueprintPersistenceException.java
new file mode 100644
index 0000000..f14956e
--- /dev/null
+++ b/src/main/java/edu/eci/arsw/blueprints/persistence/BlueprintPersistenceException.java
@@ -0,0 +1,22 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package edu.eci.arsw.blueprints.persistence;
+
+/**
+ *
+ * @author hcadavid
+ */
+public class BlueprintPersistenceException extends Exception{
+
+ public BlueprintPersistenceException(String message) {
+ super(message);
+ }
+
+ public BlueprintPersistenceException(String message, Throwable cause) {
+ super(message, cause);
+ }
+
+}
diff --git a/src/main/java/edu/eci/arsw/blueprints/persistence/BlueprintsPersistence.java b/src/main/java/edu/eci/arsw/blueprints/persistence/BlueprintsPersistence.java
new file mode 100644
index 0000000..fb61444
--- /dev/null
+++ b/src/main/java/edu/eci/arsw/blueprints/persistence/BlueprintsPersistence.java
@@ -0,0 +1,39 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package edu.eci.arsw.blueprints.persistence;
+
+import java.util.Set;
+
+import edu.eci.arsw.blueprints.model.Blueprint;
+
+/**
+ *
+ * @author hcadavid
+ */
+public interface BlueprintsPersistence {
+
+ /**
+ *
+ * @param bp the new blueprint
+ * @throws BlueprintPersistenceException if a blueprint with the same name already exists,
+ * or any other low-level persistence error occurs.
+ */
+ public void saveBlueprint(Blueprint bp) throws BlueprintPersistenceException;
+
+ /**
+ *
+ * @param author blueprint's author
+ * @param bprintname blueprint's author
+ * @return the blueprint of the given name and author
+ * @throws BlueprintNotFoundException if there is no such blueprint
+ */
+ public Blueprint getBlueprint(String author,String bprintname) throws BlueprintNotFoundException;
+
+ public Set getBlueprintsByAuthor(String author) throws BlueprintNotFoundException;
+
+ public Set getAllBlueprints() throws BlueprintNotFoundException;
+
+}
diff --git a/src/main/java/edu/eci/arsw/blueprints/persistence/impl/InMemoryBlueprintPersistence.java b/src/main/java/edu/eci/arsw/blueprints/persistence/impl/InMemoryBlueprintPersistence.java
new file mode 100644
index 0000000..a20fb27
--- /dev/null
+++ b/src/main/java/edu/eci/arsw/blueprints/persistence/impl/InMemoryBlueprintPersistence.java
@@ -0,0 +1,130 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package edu.eci.arsw.blueprints.persistence.impl;
+
+import edu.eci.arsw.blueprints.filters.Filter;
+import edu.eci.arsw.blueprints.model.Blueprint;
+import edu.eci.arsw.blueprints.model.Point;
+import edu.eci.arsw.blueprints.persistence.BlueprintNotFoundException;
+import edu.eci.arsw.blueprints.persistence.BlueprintPersistenceException;
+import edu.eci.arsw.blueprints.persistence.BlueprintsPersistence;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Component;
+
+/**
+ *
+ * @author hcadavid
+ */
+@Component("InMemoryBlueprintPersistence")
+public class InMemoryBlueprintPersistence implements BlueprintsPersistence{
+
+ @Autowired
+ @Qualifier("RedundanceFilter")
+ private Filter filter;
+
+ private final Map,Blueprint> blueprints=new ConcurrentHashMap<>();
+
+ public InMemoryBlueprintPersistence() {
+ //load stub data
+ Point[] pts=new Point[]{new Point(140, 140),new Point(115, 115)};
+ Blueprint bp=new Blueprint("_authorname_", "_bpname_ ",pts);
+ blueprints.put(new Tuple<>(bp.getAuthor(),bp.getName()), bp);
+ // Adicionando más
+ Point[] pts0 = new Point[]{new Point(40, 40),new Point(15, 15)};
+ Blueprint bp0 = new Blueprint("Profe", "mypaint",pts0);
+ blueprints.put(new Tuple<>(bp0.getAuthor(),bp0.getName()), bp0);
+ Point[] pts1 = new Point[]{new Point(0, 0),new Point(10, 10)};
+ /*
+ Blueprint bp1 = new Blueprint("Cesar", "CV",pts1);
+ blueprints.put(new Tuple<>(bp1.getAuthor(),bp1.getName()), bp1);
+ */
+ Point[] pts2 = new Point[]{new Point(35, 35),new Point(20, 20),new Point(20,20)};
+ Blueprint bp2 = new Blueprint("Yorks", "YG",pts2);
+ blueprints.put(new Tuple<>(bp2.getAuthor(),bp2.getName()), bp2);
+ Point[] pts3 = new Point[]{new Point(20, 20),new Point(50, 50)};
+ Blueprint bp3 = new Blueprint("La pulga", "Mundialito",pts3);
+ blueprints.put(new Tuple<>(bp3.getAuthor(),bp3.getName()), bp3);
+ Point[] pts4 = new Point[]{new Point(10, 10),new Point(100, 100)};
+ Blueprint bp4 = new Blueprint("Nadie", "Futbol",pts4);
+ blueprints.put(new Tuple<>(bp4.getAuthor(),bp4.getName()), bp4);
+ Point[] pts5 = new Point[]{new Point(80, 80),new Point(90, 90)};
+ Blueprint bp5 = new Blueprint("Nadie", "Tenis",pts5);
+ blueprints.put(new Tuple<>(bp5.getAuthor(),bp5.getName()), bp5);
+
+ }
+
+ @Override
+ public void saveBlueprint(Blueprint bp) throws BlueprintPersistenceException {
+ if (blueprints.containsKey(new Tuple<>(bp.getAuthor(),bp.getName()))){
+ throw new BlueprintPersistenceException("The given blueprint already exists: "+bp);
+ }
+ else{
+ blueprints.put(new Tuple<>(bp.getAuthor(),bp.getName()), bp);
+ }
+ }
+
+ @Override
+ public Blueprint getBlueprint(String author, String bprintname) throws BlueprintNotFoundException {
+ Blueprint bp= blueprints.get(new Tuple<>(author, bprintname));
+
+ synchronized(bp) {
+ if (bp==null){
+ throw new BlueprintNotFoundException("Blueprint no se pudo encontrar");
+ }
+
+ filter.filter(bp);
+ return bp;
+ }
+
+ }
+
+ @Override
+ public Set getBlueprintsByAuthor(String author) throws BlueprintNotFoundException {
+ Set> keys = blueprints.keySet();
+ HashSet bps = new HashSet();
+ synchronized(keys) {
+ for (Tuple t : keys){
+ if (author.equals(t.o1)){
+ bps.add(blueprints.get(new Tuple<>(author,(String)t.o2)));
+ }
+ }
+ if(bps.isEmpty()){
+ throw new BlueprintNotFoundException("El autor: " + author + " No existe");
+ }
+ return bps;
+ }
+
+ }
+
+ @Override
+ public Set getAllBlueprints() throws BlueprintNotFoundException {
+ Set> keys=blueprints.keySet();
+ HashSet bps=new HashSet();
+ synchronized(keys) {
+ for (Tuple t : keys){
+ bps.add(blueprints.get(new Tuple<>((String)t.o1,(String)t.o2)));
+ Blueprint bp = blueprints.get(new Tuple<>((String)t.o1,(String)t.o2));
+
+ synchronized(bp) {
+ filter.filter(bp);
+ bps.add(bp);
+ }
+
+ }
+ return bps;
+ }
+ }
+
+
+
+}
diff --git a/src/main/java/edu/eci/arsw/blueprints/persistence/impl/Tuple.java b/src/main/java/edu/eci/arsw/blueprints/persistence/impl/Tuple.java
new file mode 100644
index 0000000..64595bf
--- /dev/null
+++ b/src/main/java/edu/eci/arsw/blueprints/persistence/impl/Tuple.java
@@ -0,0 +1,54 @@
+package edu.eci.arsw.blueprints.persistence.impl;
+
+import java.util.Objects;
+
+public class Tuple {
+
+ T1 o1;
+ T2 o2;
+
+ public Tuple(T1 o1, T2 o2) {
+ super();
+ this.o1 = o1;
+ this.o2 = o2;
+ }
+
+ public T1 getElem1() {
+ return o1;
+ }
+
+ public T2 getElem2() {
+ return o2;
+ }
+
+ @Override
+ public int hashCode() {
+ int hash = 7;
+ hash = 17 * hash + Objects.hashCode(this.o1);
+ hash = 17 * hash + Objects.hashCode(this.o2);
+ return hash;
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (this == obj) {
+ return true;
+ }
+ if (obj == null) {
+ return false;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ final Tuple, ?> other = (Tuple, ?>) obj;
+ if (!Objects.equals(this.o1, other.o1)) {
+ return false;
+ }
+ if (!Objects.equals(this.o2, other.o2)) {
+ return false;
+ }
+ return true;
+ }
+
+
+}
diff --git a/src/main/java/edu/eci/arsw/blueprints/services/BlueprintsServices.java b/src/main/java/edu/eci/arsw/blueprints/services/BlueprintsServices.java
new file mode 100644
index 0000000..7233bdd
--- /dev/null
+++ b/src/main/java/edu/eci/arsw/blueprints/services/BlueprintsServices.java
@@ -0,0 +1,87 @@
+/*
+ * To change this license header, choose License Headers in Project Properties.
+ * To change this template file, choose Tools | Templates
+ * and open the template in the editor.
+ */
+package edu.eci.arsw.blueprints.services;
+
+import edu.eci.arsw.blueprints.controllers.dao.BlueprintBody;
+import edu.eci.arsw.blueprints.filters.Filter;
+import edu.eci.arsw.blueprints.model.Blueprint;
+import edu.eci.arsw.blueprints.model.Point;
+import edu.eci.arsw.blueprints.persistence.BlueprintNotFoundException;
+import edu.eci.arsw.blueprints.persistence.BlueprintPersistenceException;
+import edu.eci.arsw.blueprints.persistence.BlueprintsPersistence;
+
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import org.apache.tomcat.websocket.pojo.PojoPathParam;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.beans.factory.annotation.Qualifier;
+import org.springframework.stereotype.Service;
+
+/**
+ *
+ * @author hcadavid
+ */
+@Service("BlueprintsServices")
+public class BlueprintsServices {
+
+ @Autowired
+ @Qualifier("InMemoryBlueprintPersistence")
+ BlueprintsPersistence bpp;
+
+ @Autowired
+ @Qualifier("RedundanceFilter")
+ Filter filter;
+
+ public void addNewBlueprint(Blueprint bp) throws BlueprintPersistenceException{
+ bpp.saveBlueprint(bp);
+ }
+
+ public Set getAllBlueprints() throws BlueprintNotFoundException{
+ return bpp.getAllBlueprints();
+ }
+
+ /**
+ *
+ * @param author blueprint's author
+ * @param name blueprint's name
+ * @return the blueprint of the given name created by the given author
+ * @throws BlueprintNotFoundException if there is no such blueprint
+ */
+ public Blueprint getBlueprint(String author,String name) throws BlueprintNotFoundException{
+ Blueprint bpt = bpp.getBlueprint(author, name);
+ filter.filter(bpt);
+ return bpp.getBlueprint(author, name);
+ }
+
+ /**
+ *
+ * @param author blueprint's author
+ * @return all the blueprints of the given author
+ * @throws BlueprintNotFoundException if the given author doesn't exist
+ */
+ public Set getBlueprintsByAuthor(String author) throws BlueprintNotFoundException{
+ return bpp.getBlueprintsByAuthor(author);
+ }
+
+ public void updateBlueprint(String author, String name, BlueprintBody body) throws BlueprintNotFoundException{
+ if(body.getX1() == null ||
+ body.getX2() == null ||
+ body.getY1() == null ||
+ body.getY2() == null) return;
+
+ Blueprint bpt = bpp.getBlueprint(author, name);
+
+ ArrayList pts = new ArrayList<>();
+ pts.add(new Point(body.getX1(), body.getY1()));
+ pts.add(new Point(body.getX2(), body.getY2()));
+ bpt.setPoints(pts);
+ }
+
+
+}
diff --git a/src/test/java/edu/eci/arsw/blueprints/test/services/ApplicationServicesTests.java b/src/test/java/edu/eci/arsw/blueprints/test/services/ApplicationServicesTests.java
index 40d681e..e83b13d 100644
--- a/src/test/java/edu/eci/arsw/blueprints/test/services/ApplicationServicesTests.java
+++ b/src/test/java/edu/eci/arsw/blueprints/test/services/ApplicationServicesTests.java
@@ -9,8 +9,10 @@
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
+import edu.eci.arsw.blueprintsapi.BlueprintsAPIApplication;
+
@RunWith(SpringRunner.class)
-@SpringBootTest()
+@SpringBootTest(classes={BlueprintsAPIApplication.class})
public class ApplicationServicesTests {