diff --git a/pom.xml b/pom.xml index 1e164e1..1a923bd 100644 --- a/pom.xml +++ b/pom.xml @@ -40,6 +40,10 @@ test + + + + org.projectlombok diff --git a/src/main/java/org/gcube/spatial/data/sdi/interfaces/Metadata.java b/src/main/java/org/gcube/spatial/data/sdi/interfaces/Metadata.java index a98129e..45f976b 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/interfaces/Metadata.java +++ b/src/main/java/org/gcube/spatial/data/sdi/interfaces/Metadata.java @@ -1,15 +1,14 @@ package org.gcube.spatial.data.sdi.interfaces; import java.io.File; -import java.util.Set; import org.gcube.spatial.data.sdi.model.metadata.MetadataPublishOptions; import org.gcube.spatial.data.sdi.model.metadata.MetadataReport; -import org.gcube.spatial.data.sdi.model.metadata.TemplateDescriptor; +import org.gcube.spatial.data.sdi.model.metadata.TemplateCollection; public interface Metadata { - public Set getAvailableTemplates(); + public TemplateCollection getAvailableTemplates(); public MetadataReport pushMetadata(File toPublish); public MetadataReport pushMetadata(File toPublish,MetadataPublishOptions options); } diff --git a/src/main/java/org/gcube/spatial/data/sdi/model/MapAdapter.java b/src/main/java/org/gcube/spatial/data/sdi/model/MapAdapter.java new file mode 100644 index 0000000..068e148 --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/model/MapAdapter.java @@ -0,0 +1,50 @@ +package org.gcube.spatial.data.sdi.model; + +import java.util.HashMap; +import java.util.Map; +import java.util.Map.Entry; + +import javax.xml.bind.annotation.adapters.XmlAdapter; +import javax.xml.parsers.DocumentBuilder; +import javax.xml.parsers.DocumentBuilderFactory; + +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +public class MapAdapter extends XmlAdapter> { + + private DocumentBuilder documentBuilder; + + public MapAdapter() throws Exception { + documentBuilder = DocumentBuilderFactory.newInstance().newDocumentBuilder(); + } + + @Override + public Element marshal(Map map) throws Exception { + Document document = documentBuilder.newDocument(); + Element rootElement = document.createElement("data"); + document.appendChild(rootElement); + for(Entry entry : map.entrySet()) { + Element childElement = document.createElement(entry.getKey()); + childElement.setTextContent(entry.getValue()); + rootElement.appendChild(childElement); + } + return rootElement; + } + + @Override + public Map unmarshal(Element rootElement) throws Exception { + NodeList nodeList = rootElement.getChildNodes(); + Map map = new HashMap(nodeList.getLength()); + for(int x=0; x invocations){ setTemplateInvocations(invocations); + + } } diff --git a/src/main/java/org/gcube/spatial/data/sdi/model/metadata/MetadataReport.java b/src/main/java/org/gcube/spatial/data/sdi/model/metadata/MetadataReport.java index 3068c08..5b167dd 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/model/metadata/MetadataReport.java +++ b/src/main/java/org/gcube/spatial/data/sdi/model/metadata/MetadataReport.java @@ -21,14 +21,14 @@ import lombok.ToString; @ToString @EqualsAndHashCode @XmlRootElement -@XmlAccessorType(XmlAccessType.NONE) +@XmlAccessorType(XmlAccessType.FIELD) public class MetadataReport { - @XmlElement + private String publishedUUID; - @XmlElement + private Long publishedID; - @XmlElement + private Set appliedTemplates; } diff --git a/src/main/java/org/gcube/spatial/data/sdi/model/metadata/SetWrapper.java b/src/main/java/org/gcube/spatial/data/sdi/model/metadata/SetWrapper.java deleted file mode 100644 index e655005..0000000 --- a/src/main/java/org/gcube/spatial/data/sdi/model/metadata/SetWrapper.java +++ /dev/null @@ -1,56 +0,0 @@ -package org.gcube.spatial.data.sdi.model.metadata; - -import java.util.HashSet; -import java.util.Set; - -import javax.xml.bind.annotation.XmlAnyElement; - -public class SetWrapper { - - private Set set; - - public SetWrapper() { - set=new HashSet(); - } - - public SetWrapper(Set set){ - this.set=set; - } - - @XmlAnyElement(lax=true) - public Set getSet(){ - return set; - } - - @Override - public int hashCode() { - final int prime = 31; - int result = 1; - if(set==null) - result=prime*result; - else - for(T obj:set) - result = prime * result + ((obj == null) ? 0 : obj.hashCode()); - return result; - } - - @Override - public boolean equals(Object obj) { - if (this == obj) - return true; - if (obj == null) - return false; - if (getClass() != obj.getClass()) - return false; - SetWrapper other = (SetWrapper) obj; - if (set == null) { - if (other.set != null) - return false; - } else - if(!other.set.containsAll(set)) return false; - else if (!set.containsAll(other.set)) return false; - return true; - } - - -} diff --git a/src/main/java/org/gcube/spatial/data/sdi/model/metadata/TemplateApplicationRequest.java b/src/main/java/org/gcube/spatial/data/sdi/model/metadata/TemplateApplicationRequest.java new file mode 100644 index 0000000..2653100 --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/model/metadata/TemplateApplicationRequest.java @@ -0,0 +1,69 @@ +package org.gcube.spatial.data.sdi.model.metadata; + +import java.util.HashSet; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class TemplateApplicationRequest { + + private HashSet invocationSet; + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + if(invocationSet!=null && !invocationSet.isEmpty()) + for(TemplateInvocation inv:invocationSet) + result=prime*result+inv.hashCode(); + + return result; + } + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + TemplateApplicationRequest other = (TemplateApplicationRequest) obj; + + + if (invocationSet == null ) { + if (other.invocationSet != null) + return false; + } else if (invocationSet.size()!=other.invocationSet.size()) + return false; + else for(TemplateInvocation inv:invocationSet) { + boolean ok=false; + for(TemplateInvocation inv2:other.invocationSet) + if(inv.equals(inv2)) { + ok=true; + break; + } + if(!ok)return false; + } + + + return true; + } + + + + +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/model/metadata/TemplateCollection.java b/src/main/java/org/gcube/spatial/data/sdi/model/metadata/TemplateCollection.java new file mode 100644 index 0000000..b0dbfd1 --- /dev/null +++ b/src/main/java/org/gcube/spatial/data/sdi/model/metadata/TemplateCollection.java @@ -0,0 +1,63 @@ +package org.gcube.spatial.data.sdi.model.metadata; + +import java.util.HashSet; +import java.util.Set; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +import lombok.AllArgsConstructor; +import lombok.Getter; +import lombok.NoArgsConstructor; +import lombok.Setter; +import lombok.ToString; + +@Getter +@Setter +@NoArgsConstructor +@AllArgsConstructor +@ToString +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class TemplateCollection { + + private Set availableTemplates=new HashSet(); + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + if(availableTemplates!=null && !availableTemplates.isEmpty()) + for(TemplateDescriptor inv:availableTemplates) + result=prime*result+inv.hashCode(); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + TemplateCollection other = (TemplateCollection) obj; + + + if (availableTemplates == null ) { + if (other.availableTemplates != null) + return false; + } else if (availableTemplates.size()!=other.availableTemplates.size()) + return false; + else for(TemplateDescriptor inv:availableTemplates) + if(!other.availableTemplates.contains(inv))return false; + + + + return true; + } + + + +} diff --git a/src/main/java/org/gcube/spatial/data/sdi/model/metadata/TemplateDescriptor.java b/src/main/java/org/gcube/spatial/data/sdi/model/metadata/TemplateDescriptor.java index 456716f..d837189 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/model/metadata/TemplateDescriptor.java +++ b/src/main/java/org/gcube/spatial/data/sdi/model/metadata/TemplateDescriptor.java @@ -1,13 +1,17 @@ package org.gcube.spatial.data.sdi.model.metadata; +import java.util.HashMap; +import java.util.Map.Entry; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlID; +import javax.xml.bind.annotation.XmlAnyElement; import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +import org.gcube.spatial.data.sdi.model.MapAdapter; import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -18,18 +22,86 @@ import lombok.ToString; @NoArgsConstructor @AllArgsConstructor @ToString -@EqualsAndHashCode @XmlRootElement -@XmlAccessorType(XmlAccessType.NONE) +@XmlAccessorType(XmlAccessType.FIELD) public class TemplateDescriptor { - @XmlID - private String id; - - @XmlElement + private String id; private String name; - @XmlElement private String description; - @XmlElement private String sourceURL; + + @XmlAnyElement + @XmlJavaTypeAdapter(MapAdapter.class) + private HashMap expectedParameters; + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + + if(!(expectedParameters == null || expectedParameters.isEmpty())) + for(Entry entry:expectedParameters.entrySet()) { + result=prime*result+entry.getKey().hashCode(); + result=prime*result+entry.getValue().hashCode(); + } + + + result = prime * result + ((description == null) ? 0 : description.hashCode()); + + result = prime * result + ((id == null) ? 0 : id.hashCode()); + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((sourceURL == null) ? 0 : sourceURL.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + TemplateDescriptor other = (TemplateDescriptor) obj; + if (description == null) { + if (other.description != null) + return false; + } else if (!description.equals(other.description)) + return false; + + + + if (expectedParameters == null || expectedParameters.isEmpty()) { + if (!(other.expectedParameters == null || other.expectedParameters.isEmpty())) + return false; + } else if (expectedParameters.size()!=other.expectedParameters.size()) + return false; + else for(Entry entry:expectedParameters.entrySet()) + if(!entry.getValue().equals(other.expectedParameters.get(entry.getKey()))) return false; + + + + + + if (id == null) { + if (other.id != null) + return false; + } else if (!id.equals(other.id)) + return false; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (sourceURL == null) { + if (other.sourceURL != null) + return false; + } else if (!sourceURL.equals(other.sourceURL)) + return false; + return true; + } + + + } diff --git a/src/main/java/org/gcube/spatial/data/sdi/model/metadata/TemplateInvocation.java b/src/main/java/org/gcube/spatial/data/sdi/model/metadata/TemplateInvocation.java index f543289..2c6e4e9 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/model/metadata/TemplateInvocation.java +++ b/src/main/java/org/gcube/spatial/data/sdi/model/metadata/TemplateInvocation.java @@ -1,12 +1,17 @@ package org.gcube.spatial.data.sdi.model.metadata; +import java.util.HashMap; +import java.util.Map.Entry; + import javax.xml.bind.annotation.XmlAccessType; import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlID; -import javax.xml.bind.annotation.XmlSeeAlso; +import javax.xml.bind.annotation.XmlAnyElement; +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter; + +import org.gcube.spatial.data.sdi.model.MapAdapter; import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; import lombok.Getter; import lombok.NoArgsConstructor; import lombok.Setter; @@ -17,11 +22,58 @@ import lombok.ToString; @NoArgsConstructor @AllArgsConstructor @ToString -@EqualsAndHashCode -@XmlAccessorType(XmlAccessType.NONE) -@XmlSeeAlso({ThreddsOnlineTemplateInvocation.class}) -public abstract class TemplateInvocation { - @XmlID +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class TemplateInvocation { + private String toInvokeTemplateID; + @XmlAnyElement + @XmlJavaTypeAdapter(MapAdapter.class) + private HashMap templateParameters; + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + if(!(templateParameters == null || templateParameters.isEmpty())) + for(Entry entry:templateParameters.entrySet()) { + result=prime*result+entry.getKey().hashCode(); + result=prime*result+entry.getValue().hashCode(); + } + + + result = prime * result + ((toInvokeTemplateID == null) ? 0 : toInvokeTemplateID.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + TemplateInvocation other = (TemplateInvocation) obj; + + if (templateParameters == null ) { + if (other.templateParameters != null) + return false; + } else if (templateParameters.size()!=other.templateParameters.size()) + return false; + else for(Entry entry:templateParameters.entrySet()) + if(!entry.getValue().equals(other.templateParameters.get(entry.getKey()))) + return false; + + + if (toInvokeTemplateID == null) { + if (other.toInvokeTemplateID != null) + return false; + } else if (!toInvokeTemplateID.equals(other.toInvokeTemplateID)) + return false; + return true; + } + + } diff --git a/src/main/java/org/gcube/spatial/data/sdi/model/metadata/TemplateInvocationBuilder.java b/src/main/java/org/gcube/spatial/data/sdi/model/metadata/TemplateInvocationBuilder.java index e967a1c..8567fd8 100644 --- a/src/main/java/org/gcube/spatial/data/sdi/model/metadata/TemplateInvocationBuilder.java +++ b/src/main/java/org/gcube/spatial/data/sdi/model/metadata/TemplateInvocationBuilder.java @@ -1,22 +1,37 @@ package org.gcube.spatial.data.sdi.model.metadata; +import java.util.HashMap; import java.util.HashSet; -import java.util.Set; public class TemplateInvocationBuilder { + // Constants + public static final class THREDDS_ONLINE{ + public static final String ID="THREDDS_ONLINE_RESOURCES"; + public static final String HOSTNAME="hostname"; + public static final String FILENAME="filename"; + public static final String CATALOG="catalog"; + } - private Set invocations=new HashSet(); + + + + private HashSet invocations=new HashSet(); public TemplateInvocationBuilder threddsOnlineResources(String hostname, String filename, String catalog){ - ThreddsOnlineTemplateInvocation toAdd=new ThreddsOnlineTemplateInvocation(hostname,filename,catalog); - toAdd.setToInvokeTemplateID(ThreddsOnlineTemplateInvocation.ID); + TemplateInvocation toAdd=new TemplateInvocation(); + toAdd.setToInvokeTemplateID(THREDDS_ONLINE.ID); + HashMap parameters=new HashMap(); + parameters.put(THREDDS_ONLINE.HOSTNAME, hostname); + parameters.put(THREDDS_ONLINE.FILENAME, filename); + parameters.put(THREDDS_ONLINE.CATALOG, catalog); + toAdd.setTemplateParameters(parameters); invocations.add(toAdd); return this; } - public Set get(){ + public HashSet get(){ return invocations; } } diff --git a/src/main/java/org/gcube/spatial/data/sdi/model/metadata/ThreddsOnlineTemplateInvocation.java b/src/main/java/org/gcube/spatial/data/sdi/model/metadata/ThreddsOnlineTemplateInvocation.java deleted file mode 100644 index ec827f2..0000000 --- a/src/main/java/org/gcube/spatial/data/sdi/model/metadata/ThreddsOnlineTemplateInvocation.java +++ /dev/null @@ -1,34 +0,0 @@ -package org.gcube.spatial.data.sdi.model.metadata; - -import javax.xml.bind.annotation.XmlAccessType; -import javax.xml.bind.annotation.XmlAccessorType; -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; - -import lombok.AllArgsConstructor; -import lombok.EqualsAndHashCode; -import lombok.Getter; -import lombok.NoArgsConstructor; -import lombok.Setter; -import lombok.ToString; - -@Getter -@Setter -@NoArgsConstructor -@AllArgsConstructor -@ToString -@EqualsAndHashCode -@XmlRootElement -@XmlAccessorType(XmlAccessType.NONE) -public class ThreddsOnlineTemplateInvocation extends TemplateInvocation{ - - public static final String ID="THREDDS_ONLINE_RESOURCES"; - - @XmlElement - private String hostname; - @XmlElement - private String filename; - @XmlElement - private String catalog; - -} diff --git a/src/test/java/org/gcube/spatial/data/sdi/MarshallUnmarshallTest.java b/src/test/java/org/gcube/spatial/data/sdi/MarshallUnmarshallTest.java index 720df11..1967fab 100644 --- a/src/test/java/org/gcube/spatial/data/sdi/MarshallUnmarshallTest.java +++ b/src/test/java/org/gcube/spatial/data/sdi/MarshallUnmarshallTest.java @@ -8,11 +8,9 @@ import java.io.Reader; import java.io.StringReader; import java.io.StringWriter; import java.io.Writer; -import java.util.Collection; import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; -import java.util.Iterator; -import java.util.Set; import javax.xml.bind.JAXBContext; import javax.xml.bind.JAXBException; @@ -23,12 +21,12 @@ import javax.xml.transform.Source; import javax.xml.transform.stream.StreamResult; import javax.xml.transform.stream.StreamSource; +import org.gcube.spatial.data.sdi.model.faults.ErrorMessage; import org.gcube.spatial.data.sdi.model.metadata.MetadataReport; -import org.gcube.spatial.data.sdi.model.metadata.SetWrapper; +import org.gcube.spatial.data.sdi.model.metadata.TemplateApplicationRequest; +import org.gcube.spatial.data.sdi.model.metadata.TemplateCollection; import org.gcube.spatial.data.sdi.model.metadata.TemplateDescriptor; -import org.gcube.spatial.data.sdi.model.metadata.TemplateInvocation; import org.gcube.spatial.data.sdi.model.metadata.TemplateInvocationBuilder; -import org.gcube.spatial.data.sdi.model.metadata.ThreddsOnlineTemplateInvocation; import org.junit.BeforeClass; import org.junit.Test; @@ -36,24 +34,34 @@ public class MarshallUnmarshallTest { static JAXBContext ctx =null; + + @BeforeClass public static void init() throws JAXBException{ ctx = JAXBContext.newInstance( - MetadataReport.class, - TemplateDescriptor.class, - TemplateInvocation.class, - SetWrapper.class); + MetadataReport.class, + TemplateApplicationRequest.class, + TemplateCollection.class, + ErrorMessage.class); } public static boolean roundTrip(Object obj){ - if(obj.getClass().isAssignableFrom(SetWrapper.class)){ - for(Object x:((SetWrapper)obj).getSet()) - if(!roundTrip(x)) return false; - return true; - }else{ + Object roundTripResult=unmarshal(obj.getClass(), new StringReader(marshal(obj,new StringWriter()).toString())); return obj.equals(roundTripResult); - } + + } + + @Test + public void testHashAndEquals() { + assertTrue(getTemplateInvocations().equals(getTemplateInvocations())); + assertTrue(getTemplateInvocations().hashCode()==getTemplateInvocations().hashCode()); + assertTrue(getDescriptors().equals(getDescriptors())); + assertTrue(getDescriptors().hashCode()==getDescriptors().hashCode()); + assertTrue(getReport().equals(getReport())); + assertTrue(getReport().hashCode()==getReport().hashCode()); + assertTrue(getError().equals(getError())); + assertTrue(getError().hashCode()==getError().hashCode()); } @@ -62,12 +70,14 @@ static JAXBContext ctx =null; print(getTemplateInvocations()); print(getDescriptors()); print(getReport()); + print(getError()); } @Test public void unMarshall(){ assertTrue(roundTrip(getTemplateInvocations())); assertTrue(roundTrip(getDescriptors())); assertTrue(roundTrip(getReport())); + assertTrue(roundTrip(getError())); } @Test @@ -75,6 +85,7 @@ static JAXBContext ctx =null; System.out.println(getTemplateInvocations()); System.out.println(getDescriptors()); System.out.println(getReport()); + System.out.println(getError()); } /** @@ -167,17 +178,28 @@ static JAXBContext ctx =null; } } - private SetWrapper getTemplateInvocations(){ - return new SetWrapper(new TemplateInvocationBuilder().threddsOnlineResources("localhost", "myDataset.nc", "my Catalog").get()); + private TemplateApplicationRequest getTemplateInvocations(){ + return new TemplateApplicationRequest(new TemplateInvocationBuilder().threddsOnlineResources("localhost", "myDataset.nc", "my Catalog").get()); } - private SetWrapper getDescriptors(){ + private TemplateCollection getDescriptors(){ HashSet descriptors=new HashSet<>(); - descriptors.add(new TemplateDescriptor(ThreddsOnlineTemplateInvocation.ID,"Thredds Online Resources","Online reousrce template for thredds resources","http://some.place.org/theTemplate")); - return new SetWrapper(descriptors); + descriptors.add(new TemplateDescriptor(TemplateInvocationBuilder.THREDDS_ONLINE.ID,"Thredds Online Resources","Online reousrce template for thredds resources","http://some.place.org/theTemplate", new HashMap())); + descriptors.add(new TemplateDescriptor(TemplateInvocationBuilder.THREDDS_ONLINE.ID,"Thredds Online Resources","Online reousrce template for thredds resources","http://some.place.org/theTemplate", new HashMap())); + return new TemplateCollection(descriptors); } private MetadataReport getReport(){ - return new MetadataReport("theUUID", 12335l, Collections.singleton(ThreddsOnlineTemplateInvocation.ID)); + return new MetadataReport("theUUID", 12335l, Collections.singleton(TemplateInvocationBuilder.THREDDS_ONLINE.ID)); + } + + + private ErrorMessage getError(){ + ErrorMessage error=new ErrorMessage(); + error.setCode(500); + error.setDeveloperMessage("Develop it better!"); + error.setMessage("You didn't see anything"); + error.setLink("www.sto.ca.z.z.o.org"); + return error; } }