Newer
Older
Sonia Zorba
committed
import java.sql.Array;
import net.ivoa.xml.vospace.v2.Node;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
Sara Bertocco
committed
import java.sql.Types;
import java.util.ArrayList;
import net.ivoa.xml.vospace.v2.ContainerNode;
import net.ivoa.xml.vospace.v2.DataNode;
import net.ivoa.xml.vospace.v2.Property;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Repository;
/**
*
* @author bertocco
*/
@Repository
public class NodeDAO {
@Value("${vospace-authority}")
private String authority;
private final JdbcTemplate jdbcTemplate;
@Autowired
public NodeDAO(DataSource dataSource) {
jdbcTemplate = new JdbcTemplate(dataSource);
}
Sara Bertocco
committed
public void createNode(Node myNode) {
// check if parent path exist, else throw HTTP 404 , secondo specifica vospace
/*
Retrieve the path (ltree) and the relative_path (ltree) of the parent node:
select path, relative_path from node n
join node_vos_path p on n.node_id = p.node_id
where p.vos_path = '/path/to/parent’
Then perform the insert using the path and relative_path to fill the parent_path and parent_relative_path columns of the new node.
*/
String nodeURI = myNode.getUri();
String path = nodeURI.replaceAll("vos://[^/]+", "");
String parentPath = getParentPath(path);
String sql = "SELECT path, relative_path from "
+ "node n join node_vos_path p on n.node_id = p.node_id "
+ "where p.vos_path = ?";
List<NodePaths> paths = jdbcTemplate.query(conn -> {
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, parentPath);
return ps;
}, (row, index) -> {
return getPathsFromResultSet(row);
});
Sara Bertocco
committed
if(paths.isEmpty()) {
throw new IllegalStateException("Unable to find parent node during node creation");
}
Sara Bertocco
committed
sb.append("INSERT INTO node");
sb.append(" (name, busy_state, owner_id, creator_id, group_read, group_write,");
sb.append(" is_public, parent_path, type)");
sb.append(" VALUES (?, ?, ?, ?, ?, ?, ?, ?, ? )");
jdbcTemplate.update(conn -> {
PreparedStatement ps = conn.prepareStatement(sb.toString());
ps.setString(1, getNodeName(myNode));
ps.setBoolean(2, getIsBusy(myNode));
ps.setString(3, getProperty(myNode, getPropertyURI("creator")));
ps.setString(4, getProperty(myNode, getPropertyURI("creator")));
ps.setArray(5, fromPropertyToArray(getProperty(myNode, getPropertyURI("groupread"))));
ps.setArray(6, fromPropertyToArray(getProperty(myNode, getPropertyURI("groupwrite"))));
ps.setBoolean(7, Boolean.valueOf(getProperty(myNode, getPropertyURI("publicread"))));
//ps.setBoolean(7, true);
ps.setObject(8, paths.get(0).parentPath, Types.OTHER);
ps.setString(9, getProperty(myNode, getPropertyURI("type")));
return ps;
});
Sara Bertocco
committed
public Optional<Node> listNode(String path) {
String sql = "SELECT os.vos_path, n.node_id, type, async_trans, busy_state, owner_id, group_read, group_write, is_public, content_length, created_on, last_modified from node n\n"
+ "JOIN node_vos_path os ON n.node_id = os.node_id\n"
+ "WHERE n.path ~ (" + getFirstLevelChildrenSelector(path) + ")::lquery\n"
+ "OR os.vos_path = ? ORDER BY vos_path";
List<Node> parentAndChildren = jdbcTemplate.query(conn -> {
ps.setString(1, path);
ps.setString(2, path);
if (parentAndChildren.isEmpty()) {
return Optional.empty();
}
// Query returns parent as first node
Node node = parentAndChildren.get(0);
// Fill children
if (node instanceof ContainerNode && parentAndChildren.size() > 1) {
ContainerNode parent = (ContainerNode) node;
for (int i = 1; i < parentAndChildren.size(); i++) {
parent.getNodes().add(parentAndChildren.get(i));
}
}
}
private String getFirstLevelChildrenSelector(String path) {
String select = "(SELECT path FROM node WHERE node_id = (SELECT node_id FROM node_vos_path WHERE vos_path = ?))::varchar || '";
if (!"/".equals(path)) {
select += ".";
}
select += "*{1}'";
return select;
private Node getNodeFromResultSet(ResultSet rs) throws SQLException {
Node node = getTypedNode(rs.getString("type"));
Sonia Zorba
committed
if (node instanceof DataNode) {
((DataNode) node).setBusy(rs.getBoolean("busy_state"));
Sonia Zorba
committed
}
node.setUri(getUri(rs.getString("vos_path")));
List<Property> properties = new ArrayList<>();
Sonia Zorba
committed
addProperty(getPropertyURI("length"), rs.getString("content_length"),
properties);
Sonia Zorba
committed
addProperty(getPropertyURI("btime"), rs.getString("created_on"),
properties);
Sonia Zorba
committed
addProperty(getPropertyURI("mtime"), rs.getString("last_modified"),
properties);
Sonia Zorba
committed
addProperty(getPropertyURI("groupread"), getGroupsString(rs, "group_read"),
properties);
Sonia Zorba
committed
addProperty(getPropertyURI("groupwrite"), getGroupsString(rs, "group_write"),
properties);
Sonia Zorba
committed
addProperty(getPropertyURI("publicread"), rs.getString("is_public"),
properties);
Sonia Zorba
committed
addProperty("urn:async_trans", rs.getString("async_trans"),
properties);
Sonia Zorba
committed
node.setProperties(properties);
private String getPropertyURI(String propertyName) {
return "ivo://ivoa.net/vospace/core#".concat(propertyName);
}
Sonia Zorba
committed
private String getGroupsString(ResultSet rs, String column) throws SQLException {
Array array = rs.getArray(column);
if (array == null) {
return null;
}
return String.join(" ", (String[]) array.getArray());
}
// If value is null does nothing
private void addProperty(String uri, String value, List<Property> list) {
if (value != null) {
Property prop = new Property();
prop.setUri(uri);
prop.setValue(value);
list.add(prop);
}
}
private Node getTypedNode(String type) {
Node node;
switch (type) {
case "container":
node = new ContainerNode();
break;
case "data":
node = new DataNode();
break;
default:
throw new UnsupportedOperationException("Node type " + type + " not supported yet");
}
return node;
}
private String getUri(String path) {
return "vos://" + authority + path;
}
Sara Bertocco
committed
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
private NodePaths getPathsFromResultSet(ResultSet rs) throws SQLException {
NodePaths paths = new NodePaths(rs.getString("path"), rs.getString("relative_path"));
return paths;
}
private String getNodeName(String path) {
String[] parsedPath = path.split("/");
return parsedPath[parsedPath.length -1];
}
private String getNodeName(Node myNode) {
String uri = myNode.getUri();
return getNodeName(uri);
}
private boolean getIsBusy(Node myNode) {
if (myNode instanceof DataNode) {
DataNode dataNode = (DataNode)myNode;
return dataNode.isBusy();
}
return false;
}
private String getParentPath(String path) {
String[] parsedPath = path.split("/");
StringBuilder sb = new StringBuilder();
for (int i = 0; i < parsedPath.length - 1; i++) {
sb.append("/").append(parsedPath[i]);
}
return sb.toString();
}
private String getProperty(Node node, String uri) {
for (Property property : node.getProperties()) {
if (uri.equals(property.getUri())) {
return property.getValue();
}
}
return null;
}
private Array fromPropertyToArray(String myProperty) {
if (myProperty == null || myProperty.isBlank())
return null;
else {
//myProperty.split(" ")
return null;
}
}
private class NodePaths {
private String path;
private String parentPath;
public NodePaths(String myPath, String myParentPath) {
this.path = myPath;
this.parentPath = myParentPath;
}
public String toString() {
return parentPath + " " + path;
}
}