diff --git a/main/src/com/google/refine/exporters/TemplatingExporter.java b/main/src/com/google/refine/exporters/TemplatingExporter.java index 996ce4591..05568fbf5 100644 --- a/main/src/com/google/refine/exporters/TemplatingExporter.java +++ b/main/src/com/google/refine/exporters/TemplatingExporter.java @@ -34,13 +34,13 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. package com.google.refine.exporters; import java.io.IOException; -import java.io.StringWriter; import java.io.Writer; import java.util.Properties; import org.json.JSONException; import org.json.JSONObject; -import org.json.JSONWriter; + +import com.fasterxml.jackson.annotation.JsonProperty; import com.google.refine.browsing.Engine; import com.google.refine.browsing.Engine.Mode; @@ -63,6 +63,26 @@ public class TemplatingExporter implements WriterExporter { public String getContentType() { return "application/x-unknown"; } + + protected static class TemplateConfig { + @JsonProperty("template") + protected String template; + @JsonProperty("prefix") + protected String prefix; + @JsonProperty("suffix") + protected String suffix; + @JsonProperty("separator") + protected String separator; + + protected TemplateConfig( + String template, String prefix, + String suffix, String separator) { + this.template = template; + this.prefix = prefix; + this.suffix = suffix; + this.separator = separator; + } + } @Override public void export(Project project, Properties options, Engine engine, Writer writer) throws IOException { @@ -94,20 +114,10 @@ public class TemplatingExporter implements WriterExporter { template.setSeparator(separatorString); if (!"true".equals(options.getProperty("preview"))) { - StringWriter stringWriter = new StringWriter(); - JSONWriter jsonWriter = new JSONWriter(stringWriter); - try { - jsonWriter.object(); - jsonWriter.key("template"); jsonWriter.value(templateString); - jsonWriter.key("prefix"); jsonWriter.value(prefixString); - jsonWriter.key("suffix"); jsonWriter.value(suffixString); - jsonWriter.key("separator"); jsonWriter.value(separatorString); - jsonWriter.endObject(); - } catch (JSONException e) { - // ignore - } - - project.getMetadata().getPreferenceStore().put("exporters.templating.template", stringWriter.toString()); + TemplateConfig config = new TemplateConfig(templateString, prefixString, + suffixString, separatorString); + project.getMetadata().getPreferenceStore().put("exporters.templating.template", + ParsingUtilities.defaultWriter.writeValueAsString(config)); } if (engine.getMode() == Mode.RowBased) { diff --git a/main/src/com/google/refine/importing/DefaultImportingController.java b/main/src/com/google/refine/importing/DefaultImportingController.java index b7b920dae..6c5647261 100644 --- a/main/src/com/google/refine/importing/DefaultImportingController.java +++ b/main/src/com/google/refine/importing/DefaultImportingController.java @@ -48,9 +48,9 @@ import javax.servlet.http.HttpServletResponse; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import org.json.JSONWriter; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonGenerator; import com.google.refine.RefineServlet; import com.google.refine.commands.HttpUtilities; @@ -187,22 +187,21 @@ public class DefaultImportingController implements ImportingController { ImportingUtilities.previewParse(job, format, optionObj, exceptions); Writer w = response.getWriter(); - JSONWriter writer = new JSONWriter(w); + JsonGenerator writer = ParsingUtilities.mapper.getFactory().createGenerator(w); try { - writer.object(); + writer.writeStartObject(); if (exceptions.size() == 0) { job.project.update(); // update all internal models, indexes, caches, etc. - writer.key("status"); writer.value("ok"); + writer.writeStringField("status", "ok"); } else { - writer.key("status"); writer.value("error"); - writer.key("errors"); - writer.array(); + writer.writeStringField("status", "error"); + writer.writeArrayFieldStart("errors"); writeErrors(writer, exceptions); - writer.endArray(); + writer.writeEndArray(); } - writer.endObject(); - } catch (JSONException e) { + writer.writeEndObject(); + } catch (IOException e) { throw new ServletException(e); } finally { w.flush(); @@ -304,17 +303,15 @@ public class DefaultImportingController implements ImportingController { w.close(); } - static public void writeErrors(JSONWriter writer, List exceptions) throws JSONException { + static public void writeErrors(JsonGenerator writer, List exceptions) throws IOException { for (Exception e : exceptions) { StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); - writer.object(); - writer.key("message"); - writer.value(e.getLocalizedMessage()); - writer.key("stack"); - writer.value(sw.toString()); - writer.endObject(); + writer.writeStartObject(); + writer.writeStringField("message", e.getLocalizedMessage()); + writer.writeStringField("stack", sw.toString()); + writer.writeEndObject(); } } diff --git a/main/src/com/google/refine/importing/ImportingManager.java b/main/src/com/google/refine/importing/ImportingManager.java index 53b041adf..39792c34d 100644 --- a/main/src/com/google/refine/importing/ImportingManager.java +++ b/main/src/com/google/refine/importing/ImportingManager.java @@ -43,15 +43,12 @@ import java.util.HashSet; import java.util.LinkedList; import java.util.List; import java.util.Map; -import java.util.Properties; import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; import org.apache.commons.io.FileUtils; -import org.json.JSONException; -import org.json.JSONWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; diff --git a/main/src/com/google/refine/model/recon/StandardReconConfig.java b/main/src/com/google/refine/model/recon/StandardReconConfig.java index b6156d29a..692e0958e 100644 --- a/main/src/com/google/refine/model/recon/StandardReconConfig.java +++ b/main/src/com/google/refine/model/recon/StandardReconConfig.java @@ -40,15 +40,17 @@ import java.net.HttpURLConnection; import java.net.URL; import java.time.OffsetDateTime; import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; import org.apache.commons.lang3.StringUtils; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import org.json.JSONWriter; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -56,6 +58,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; +import com.fasterxml.jackson.core.JsonProcessingException; import com.google.refine.expr.ExpressionUtils; import com.google.refine.model.Cell; @@ -234,19 +237,70 @@ public class StandardReconConfig extends ReconConfig { */ StandardReconJob job = new StandardReconJob(); try { - StringWriter stringWriter = new StringWriter(); - JSONWriter jsonWriter = new JSONWriter(stringWriter); - jsonWriter.object(); - jsonWriter.key("query"); - jsonWriter.value(query); - jsonWriter.endObject(); + String queryJson = ParsingUtilities.defaultWriter.writeValueAsString( + Collections.singletonMap("query", query)); job.text = query; - job.code = stringWriter.toString(); + job.code = queryJson; return job; - } catch (JSONException je) { + } catch (JsonProcessingException e) { + e.printStackTrace(); return null; } } + + protected static class QueryProperty { + @JsonProperty("pid") + String pid; + @JsonProperty("v") + Object v; + + protected QueryProperty( + String pid, + Object v) { + this.pid = pid; + this.v = v; + } + } + + protected static class ReconQuery { + @JsonProperty("query") + protected String query; + + @JsonProperty("type") + @JsonInclude(Include.NON_NULL) + protected String typeID; + + @JsonProperty("type_strict") + @JsonInclude(Include.NON_NULL) + public String isTypeStrict() { + if(typeID != null) { + return "should"; + } + return null; + } + + @JsonProperty("properties") + @JsonInclude(Include.NON_EMPTY) + protected List properties; + + // Only send limit if it's non-default to preserve backward compatibility with + // services which might choke on this + @JsonProperty("limit") + @JsonInclude(Include.NON_DEFAULT) + protected int limit; + + public ReconQuery( + String query, + String typeID, + List properties, + int limit) { + this.query = query; + this.typeID = typeID; + this.properties = properties; + this.limit = limit; + } + + } @Override public ReconJob createJob(Project project, int rowIndex, Row row, @@ -254,74 +308,48 @@ public class StandardReconConfig extends ReconConfig { StandardReconJob job = new StandardReconJob(); - try { - StringWriter stringWriter = new StringWriter(); - JSONWriter jsonWriter = new JSONWriter(stringWriter); - - jsonWriter.object(); - jsonWriter.key("query"); jsonWriter.value(cell.value.toString()); - if (typeID != null) { - jsonWriter.key("type"); jsonWriter.value(typeID); - jsonWriter.key("type_strict"); jsonWriter.value("should"); - } + List properties = new ArrayList<>(); - if (columnDetails.size() > 0) { - jsonWriter.key("properties"); - jsonWriter.array(); + for (ColumnDetail c : columnDetails) { + int detailCellIndex = project.columnModel.getColumnByName(c.columnName).getCellIndex(); + + Cell cell2 = row.getCell(detailCellIndex); + if (cell2 == null || !ExpressionUtils.isNonBlankData(cell2.value)) { + int cellIndex = project.columnModel.getColumnByName(columnName).getCellIndex(); - for (ColumnDetail c : columnDetails) { - int detailCellIndex = project.columnModel.getColumnByName(c.columnName).getCellIndex(); - - Cell cell2 = row.getCell(detailCellIndex); - if (cell2 == null || !ExpressionUtils.isNonBlankData(cell2.value)) { - int cellIndex = project.columnModel.getColumnByName(columnName).getCellIndex(); + RowDependency rd = project.recordModel.getRowDependency(rowIndex); + if (rd != null && rd.cellDependencies != null) { + int contextRowIndex = rd.cellDependencies[cellIndex].rowIndex; + if (contextRowIndex >= 0 && contextRowIndex < project.rows.size()) { + Row row2 = project.rows.get(contextRowIndex); - RowDependency rd = project.recordModel.getRowDependency(rowIndex); - if (rd != null && rd.cellDependencies != null) { - int contextRowIndex = rd.cellDependencies[cellIndex].rowIndex; - if (contextRowIndex >= 0 && contextRowIndex < project.rows.size()) { - Row row2 = project.rows.get(contextRowIndex); - - cell2 = row2.getCell(detailCellIndex); - } - } - } - - if (cell2 != null && ExpressionUtils.isNonBlankData(cell2.value)) { - jsonWriter.object(); - - jsonWriter.key("pid"); jsonWriter.value(c.propertyID); - jsonWriter.key("v"); - if (cell2.recon != null && cell2.recon.match != null) { - jsonWriter.object(); - jsonWriter.key("id"); jsonWriter.value(cell2.recon.match.id); - jsonWriter.key("name"); jsonWriter.value(cell2.recon.match.name); - jsonWriter.endObject(); - } else if (cell2.value instanceof OffsetDateTime) { - jsonWriter.value(ParsingUtilities.dateToString((OffsetDateTime) cell2.value)); - } else { - jsonWriter.value(cell2.value.toString()); - } - - jsonWriter.endObject(); + cell2 = row2.getCell(detailCellIndex); } } - - jsonWriter.endArray(); } - // Only send limit if it's non-default to preserve backward compatibility with - // services which might choke on this - if (limit != 0) { - jsonWriter.key("limit"); jsonWriter.value(limit); + if (cell2 != null && ExpressionUtils.isNonBlankData(cell2.value)) { + Object v = null; + if (cell2.recon != null && cell2.recon.match != null) { + Map recon = new HashMap<>(); + recon.put("id", cell2.recon.match.id); + recon.put("name", cell2.recon.match.name); + v = recon; + } else { + v = cell2.value; + } + properties.add(new QueryProperty(c.propertyID, v)); + } + } - - jsonWriter.endObject(); - - job.text = cell.value.toString(); - job.code = stringWriter.toString(); - } catch (JSONException e) { - // + + ReconQuery query = new ReconQuery(cell.value.toString(), typeID, properties, limit); + + job.text = cell.value.toString(); + try { + job.code = ParsingUtilities.defaultWriter.writeValueAsString(query); + } catch (JsonProcessingException e) { + e.printStackTrace(); } return job; } diff --git a/main/src/com/google/refine/util/JSONUtilities.java b/main/src/com/google/refine/util/JSONUtilities.java index 925adcc1a..ea94a17e8 100644 --- a/main/src/com/google/refine/util/JSONUtilities.java +++ b/main/src/com/google/refine/util/JSONUtilities.java @@ -46,7 +46,6 @@ import java.util.Map; import org.json.JSONArray; import org.json.JSONException; import org.json.JSONObject; -import org.json.JSONWriter; public class JSONUtilities { @@ -172,22 +171,6 @@ public class JSONUtilities { } } - static public void writeStringList(JSONWriter writer, List list) throws JSONException { - writer.array(); - for (String s : list) { - writer.value(s); - } - writer.endArray(); - } - - static public void writeStringArray(JSONWriter writer, String[] strings) throws JSONException { - writer.array(); - for (String s : strings) { - writer.value(s); - } - writer.endArray(); - } - static public void putField(JSONObject obj, String key, Object value) throws JSONException { if (value instanceof Integer) { obj.put(key, ((Integer) value).intValue());