From ec32b948bce916320d2696fb2785239077d34964 Mon Sep 17 00:00:00 2001 From: Miguel Reboiro-Jato Date: Mon, 27 Nov 2023 12:54:21 +0100 Subject: [PATCH] Adds advance examples These examples include the use of JAX-B advanced features. --- pom.xml | 2 +- .../ws/calculator/CalculatorException.java | 8 +- .../dai/ws/calculator/CalculatorService.java | 46 ++++++++- .../calculator/CalculatorServiceClient.java | 34 ++++++- .../ws/calculator/CalculatorServiceImpl.java | 93 +++++++++++++++++-- .../esei/dai/ws/calculator/Operation.java | 27 ++++++ .../calculator/adapters/NamedOperations.java | 31 +++++++ .../adapters/NamedOperationsEntry.java | 38 ++++++++ .../adapters/NamedOperationsMap.java | 42 +++++++++ .../adapters/NamedOperationsMapAdapter.java | 20 ++++ .../ws/calculator/adapters/NamedResults.java | 29 ++++++ .../adapters/NamedResultsEntry.java | 36 +++++++ .../calculator/adapters/NamedResultsMap.java | 40 ++++++++ .../adapters/NamedResultsMapAdapter.java | 19 ++++ 14 files changed, 448 insertions(+), 17 deletions(-) create mode 100644 src/main/java/es/uvigo/esei/dai/ws/calculator/Operation.java create mode 100644 src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedOperations.java create mode 100644 src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedOperationsEntry.java create mode 100644 src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedOperationsMap.java create mode 100644 src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedOperationsMapAdapter.java create mode 100644 src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedResults.java create mode 100644 src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedResultsEntry.java create mode 100644 src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedResultsMap.java create mode 100644 src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedResultsMapAdapter.java diff --git a/pom.xml b/pom.xml index 2e6df14..11f6854 100644 --- a/pom.xml +++ b/pom.xml @@ -7,7 +7,7 @@ es.uvigo.esei.dai.ws calculator_service - 1.0.0 + 1.1.0 Ejemplos de DAI - Servicios Web: Calculator Service 2014 diff --git a/src/main/java/es/uvigo/esei/dai/ws/calculator/CalculatorException.java b/src/main/java/es/uvigo/esei/dai/ws/calculator/CalculatorException.java index 0df1d0e..315605a 100644 --- a/src/main/java/es/uvigo/esei/dai/ws/calculator/CalculatorException.java +++ b/src/main/java/es/uvigo/esei/dai/ws/calculator/CalculatorException.java @@ -4,17 +4,17 @@ public class CalculatorException extends RuntimeException { private static final long serialVersionUID = 1L; private final String faultInfo; - + public CalculatorException(String message) { this(message, message); } - + public CalculatorException(String message, String faultInfo) { super(message); - + this.faultInfo = faultInfo; } - + public String getFaultInfo() { return faultInfo; } diff --git a/src/main/java/es/uvigo/esei/dai/ws/calculator/CalculatorService.java b/src/main/java/es/uvigo/esei/dai/ws/calculator/CalculatorService.java index c56d95b..5a6fd9e 100644 --- a/src/main/java/es/uvigo/esei/dai/ws/calculator/CalculatorService.java +++ b/src/main/java/es/uvigo/esei/dai/ws/calculator/CalculatorService.java @@ -1,20 +1,56 @@ package es.uvigo.esei.dai.ws.calculator; +import java.util.Collection; + +import es.uvigo.esei.dai.ws.calculator.adapters.NamedOperations; +import es.uvigo.esei.dai.ws.calculator.adapters.NamedResults; import jakarta.jws.WebMethod; import jakarta.jws.WebService; @WebService -// @SOAPBinding(style = Style.RPC) public interface CalculatorService { @WebMethod public double add(double op1, double op2); - + @WebMethod public double subtract(double op1, double op2); - + @WebMethod public double multiply(double op1, double op2); - + + @WebMethod + public double divide(double op1, double op2) + throws CalculatorException; + + @WebMethod + public double operate(Operation operation, double op1, double op2) + throws CalculatorException; + + @WebMethod + public double serialOperate(Operation operation, double ... op) + throws CalculatorException; + + @WebMethod + public double arrayOperate(Operation operation, double[] op) + throws CalculatorException; + + @WebMethod + public double listOperate(Operation operation, Collection op) + throws CalculatorException; + + /* + * JAXB no soporta esta declaración de método porque hace uso de Map, + * que es una interfaz y JAXB no es capaz de trabajar con interfaces + * directamente. + * + * @WebMethod + * public Map mapOperate( + * Map operations, double op1, double op2 + * ) throws CalculatorException; + */ + @WebMethod - public double divide(double op1, double op2) throws CalculatorException; + public NamedResults mapOperate( + NamedOperations operations, double op1, double op2 + ) throws CalculatorException; } diff --git a/src/main/java/es/uvigo/esei/dai/ws/calculator/CalculatorServiceClient.java b/src/main/java/es/uvigo/esei/dai/ws/calculator/CalculatorServiceClient.java index 963b46c..370536f 100644 --- a/src/main/java/es/uvigo/esei/dai/ws/calculator/CalculatorServiceClient.java +++ b/src/main/java/es/uvigo/esei/dai/ws/calculator/CalculatorServiceClient.java @@ -2,9 +2,14 @@ package es.uvigo.esei.dai.ws.calculator; import java.net.MalformedURLException; import java.net.URL; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; import javax.xml.namespace.QName; +import es.uvigo.esei.dai.ws.calculator.adapters.NamedOperations; +import es.uvigo.esei.dai.ws.calculator.adapters.NamedResults; import jakarta.xml.ws.Service; public class CalculatorServiceClient { @@ -20,10 +25,37 @@ public class CalculatorServiceClient { final CalculatorService calculator = service.getPort(CalculatorService.class); + System.out.println("Basic methods results"); System.out.println(calculator.add(20d, 30d)); System.out.println(calculator.subtract(20d, 30d)); - System.out.println(calculator.multiply(20d, 0d)); + System.out.println(calculator.multiply(20d, 30d)); System.out.println(calculator.divide(20d, 30d)); + + System.out.println("\nOperate results"); + System.out.println(calculator.operate(Operation.ADD, 20d, 30d)); + System.out.println(calculator.operate(Operation.SUB, 20d, 30d)); + System.out.println(calculator.operate(Operation.MUL, 20d, 30d)); + System.out.println(calculator.operate(Operation.DIV, 20d, 30d)); + + System.out.println("\nCollections results"); + System.out.println("Serial: " + calculator.serialOperate(Operation.ADD, 10d, 20d, 30d)); + System.out.println("Array: " + calculator.arrayOperate(Operation.ADD, new double[]{10d, 20d, 30d})); + System.out.println("List: " + calculator.listOperate(Operation.ADD, Arrays.asList(10d, 20d, 30d))); + + System.out.println("\nMap results"); + final Map operations = new HashMap(); + for (Operation operation : Operation.values()) { + operations.put(operation.name(), operation); + } + + final NamedResults results = calculator.mapOperate( + new NamedOperations(operations), 20d, 30d + ); + for (Map.Entry entry : results.getResults().entrySet()) { + System.out.println(entry.getKey() + ": " + entry.getValue()); + } + + System.out.println("\nException"); try { System.out.println(calculator.divide(20d, 0d)); } catch (CalculatorException e) { diff --git a/src/main/java/es/uvigo/esei/dai/ws/calculator/CalculatorServiceImpl.java b/src/main/java/es/uvigo/esei/dai/ws/calculator/CalculatorServiceImpl.java index 008a776..b68be4d 100644 --- a/src/main/java/es/uvigo/esei/dai/ws/calculator/CalculatorServiceImpl.java +++ b/src/main/java/es/uvigo/esei/dai/ws/calculator/CalculatorServiceImpl.java @@ -1,29 +1,110 @@ package es.uvigo.esei.dai.ws.calculator; +import java.util.ArrayList; +import java.util.Collection; +import java.util.List; +import java.util.Map; + +import es.uvigo.esei.dai.ws.calculator.adapters.NamedOperations; +import es.uvigo.esei.dai.ws.calculator.adapters.NamedResults; import jakarta.jws.WebService; @WebService(endpointInterface = "es.uvigo.esei.dai.ws.calculator.CalculatorService") public class CalculatorServiceImpl implements CalculatorService { @Override public double add(double op1, double op2) { - return op1 + op2; + return this.operate(Operation.ADD, op1, op2); } @Override public double subtract(double op1, double op2) { - return op1 - op2; + return this.operate(Operation.SUB, op1, op2); } @Override public double multiply(double op1, double op2) { - return op1 * op2; + return this.operate(Operation.MUL, op1, op2); } @Override public double divide(double op1, double op2) throws CalculatorException { - if (op2 == 0d) - throw new CalculatorException("op2 can't be zero"); + return this.operate(Operation.DIV, op1, op2); + } + + @Override + public double operate(Operation operation, double op1, double op2) + throws CalculatorException { + return operation.calculate(op1, op2); + } + + @Override + public double serialOperate(Operation operation, double ... op) + throws CalculatorException { + if (op.length <= 1) { + throw new CalculatorException("There must be, at least, two operands"); + } else { + double result = op[0]; + + for (int i = 1; i < op.length; i++) { + result = operation.calculate(result, op[i]); + } + + return result; + } + } - return op1 / op2; + @Override + public double arrayOperate(Operation operation, double[] op) + throws CalculatorException { + return this.serialOperate(operation, op); + } + + @Override + public double listOperate(Operation operation, Collection op) + throws CalculatorException { + if (op.size() <= 1) { + throw new CalculatorException("There must be, at least, two operands"); + } else { + final List values = new ArrayList(op); + double result = values.get(0); + + for (int i = 1; i < op.size(); i++) { + result = operation.calculate(result, values.get(i)); + } + + return result; + } + } + + /* + * Ejemplo de implementación para declaración no válida de "mapOperate" + * + * @Override + * public Map mapOperate( + * Map operations, double op1, double op2 + * ) throws CalculatorException { + * final Map results = new HashMap(); + * + * for (Map.Entry entry : operations.entrySet()) { + * results.put(entry.getKey(), entry.getValue().calculate(op1, op2)); + * } + * return results; + * } + */ + + @Override + public NamedResults mapOperate( + NamedOperations operations, double op1, double op2 + ) throws CalculatorException { + final NamedResults results = new NamedResults(); + + final Map operationsMap = operations.getOperations(); + final Map resultsMap = results.getResults(); + + for (Map.Entry entry : operationsMap.entrySet()) { + resultsMap.put(entry.getKey(), entry.getValue().calculate(op1, op2)); + } + + return results; } } diff --git a/src/main/java/es/uvigo/esei/dai/ws/calculator/Operation.java b/src/main/java/es/uvigo/esei/dai/ws/calculator/Operation.java new file mode 100644 index 0000000..8cf3f5f --- /dev/null +++ b/src/main/java/es/uvigo/esei/dai/ws/calculator/Operation.java @@ -0,0 +1,27 @@ +package es.uvigo.esei.dai.ws.calculator; + +public enum Operation { + ADD, SUB, MUL, DIV; + + public double calculate(double op1, double op2) + throws CalculatorException { + switch(this) { + case ADD: return op1 + op2; + case SUB: return op1 - op2; + case MUL: return op1 * op2; + case DIV: + if (op2 == 0d) { + throw new CalculatorException( + "op2 can't be zero", "op2 can't be zero" + ); + } else { + return op1 / op2; + } + default: + throw new CalculatorException( + "Unknown operation: " + this, + "Unknown operation: " + this + ); + } + } +} diff --git a/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedOperations.java b/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedOperations.java new file mode 100644 index 0000000..40415e8 --- /dev/null +++ b/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedOperations.java @@ -0,0 +1,31 @@ +package es.uvigo.esei.dai.ws.calculator.adapters; + +import java.util.HashMap; +import java.util.Map; + +import es.uvigo.esei.dai.ws.calculator.Operation; +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +@XmlRootElement +public class NamedOperations { + private Map operations; + + public NamedOperations() { + this.operations = new HashMap(); + } + + public NamedOperations(Map operations) { + super(); + this.operations = operations; + } + + @XmlJavaTypeAdapter(NamedOperationsMapAdapter.class) + public Map getOperations() { + return operations; + } + + public void setOperations(Map operations) { + this.operations = operations; + } +} diff --git a/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedOperationsEntry.java b/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedOperationsEntry.java new file mode 100644 index 0000000..b61ecaa --- /dev/null +++ b/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedOperationsEntry.java @@ -0,0 +1,38 @@ +package es.uvigo.esei.dai.ws.calculator.adapters; + +import java.util.Map; + +import es.uvigo.esei.dai.ws.calculator.Operation; + +public class NamedOperationsEntry { + private String key; + private Operation value; + + public NamedOperationsEntry() { + } + + public NamedOperationsEntry(String key, Operation value) { + this.key = key; + this.value = value; + } + + public NamedOperationsEntry(Map.Entry entry) { + this(entry.getKey(), entry.getValue()); + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public Operation getValue() { + return value; + } + + public void setValue(Operation value) { + this.value = value; + } +} diff --git a/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedOperationsMap.java b/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedOperationsMap.java new file mode 100644 index 0000000..36a49e3 --- /dev/null +++ b/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedOperationsMap.java @@ -0,0 +1,42 @@ +package es.uvigo.esei.dai.ws.calculator.adapters; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +import es.uvigo.esei.dai.ws.calculator.Operation; + +public class NamedOperationsMap { + private List entries; + + public NamedOperationsMap() { + this.entries = new LinkedList(); + } + + public NamedOperationsMap(Map map) { + this(); + + for (Map.Entry entry : map.entrySet()) { + this.entries.add(new NamedOperationsEntry(entry)); + } + } + + public Map createMap() { + final Map map = new HashMap(); + + for (NamedOperationsEntry entry : this.entries) { + map.put(entry.getKey(), entry.getValue()); + } + + return map; + } + + public List getEntries() { + return entries; + } + + public void setEntries(List entries) { + this.entries = entries; + } +} diff --git a/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedOperationsMapAdapter.java b/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedOperationsMapAdapter.java new file mode 100644 index 0000000..d9a1cab --- /dev/null +++ b/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedOperationsMapAdapter.java @@ -0,0 +1,20 @@ +package es.uvigo.esei.dai.ws.calculator.adapters; + +import java.util.Map; + +import es.uvigo.esei.dai.ws.calculator.Operation; +import jakarta.xml.bind.annotation.adapters.XmlAdapter; + +public class NamedOperationsMapAdapter +extends XmlAdapter> { + + @Override + public Map unmarshal(NamedOperationsMap v) { + return v.createMap(); + } + + @Override + public NamedOperationsMap marshal(Map v) { + return new NamedOperationsMap(v); + } +} diff --git a/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedResults.java b/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedResults.java new file mode 100644 index 0000000..3cd1290 --- /dev/null +++ b/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedResults.java @@ -0,0 +1,29 @@ +package es.uvigo.esei.dai.ws.calculator.adapters; + +import java.util.HashMap; +import java.util.Map; + +import jakarta.xml.bind.annotation.XmlRootElement; +import jakarta.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +@XmlRootElement +public class NamedResults { + private Map results; + + public NamedResults() { + this.results = new HashMap(); + } + + public NamedResults(Map results) { + this.results = results; + } + + @XmlJavaTypeAdapter(NamedResultsMapAdapter.class) + public Map getResults() { + return results; + } + + public void setResults(Map results) { + this.results = results; + } +} diff --git a/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedResultsEntry.java b/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedResultsEntry.java new file mode 100644 index 0000000..ad76459 --- /dev/null +++ b/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedResultsEntry.java @@ -0,0 +1,36 @@ +package es.uvigo.esei.dai.ws.calculator.adapters; + +import java.util.Map; + +public class NamedResultsEntry { + private String key; + private Double value; + + public NamedResultsEntry() { + } + + public NamedResultsEntry(String key, Double value) { + this.key = key; + this.value = value; + } + + public NamedResultsEntry(Map.Entry entry) { + this(entry.getKey(), entry.getValue()); + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public Double getValue() { + return value; + } + + public void setValue(Double value) { + this.value = value; + } +} diff --git a/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedResultsMap.java b/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedResultsMap.java new file mode 100644 index 0000000..d9ef637 --- /dev/null +++ b/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedResultsMap.java @@ -0,0 +1,40 @@ +package es.uvigo.esei.dai.ws.calculator.adapters; + +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; + +public class NamedResultsMap { + private List entries; + + public NamedResultsMap() { + this.entries = new LinkedList(); + } + + public NamedResultsMap(Map map) { + this(); + + for (Map.Entry entry : map.entrySet()) { + this.entries.add(new NamedResultsEntry(entry)); + } + } + + public Map createMap() { + final Map map = new HashMap(); + + for (NamedResultsEntry entry : this.entries) { + map.put(entry.getKey(), entry.getValue()); + } + + return map; + } + + public List getEntries() { + return entries; + } + + public void setEntries(List entries) { + this.entries = entries; + } +} diff --git a/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedResultsMapAdapter.java b/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedResultsMapAdapter.java new file mode 100644 index 0000000..5bf7a7b --- /dev/null +++ b/src/main/java/es/uvigo/esei/dai/ws/calculator/adapters/NamedResultsMapAdapter.java @@ -0,0 +1,19 @@ +package es.uvigo.esei.dai.ws.calculator.adapters; + +import java.util.Map; + +import jakarta.xml.bind.annotation.adapters.XmlAdapter; + +public class NamedResultsMapAdapter +extends XmlAdapter> { + + @Override + public Map unmarshal(NamedResultsMap v) { + return v.createMap(); + } + + @Override + public NamedResultsMap marshal(Map v) { + return new NamedResultsMap(v); + } +} -- 2.18.1