Skip to content

Commit

Permalink
Merge pull request GreenButtonAlliance#32 from jateeter/master
Browse files Browse the repository at this point in the history
Self and UP <link> support in the export path.
  • Loading branch information
jateeter committed Jan 4, 2014
2 parents d9030a0 + 8bebce1 commit 9349c43
Show file tree
Hide file tree
Showing 5 changed files with 132 additions and 33 deletions.
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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<JAXBElement<TimeConfiguration>, TimeConfiguration> {

@Override
public TimeConfiguration unmarshal(JAXBElement<TimeConfiguration> v) throws Exception {
return v.getValue();
Expand All @@ -34,6 +34,7 @@ public JAXBElement<TimeConfiguration> marshal(TimeConfiguration v) throws Except
if(v == null) {
return null;
}
return new JAXBElement<>(ObjectFactory.LocalTimeParameters_QNAME, TimeConfiguration.class, v);
JAXBElement<TimeConfiguration> element = new JAXBElement<>(ObjectFactory.LocalTimeParameters_QNAME, TimeConfiguration.class, v);
return element;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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();

}
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,10 @@
@Transactional
public class ApplicationInformationServiceImpl implements ApplicationInformationService {

// the cached operational object for this service
//
private ApplicationInformation applicationInformation;

@Autowired
private ApplicationInformationRepository applicationInformationRepository;

Expand All @@ -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<ApplicationInformation> findAll() {
return applicationInformationRepository.findAll();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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;

Expand Down Expand Up @@ -471,15 +473,12 @@ public void exportUsagePointFull(Long usagePointId, Long retailCustomerId,
//

private void buildHeader (OutputStream stream, String hrefFragment) throws IOException {

String selfRef = "<link ref=\"self\" href=\"" + applicationInformationService.getDataCustodianResourceEndpoint() + hrefFragment + "\"/>";
DateTimeType updated = DateConverter.toDateTimeType(new Date());
String temp = updated.getValue().toXMLFormat();
String uuid = UUID.randomUUID().toString();

String selfRef = "<link rel=\"self\" href=\"/espi/1_1/resource" + hrefFragment + "\"/>\n";

//GregorianCalendar updated = new GregorianCalendar();
//updated.setTimeZone(TimeZone.getTimeZone("UTC"))
//String temp = DateConverter.epoch().toString();

stream.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n".getBytes());
stream.write("<feed xmlns=\"http://www.w3.org/2005/Atom\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\">".getBytes());
stream.write("<id>urn:uuid:".getBytes());
Expand All @@ -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("</feed>".getBytes());
}

}
}
stream.write("</feed>".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("</feed>".getBytes());
}

}
}
stream.write("</feed>".getBytes());
}

// to export a single entry (w/o the <feed>...</feed> 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)) {
Expand All @@ -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 <feed> header components
//
buildHeader(stream, hrefFragment);

if (entries != null) {

Expand All @@ -550,8 +557,13 @@ private void exportEntriesFull(EntryTypeIterator entries, OutputStream stream, E
// to export a single entry (w/o the <feed>...</feed> 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)) {
Expand Down
Original file line number Diff line number Diff line change
@@ -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;

}
}

0 comments on commit 9349c43

Please sign in to comment.