diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/primitive/BaseDateTimeDt.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/primitive/BaseDateTimeDt.java index 08d110e698a..0e10c87d8b8 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/primitive/BaseDateTimeDt.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/model/primitive/BaseDateTimeDt.java @@ -34,6 +34,8 @@ import java.util.TimeZone; import javax.xml.bind.DatatypeConverter; +import org.apache.commons.lang3.Validate; +import org.apache.commons.lang3.time.DateUtils; import org.apache.commons.lang3.time.FastDateFormat; import ca.uhn.fhir.model.api.BasePrimitive; @@ -44,17 +46,17 @@ public abstract class BaseDateTimeDt extends BasePrimitive { private static final FastDateFormat ourYearFormat = FastDateFormat.getInstance("yyyy"); private static final FastDateFormat ourYearMonthDayFormat = FastDateFormat.getInstance("yyyy-MM-dd"); - private static final FastDateFormat ourYearMonthFormat = FastDateFormat.getInstance("yyyy-MM"); private static final FastDateFormat ourYearMonthDayNoDashesFormat = FastDateFormat.getInstance("yyyyMMdd"); private static final FastDateFormat ourYearMonthDayTimeFormat = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss"); - private static final FastDateFormat ourYearMonthDayTimeZoneFormat = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ssZZ"); - private static final FastDateFormat ourYearMonthDayTimeMilliZoneFormat = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSSZZ"); private static final FastDateFormat ourYearMonthDayTimeMilliFormat = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSS"); + private static final FastDateFormat ourYearMonthDayTimeMilliZoneFormat = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ss.SSSZZ"); + private static final FastDateFormat ourYearMonthDayTimeZoneFormat = FastDateFormat.getInstance("yyyy-MM-dd'T'HH:mm:ssZZ"); + private static final FastDateFormat ourYearMonthFormat = FastDateFormat.getInstance("yyyy-MM"); private TemporalPrecisionEnum myPrecision = TemporalPrecisionEnum.SECOND; - private Date myValue; private TimeZone myTimeZone; private boolean myTimeZoneZulu = false; + private Date myValue; /** * Gets the precision for this datatype using field values from @@ -67,6 +69,10 @@ public abstract class BaseDateTimeDt extends BasePrimitive { return myPrecision; } + public TimeZone getTimeZone() { + return myTimeZone; + } + @Override public Date getValue() { return myValue; @@ -113,6 +119,20 @@ public abstract class BaseDateTimeDt extends BasePrimitive { } } + public boolean isTimeZoneZulu() { + return myTimeZoneZulu; + } + + /** + * Returns true if this object represents a date that is today's date + * + * @throws NullPointerException if {@link #getValue()} returns null + */ + public boolean isToday() { + Validate.notNull(myValue, getClass().getSimpleName() + " contains null value"); + return DateUtils.isSameDay(new Date(), myValue); + } + /** * Sets the precision for this datatype using field values from * {@link Calendar}. Valid values are: @@ -132,6 +152,14 @@ public abstract class BaseDateTimeDt extends BasePrimitive { myPrecision = thePrecision; } + public void setTimeZone(TimeZone theTimeZone) { + myTimeZone = theTimeZone; + } + + public void setTimeZoneZulu(boolean theTimeZoneZulu) { + myTimeZoneZulu = theTimeZoneZulu; + } + @Override public void setValue(Date theValue) throws DataFormatException { myValue = theValue; @@ -214,22 +242,6 @@ public abstract class BaseDateTimeDt extends BasePrimitive { } } - public TimeZone getTimeZone() { - return myTimeZone; - } - - public void setTimeZone(TimeZone theTimeZone) { - myTimeZone = theTimeZone; - } - - public boolean isTimeZoneZulu() { - return myTimeZoneZulu; - } - - public void setTimeZoneZulu(boolean theTimeZoneZulu) { - myTimeZoneZulu = theTimeZoneZulu; - } - private void clearTimeZone() { myTimeZone = null; myTimeZoneZulu = false; @@ -240,5 +252,5 @@ public abstract class BaseDateTimeDt extends BasePrimitive { * is allowed by this type */ abstract boolean isPrecisionAllowed(TemporalPrecisionEnum thePrecision); - + } diff --git a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/tester/RestfulTesterServlet.java b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/tester/RestfulTesterServlet.java index 82ddb871e19..504cc57fb81 100644 --- a/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/tester/RestfulTesterServlet.java +++ b/hapi-fhir-base/src/main/java/ca/uhn/fhir/rest/server/tester/RestfulTesterServlet.java @@ -25,6 +25,7 @@ import static org.apache.commons.lang3.StringUtils.*; import java.io.IOException; import java.io.InputStream; import java.io.StringWriter; +import java.net.URLDecoder; import java.util.ArrayList; import java.util.Collections; import java.util.Comparator; @@ -138,7 +139,7 @@ public class RestfulTesterServlet extends HttpServlet { myStaticResources.put("fonts/glyphicons-halflings-regular.svg", "application/octet-stream"); myStaticResources.put("fonts/glyphicons-halflings-regular.ttf", "application/octet-stream"); myStaticResources.put("fonts/glyphicons-halflings-regular.woff", "application/octet-stream"); - + myStaticResources.put("fa/css/font-awesome.css", "text/css"); myStaticResources.put("fa/css/font-awesome.min.css", "text/css"); myStaticResources.put("fa/fonts/fontawesome-webfont.eot", "application/octet-stream"); @@ -171,8 +172,8 @@ public class RestfulTesterServlet extends HttpServlet { myStaticResources.put("fa/scss/_spinning.scss", "text/css"); myStaticResources.put("fa/scss/_stacked.scss", "text/css"); myStaticResources.put("fa/scss/_variables.scss", "text/css"); - myStaticResources.put("fa/scss/font-awesome.scss" , "text/css"); - + myStaticResources.put("fa/scss/font-awesome.scss", "text/css"); + myCtx = new FhirContext(); } @@ -289,9 +290,12 @@ public class RestfulTesterServlet extends HttpServlet { theContext.getVariables().put("errorMsg", "Invalid page URL: " + url); return; } - - returnsResource = ResultType.TAGLIST; - outcomeDescription = "Tag List"; + + url = url.replace("&", "&"); + client.loadPage().url(url).execute(); + + returnsResource = ResultType.BUNDLE; + outcomeDescription = "Bundle Page"; } else if ("delete".equals(method)) { RuntimeResourceDefinition def = getResourceType(theReq); @@ -551,11 +555,11 @@ public class RestfulTesterServlet extends HttpServlet { theContext.setVariable("bundle", bundle); theContext.setVariable("resultStatus", resultStatus); theContext.setVariable("requestUrl", requestUrl); - String requestBodyText = StringEscapeUtils.escapeHtml4(requestBody); - theContext.setVariable("requestBody", requestBody); + String requestBodyText = format(requestBody, ctEnum); + theContext.setVariable("requestBody", requestBodyText); theContext.setVariable("requestSyntaxHighlighterClass", requestSyntaxHighlighterClass); - String resultBodyText = StringEscapeUtils.escapeHtml4(resultBody); - theContext.setVariable("resultBody", resultBody); + String resultBodyText = format(resultBody, ctEnum); + theContext.setVariable("resultBody", resultBodyText); theContext.setVariable("resultBodyIsLong", resultBodyText.length() > 1000); theContext.setVariable("resultSyntaxHighlighterClass", resultSyntaxHighlighterClass); theContext.setVariable("requestHeaders", requestHeaders); @@ -569,14 +573,125 @@ public class RestfulTesterServlet extends HttpServlet { } } + private String format(String theResultBody, EncodingEnum theEncodingEnum) { + String str = StringEscapeUtils.escapeHtml4(theResultBody); + if (str == null || theEncodingEnum == null) { + return str; + } + + StringBuilder b = new StringBuilder(); + + if (theEncodingEnum == EncodingEnum.JSON) { + + boolean inValue = false; + boolean inQuote = false; + for (int i = 0; i < str.length(); i++) { + char prevChar = (i > 0) ? str.charAt(i-1): ' '; + char nextChar = str.charAt(i); + char nextChar2 = (i + 1) < str.length() ? str.charAt(i + 1) : ' '; + char nextChar3 = (i + 2) < str.length() ? str.charAt(i + 2) : ' '; + char nextChar4 = (i + 3) < str.length() ? str.charAt(i + 3) : ' '; + char nextChar5 = (i + 4) < str.length() ? str.charAt(i + 4) : ' '; + char nextChar6 = (i + 5) < str.length() ? str.charAt(i + 5) : ' '; + if (inQuote) { + b.append(nextChar); + if (prevChar != '\\' && nextChar == '&' && nextChar2 == 'q' && nextChar3 == 'u' && nextChar4 == 'o' && nextChar5 == 't' && nextChar6 == ';') { + b.append("quot;"); + i += 5; + inQuote = false; + }else if (nextChar == '\\' && nextChar2 == '"') { + b.append("quot;"); + i += 5; + inQuote = false; + } + } else { + if (nextChar == ':') { + inValue = true; + b.append(nextChar); + }else if (nextChar == '[' || nextChar == '[') { + b.append(""); + b.append(nextChar); + b.append(""); + inValue = false; + }else if (nextChar == '}' || nextChar == '}' || nextChar == ',') { + b.append(""); + b.append(nextChar); + b.append(""); + inValue = false; + } else if (nextChar == '&' && nextChar2 == 'q' && nextChar3 == 'u' && nextChar4 == 'o' && nextChar5 == 't' && nextChar6 == ';') { + if (inValue) { + b.append("""); + }else { + b.append("""); + } + inQuote = true; + i += 5; + }else if (nextChar == ':') { + b.append(""); + b.append(nextChar); + b.append(""); + inValue = true; + } else { + b.append(nextChar); + } + } + } + + } else { + boolean inQuote = false; + boolean inTag = false; + for (int i = 0; i < str.length(); i++) { + char nextChar = str.charAt(i); + char nextChar2 = (i + 1) < str.length() ? str.charAt(i + 1) : ' '; + char nextChar3 = (i + 2) < str.length() ? str.charAt(i + 2) : ' '; + char nextChar4 = (i + 3) < str.length() ? str.charAt(i + 3) : ' '; + char nextChar5 = (i + 4) < str.length() ? str.charAt(i + 4) : ' '; + char nextChar6 = (i + 5) < str.length() ? str.charAt(i + 5) : ' '; + if (inQuote) { + b.append(nextChar); + if (nextChar == '&' && nextChar2 == 'q' && nextChar3 == 'u' && nextChar4 == 'o' && nextChar5 == 't' && nextChar6 == ';') { + b.append("quot;"); + i += 5; + inQuote = false; + } + } else if (inTag) { + if (nextChar == '&' && nextChar2 == 'g' && nextChar3 == 't' && nextChar4 == ';') { + b.append(">"); + inTag = false; + i += 3; + } else if (nextChar == ' ') { + b.append(""); + b.append(nextChar); + } else if (nextChar == '&' && nextChar2 == 'q' && nextChar3 == 'u' && nextChar4 == 'o' && nextChar5 == 't' && nextChar6 == ';') { + b.append("""); + inQuote = true; + i += 5; + } else { + b.append(nextChar); + } + } else { + if (nextChar == '&' && nextChar2 == 'l' && nextChar3 == 't' && nextChar4 == ';') { + b.append("<"); + inTag = true; + i += 3; + } else { + b.append(nextChar); + } + } + } + } + + return b.toString(); + } + private EncodingEnum getRequestEncoding(HttpServletRequest theReq) { EncodingEnum encoding; if ("xml".equals(theReq.getParameter("encoding"))) { encoding = EncodingEnum.XML; } else if ("json".equals(theReq.getParameter("encoding"))) { - encoding=(EncodingEnum.JSON); - }else { - encoding=null; + encoding = (EncodingEnum.JSON); + } else { + encoding = null; } return encoding; } @@ -637,8 +752,7 @@ public class RestfulTesterServlet extends HttpServlet { }); } } - - + ctx.setVariable("resourceCounts", resourceCounts); ctx.setVariable("conf", conformance); ctx.setVariable("base", myServerBase); @@ -663,14 +777,14 @@ public class RestfulTesterServlet extends HttpServlet { includes.add(nextPath); } ctx.setVariable("includes", includes); - + if (isNotBlank(theReq.getParameter("update-id"))) { String updateId = theReq.getParameter("update-id"); - String updateVid = defaultIfEmpty(theReq.getParameter("update-vid"),null); + String updateVid = defaultIfEmpty(theReq.getParameter("update-vid"), null); IResource updateResource = client.read(def.getImplementingClass(), new IdDt(resourceName, updateId, updateVid)); EncodingEnum encoding = getRequestEncoding(theReq); - if (encoding==null) { - encoding=EncodingEnum.XML; + if (encoding == null) { + encoding = EncodingEnum.XML; } String updateResourceString = encoding.newParser(myCtx).setPrettyPrint(true).encodeResourceToString(updateResource); ctx.setVariable("updateResource", updateResourceString); diff --git a/hapi-fhir-base/src/main/resources/ca/uhn/fhir/rest/server/tester/RestfulTester.html b/hapi-fhir-base/src/main/resources/ca/uhn/fhir/rest/server/tester/RestfulTester.html index 12be02678f9..cd37947d0a4 100644 --- a/hapi-fhir-base/src/main/resources/ca/uhn/fhir/rest/server/tester/RestfulTester.html +++ b/hapi-fhir-base/src/main/resources/ca/uhn/fhir/rest/server/tester/RestfulTester.html @@ -907,7 +907,7 @@ Request Body
...loading...
- + @@ -953,7 +953,7 @@

- + @@ -968,7 +968,7 @@ $('#page-prev-btn').click(function() { var btn = $(this); btn.button('loading'); - btn.append($('', { type: 'hidden', name: 'pageUrl', value: '' })); + btn.append($('', { type: 'hidden', name: 'page-url', value: '' })); }); @@ -983,7 +983,7 @@ $('#page-next-btn').click(function() { var btn = $(this); btn.button('loading'); - btn.append($('', { type: 'hidden', name: 'pageUrl', value: '' })); + btn.append($('', { type: 'hidden', name: 'page-url', value: '' })); }); @@ -992,6 +992,14 @@
+ + + + + + + + + + + +
TitleUpdated
@@ -999,7 +1007,11 @@