From 6ad03a8078c117c30dadf02c7ea1b4976bf7259c Mon Sep 17 00:00:00 2001 From: gmantele <gmantele@ari.uni-heidelberg.de> Date: Wed, 27 Sep 2017 15:27:14 +0200 Subject: [PATCH] [UWS] Fix missing xlink:type (though it is optional) in jobRef (in XML job list). This commit also includes the 2 following points: - for (really really tiny) optimisation purpose, replace String by a char when there is only one character to append to a StringBuffer - add a bit more details about Result.type in the Javadoc (it should be a xlink:type and not a random custom type) --- src/uws/job/Result.java | 67 +++++++------ src/uws/job/serializer/XMLSerializer.java | 113 +++++++++++----------- 2 files changed, 96 insertions(+), 84 deletions(-) diff --git a/src/uws/job/Result.java b/src/uws/job/Result.java index fa45a75..8991856 100644 --- a/src/uws/job/Result.java +++ b/src/uws/job/Result.java @@ -2,21 +2,21 @@ package uws.job; /* * This file is part of UWSLibrary. - * + * * UWSLibrary is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * UWSLibrary is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with UWSLibrary. If not, see <http://www.gnu.org/licenses/>. - * - * Copyright 2012,2014 - UDS/Centre de Données astronomiques de Strasbourg (CDS), + * + * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -27,9 +27,9 @@ import uws.service.UWSUrl; /** * This class gives a short description (mainly an ID and a URL) of a job result. - * + * * @author Grégory Mantelet (CDS;ARI) - * @version 4.1 (08/2014) + * @version 4.1 (09/2017) */ public class Result extends SerializableUWSObject { private static final long serialVersionUID = 1L; @@ -61,7 +61,7 @@ public class Result extends SerializableUWSObject { /* ************ */ /** * Builds a result with the URL toward the file which contains the result content. - * + * * @param job Job which will own this result. * @param resultUrl Result file URL. */ @@ -77,7 +77,7 @@ public class Result extends SerializableUWSObject { /** * Builds a result with just a name/ID. - * + * * @param job Job which will own this result. * @param name Name of ID of the result. */ @@ -90,11 +90,11 @@ public class Result extends SerializableUWSObject { /** * Builds a result with an ID/name and the URL toward the file which contains the result content. - * + * * @param job Job which will own this result. * @param name Name or ID of the result. * @param resultUrl Result file URL. - * + * * @see #Result(UWSJob, String) */ public Result(final UWSJob job, String name, String resultUrl){ @@ -106,12 +106,13 @@ public class Result extends SerializableUWSObject { /** * Builds a result with an ID/name, a result type and the URL toward the file which contains the result content. - * + * * @param job Job which will own this result. * @param name Name or ID or the result. * @param resultType Type of result. + * <i>Note: it should be a XLINK URL type (one among simple (default), extended, locator, arc, resource, title or none ; see http://www.w3.org/TR/xlink/#linking-elements for more details).</i> * @param resultUrl Result file URL. - * + * * @see #Result(UWSJob, String, String) */ public Result(final UWSJob job, String name, String resultType, String resultUrl){ @@ -121,9 +122,10 @@ public class Result extends SerializableUWSObject { /** * Builds MANUALLY a result with an ID/name, a result type and the URL toward the file which contains the result content. - * + * * @param name Name or ID or the result. * @param resultType Type of result. + * <i>Note: it should be a XLINK URL type (one among simple (default), extended, locator, arc, resource, title or none ; see http://www.w3.org/TR/xlink/#linking-elements for more details).</i> * @param resultUrl Result file URL. * @param redirection <i>true</i> if a redirection toward the given URL is required to get the result content, <i>false</i> otherwise. * <i><u>note:</u> This parameter is ignored if the given URL is NULL or empty ! In this case, redirection = FALSE.</i> @@ -137,10 +139,10 @@ public class Result extends SerializableUWSObject { /** * Gets the HREF as {jobList}/{job}/results/ID. - * + * * @param id ID of the concerned Result. * @param job The job which has to contain the Result instance. - * + * * @return The HREF field of the Result or <i>null</i> if the URL of the job is unknown (which is the case when the job is not in a job list). */ public static final String getDefaultUrl(String id, UWSJob job){ @@ -155,18 +157,18 @@ public class Result extends SerializableUWSObject { /** * <p>Tells whether the given URL is different from the default URL of the specified result of the given job.</p> - * + * * <p>When this function returns <i>true</i> a redirection toward the given URL is required to get the result content. * Otherwise, the result content must be read from a file managed by the {@link uws.service.file.UWSFileManager}.</p> - * + * * <p><i><u>note:</u> If at least one of the parameter of this function is null or an empty string, this function returns false.</i></p> - * + * * @param url Result URL to test. * @param resultId ID of the result. * @param job Job which owns the result. - * + * * @return <i>true</i> if a redirection is required to get the result content, <i>false</i> otherwise. - * + * * @see #getDefaultUrl(String, UWSJob) */ public static final boolean isRedirectionUrl(final String url, final String resultId, final UWSJob job){ @@ -181,7 +183,7 @@ public class Result extends SerializableUWSObject { /* ******* */ /** * Gets the id/name of this result. - * + * * @return The result id or name. */ public final String getId(){ @@ -190,7 +192,7 @@ public class Result extends SerializableUWSObject { /** * Gets the URL of the result file. - * + * * @return The result file URL. */ public final String getHref(){ @@ -200,7 +202,7 @@ public class Result extends SerializableUWSObject { /** * Tells whether a redirection toward the URL of this result is required to get the result content. * If NOT, its content must be read from the corresponding file managed by the {@link uws.service.file.UWSFileManager}. - * + * * @return <i>true</i> if a redirection is required to get the result content, <i>false</i> otherwise. */ public final boolean isRedirectionRequired(){ @@ -208,8 +210,15 @@ public class Result extends SerializableUWSObject { } /** - * Gets the type of this result. - * + * Get the type of this result. + * + * <p><i>Note: + * The returned type should be a XLINK URL type + * (one among simple (default), extended, locator, arc, resource, title or + * none ; see http://www.w3.org/TR/xlink/#linking-elements for more + * details). + * </i></p> + * * @return The result type. */ public final String getType(){ @@ -218,7 +227,7 @@ public class Result extends SerializableUWSObject { /** * Gets the MIME type of this result. - * + * * @return The MIME Type. */ public final String getMimeType(){ @@ -227,7 +236,7 @@ public class Result extends SerializableUWSObject { /** * Sets the MIME type of this result. - * + * * @param mimeType The MIME type to set. */ public final void setMimeType(String mimeType){ @@ -236,7 +245,7 @@ public class Result extends SerializableUWSObject { /** * Gets the size of the corresponding result file. - * + * * @return Result file size (in bytes). */ public final long getSize(){ diff --git a/src/uws/job/serializer/XMLSerializer.java b/src/uws/job/serializer/XMLSerializer.java index e59cdc3..159572d 100644 --- a/src/uws/job/serializer/XMLSerializer.java +++ b/src/uws/job/serializer/XMLSerializer.java @@ -2,20 +2,20 @@ package uws.job.serializer; /* * This file is part of UWSLibrary. - * + * * UWSLibrary is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. - * + * * UWSLibrary is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public License * along with UWSLibrary. If not, see <http://www.gnu.org/licenses/>. - * + * * Copyright 2012-2017 - UDS/Centre de Données astronomiques de Strasbourg (CDS), * Astronomisches Rechen Institut (ARI) */ @@ -38,9 +38,9 @@ import uws.service.request.UploadFile; /** * Lets serializing any UWS resource in XML. - * + * * @author Grégory Mantelet (CDS;ARI) - * @version 4.2 (06/2017) + * @version 4.2 (09/2017) */ public class XMLSerializer extends UWSSerializer { private static final long serialVersionUID = 1L; @@ -60,7 +60,7 @@ public class XMLSerializer extends UWSSerializer { /** * Builds a XML serializer with a XSLT link. - * + * * @param xsltPath Path of a XSLT style-sheet. */ public XMLSerializer(final String xsltPath){ @@ -69,7 +69,7 @@ public class XMLSerializer extends UWSSerializer { /** * Gets the path/URL of the XSLT style-sheet to use. - * + * * @return XSLT path/url. */ public final String getXSLTPath(){ @@ -78,7 +78,7 @@ public class XMLSerializer extends UWSSerializer { /** * Sets the path/URL of the XSLT style-sheet to use. - * + * * @param path The new XSLT path/URL. */ public final void setXSLTPath(final String path){ @@ -94,12 +94,12 @@ public class XMLSerializer extends UWSSerializer { /** * Gets the XML file header (xml version, encoding and the xslt * style-sheet link if any). - * + * * <p> * It is always called by the implementation of the UWSSerializer functions * if their boolean parameter (<i>root</i>) is <i>true</i>. * </p> - * + * * @return The XML file header. */ public String getHeader(){ @@ -112,7 +112,7 @@ public class XMLSerializer extends UWSSerializer { /** * Gets all UWS namespaces declarations needed for an XML representation of * a UWS object. - * + * * @return The UWS namespaces: <br /> (i.e. <i>= "xmlns:uws=[...] * xmlns:xlink=[...] xmlns:xs=[...] xmlns:xsi=[...] * xsi:schemaLocation=[...]"</i>). @@ -123,14 +123,14 @@ public class XMLSerializer extends UWSSerializer { /** * Gets the node attributes which declare the UWS namespace. - * + * * @param root <i>false</i> if the attribute to serialize will be included * in a top level serialization (for a job attribute: job), * <i>true</i> otherwise. - * + * * @return "" if <i>root</i> is <i>false</i>, " "+UWSNamespace * otherwise. - * + * * @see #getUWSNamespace() */ protected final String getUWSNamespace(boolean root){ @@ -152,7 +152,7 @@ public class XMLSerializer extends UWSSerializer { xml.append("<uws").append(getUWSNamespace(true)); if (name != null) - xml.append(" name=\"").append(escapeXMLAttribute(name)).append("\""); + xml.append(" name=\"").append(escapeXMLAttribute(name)).append('"'); xml.append(">\n"); if (description != null) @@ -183,7 +183,7 @@ public class XMLSerializer extends UWSSerializer { * if (name != null) * xml.append(" name=\"").append(escapeXMLAttribute(name)).append("\""); */ - xml.append(">"); + xml.append('>'); UWSUrl jobsListUrl = jobsList.getUrl(); Iterator<UWSJob> it = jobsList.getJobs(owner); @@ -201,7 +201,7 @@ public class XMLSerializer extends UWSSerializer { String newLine = "\n\t"; // general information: - xml.append("<job").append(getUWSNamespace(root)).append(">"); + xml.append("<job").append(getUWSNamespace(root)).append('>'); xml.append(newLine).append(getJobID(job, false)); if (job.getRunId() != null) xml.append(newLine).append(getRunID(job, false)); @@ -243,22 +243,25 @@ public class XMLSerializer extends UWSSerializer { } StringBuffer xml = new StringBuffer("<jobref id=\""); - xml.append(escapeXMLAttribute(job.getJobId())); + xml.append(escapeXMLAttribute(job.getJobId())).append('"'); /* NOTE: NO ATTRIBUTE "runId" IN THE XML SCHEMA! * if (job.getRunId() != null && job.getRunId().length() > 0) * xml.append("\" runId=\"").append(escapeXMLAttribute(job.getRunId())); */ - xml.append("\" xlink:href=\""); + + /* The XLink attributes are optional. So if no URL is available for this + * Job reference, none is written here: */ if (url != null) - xml.append(escapeXMLAttribute(url)); - xml.append("\">\n\t\t").append(getPhase(job, false)).append("\n\t</jobref>"); + xml.append(" xlink:type=\"simple\" xlink:href=\"").append(escapeXMLAttribute(url)).append('"'); + + xml.append(">\n\t\t").append(getPhase(job, false)).append("\n\t</jobref>"); return xml.toString(); } @Override public String getJobID(final UWSJob job, final boolean root){ - return (new StringBuffer(root ? getHeader() : "")).append("<jobId").append(getUWSNamespace(root)).append(">").append(escapeXMLData(job.getJobId())).append("</jobId>").toString(); + return (new StringBuffer(root ? getHeader() : "")).append("<jobId").append(getUWSNamespace(root)).append('>').append(escapeXMLData(job.getJobId())).append("</jobId>").toString(); } @Override @@ -266,7 +269,7 @@ public class XMLSerializer extends UWSSerializer { if (job.getRunId() != null){ StringBuffer xml = new StringBuffer(root ? getHeader() : ""); xml.append("<runId").append(getUWSNamespace(root)); - xml.append(">").append(escapeXMLData(job.getRunId())).append("</runId>"); + xml.append('>').append(escapeXMLData(job.getRunId())).append("</runId>"); return xml.toString(); }else return ""; @@ -279,13 +282,13 @@ public class XMLSerializer extends UWSSerializer { if (job.getOwner() == null) xml.append(" xsi:nil=\"true\" />"); else - xml.append(">").append(escapeXMLData(job.getOwner().getPseudo())).append("</ownerId>"); + xml.append('>').append(escapeXMLData(job.getOwner().getPseudo())).append("</ownerId>"); return xml.toString(); } @Override public String getPhase(final UWSJob job, final boolean root){ - return (new StringBuffer(root ? getHeader() : "")).append("<phase").append(getUWSNamespace(root)).append(">").append(job.getPhase()).append("</phase>").toString(); + return (new StringBuffer(root ? getHeader() : "")).append("<phase").append(getUWSNamespace(root)).append('>').append(job.getPhase()).append("</phase>").toString(); } @Override @@ -295,7 +298,7 @@ public class XMLSerializer extends UWSSerializer { if (job.getQuote() <= 0) xml.append(" xsi:nil=\"true\" />"); else - xml.append(">").append(job.getQuote()).append("</quote>"); + xml.append('>').append(job.getQuote()).append("</quote>"); return xml.toString(); } @@ -306,7 +309,7 @@ public class XMLSerializer extends UWSSerializer { if (job.getStartTime() == null) xml.append(" xsi:nil=\"true\" />"); else - xml.append(">").append(ISO8601Format.format(job.getStartTime())).append("</startTime>"); + xml.append('>').append(ISO8601Format.format(job.getStartTime())).append("</startTime>"); return xml.toString(); } @@ -317,7 +320,7 @@ public class XMLSerializer extends UWSSerializer { if (job.getEndTime() == null) xml.append(" xsi:nil=\"true\" />"); else - xml.append(">").append(ISO8601Format.format(job.getEndTime())).append("</endTime>"); + xml.append('>').append(ISO8601Format.format(job.getEndTime())).append("</endTime>"); return xml.toString(); } @@ -328,13 +331,13 @@ public class XMLSerializer extends UWSSerializer { if (job.getDestructionTime() == null) xml.append(" xsi:nil=\"true\" />"); else - xml.append(">").append(ISO8601Format.format(job.getDestructionTime())).append("</destruction>"); + xml.append('>').append(ISO8601Format.format(job.getDestructionTime())).append("</destruction>"); return xml.toString(); } @Override public String getExecutionDuration(final UWSJob job, final boolean root){ - return (new StringBuffer(root ? getHeader() : "")).append("<executionDuration").append(getUWSNamespace(root)).append(">").append(job.getExecutionDuration()).append("</executionDuration>").toString(); + return (new StringBuffer(root ? getHeader() : "")).append("<executionDuration").append(getUWSNamespace(root)).append('>').append(job.getExecutionDuration()).append("</executionDuration>").toString(); } @Override @@ -342,9 +345,9 @@ public class XMLSerializer extends UWSSerializer { if (error != null){ StringBuffer xml = new StringBuffer(root ? getHeader() : ""); xml.append(tabPrefix).append("<errorSummary").append(getUWSNamespace(root)); - xml.append(" type=\"").append(error.getType()).append("\"").append(" hasDetail=\"").append(error.hasDetail()).append("\">"); + xml.append(" type=\"").append(error.getType()).append('"').append(" hasDetail=\"").append(error.hasDetail()).append("\">"); xml.append("\n\t").append(tabPrefix).append("<message>").append(escapeXMLData(error.getMessage())).append("</message>"); - xml.append("\n").append(tabPrefix).append("</errorSummary>"); + xml.append('\n').append(tabPrefix).append("</errorSummary>"); return xml.toString(); }else return ""; @@ -357,7 +360,7 @@ public class XMLSerializer extends UWSSerializer { String newLine = "\n\t" + tabPrefix; for(String paramName : job.getAdditionalParameters()) xml.append(newLine).append(getAdditionalParameter(paramName, job.getAdditionalParameterValue(paramName), false)); - xml.append("\n").append(tabPrefix).append("</parameters>"); + xml.append('\n').append(tabPrefix).append("</parameters>"); return xml.toString(); } @@ -412,18 +415,18 @@ public class XMLSerializer extends UWSSerializer { String newLine = "\n\t" + tabPrefix; while(it.hasNext()) xml.append(newLine).append(getResult(it.next(), false)); - xml.append("\n").append(tabPrefix).append("</results>"); + xml.append('\n').append(tabPrefix).append("</results>"); return xml.toString(); } @Override public String getResult(final Result result, final boolean root){ StringBuffer xml = new StringBuffer(root ? getHeader() : ""); - xml.append("<result").append(getUWSNamespace(root)).append(" id=\"").append(escapeXMLAttribute(result.getId())).append("\""); + xml.append("<result").append(getUWSNamespace(root)).append(" id=\"").append(escapeXMLAttribute(result.getId())).append('"'); if (result.getHref() != null){ if (result.getType() != null) - xml.append(" xlink:type=\"").append(escapeXMLAttribute(result.getType())).append("\""); - xml.append(" xlink:href=\"").append(escapeXMLAttribute(result.getHref())).append("\""); + xml.append(" xlink:type=\"").append(escapeXMLAttribute(result.getType())).append('"'); + xml.append(" xlink:href=\"").append(escapeXMLAttribute(result.getHref())).append('"'); } /* NOTE: THE FOLLOWING ATTRIBUTES MAY PROVIDE USEFUL INFORMATION TO USERS, BUT THEY ARE NOT ALLOWED BY THE CURRENT UWS STANDARD. @@ -440,18 +443,18 @@ public class XMLSerializer extends UWSSerializer { /** * Serialize into XML the {@link JobInfo} of the given job, if any. - * + * * <p><b>Important note:</b> * By default, this function wrap the XML content returned by * {@link JobInfo#getXML(String)} inside an XML node "jobInfo". * To change this behavior, you should overwrite this function. * </p> - * + * * @param job The job whose the jobInfo must be serialized into XML. - * + * * @return The XML serialization of the given job's jobInfo, * or an empty string if the given job has no jobInfo. - * + * * @since 4.2 */ public String getJobInfo(final UWSJob job) throws UWSException{ @@ -470,9 +473,9 @@ public class XMLSerializer extends UWSSerializer { /* ************** */ /** * Escapes the content of a node (data between the open and the close tags). - * + * * @param data Data to escape. - * + * * @return Escaped data. */ public static String escapeXMLData(final String data){ @@ -498,9 +501,9 @@ public class XMLSerializer extends UWSSerializer { /** * Escapes the given value of an XML attribute. - * + * * @param value Value of an XML attribute. - * + * * @return The escaped value. */ public static String escapeXMLAttribute(final String value){ @@ -529,11 +532,11 @@ public class XMLSerializer extends UWSSerializer { /** * Escapes the given URL. - * + * * @param url URL to escape. - * + * * @return The escaped URL. - * + * * @see URLEncoder * @see #escapeXMLAttribute(String) */ @@ -551,14 +554,14 @@ public class XMLSerializer extends UWSSerializer { * If the input character is legal in XML, it is returned; * otherwise some other weird but legal character * (currently the inverted question mark, "\u00BF") is returned instead.</p> - * + * * <p><i>Note: * copy of the STILTS VOSerializer.ensureLegalXml(char) function. * </i></p> * * @param c input character * @return legal XML character, <code>c</code> if possible - * + * * @since 4.1 */ public static char ensureLegalXml(char c){ @@ -585,7 +588,7 @@ public class XMLSerializer extends UWSSerializer { /** * Determine whether the given name is a valid XML node name * according to the W3C (XML 1.1). - * + * * <p><i>Note: * In addition of validating the given name against the regular expression * provided by the W3C (see {@link #XML_NODE_NAME_REGEX}), this function @@ -593,12 +596,12 @@ public class XMLSerializer extends UWSSerializer { * following W3C note: * <a href="https://www.w3.org/TR/2006/REC-xml11-20060816/#dt-name">https://www.w3.org/TR/2006/REC-xml11-20060816/#dt-name</a> * </i></p> - * + * * @param nodeName XML node name to test. - * + * * @return <code>true</code> if the given node name is valid, * <code>false</code> otherwise. - * + * * @since 4.2 */ public static boolean isValidXMLNodeName(final String nodeName){ -- GitLab