}
}
}
<<<<<<< HEAD
protected static String getLocalReadAcl(Connection conn, String id)
throws SQLException {
String sql = "SELECT \"GRANT\", \"USER\"" //
+ " FROM ACLS" //
+ " WHERE" //
+ " \"ID\" = '"
+ id
+ "'"//
+ " AND \"PERMISSION\" IN ('Read', 'ReadWrite', 'Everything', 'Browse')"
+ " ORDER BY \"POS\"";
if (isLogEnabled()) {
logDebug(sql);
}
PreparedStatement ps = conn.prepareStatement(sql);
ResultSet rs = ps.executeQuery();
StringBuffer readAcl = new StringBuffer();
try {
while (rs.next()) {
Boolean grant = rs.getBoolean(1);
String op;
if (grant) {
op = rs.getString(2);
} else {
op = '-' + rs.getString(2);
}
if (readAcl.length() == 0) {
readAcl.append(op);
} else {
readAcl.append("," + op);
}
}
} finally {
if (ps != null) {
ps.close();
}
}
return readAcl.toString();
public static String getReadAcl(Connection conn, String id)
throws SQLException {
String localReadAcl;
StringBuffer readAcl = new StringBuffer();
PreparedStatement ps1 = null;
PreparedStatement ps2 = null;
try {
ps1 = conn.prepareStatement("SELECT PARENTID FROM HIERARCHY WHERE ID = ?;");
boolean first = true;
do {
// local acl
localReadAcl = getLocalReadAcl(conn, id);
if (localReadAcl != null && (localReadAcl.length() > 0)) {
if (readAcl.length() == 0) {
readAcl.append(localReadAcl);
} else {
readAcl.append(',' + localReadAcl);
}
}
// get parent
ps1.setObject(1, id);
ResultSet rs = ps1.executeQuery();
String newId;
if (rs.next()) {
newId = (String) rs.getObject(1);
if (rs.wasNull()) {
newId = null;
}
} else {
// no such id
newId = null;
}
if (first && newId == null) {
// there is no parent for the first level
// we may have a version on our hands, find the live doc
ps2 = conn.prepareStatement("SELECT VERSIONABLEID FROM VERSIONS WHERE ID = ?;");
ps2.setObject(1, id);
rs = ps2.executeQuery();
if (rs.next()) {
newId = (String) rs.getObject(1);
if (rs.wasNull()) {
newId = null;
}
} else {
// no such id
newId = null;
}
}
first = false;
id = newId;
} while (id != null);
} finally {
if (ps1 != null) {
ps1.close();
}
if (ps2 != null) {
ps2.close();
}
}
return readAcl.toString();
}
public static ResultSet getReadAclsFor(Connection conn, String principals)
throws SQLException {
DatabaseMetaData meta = conn.getMetaData();
SimpleResultSet result = new SimpleResultSet();
result.addColumn("ID", Types.VARCHAR, 0, 0); // String id
if (meta.getURL().startsWith("jdbc:columnlist:")) {
// this is just to query the result set columns
return result;
}
if (principals == null) {
return result;
}
Set principalsList = split(principals);
Set blackList = new HashSet();
for (String user : principalsList) {
blackList.add('-' + user);
}
// log.debug("getReadAclFor " + principals);
PreparedStatement ps = null;
ResultSet rs = null;
try {
ps = conn.prepareStatement("SELECT \"ID\", \"ACL\" FROM READ_ACLS");
rs = ps.executeQuery();
while (rs.next()) {
String id = rs.getString(1);
String[] acl = rs.getString(2).split(",");
for (String ace : acl) {
// log.debug("ace: " + ace);
if (principalsList.contains(ace)) {
result.addRow(new Object[] { id });
// log.debug("allowed: " + id);
} else if (blackList.contains(ace)) {
// log.debug("deny: " + id);
break;
}
}
}
} finally {
if (rs != null) {
rs.close();
}
if (ps != null) {
ps.close();
}
}
return result;
}
public static class LogAclsModified implements org.h2.api.Trigger,
CloseListener {
private String idName = "ID";
private int idIndex;
private int idType;
/**
* Trigger interface: initialization.
*/
public void init(Connection conn, String schema, String triggerName,
String table, boolean before, int opType) throws SQLException {
ResultSet rs = null;
try {
DatabaseMetaData meta = conn.getMetaData();
rs = meta.getColumns(null, schema, table, idName);
if (!rs.next()) {
if (oldRow == null) {
throw new SQLException("No id key for: " + schema + '.'
+ table);
}
idType = rs.getInt("DATA_TYPE");
idIndex = rs.getInt("ORDINAL_POSITION") - 1;
} finally {
if (rs != null) {
rs.close();
}
}
}
/**
* Trigger interface.
*/
public void fire(Connection conn, Object[] oldRow, Object[] newRow)
throws SQLException {
if (newRow != null) {
PreparedStatement ps = null;
try {
ps = conn.prepareStatement("INSERT INTO hierarchy_modified_acl VALUES(?, ?);");
ps.setString(2, "f");
if (oldRow != null) {
// update or delete
ps.setString(1, oldRow[idIndex].toString());
} else {
// insert
ps.setString(1, newRow[idIndex].toString());
}
ps.executeUpdate();
} finally {
if (ps != null) {
ps.close();
}
}
}
}
public void close() throws SQLException {
}
public void remove() {
}
}
public static class LogHierarchyModified implements org.h2.api.Trigger,
CloseListener {
private String idName = "ID";
private int idIndex;
private int idType;
private String parentIdName = "PARENTID";
private int parentIdIndex;
/**
* Trigger interface: initialization.
*/
public void init(Connection conn, String schema, String triggerName,
String table, boolean before, int opType) throws SQLException {
ResultSet rs = null;
try {
DatabaseMetaData meta = conn.getMetaData();
rs = meta.getColumns(null, schema, table, idName);
if (!rs.next()) {
throw new SQLException("No id key for: " + schema + '.'
+ table);
}
idType = rs.getInt("DATA_TYPE");
idIndex = rs.getInt("ORDINAL_POSITION") - 1;
rs.close();
rs = meta.getColumns(null, schema, table, parentIdName);
if (!rs.next()) {
throw new SQLException("No parentid for in " + schema + '.'
+ table);
}
parentIdIndex = rs.getInt("ORDINAL_POSITION") - 1;
} finally {
if (rs != null) {
rs.close();
}
}
}
/**
* Trigger interface.
*/
public void fire(Connection conn, Object[] oldRow, Object[] newRow)
throws SQLException {
if (newRow != null) {
PreparedStatement ps = null;
try {
ps = conn.prepareStatement("INSERT INTO hierarchy_modified_acl VALUES(?, ?);");
ps.setString(1, newRow[idIndex].toString());
// Insert
ps.setString(2, "t");
ps.executeUpdate();
} else if (oldRow[parentIdIndex] != newRow[parentIdIndex]) {
// Update with new parent
ps.setString(2, "f");
ps.executeUpdate();
}
} finally {
if (ps != null) {
ps.close();
}
}
}
}
public void close() throws SQLException {
}
public void remove() {
}
}
public static ResultSet rebuildReadAcls(Connection conn)
throws SQLException {
SimpleResultSet result = new SimpleResultSet();
PreparedStatement ps = null;
try {
ps = conn.prepareStatement("TRUNCATE TABLE hierarchy_read_acl;");
ps.executeUpdate();
ps = conn.prepareStatement("INSERT INTO hierarchy_read_acl" //
+ " SELECT id, nx_get_read_acl(id)"
+ " FROM (SELECT DISTINCT(id) AS id FROM hierarchy) AS uids;");
ps.executeUpdate();
ps = conn.prepareStatement("TRUNCATE TABLE read_acls;");
ps.executeUpdate();
// TODO: use md5 of the acl as key
ps = conn.prepareStatement("INSERT INTO read_acls" //
+ " SELECT acl, acl" //
+ " FROM (SELECT DISTINCT(nx_get_read_acl(id)) AS acl" //
+ " FROM (SELECT DISTINCT(id) AS id" //
+ " FROM acls) AS uids) AS read_acls_input;");
ps.executeUpdate();
ps = conn.prepareStatement("TRUNCATE TABLE hierarchy_modified_acl;");
ps.executeUpdate();
} finally {
if (ps != null) {
ps.close();
}
}
return result;
}
public static ResultSet updateReadAcls(Connection conn) throws SQLException {
SimpleResultSet result = new SimpleResultSet();
PreparedStatement ps = null;
int rowCount = 0;
try {
ps = conn.prepareStatement("TRUNCATE TABLE read_acls;");
ps.executeUpdate();
// TODO: use md5 of the acl as key
ps = conn.prepareStatement("INSERT INTO read_acls" //
+ " SELECT acl, acl" //
+ " FROM (SELECT DISTINCT(nx_get_read_acl(id)) AS acl" //
+ " FROM (SELECT DISTINCT(id) AS id" //
+ " FROM acls) AS uids) AS read_acls_input;");
ps.executeUpdate();
// New hierarchy_read_acl entry
ps = conn.prepareStatement("INSERT INTO hierarchy_read_acl" //
+ " SELECT id, nx_get_read_acl(id)" //
+ " FROM (SELECT DISTINCT(id) AS id" //
+ " FROM hierarchy_modified_acl" //
+ " WHERE is_new AND" //
+ " EXISTS (SELECT 1 FROM hierarchy WHERE hierarchy_modified_acl.id=hierarchy.id)) AS uids;");
rowCount = ps.executeUpdate();
ps = conn.prepareStatement("DELETE FROM hierarchy_modified_acl WHERE is_new;");
ps.executeUpdate();
// Update hierarchy_read_acl entry
// Mark acl that need to be updated (set to NULL)
ps = conn.prepareStatement("UPDATE hierarchy_read_acl SET acl_id = NULL WHERE id IN (" //
+ " SELECT DISTINCT(id) AS id FROM hierarchy_modified_acl WHERE NOT is_new);");
rowCount = ps.executeUpdate();
ps = conn.prepareStatement("DELETE FROM hierarchy_modified_acl WHERE NOT is_new;");
ps.executeUpdate();
ps = conn.prepareStatement("UPDATE hierarchy_read_acl SET acl_id = NULL WHERE id IN (" //
+ " SELECT h.id" //
+ " FROM hierarchy AS h" //
+ " LEFT JOIN hierarchy_read_acl AS r ON h.id = r.id" //
+ " WHERE r.acl_id IS NOT NULL" //
+ " AND h.parentid IN (SELECT id FROM hierarchy_read_acl WHERE acl_id IS NULL));");
// Mark all childrens
do {
rowCount = ps.executeUpdate();
} while (rowCount > 0);
// Update hierarchy_read_acl acl_ids
// TODO use the md5 for acl_id
ps = conn.prepareStatement("UPDATE hierarchy_read_acl SET acl_id = nx_get_read_acl(id) WHERE acl_id IS NULL;");
ps.executeUpdate();
} finally {
if (ps != null) {
ps.close();
}
}
return result;
}
=======
/**
* Rebuild the complete descendants tree.
*/
public static void initDescendants(Connection conn) throws SQLException {
String sql;
LinkedList todo = new LinkedList();
// find roots
Statement s = conn.createStatement();
sql = "SELECT ID FROM REPOSITORIES";
logDebug(sql);
ResultSet rs = s.executeQuery(sql);
while (rs.next()) {
String rootId = rs.getString(1);
todo.add(rootId);
}
rs.close();
log.trace("SQL: -> " + todo);
if (todo.size() == 0) {
// db not yet initialized, ignore
s.close();
return;
}
// truncate table
String table = "DESCENDANTS";
sql = String.format("TRUNCATE TABLE %s", table);
logDebug(sql);
s.execute(sql);
s.close();
// traverse from roots
Map> ancestors = new HashMap>();
Map> descendants = new HashMap>();
do {
String p = todo.remove();
sql = "SELECT ID FROM HIERARCHY WHERE PARENTID = ? AND ISPROPERTY = 0";
PreparedStatement ps = conn.prepareStatement(sql);
ps.setString(1, p);
// logDebug(sql, p);
rs = ps.executeQuery();
// for each child
while (rs.next()) {
String c = rs.getString(1);
todo.add(c);
// child's ancestors
Set cans = ancestors.get(c);
if (cans == null) {
ancestors.put(c, cans = new HashSet());
}
Set pans = ancestors.get(p);
if (pans != null) {
cans.addAll(pans);
}
cans.add(p);
// all ancestors have it as descendant
for (String pp : cans) {
Set desc = descendants.get(pp);
if (desc == null) {
descendants.put(pp, desc = new HashSet());
}
desc.add(c);
}
}
ps.close();
} while (!todo.isEmpty());
// insert descendants into table
sql = String.format("INSERT INTO %s (ID, DESCENDANTID) VALUES (?, ?)",
table);
PreparedStatement ps = conn.prepareStatement(sql);
int n = 0;
for (Entry> e : descendants.entrySet()) {
String p = e.getKey();
for (String c : e.getValue()) {
ps.setString(1, p);
ps.setString(2, c);
// logDebug(sql, p, c);
ps.execute();
n++;
}
}
logDebug(String.format("-- inserted %s rows into %s", Long.valueOf(n),
table));
ps.close();
}
>>>>>>> f5ac6c074337f5be4ab732b46312fe57d3803bd6
} |