diff --git a/build.gradle b/build.gradle
index 1086268cd6..56c9944868 100644
--- a/build.gradle
+++ b/build.gradle
@@ -12,3 +12,7 @@ subprojects {
apply from: "$fireflyPath/buildScript/utils.gincl"
+task purge << {
+ println('Removes all firefly build directories.')
+ delete "${fireflyPath}/build", "${fireflyPath}/jars/build", "${fireflyPath}/node_modules"
+}
diff --git a/buildScript/utils.gincl b/buildScript/utils.gincl
index 3a9cf1c2ca..2a1f130a00 100644
--- a/buildScript/utils.gincl
+++ b/buildScript/utils.gincl
@@ -85,7 +85,3 @@ def execCmd(remoteHost, ignoreFailure, cmdLine) {
}
-task purge << {
- println('Removes all build directories.')
- delete "${fireflyPath}/build", "${fireflyPath}/jars/build", "${fireflyPath}/node_modules"
-}
diff --git a/buildScript/webpack.config.js b/buildScript/webpack.config.js
index 336e3f9a4d..705db9f5f6 100644
--- a/buildScript/webpack.config.js
+++ b/buildScript/webpack.config.js
@@ -10,10 +10,24 @@ import fs from 'fs';
var exclude_dirs = [/node_modules/, /java/, /python/, /config/, /test/];
-function makeWebpackConfig(config) {
+/**
+ * A helper function to create the webpack config object to be sent to webpack module bundler.
+ * @param {Object} config configuration parameters used to create the webpack config object.
+ * @param {string} config.src source directory
+ * @param {string} config.firefly_root Firefly's build root
+ * @param {string} [config.firefly_dir] Firefly's JS source directory
+ * @param {Object} [config.alias] additional alias
+ * @param {boolean=true} [config.use_loader] generate a loader to load compiled JS script(s). Defautls to true
+ * @param {string} [config.project] project name
+ * @param {string} [config.filename] name of the generated JS script.
+ * @returns {Object} a webpack config object.
+ */
+export default function makeWebpackConfig(config) {
// setting defaults
- config.firefly_dir = config.firefly_dir || config.src;
+ config.src = config.src || __dirname;
+ config.firefly_root = config.firefly_root || path.resolve(config.src, '../..');
+ config.firefly_dir = config.firefly_dir || path.resolve(config.firefly_root, 'src/firefly');
config.project = config.project || path.resolve(config.src, '../../');
var def_config = {
@@ -229,11 +243,6 @@ function makeWebpackConfig(config) {
-
-export default makeWebpackConfig;
-
-
-
function firefly_loader(loadScript, outpath, debug=true) {
return function () {
this.plugin('done', function (stats) {
@@ -249,7 +258,7 @@ function firefly_loader(loadScript, outpath, debug=true) {
}`;
}
var content = fs.readFileSync(loadScript);
- content += `\nloadScript('/${cxt_name}/${cxt_name}-${hash}.js'${callback});`;
+ content += `\nloadScript('/${cxt_name}/firefly-${hash}.js'${callback});`;
var loader = path.join(outpath, 'firefly_loader.js');
fs.writeFileSync(loader, content);
});
diff --git a/src/fftools/config/web.xml b/src/fftools/config/web.xml
index a0361a3eb6..6e702d28a1 100644
--- a/src/fftools/config/web.xml
+++ b/src/fftools/config/web.xml
@@ -190,7 +190,7 @@
- edu.caltech.ipac.firefly.server.servlets.SearchServices
+ edu.caltech.ipac.firefly.server.servlets.JsonSearchServicesFireFly SearchService
diff --git a/src/fftools/webpack.config.js b/src/fftools/webpack.config.js
index e12c522f8d..d8d6d46186 100644
--- a/src/fftools/webpack.config.js
+++ b/src/fftools/webpack.config.js
@@ -4,15 +4,7 @@ require('babel/register');
var path = require('path');
var firefly_root = path.resolve(__dirname, '../..');
+var name = 'fftools';
+var entry = {fflib: path.resolve(firefly_root, 'src/firefly/js/fireflyJSLib.js')};
-var config = {
- name : 'fftools',
- src : __dirname,
- use_loader: false,
- entry : {
- fflib: path.resolve(firefly_root, 'src/firefly/js/fireflyJSLib.js')
- },
- firefly_dir : path.resolve(firefly_root, 'src/firefly')
-};
-
-module.exports = require(firefly_root + '/buildScript/webpack.config.js')(config);
+module.exports = require(firefly_root + '/buildScript/webpack.config.js')({firefly_root, name, entry, user_loader: false});
diff --git a/src/firefly/config/web.xml b/src/firefly/config/web.xml
index f9df237ad6..e73529e6bf 100644
--- a/src/firefly/config/web.xml
+++ b/src/firefly/config/web.xml
@@ -134,7 +134,7 @@
- edu.caltech.ipac.firefly.server.servlets.SearchServices
+ edu.caltech.ipac.firefly.server.servlets.JsonSearchServicesFireFly SearchService
diff --git a/src/firefly/html/css/global.css b/src/firefly/html/css/global.css
index 25d27e636e..ffcee53270 100644
--- a/src/firefly/html/css/global.css
+++ b/src/firefly/html/css/global.css
@@ -78,19 +78,20 @@
order: 3;
}
-.button-std {
- height: 23px;
+.button {
padding: 0 3px;
margin-right: 3px;
}
-.button-hl {
- font-weight: bold;
+.button.std {
height: 23px;
- padding: 0 3px;
}
-.button-std:hover, .button-hl:hover {
+.button.hl {
+ font-weight: bold;
+}
+
+.button:hover {
cursor: pointer;
}
diff --git a/src/firefly/html/firefly.html b/src/firefly/html/firefly.html
index 9b07c24401..ae7cc51b3c 100644
--- a/src/firefly/html/firefly.html
+++ b/src/firefly/html/firefly.html
@@ -15,7 +15,7 @@
window.firefly = {app: {}};
-
+
diff --git a/src/firefly/java/edu/caltech/ipac/firefly/data/table/TableMeta.java b/src/firefly/java/edu/caltech/ipac/firefly/data/table/TableMeta.java
index 831e2b5800..76d80be5f1 100644
--- a/src/firefly/java/edu/caltech/ipac/firefly/data/table/TableMeta.java
+++ b/src/firefly/java/edu/caltech/ipac/firefly/data/table/TableMeta.java
@@ -202,6 +202,9 @@ public void setAttribute(String key, Number value) {
public void setAttribute(String key, String value) {
attributes.put(key, value);
}
+ public void removeAttribute(String key) {
+ attributes.remove(key);
+ }
public void setWorldPtAttribute(String key, WorldPt pt) {
diff --git a/src/firefly/java/edu/caltech/ipac/firefly/server/query/JsonDataProcessor.java b/src/firefly/java/edu/caltech/ipac/firefly/server/query/JsonDataProcessor.java
new file mode 100644
index 0000000000..9481024ea0
--- /dev/null
+++ b/src/firefly/java/edu/caltech/ipac/firefly/server/query/JsonDataProcessor.java
@@ -0,0 +1,98 @@
+/*
+ * License information at https://github.com/Caltech-IPAC/firefly/blob/master/License.txt
+ */
+package edu.caltech.ipac.firefly.server.query;
+
+import edu.caltech.ipac.firefly.data.*;
+import edu.caltech.ipac.firefly.data.table.TableMeta;
+import edu.caltech.ipac.firefly.server.util.Logger;
+import edu.caltech.ipac.util.*;
+import org.json.simple.JSONArray;
+import org.json.simple.JSONObject;
+
+import java.io.*;
+import java.util.*;
+
+
+/**
+ * Subclasses of this processor return JSONObject. This helper class provides SearchProcessor's
+ * supported features and helper functions.
+ *
+ * @author loi
+ * @version $Id: IpacTablePartProcessor.java,v 1.33 2012/10/23 18:37:22 loi Exp $
+ */
+abstract public class JsonDataProcessor implements SearchProcessor {
+
+ public static final boolean useWorkspace = AppProperties.getBooleanProperty("useWorkspace", false);
+
+ public static final Logger.LoggerImpl SEARCH_LOGGER = Logger.getLogger(Logger.SEARCH_LOGGER);
+ public static final Logger.LoggerImpl LOGGER = Logger.getLogger();
+
+ public ServerRequest inspectRequest(ServerRequest request) { return request; };
+
+ public void prepareTableMeta(TableMeta defaults, List columns, ServerRequest request) {}
+
+ public QueryDescResolver getDescResolver() { return null;}
+
+ public void onComplete(ServerRequest request, String results) throws DataAccessException {}
+
+ public void writeData(OutputStream out, ServerRequest request) throws DataAccessException {}
+
+ public boolean doCache() { return false; }
+
+ public boolean doLogging() { return false; }
+
+
+ public String getUniqueID(ServerRequest request) {
+ String uid = request.getRequestId() + "-";
+
+ // parameters to get original data (before filter, sort, etc.)
+ List srvParams = new ArrayList<>();
+ for (Param p : request.getParams()) {
+ srvParams.add(p);
+ }
+
+ // sort by parameter name
+ Collections.sort(srvParams, (p1, p2) -> p1.getName().compareTo(p2.getName()));
+ for (Param p : srvParams) {
+ uid += "|" + p.toString();
+ }
+ return uid;
+ }
+
+ abstract public String getData(ServerRequest request) throws DataAccessException;
+
+
+ protected JSONArray toJsonArray(List values) {
+ JSONArray jAry = new JSONArray();
+ for (Object v : values) {
+ if (v instanceof List) {
+
+ } else if(v instanceof Map) {
+ jAry.add(toJsonObject((Map) v));
+ } else {
+ jAry.add(v);
+ }
+ }
+ return jAry;
+ }
+
+ protected JSONObject toJsonObject(Map values) {
+
+ JSONObject jObj = new JSONObject();
+ for (Object k : values.keySet()) {
+ String name = String.valueOf(k);
+ Object v = values.get(k);
+ if (v instanceof List) {
+ jObj.put(name, toJsonArray((List) v));
+ } else if(v instanceof Map) {
+ jObj.put(name, toJsonObject((Map) v));
+ } else {
+ jObj.put(name, v);
+ }
+ }
+ return jObj;
+ }
+
+}
+
diff --git a/src/firefly/java/edu/caltech/ipac/firefly/server/query/SearchManager.java b/src/firefly/java/edu/caltech/ipac/firefly/server/query/SearchManager.java
index 4d15ba3d70..e5d15b21f0 100644
--- a/src/firefly/java/edu/caltech/ipac/firefly/server/query/SearchManager.java
+++ b/src/firefly/java/edu/caltech/ipac/firefly/server/query/SearchManager.java
@@ -7,12 +7,7 @@
import edu.caltech.ipac.firefly.core.RPCException;
import edu.caltech.ipac.firefly.core.background.BackgroundState;
import edu.caltech.ipac.firefly.core.background.BackgroundStatus;
-import edu.caltech.ipac.firefly.data.DownloadRequest;
-import edu.caltech.ipac.firefly.data.FileStatus;
-import edu.caltech.ipac.firefly.data.Request;
-import edu.caltech.ipac.firefly.data.ServerParams;
-import edu.caltech.ipac.firefly.data.ServerRequest;
-import edu.caltech.ipac.firefly.data.TableServerRequest;
+import edu.caltech.ipac.firefly.data.*;
import edu.caltech.ipac.firefly.data.table.RawDataSet;
import edu.caltech.ipac.firefly.data.table.TableMeta;
import edu.caltech.ipac.firefly.server.ServerContext;
@@ -23,11 +18,12 @@
import edu.caltech.ipac.firefly.server.util.QueryUtil;
import edu.caltech.ipac.firefly.server.util.ipactable.*;
import edu.caltech.ipac.util.Assert;
+import edu.caltech.ipac.util.DataGroup;
+import edu.caltech.ipac.util.IpacTableUtil;
import org.json.simple.JSONObject;
import org.json.simple.JSONValue;
import org.json.simple.parser.JSONParser;
import org.json.simple.parser.ParseException;
-import edu.caltech.ipac.util.IpacTableUtil;
import java.io.File;
import java.io.IOException;
@@ -43,59 +39,38 @@
public class SearchManager {
public static final Logger.LoggerImpl LOGGER = Logger.getLogger();
-
+//====================================================================
+// RPC.. returning RawDataSet
+//====================================================================
public RawDataSet getRawDataSet(TableServerRequest request) throws DataAccessException {
- SearchProcessor processor = getProcessor(request.getRequestId());
- ServerRequest req = processor.inspectRequest(request);
- if (req != null) {
- DataGroupPart dgp = null;
- try {
- dgp = (DataGroupPart) processor.getData(req);
- RawDataSet ds = QueryUtil.getRawDataSet(dgp);
- DataGroupPart.State status = dgp.getTableDef().getStatus();
- ds.getMeta().setIsLoaded(!status.equals(DataGroupPart.State.INPROGRESS));
-
- processor.prepareTableMeta(ds.getMeta(),
- Collections.unmodifiableList(dgp.getTableDef().getCols()),
- req);
-
- return ds;
- } catch (Exception ex) {
- String source = dgp != null && dgp.getTableDef() != null ? dgp.getTableDef().getSource() : "unknown";
- String errMsg = ex.getClass().getSimpleName() + ":" + ex.getMessage() + " from:" + source ;
- LOGGER.error(ex, errMsg);
- throw new DataAccessException(errMsg, ex);
- }
- } else {
- throw new DataAccessException("Request fail inspection. Operation aborted.");
- }
+ DataGroupPart dgp = getDataGroup(request);
+ RawDataSet ds = QueryUtil.getRawDataSet(dgp);
+ // merge TableDef info into ds.meta
+ dgp.getTableDef().setMetaTo(ds.getMeta());
+ return ds;
}
- public String getJsonString(TableServerRequest request) throws DataAccessException {
+//====================================================================
+// JSON.. top level handler, return JSON string.
+//====================================================================
+ public String handleJsonRequest(TableServerRequest request) throws DataAccessException {
SearchProcessor processor = getProcessor(request.getRequestId());
- ServerRequest req = processor.inspectRequest(request);
- if (req != null) {
- DataGroupPart dgp = null;
- try {
- dgp = (DataGroupPart) processor.getData(req);
- TableMeta meta = new TableMeta();
- DataGroupPart.State status = dgp.getTableDef().getStatus();
- meta.setIsLoaded(!status.equals(DataGroupPart.State.INPROGRESS));
-
- processor.prepareTableMeta(meta,
- Collections.unmodifiableList(dgp.getTableDef().getCols()),
- req);
- JSONObject json = JsonTableUtil.toJsonTableModel(dgp, meta, request);
- return json.toJSONString();
+ if (processor instanceof IpacTablePartProcessor) {
+ return jsonTablePartRequest(request);
+ } else if (processor instanceof JsonDataProcessor) {
+ return (String)processor.getData(request);
+ }
+ throw new DataAccessException("Unable to resolve a search processor for this request. Operation aborted:" + request.getRequestId());
+ }
- } catch (Exception ex) {
- String source = dgp != null && dgp.getTableDef() != null ? dgp.getTableDef().getSource() : "unknown";
- String errMsg = ex.getClass().getSimpleName() + ":" + ex.getMessage() + " from:" + source ;
- LOGGER.error(ex, errMsg);
- throw new DataAccessException(errMsg, ex);
- }
- } else {
- throw new DataAccessException("Request fail inspection. Operation aborted.");
+ private String jsonTablePartRequest(TableServerRequest request) throws DataAccessException {
+ try {
+ DataGroupPart dgp = getDataGroup(request);
+ JSONObject json = JsonTableUtil.toJsonTableModel(dgp, request);
+ return json.toJSONString();
+ } catch (IOException ex) {
+ LOGGER.error(ex);
+ throw new DataAccessException("Fail convert data to JSON.", ex);
}
}
@@ -121,13 +96,33 @@ public String getJSONData(ServerRequest request) throws DataAccessException {
}
}
+//====================================================================
+// search related funtions...
+//====================================================================
public DataGroupPart getDataGroup(TableServerRequest request) throws DataAccessException {
SearchProcessor processor = getProcessor(request.getRequestId());
+ DataGroupPart dgp = null;
ServerRequest req = processor.inspectRequest(request);
if (req != null) {
- DataGroupPart dgp = (DataGroupPart) processor.getData(req);
- return dgp;
+ try {
+ dgp = (DataGroupPart) processor.getData(req);
+ TableMeta meta = new TableMeta();
+ DataGroupPart.State status = dgp.getTableDef().getStatus();
+ meta.setIsLoaded(!status.equals(DataGroupPart.State.INPROGRESS));
+
+ processor.prepareTableMeta(meta,
+ Collections.unmodifiableList(dgp.getTableDef().getCols()),
+ req);
+ // merge meta info with TableDef info
+ dgp.getTableDef().getMetaFrom(meta);
+ return dgp;
+ } catch (Exception ex) {
+ String source = dgp != null && dgp.getTableDef() != null ? dgp.getTableDef().getSource() : "unknown";
+ String errMsg = ex.getClass().getSimpleName() + ":" + ex.getMessage() + " from:" + source;
+ LOGGER.error(ex, errMsg);
+ throw new DataAccessException(errMsg, ex);
+ }
} else {
throw new DataAccessException("Request fail inspection. Operation aborted.");
}
diff --git a/src/firefly/java/edu/caltech/ipac/firefly/server/query/IpacTableFromSource.java b/src/firefly/java/edu/caltech/ipac/firefly/server/query/tables/IpacTableFromSource.java
similarity index 97%
rename from src/firefly/java/edu/caltech/ipac/firefly/server/query/IpacTableFromSource.java
rename to src/firefly/java/edu/caltech/ipac/firefly/server/query/tables/IpacTableFromSource.java
index f5e70b33cf..7e76a3e538 100644
--- a/src/firefly/java/edu/caltech/ipac/firefly/server/query/IpacTableFromSource.java
+++ b/src/firefly/java/edu/caltech/ipac/firefly/server/query/tables/IpacTableFromSource.java
@@ -1,7 +1,7 @@
/*
* License information at https://github.com/Caltech-IPAC/firefly/blob/master/License.txt
*/
-package edu.caltech.ipac.firefly.server.query;
+package edu.caltech.ipac.firefly.server.query.tables;
import edu.caltech.ipac.firefly.data.Param;
import edu.caltech.ipac.firefly.data.ServerParams;
@@ -10,6 +10,7 @@
import edu.caltech.ipac.firefly.data.table.TableMeta;
import edu.caltech.ipac.firefly.server.ServerContext;
import edu.caltech.ipac.firefly.server.packagedata.FileInfo;
+import edu.caltech.ipac.firefly.server.query.*;
import edu.caltech.ipac.util.DataType;
import edu.caltech.ipac.util.FileUtil;
import edu.caltech.ipac.util.StringUtils;
diff --git a/src/firefly/java/edu/caltech/ipac/firefly/server/query/tables/TableServices.java b/src/firefly/java/edu/caltech/ipac/firefly/server/query/tables/TableServices.java
new file mode 100644
index 0000000000..bca1efeacf
--- /dev/null
+++ b/src/firefly/java/edu/caltech/ipac/firefly/server/query/tables/TableServices.java
@@ -0,0 +1,38 @@
+package edu.caltech.ipac.firefly.server.query.tables;
+
+import edu.caltech.ipac.firefly.core.RPCException;
+import edu.caltech.ipac.firefly.data.ServerRequest;
+import edu.caltech.ipac.firefly.server.ServerContext;
+import edu.caltech.ipac.firefly.server.query.*;
+import edu.caltech.ipac.util.StringUtils;
+import org.json.simple.JSONObject;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+public class TableServices {
+
+
+ @SearchProcessorImpl(id = "Table__SelectedValues", params ={
+ @ParamDoc(name = "filePath", desc = "The path of the file on the server."),
+ @ParamDoc(name = "selectedRows", desc = "Selected row indices separated by comma."),
+ @ParamDoc(name = "columnName", desc = "The name of the column to get the data from."),
+ })
+ static public class SelectedValues extends JsonDataProcessor {
+ public String getData(ServerRequest request) throws DataAccessException {
+ String filePath = request.getParam("filePath");
+ try {
+ String selRows = request.getParam("selectedRows");
+ String columnName = request.getParam("columnName");
+ List rows = StringUtils.convertToListInteger(selRows, ",");
+ List values = new SearchManager().getDataFileValues(ServerContext.convertToFile(filePath), rows, columnName);
+ return toJsonArray(values).toJSONString();
+ } catch (IOException e) {
+ throw new DataAccessException("Fail to retrieve data for file:" + filePath);
+ }
+ }
+
+ }
+
+}
diff --git a/src/firefly/java/edu/caltech/ipac/firefly/server/servlets/SearchServices.java b/src/firefly/java/edu/caltech/ipac/firefly/server/servlets/JsonSearchServices.java
similarity index 89%
rename from src/firefly/java/edu/caltech/ipac/firefly/server/servlets/SearchServices.java
rename to src/firefly/java/edu/caltech/ipac/firefly/server/servlets/JsonSearchServices.java
index 669ed3021a..676ac0b265 100644
--- a/src/firefly/java/edu/caltech/ipac/firefly/server/servlets/SearchServices.java
+++ b/src/firefly/java/edu/caltech/ipac/firefly/server/servlets/JsonSearchServices.java
@@ -4,7 +4,6 @@
package edu.caltech.ipac.firefly.server.servlets;
import edu.caltech.ipac.firefly.core.EndUserException;
-import edu.caltech.ipac.firefly.core.RPCException;
import edu.caltech.ipac.firefly.data.TableServerRequest;
import edu.caltech.ipac.firefly.server.query.SearchManager;
import edu.caltech.ipac.firefly.server.util.QueryUtil;
@@ -19,13 +18,13 @@
*/
@MultipartConfig
-public class SearchServices extends BaseHttpServlet {
+public class JsonSearchServices extends BaseHttpServlet {
@Override
protected void processRequest(HttpServletRequest req, HttpServletResponse res) throws Exception {
TableServerRequest tsr = QueryUtil.convertToServerRequest(req);
try {
- String jsonStr = new SearchManager().getJsonString(tsr);
+ String jsonStr = new SearchManager().handleJsonRequest(tsr);
res.setContentType("application/json");
FileUtil.writeStringToStream(jsonStr, res.getOutputStream());
diff --git a/src/firefly/java/edu/caltech/ipac/firefly/server/util/QueryUtil.java b/src/firefly/java/edu/caltech/ipac/firefly/server/util/QueryUtil.java
index abf445217a..d71e65bffa 100644
--- a/src/firefly/java/edu/caltech/ipac/firefly/server/util/QueryUtil.java
+++ b/src/firefly/java/edu/caltech/ipac/firefly/server/util/QueryUtil.java
@@ -302,7 +302,7 @@ public static DataGroupPart convertToDataGroupPart(DataGroup dg, int startIdx, i
DataGroup page = dg.subset(startIdx, startIdx+pageSize);
page.setRowIdxOffset(startIdx);
TableDef tableDef = new TableDef();
- tableDef.setSource("unknown");
+ tableDef.addAttributes(dg.getKeywords().toArray(new DataGroup.Attribute[0]));
tableDef.setStatus(DataGroupPart.State.COMPLETED);
tableDef.setCols(Arrays.asList(page.getDataDefinitions()));
diff --git a/src/firefly/java/edu/caltech/ipac/firefly/server/util/ipactable/JsonTableUtil.java b/src/firefly/java/edu/caltech/ipac/firefly/server/util/ipactable/JsonTableUtil.java
index 9392a5ae91..575206938e 100644
--- a/src/firefly/java/edu/caltech/ipac/firefly/server/util/ipactable/JsonTableUtil.java
+++ b/src/firefly/java/edu/caltech/ipac/firefly/server/util/ipactable/JsonTableUtil.java
@@ -30,43 +30,29 @@ public class JsonTableUtil {
* convert data to JSON TableModel. Use toJSONString() to turn it into a String.
*
* @param page
- * @param meta
* @param request
* @return
* @throws IOException
*/
- public static JSONObject toJsonTableModel(DataGroupPart page, TableMeta meta, TableServerRequest request) throws IOException {
+ public static JSONObject toJsonTableModel(DataGroupPart page, TableServerRequest request) throws IOException {
- if (meta == null) {
- meta = new TableMeta();
- }
- if (page.getTableDef()!=null && page.getTableDef().getAttributes() != null) {
- if (StringUtils.isEmpty(meta.getSource())) {
- meta.setSource(page.getTableDef().getSource());
- }
- // merge tableDef's attributes with tablemeta's.
- for (DataGroup.Attribute attr : page.getTableDef().getAttributes()) {
- // meta override tabledef's.
- if (!StringUtils.isEmpty(attr.getValue()) && !attr.isComment() && !meta.contains(attr.getKey())) {
- meta.setAttribute(attr.getKey(), attr.getValue());
- }
- }
- }
+ TableDef meta = page.getTableDef();
if (request != null && request.getMeta() != null) {
for (String key : request.getMeta().keySet()) {
meta.setAttribute(key, request.getMeta(key));
}
}
- String tbl_id = meta.getAttribute(TableServerRequest.TBL_ID);
JSONObject tableModel = new JSONObject();
- tableModel.put("tbl_id", tbl_id);
+ if (meta.contains(TableServerRequest.TBL_ID)) {
+ tableModel.put("tbl_id", meta.getAttribute(TableServerRequest.TBL_ID).getValue());
+ }
tableModel.put("title", page.getData().getTitle());
tableModel.put("type", guessType(meta));
tableModel.put("totalRows", page.getRowCount());
if (page.getData() != null ) {
- tableModel.put("tableData", toJsonTableData(page.getData(), page.getTableDef(), meta));
+ tableModel.put("tableData", toJsonTableData(page.getData(), page.getTableDef()));
}
@@ -117,7 +103,7 @@ public static JSONObject toJsonTableRequest(TableServerRequest req) {
* @param tableDef
* @return
*/
- public static JSONObject toJsonTableData(DataGroup data, TableDef tableDef, TableMeta meta) {
+ public static JSONObject toJsonTableData(DataGroup data, TableDef tableDef) {
List> tableData = new ArrayList>();
for (int i = 0; i < data.size(); i++) {
List row = new ArrayList();
@@ -129,7 +115,7 @@ public static JSONObject toJsonTableData(DataGroup data, TableDef tableDef, Tabl
JSONObject tdata = new JSONObject();
- tdata.put("columns", toJsonTableColumn(tableDef!=null?tableDef.getCols().toArray(new DataType[0]):data.getDataDefinitions() , meta));
+ tdata.put("columns", toJsonTableColumn(data, tableDef));
tdata.put("data", tableData);
return tdata;
}
@@ -140,19 +126,11 @@ public static JSONObject toJsonTableData(DataGroup data, TableDef tableDef, Tabl
* @param meta
* @return
*/
- public static JSONObject toJsonTableMeta(TableMeta meta) {
+ public static JSONObject toJsonTableMeta(TableDef meta) {
JSONObject tmeta = new JSONObject();
- tmeta.put("source", meta.getSource());
- tmeta.put("fileSize", meta.getFileSize());
- if (meta.getRelatedCols() != null) {
- tmeta.put("relatedCols", StringUtils.toString(meta.getRelatedCols(), ","));
- }
- if (meta.getGroupByCols() != null) {
- tmeta.put("groupByCols", StringUtils.toString(meta.getGroupByCols(), ","));
- }
- if (meta.getAttributes() != null) {
- for (String key : meta.getAttributes().keySet()) {
- tmeta.put(key, meta.getAttribute(key));
+ for (DataGroup.Attribute att : meta.getAttributes()) {
+ if (!att.isComment()) {
+ tmeta.put(att.getKey(), att.getValue());
}
}
return tmeta;
@@ -162,7 +140,9 @@ public static JSONObject toJsonTableMeta(TableMeta meta) {
//
//====================================================================
- private static List toJsonTableColumn(DataType[] dataTypes, TableMeta meta) {
+ private static List toJsonTableColumn(DataGroup dataGroup, TableDef meta) {
+
+ DataType[] dataTypes = meta.getCols().size() > 0 ? meta.getCols().toArray(new DataType[0]) : dataGroup.getDataDefinitions();
ArrayList cols = new ArrayList();
for (DataType dt :dataTypes) {
@@ -182,53 +162,65 @@ private static List toJsonTableColumn(DataType[] dataTypes, TableMet
}
// modify column's attributes based on meta
- String label = meta.getAttribute( makeAttribKey(LABEL_TAG, cname) );
+ String label = getColAttr(meta, LABEL_TAG, cname);
if (!StringUtils.isEmpty(label)) {
c.put("label", label);
}
- String desc = meta.getAttribute( makeAttribKey(DESC_TAG, cname) );
+ String desc = getColAttr(meta, DESC_TAG, cname);
if (!StringUtils.isEmpty(desc)) {
c.put("desc", desc);
}
- String visibility = meta.getAttribute( makeAttribKey(VISI_TAG, cname) );
+ String visibility = getColAttr(meta, VISI_TAG, cname);
if (!StringUtils.isEmpty(visibility)) {
c.put("visibility", visibility);
}
- String width = meta.getAttribute( makeAttribKey(WIDTH_TAG, cname) );
+ String width = getColAttr(meta, WIDTH_TAG, cname);
if (!StringUtils.isEmpty(width)) {
c.put("width", width);
}
- String prefWidth = meta.getAttribute( makeAttribKey(PREF_WIDTH_TAG, cname) );
+ String prefWidth = getColAttr(meta, PREF_WIDTH_TAG, cname);
if (!StringUtils.isEmpty(prefWidth)) {
c.put("prefWidth", prefWidth);
}
- String sortable = meta.getAttribute( makeAttribKey(SORTABLE_TAG, cname) );
+ String sortable = getColAttr(meta, SORTABLE_TAG, cname);
if (!StringUtils.isEmpty(sortable)) {
c.put("sortable", sortable);
}
- String units = meta.getAttribute( makeAttribKey(UNIT_TAG, cname) );
+ String units = getColAttr(meta, UNIT_TAG, cname);
if (!StringUtils.isEmpty(units)) {
c.put("units", units);
}
- String items = meta.getAttribute( makeAttribKey(ITEMS_TAG, cname) );
+ String items = getColAttr(meta, ITEMS_TAG, cname);
if (!StringUtils.isEmpty(items)) {
c.put("items", items);
}
- String sortBy = meta.getAttribute( makeAttribKey(SORT_BY_TAG, cname) );
+ String sortBy = getColAttr(meta, SORT_BY_TAG, cname);
if (!StringUtils.isEmpty(sortBy)) {
- c.put("sortBy", sortBy);
+ c.put("sortByCols", sortBy);
}
cols.add(c);
}
+ for (DataGroup.Attribute att : meta.getAttributes()) {
+ // clean up all of the column's attributes since we already set it to the columns
+ if (att.getKey().startsWith("col.")) {
+ meta.removeAttribute(att.getKey());
+ }
+ }
return cols;
}
+
+ private static String getColAttr(TableDef meta, String tag, String cname) {
+ DataGroup.Attribute att = meta.getAttribute(makeAttribKey(tag, cname));
+ return (att == null) ? "" : att.getValue();
+ }
+
/**
* get the type of data this table contains based on its meta information
*
* @param meta
* @return
*/
- private static Object guessType(TableMeta meta) {
+ private static Object guessType(TableDef meta) {
return "table";
}
@@ -236,12 +228,11 @@ private static Object guessType(TableMeta meta) {
//=============================
//LZ DM-4494
- public static JSONObject toJsonTableModelMap(Map dataMap, Map metaMap, TableServerRequest request) throws IOException {
+ public static JSONObject toJsonTableModelMap(Map dataMap, TableServerRequest request) throws IOException {
JSONObject jsoObj = new JSONObject();
for (Object key : dataMap.keySet()) {
- TableMeta meta = metaMap.get(key);
DataGroupPart dp = QueryUtil.convertToDataGroupPart(dataMap.get(key), 0, Integer.MAX_VALUE);
- JSONObject aJsonTable = JsonTableUtil.toJsonTableModel(dp, meta, request);
+ JSONObject aJsonTable = JsonTableUtil.toJsonTableModel(dp, request);
jsoObj.put(key, aJsonTable);
diff --git a/src/firefly/java/edu/caltech/ipac/firefly/server/util/ipactable/TableDef.java b/src/firefly/java/edu/caltech/ipac/firefly/server/util/ipactable/TableDef.java
index b201b1589d..873a056cd5 100644
--- a/src/firefly/java/edu/caltech/ipac/firefly/server/util/ipactable/TableDef.java
+++ b/src/firefly/java/edu/caltech/ipac/firefly/server/util/ipactable/TableDef.java
@@ -1,10 +1,13 @@
package edu.caltech.ipac.firefly.server.util.ipactable;
+import edu.caltech.ipac.firefly.data.table.TableMeta;
import edu.caltech.ipac.util.DataGroup;
import edu.caltech.ipac.util.DataType;
import edu.caltech.ipac.util.StringUtils;
import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
import java.util.List;
/**
@@ -15,18 +18,16 @@
*/
public class TableDef {
private List cols = new ArrayList();
- private ArrayList attributes = new ArrayList();
+ private HashMap attributes = new HashMap<>();
private int lineWidth;
private int rowCount;
- private int colCount;
private int rowStartOffset;
- private String sourceFile;
private int lineSepLength;
public void addAttributes(DataGroup.Attribute... attributes) {
if (attributes != null) {
for(DataGroup.Attribute a : attributes) {
- this.attributes.add(a);
+ this.attributes.put(a.getKey(), a);
}
}
}
@@ -36,20 +37,18 @@ public List getCols() {
return cols;
}
- public void addCols(DataType col) {
- cols.add(col);
- }
-
public List getAttributes() {
- return attributes;
+ return new ArrayList<>(attributes.values());
}
+ public boolean contains(String name) { return attributes.containsKey(name);};
+
public void setAttribute(String name, String value) {
- DataGroup.Attribute att = getAttribute(name);
- if (att != null) {
- attributes.remove(att);
- }
- attributes.add(new DataGroup.Attribute(name, value));
+ attributes.put(name, new DataGroup.Attribute(name, value));
+ }
+
+ public void removeAttribute(String name) {
+ attributes.remove(name);
}
public void setStatus(DataGroupPart.State status) {
@@ -57,10 +56,7 @@ public void setStatus(DataGroupPart.State status) {
}
DataGroup.Attribute getAttribute(String key) {
- for (DataGroup.Attribute at : attributes) {
- if (at.getKey().equals(key)) return at;
- }
- return null;
+ return attributes.get(key);
}
public void ensureStatus() {
@@ -109,11 +105,52 @@ public void setRowStartOffset(int rowStartOffset) {
}
public String getSource() {
- return sourceFile;
+ DataGroup.Attribute source = getAttribute("source");
+ return source != null ? source.getValue() : null;
}
public void setSource(String sourceFile) {
- this.sourceFile = sourceFile;
+ setAttribute("source", sourceFile);
+ }
+
+ public void setMetaTo(TableMeta meta) {
+ if (meta == null) return;
+ if (contains("groupByCols")) {
+ meta.setGroupByCols(StringUtils.asList(getAttribute("groupByCols").getValue(), ","));
+ }
+ if (contains("relatedCols")) {
+ meta.setRelatedCols(StringUtils.asList(getAttribute("relatedCols").getValue(), ","));
+ }
+ if (contains("fileSize")) {
+ meta.setFileSize(Long.parseLong(getAttribute("fileSize").getValue()));
+ }
+ if (getSource() != null) {
+ meta.setSource(getSource());
+ }
+ meta.setIsLoaded(Boolean.parseBoolean(getAttribute("isFullyLoaded").getValue()));
+ for (String key : meta.getAttributes().keySet()) {
+ setAttribute(key, meta.getAttribute(key));
+ }
+ }
+
+ public void getMetaFrom(TableMeta meta) {
+ if (meta == null) return;
+ if (meta.getGroupByCols().size() > 0) {
+ setAttribute("groupByCols", StringUtils.toString(meta.getGroupByCols()));
+ }
+ if (meta.getRelatedCols().size() > 0) {
+ setAttribute("relatedCols", StringUtils.toString(meta.getRelatedCols()));
+ }
+ if (meta.getFileSize() > 0) {
+ setAttribute("fileSize", String.valueOf( meta.getFileSize()) );
+ }
+ if (meta.getSource() != null) {
+ setSource(meta.getSource());
+ }
+ setAttribute("isFullyLoaded", String.valueOf(meta.isLoaded()));
+ for (String key : meta.getAttributes().keySet()) {
+ setAttribute(key, meta.getAttribute(key));
+ }
}
}
/*
diff --git a/src/firefly/java/edu/caltech/ipac/firefly/server/visualize/VisServerCommands.java b/src/firefly/java/edu/caltech/ipac/firefly/server/visualize/VisServerCommands.java
index 4e57ec6c53..715ae2e8e8 100644
--- a/src/firefly/java/edu/caltech/ipac/firefly/server/visualize/VisServerCommands.java
+++ b/src/firefly/java/edu/caltech/ipac/firefly/server/visualize/VisServerCommands.java
@@ -300,13 +300,11 @@ public String doCommand(Map paramMap) throws IllegalArgumentEx
//TableServerRequest req=TableServerRequest.parse(sp.getRequired(ServerParams.FITS_HEADER));
PlotState state= sp.getState();
- Object[] dataInfo = VisServerOps.getFitsHeader(state, tableID);
- HashMap dataGroupMap= (HashMap ) dataInfo[0];
- HashMap metaMap = ( HashMap ) dataInfo[1];
+ HashMap dataGroupMap = VisServerOps.getFitsHeader(state, tableID);
TableServerRequest treq = new TableServerRequest("fitsHeaderTale");
treq.setPageSize(Integer.MAX_VALUE);
- return JsonTableUtil.toJsonTableModelMap(dataGroupMap, metaMap, treq).toJSONString();
+ return JsonTableUtil.toJsonTableModelMap(dataGroupMap, treq).toJSONString();
}
diff --git a/src/firefly/java/edu/caltech/ipac/firefly/server/visualize/VisServerOps.java b/src/firefly/java/edu/caltech/ipac/firefly/server/visualize/VisServerOps.java
index 5724fe1b96..acb715aec7 100644
--- a/src/firefly/java/edu/caltech/ipac/firefly/server/visualize/VisServerOps.java
+++ b/src/firefly/java/edu/caltech/ipac/firefly/server/visualize/VisServerOps.java
@@ -7,12 +7,12 @@
import edu.caltech.ipac.firefly.data.DataEntry;
import edu.caltech.ipac.firefly.data.TableServerRequest;
import edu.caltech.ipac.firefly.data.table.RawDataSet;
-import edu.caltech.ipac.firefly.data.table.TableMeta;
import edu.caltech.ipac.firefly.server.Counters;
import edu.caltech.ipac.firefly.server.ServerContext;
import edu.caltech.ipac.firefly.server.cache.UserCache;
import edu.caltech.ipac.firefly.server.util.Logger;
import edu.caltech.ipac.firefly.server.util.QueryUtil;
+import edu.caltech.ipac.firefly.server.util.ipactable.TableDef;
import edu.caltech.ipac.firefly.server.util.multipart.UploadFileInfo;
import edu.caltech.ipac.firefly.visualize.Band;
import edu.caltech.ipac.firefly.visualize.ClientFitsHeader;
@@ -47,11 +47,7 @@
import edu.caltech.ipac.visualize.draw.Metric;
import edu.caltech.ipac.visualize.draw.Metrics;
import edu.caltech.ipac.visualize.plot.*;
-import nom.tam.fits.BasicHDU;
-import nom.tam.fits.Fits;
-import nom.tam.fits.FitsException;
-import nom.tam.fits.Header;
-import nom.tam.fits.HeaderCard;
+import nom.tam.fits.*;
import nom.tam.util.Cursor;
import java.awt.*;
@@ -876,12 +872,12 @@ public static DataGroup getFitsHeaders(Header headers, String name) {
DataType comment = new DataType("Comments", String.class);
DataType keyword = new DataType("Keyword", String.class);
DataType value = new DataType("Value", String.class);
- comment.getFormatInfo().setWidth(80);
- value.getFormatInfo().setWidth(80);
- keyword.getFormatInfo().setWidth(68);
- DataType[] types = new DataType[]{
- new DataType("#", Integer.class),
- keyword, value, comment};
+ DataType num = new DataType("#", Integer.class);
+ comment.getFormatInfo().setWidth(30);
+ value.getFormatInfo().setWidth(10);
+ keyword.getFormatInfo().setWidth(10);
+ num.getFormatInfo().setWidth(3);
+ DataType[] types = new DataType[]{num, keyword, value, comment};
DataGroup dg = new DataGroup("Headers - " + name, types);
int i = 0;
@@ -946,10 +942,11 @@ public static WebPlotResult getFitsHeaderInfo(PlotState state) {
* DM-4494
*
* @param state
- * @return
+ * @param f
+ *@param tableID @return
*/
- public static Map getFitsHeaderExtend(PlotState state) throws FitsException {
+ private static Map getFitsHeaderExtend(PlotState state, File f, String tableID) throws FitsException {
HashMap dataMap = new HashMap();
ActiveCallCtx ctx = null;
@@ -960,9 +957,11 @@ public static Map getFitsHeaderExtend(PlotState state) throws FitsException {
for (Band band : state.getBands()) {
FitsRead fr = plot.getHistogramOps(band, ctx.getFitsReadGroup()).getFitsRead();
DataGroup dg = getFitsHeaders(fr.getHeader(), plot.getPlotDesc());
+ dg.addAttribute("source", ServerContext.replaceWithPrefix(f));
+ dg.addAttribute("fileSize", String.valueOf(f.length()));
+ dg.addAttribute(TableServerRequest.TBL_ID, tableID + '-' + band.name());
dataMap.put(band.name(), dg);
-
}
return dataMap;
@@ -981,12 +980,10 @@ public static Map getFitsHeaderExtend(PlotState state) throws FitsException {
* @return
*/
- public static Object[] getFitsHeader(PlotState state, String tableID) throws FitsException {
+ public static HashMap getFitsHeader(PlotState state, String tableID) throws FitsException {
HashMap dataMap = new HashMap();
-
- HashMap metaMap = new HashMap();
try {
for (Band band : state.getBands()) {
File f = PlotStateUtil.getWorkingFitsFile(state, band);
@@ -995,25 +992,21 @@ public static Object[] getFitsHeader(PlotState state, String tableID) throws Fi
TableServerRequest request = new TableServerRequest("fitsHeaderTale");
request.setTblId(tableID);
- TableMeta meta = new TableMeta("fitsHeader");
- meta.setFileSize(f.length());
- meta.setAttribute(TableServerRequest.TBL_ID, tableID + '-' + band.name());
-
- metaMap.put(band.name(), meta);
BasicHDU hdu[] = fits.read();
Header header = hdu[0].getHeader();
if (header.containsKey("EXTEND") && header.getBooleanValue("EXTEND")) {
- dataMap = (HashMap) getFitsHeaderExtend(state);
+ dataMap = (HashMap) getFitsHeaderExtend(state, f, tableID);
} else {
DataGroup dg = getFitsHeaders(header, "fits data");
-
+ dg.addAttribute("source", ServerContext.replaceWithPrefix(f));
+ dg.addAttribute("fileSize", String.valueOf(f.length()));
+ dg.addAttribute(TableServerRequest.TBL_ID, tableID + '-' + band.name());
dataMap.put(band.name(), dg);
}
}
////LZcounters.incrementVis("Fits header");
- Object[] mapObj = {dataMap, metaMap};
- return mapObj;
+ return dataMap;
}
catch (Exception e ) {
diff --git a/src/firefly/js/core/AppDataCntlr.js b/src/firefly/js/core/AppDataCntlr.js
index 9545740c64..3e5345b217 100644
--- a/src/firefly/js/core/AppDataCntlr.js
+++ b/src/firefly/js/core/AppDataCntlr.js
@@ -3,12 +3,13 @@
*/
import {take} from 'redux-saga/effects';
+import shallowequal from 'shallowequal';
import {get} from 'lodash';
import {flux} from '../Firefly.js';
import {dispatchAddSaga} from '../core/MasterSaga.js';
import BrowserCache from '../util/BrowserCache.js';
-import menuRenderer from './reducers/MenuReducer.js';
+import {menuReducer} from './reducers/MenuReducer.js';
import Point, {isValidPoint} from '../visualize/Point.js';
import {getModuleName} from '../util/WebUtil.js';
@@ -186,21 +187,14 @@ function initPreferences() {
export function reducer(state=getInitState(), action={}) {
- if (action.type && !action.type.startsWith(APP_DATA_PATH)) return state;
+ var nstate = appDataReducer(state, action);
+ nstate.menu = menuReducer(nstate.menu, action);
- var newState = appDataReducer(state, action);
-
- var menu = menuRenderer.reducer(newState.menu, action);
-
- return mergeAll(state, newState, {menu});
-}
-
-function mergeAll(orig, newval, updates) {
-
- var hasChanged = orig !== newval;
- hasChanged = hasChanged || Object.keys(updates).reduce( (prev, next) => prev || orig[next] != updates[next], false);
-
- return hasChanged ? Object.assign({}, newval, updates) : orig;
+ if (shallowequal(state, nstate)) {
+ return state;
+ } else {
+ return nstate;
+ }
}
function appDataReducer(state, action={}) {
@@ -310,7 +304,7 @@ export function dispatchOnAppReady(callback) {
/*---------------------------- EXPORTED FUNTIONS -----------------------------*/
export function isAppReady() {
return get(flux.getState(), [APP_DATA_PATH, 'isReady']) &&
- get(flux.getState(), [APP_DATA_PATH, 'gwtLoaded']);
+ (get(window, 'firefly.noGWT') || get(flux.getState(), [APP_DATA_PATH, 'gwtLoaded']));
}
export function getMenu() {
diff --git a/src/firefly/js/core/FireflyViewer.js b/src/firefly/js/core/FireflyViewer.js
index 958bb33740..a88b4847d7 100644
--- a/src/firefly/js/core/FireflyViewer.js
+++ b/src/firefly/js/core/FireflyViewer.js
@@ -32,6 +32,7 @@ import {dispatchAddSaga} from '../core/MasterSaga.js';
*
menu: menu is an array of menu items {label, action, icon, desc, type}. Leave type blank for dropdown. If type='COMMAND', it will fire the action without triggering dropdown.
*
appTitle: The title of the FireflyViewer. It will appears at top left of the banner. Defaults to 'Firefly'.
*
appIcon: A url string to the icon to appear on the banner.
+ *
footer: A react elements to place on the footer when the menu drop down.
*
searchPanels: An array of additional react elements which are mapped to a menu item's action.
*
views: The type of result view. Choices are 'images', 'tables', and 'xyPlots'. They can be combined with ' | ', i.e. 'images | tables'