diff --git a/src/main/java/org/energyos/espi/common/models/atom/adapters/TimeConfigurationAdapter.java b/src/main/java/org/energyos/espi/common/models/atom/adapters/TimeConfigurationAdapter.java index 6c303808..0a515351 100644 --- a/src/main/java/org/energyos/espi/common/models/atom/adapters/TimeConfigurationAdapter.java +++ b/src/main/java/org/energyos/espi/common/models/atom/adapters/TimeConfigurationAdapter.java @@ -1,5 +1,5 @@ /* - * Copyright 2013 EnergyOS.org + * Copyright 2013, 2014 EnergyOS.org * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,12 +18,12 @@ import org.energyos.espi.common.domain.ObjectFactory; import org.energyos.espi.common.domain.TimeConfiguration; +import org.energyos.espi.common.utils.AtomMarshallerListener; import javax.xml.bind.JAXBElement; import javax.xml.bind.annotation.adapters.XmlAdapter; - public class TimeConfigurationAdapter extends XmlAdapter, TimeConfiguration> { - + @Override public TimeConfiguration unmarshal(JAXBElement v) throws Exception { return v.getValue(); @@ -34,6 +34,7 @@ public JAXBElement marshal(TimeConfiguration v) throws Except if(v == null) { return null; } - return new JAXBElement<>(ObjectFactory.LocalTimeParameters_QNAME, TimeConfiguration.class, v); + JAXBElement element = new JAXBElement<>(ObjectFactory.LocalTimeParameters_QNAME, TimeConfiguration.class, v); + return element; } } diff --git a/src/main/java/org/energyos/espi/common/service/ApplicationInformationService.java b/src/main/java/org/energyos/espi/common/service/ApplicationInformationService.java index d5e7b49d..f3f963f9 100755 --- a/src/main/java/org/energyos/espi/common/service/ApplicationInformationService.java +++ b/src/main/java/org/energyos/espi/common/service/ApplicationInformationService.java @@ -49,6 +49,10 @@ public ApplicationInformation findByDataCustodianClientId( // import-export services public ApplicationInformation importResource(InputStream stream); - ApplicationInformation findByUUID(UUID uuid); + public ApplicationInformation findByUUID(UUID uuid); + + public void setApplicationInformation(ApplicationInformation applicationInformation); + + public String getDataCustodianResourceEndpoint(); } diff --git a/src/main/java/org/energyos/espi/common/service/impl/ApplicationInformationServiceImpl.java b/src/main/java/org/energyos/espi/common/service/impl/ApplicationInformationServiceImpl.java index f6877822..cec2732b 100755 --- a/src/main/java/org/energyos/espi/common/service/impl/ApplicationInformationServiceImpl.java +++ b/src/main/java/org/energyos/espi/common/service/impl/ApplicationInformationServiceImpl.java @@ -26,6 +26,10 @@ @Transactional public class ApplicationInformationServiceImpl implements ApplicationInformationService { + // the cached operational object for this service + // + private ApplicationInformation applicationInformation; + @Autowired private ApplicationInformationRepository applicationInformationRepository; @@ -46,6 +50,23 @@ public void setApplicationInformationRepository(ApplicationInformationRepository this.applicationInformationRepository = applicationInformationRepository; } + // configuration accessors + + @Override + public void setApplicationInformation(ApplicationInformation applicationInformation) { + this.applicationInformation = applicationInformation; + } + + @Override + public String getDataCustodianResourceEndpoint() { + if (this.applicationInformation == null) { + // default it to the seed value + this.setApplicationInformation(this.findById(1L)); + } + return applicationInformation.getDataCustodianResourceEndpoint(); + // return "http://localhost:8080/DataCustodian/espi/1_1/resource"; + } + @Override public List findAll() { return applicationInformationRepository.findAll(); diff --git a/src/main/java/org/energyos/espi/common/service/impl/ExportServiceImpl.java b/src/main/java/org/energyos/espi/common/service/impl/ExportServiceImpl.java index 9e4ddcf3..602bfcfd 100644 --- a/src/main/java/org/energyos/espi/common/service/impl/ExportServiceImpl.java +++ b/src/main/java/org/energyos/espi/common/service/impl/ExportServiceImpl.java @@ -18,6 +18,7 @@ import org.energyos.espi.common.utils.DateConverter; import org.energyos.espi.common.utils.EntryTypeIterator; import org.energyos.espi.common.utils.ExportFilter; +import org.energyos.espi.common.utils.AtomMarshallerListener; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.oxm.jaxb.Jaxb2Marshaller; @@ -26,6 +27,7 @@ import javax.servlet.ServletOutputStream; import javax.xml.bind.JAXBException; +import javax.xml.bind.Marshaller; import javax.xml.bind.Unmarshaller; import javax.xml.transform.stream.StreamResult; @@ -471,15 +473,12 @@ public void exportUsagePointFull(Long usagePointId, Long retailCustomerId, // private void buildHeader (OutputStream stream, String hrefFragment) throws IOException { + + String selfRef = ""; DateTimeType updated = DateConverter.toDateTimeType(new Date()); String temp = updated.getValue().toXMLFormat(); String uuid = UUID.randomUUID().toString(); - - String selfRef = "\n"; - - //GregorianCalendar updated = new GregorianCalendar(); - //updated.setTimeZone(TimeZone.getTimeZone("UTC")) - //String temp = DateConverter.epoch().toString(); + stream.write("\n".getBytes()); stream.write("".getBytes()); stream.write("urn:uuid:".getBytes()); @@ -492,31 +491,37 @@ private void buildHeader (OutputStream stream, String hrefFragment) throws IOExc stream.write(selfRef.getBytes()); } - private void exportEntries(EntryTypeIterator entries, OutputStream stream, ExportFilter exportFilter, Class resourceClass, String hrefFragment) throws IOException { - - buildHeader(stream, hrefFragment); + private void exportEntries(EntryTypeIterator entries, OutputStream stream, + ExportFilter exportFilter, Class resourceClass, String hrefFragment) + throws IOException { - if (entries != null) { - - while (entries.hasNext()) { - try { - EntryType entry = entries.nextEntry(resourceClass); - exportEntry(entry, stream, exportFilter, hrefFragment); - } catch (Exception e) { - stream.write("/* The requested collection contains no resources */".getBytes()); - stream.write("".getBytes()); - } - - } - } - stream.write("".getBytes()); - } + buildHeader(stream, hrefFragment); + + if (entries != null) { + + while (entries.hasNext()) { + try { + EntryType entry = entries.nextEntry(resourceClass); + exportEntry(entry, stream, exportFilter, hrefFragment); + } catch (Exception e) { + stream.write("/* The requested collection contains no resources */" + .getBytes()); + stream.write("".getBytes()); + } + + } + } + stream.write("".getBytes()); + } // to export a single entry (w/o the ... wrappers private void exportEntry(EntryType entry, OutputStream stream, ExportFilter exportFilter, String hrefFragment) throws IOException { + AtomMarshallerListener uriListener = new AtomMarshallerListener(applicationInformationService.getDataCustodianResourceEndpoint() + hrefFragment); + fragmentMarshaller.setMarshallerListener(uriListener); + StreamResult result = new StreamResult(stream); try { if (exportFilter.matches(entry)) { @@ -528,8 +533,10 @@ private void exportEntry(EntryType entry, OutputStream stream, } private void exportEntriesFull(EntryTypeIterator entries, OutputStream stream, ExportFilter exportFilter, String hrefFragment) throws IOException { - - buildHeader(stream, hrefFragment); + + // construct the header components + // + buildHeader(stream, hrefFragment); if (entries != null) { @@ -550,8 +557,13 @@ private void exportEntriesFull(EntryTypeIterator entries, OutputStream stream, E // to export a single entry (w/o the ... wrappers private void exportEntryFull(EntryType entry, OutputStream stream, - ExportFilter exportFilter, String hrefFragement) throws IOException { - + ExportFilter exportFilter, String hrefFragment) throws IOException { + + // setup a listener so that the adapters may later be fed the href fragment; + // + AtomMarshallerListener uriListener = new AtomMarshallerListener(applicationInformationService.getDataCustodianResourceEndpoint() + hrefFragment); + fragmentMarshaller.setMarshallerListener(uriListener); + StreamResult result = new StreamResult(stream); try { if (exportFilter.matches(entry)) { diff --git a/src/main/java/org/energyos/espi/common/utils/AtomMarshallerListener.java b/src/main/java/org/energyos/espi/common/utils/AtomMarshallerListener.java new file mode 100644 index 00000000..62ee5a9a --- /dev/null +++ b/src/main/java/org/energyos/espi/common/utils/AtomMarshallerListener.java @@ -0,0 +1,61 @@ + +package org.energyos.espi.common.utils; + +import javax.xml.bind.Marshaller; + +import org.energyos.espi.common.models.atom.EntryType; +import org.energyos.espi.common.models.atom.LinkType; + +public class AtomMarshallerListener extends Marshaller.Listener { + + private String hrefFragment; + long depth; + + public AtomMarshallerListener(String fragment) { + this.hrefFragment = fragment; + } + + @Override + public void beforeMarshal(Object source) { + depth++; + if ((source instanceof LinkType) && (((LinkType) source).getRel().equals("self"))) { + ((LinkType) source).setHref(mutateFragment((LinkType) source, this.hrefFragment, 0)); + } + if ((source instanceof LinkType) && (((LinkType) source).getRel().equals("up"))) { + + ((LinkType) source).setHref(mutateFragment((LinkType) source, this.hrefFragment, 1)); + } + } + + @Override + public void afterMarshal(Object source) { + depth--; + } + + public String getHrefFragment() { + return this.hrefFragment; + } + + // mutate the fragment based upon up/self/ref semantics + // + private String mutateFragment(Object source, String hrefFragment, Integer key) { + String temp = hrefFragment; + switch (key) { + case 0: // a "self" reference - it should be fine + break; + case 1: // an "up" reference - make sure that if it has a "/id" on the tail, that it is dropped, otherwise its "" + Integer i = temp.lastIndexOf("/"); + String t = temp.substring(i+1); + if (t.matches("-?\\d+(\\.\\d+)?")) { + temp = temp.substring(0, i); + } + break; + default: + // TODO for now, do nothing, but rel="ref" will be a problem + break; + + } + return temp; + + } +} \ No newline at end of file