/***************************************************
*
* cismet GmbH, Saarbruecken, Germany
*
* ... and it just works.
*
****************************************************/
package Sirius.server.localserver.tree;
import Sirius.server.AbstractShutdownable;
import Sirius.server.ServerExitError;
import Sirius.server.Shutdown;
import Sirius.server.localserver._class.ClassCache;
import Sirius.server.middleware.types.Link;
import Sirius.server.middleware.types.MetaClassNode;
import Sirius.server.middleware.types.MetaNode;
import Sirius.server.middleware.types.MetaObjectNode;
import Sirius.server.middleware.types.Node;
import Sirius.server.newuser.User;
import Sirius.server.newuser.UserGroup;
import Sirius.server.newuser.permission.Permission;
import Sirius.server.newuser.permission.Policy;
import Sirius.server.newuser.permission.PolicyHolder;
import Sirius.server.property.ServerProperties;
import Sirius.server.sql.DBBackend;
import Sirius.server.sql.DBConnection;
import Sirius.server.sql.DBConnectionPool;
import org.apache.log4j.Logger;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import de.cismet.tools.StringTools;
/**
* Klasse um auf den in der DB gespeicherten Graphen zuzugreifen.
*
* @author schlob
* @version $Revision$, $Date$
*/
public class VirtualTree extends Shutdown implements AbstractTree {
//~ Static fields/initializers ---------------------------------------------
private static final transient Logger LOG = Logger.getLogger(VirtualTree.class);
//~ Instance fields --------------------------------------------------------
private ServerProperties properties;
private DBConnectionPool conPool;
private HashSet<Integer> nonLeafs;
private UserGroupIdentifiers idMap;
private PolicyHolder policyHolder = null;
private ClassCache classCache = null;
//~ Constructors -----------------------------------------------------------
/**
* Creates a new VirtualTree object.
*
* @param conPool DOCUMENT ME!
* @param properties DOCUMENT ME!
* @param policyHolder DOCUMENT ME!
* @param classCache DOCUMENT ME!
*/
public VirtualTree(final DBConnectionPool conPool,
final ServerProperties properties,
final PolicyHolder policyHolder,
final ClassCache classCache) {
this.conPool = conPool;
this.properties = properties;
this.nonLeafs = initNonLeafs();
this.idMap = new UserGroupIdentifiers(conPool);
this.policyHolder = policyHolder;
this.classCache = classCache;
addShutdown(new AbstractShutdownable() {
@Override
protected void internalShutdown() throws ServerExitError {
if (LOG.isDebugEnabled()) {
LOG.debug("shutting down VirtualTree"); // NOI18N
}
idMap.idsByUgIdentifier.clear();
nonLeafs.clear();
}
});
}
//~ Methods ----------------------------------------------------------------
/**
* DOCUMENT ME!
*
* @param nodeId DOCUMENT ME!
* @param ug DOCUMENT ME!
* @param parentPolicy DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws SQLException DOCUMENT ME!
*/
@Override
public NodeReferenceList getChildren(final int nodeId, final UserGroup ug, final Policy parentPolicy)
throws SQLException {
final int ug_id = idMap.getLocalUgId(ug);
boolean artificialIdSupported = false;
ResultSet set = null;
try {
set = conPool.submitInternalQuery(DBBackend.DESC_TABLE_HAS_COLUMN, "cs_cat_node", "artificial_id"); // NOI18N
artificialIdSupported = set.next();
} catch (final SQLException e) {
LOG.warn("cannot test for artificial id support, support disabled", e); // NOI18N
} finally {
DBConnection.closeResultSets(set);
}
//J-
final String localChildren =
"SELECT " // NOI18N
+ "y.id AS id, " // NOI18N
+ "name, " // NOI18N
+ "class_id, " // NOI18N
+ "object_id, " // NOI18N
+ "node_type, " // NOI18N
+ "dynamic_children, " // NOI18N
+ "sql_sort, " // NOI18N
+ "url, " // NOI18N
+ "p.permission AS perm_id, " // NOI18N
+ "p.ug_id, " // NOI18N
+ "pp.key AS perm_key, " // NOI18N
+ "y.policy, " // NOI18N
+ "iconfactory, " // NOI18N
+ "icon, " // NOI18N
+ "derive_permissions_from_class" // NOI18N
+ (artificialIdSupported ? ", artificial_id " : " ") // NOI18N
+ "FROM " // NOI18N
+ "(" // NOI18N
+ "SELECT " // NOI18N
+ "n.id AS id, " // NOI18N
+ "name, " // NOI18N
+ "class_id, " // NOI18N
+ "object_id, " // NOI18N
+ "node_type, " // NOI18N
+ "dynamic_children, " // NOI18N
+ "sql_sort, " // NOI18N
+ "n.policy, " // NOI18N
+ "prot_prefix || server || path || object_name AS url, " // NOI18N
+ "iconfactory, " // NOI18N
+ "icon, " // NOI18N
+ "derive_permissions_from_class" // NOI18N
+ (artificialIdSupported ? ", artificial_id " : " ") // NOI18N
+ "FROM " // NOI18N
+ "cs_cat_node AS n " // NOI18N
+ "LEFT OUTER JOIN url ON (n.descr = url.id) " // NOI18N
+ "LEFT OUTER JOIN url_base AS ub ON (url.url_base_id = ub.id) " // NOI18N
+ ") AS y " // NOI18N
+ "LEFT OUTER JOIN cs_ug_cat_node_perm AS p ON (p.cat_node_id = y.id) " // NOI18N
+ "LEFT OUTER JOIN cs_permission AS pp ON (p.permission = pp.id AND ug_id = " + ug_id + ") " // NOI18N
+ "WHERE " // NOI18N
+ "y.id IN (SELECT id_to FROM cs_cat_link WHERE id_from = " + nodeId + ") "; // NOI18N
//J+
if (LOG.isDebugEnabled()) {
LOG.debug("getChildren for " + nodeId + " called\nlocalChildren from:" + localChildren); // NOI18N
}
// select remote child links
//J-
final String remoteChildren =
"SELECT " // NOI18N
+ "id_to AS id, " // NOI18N
+ "domain_to AS domain " // NOI18N
+ "FROM " // NOI18N
+ "cs_cat_link " // NOI18N
+ "WHERE " // NOI18N
+ "domain_to NOT IN " // NOI18N
+ "( " // NOI18N
+ "SELECT " // NOI18N
+ "id " // NOI18N
+ "FROM " // NOI18N
+ "cs_domain " // NOI18N
+ "WHERE " // NOI18N
+ "lower(name)='local' " // NOI18N
+ "OR lower(name)= lower('" + properties.getServerName().trim() + "')" // NOI18N
+ ") " // NOI18N
+ "AND id_from = " + nodeId; // NOI18N
//J+
Statement stmt = null;
ResultSet rs = null;
try {
stmt = conPool.getConnection().createStatement();
rs = stmt.executeQuery(localChildren);
// add local children to result (nodes)
final NodeReferenceList result = new NodeReferenceList(
removeUnReadableNodes(nodesFromResult(rs, ug, parentPolicy), ug));
DBConnection.closeResultSets(rs);
rs = stmt.executeQuery(remoteChildren);
// add remote children (links)
result.setRemotes(linksFromResult(rs));
return result;
} finally {
DBConnection.closeResultSets(rs);
DBConnection.closeStatements(stmt);
}
}
/**
* DOCUMENT ME!
*
* @param parentNode DOCUMENT ME!
* @param ug DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws SQLException DOCUMENT ME!
*/
@Override
public NodeReferenceList getChildren(final Node parentNode, final UserGroup ug) throws SQLException {
if (LOG.isDebugEnabled()) {
LOG.debug("NodeReferenceList getChildren(Node node, UserGroup ug) "); // NOI18N
}
final String statement = parentNode.getDynamicChildrenStatement();
if (statement == null) {
return this.getChildren(parentNode.getId(), ug, null);
}
if (LOG.isDebugEnabled()) {
LOG.debug("getChildren called (dynamic children)\nstatement:" + statement); // NOI18N
}
Statement stmt = null;
ResultSet rs = null;
try {
stmt = conPool.getConnection().createStatement();
rs = stmt.executeQuery(statement);
final List<Node> result = nodesFromResult(rs, ug);
for (final Node n : result) {
if (!n.isDerivePermissionsFromClass()) {
if (LOG.isDebugEnabled()) {
LOG.debug(n + ": Assigning rights of the parent node."); // NOI18N
}
n.setPermissions(parentNode.getPermissions());
}
n.setDynamic(true);
// if dynamic and has no children
n.setLeaf(n.getDynamicChildrenStatement() == null);
}
return new NodeReferenceList(removeUnReadableNodes(result, ug));
} finally {
DBConnection.closeResultSets(rs);
DBConnection.closeStatements(stmt);
}
}
/**
* DOCUMENT ME!
*
* @param node DOCUMENT ME!
* @param parent DOCUMENT ME!
* @param user DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws SQLException DOCUMENT ME!
*/
@Override
public Sirius.server.middleware.types.Node addNode(final Node node, final Link parent, final User user)
throws SQLException {
if (LOG.isDebugEnabled()) {
LOG.debug("addNode called :: " + node); // NOI18N
}
Integer classId = null;
Integer objectId = null;
char nodeType = 'N';
if (node instanceof MetaObjectNode) {
final MetaObjectNode oNode = (MetaObjectNode)node;
objectId = new Integer(oNode.getObjectId());
classId = new Integer(oNode.getClassId());
nodeType = 'O';
} else if (node instanceof MetaClassNode) {
final MetaClassNode cNode = (MetaClassNode)node;
classId = new Integer(cNode.getClassId());
nodeType = 'C';
}
boolean isRoot = false;
char root = 'F';
String policy = "null"; // NOI18N
if ((parent == null) && (parent.getNodeId() < 0)) {
isRoot = true;
root = 'T';
} else {
final Node parentNode = getNode(parent.getNodeId(), user.getUserGroup());
policy = parentNode.getPermissions().getPolicy().getDbID() + ""; // NOI18N
}
final int nodeId = getNextNodeID();
final String addNode =
"insert into cs_cat_node (id, name, descr, class_id, object_id, node_type, is_root, org,dynamic_children,sql_sort,policy) values ( " // NOI18N
+ nodeId
+ ",'" // NOI18N
+ node.getName()
+ "',1," // NOI18N
+ classId
+ "," // NOI18N
+ objectId
+ ",'" // NOI18N
+ nodeType
+ "','" // NOI18N
+ root
+ "', NULL,NULL,false," // NOI18N
+ policy
+ " )"; // NOI18N
Statement stmt = null;
try {
stmt = conPool.getConnection().createStatement();
final int count = stmt.executeUpdate(addNode);
// \u00FCbertrage rechte des Vaterknotens
inheritNodePermission(nodeId, parent.getNodeId());
if (!isRoot) {
addLink(getNode(parent.getNodeId(), user.getUserGroup()), getNode(nodeId, user.getUserGroup()), user);
}
final Node n = getNode(nodeId, user.getUserGroup());
return n;
} finally {
DBConnection.closeStatements(stmt);
}
}
/**
* DOCUMENT ME!
*
* @param node DOCUMENT ME!
* @param user DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws SQLException DOCUMENT ME!
*/
@Override
public boolean deleteNode(final Node node, final User user) throws SQLException {
if (!nodeIsLeaf(node.getId())) {
LOG.error("Node is no leaf, cannot delete!!!"); // NOI18N
return false;
}
final String deleteNode = "DELETE FROM cs_cat_node where id = "
+ node.getId(); // NOI18N
if (LOG.isDebugEnabled()) {
LOG.debug("delete Node " + deleteNode); // NOI18N
}
final String delLink = "DELETE FROM cs_cat_link where id_to = "
+ node.getId(); // NOI18N
if (LOG.isDebugEnabled()) {
LOG.debug("delte Link in delete node " + delLink); // NOI18N
}
final String delPerm = "DELETE FROM cs_ug_cat_node_perm where cat_node_id = "
+ node.getId(); // NOI18N
if (LOG.isDebugEnabled()) {
LOG.debug("delete permission statement; " + delPerm); // NOI18N
}
Statement stmt = null;
try {
stmt = conPool.getConnection().createStatement();
stmt.executeUpdate(deleteNode);
stmt.executeUpdate(delLink);
stmt.executeUpdate(delPerm);
} finally {
DBConnection.closeStatements(stmt);
}
return true;
}
/**
* DOCUMENT ME!
*
* @param father DOCUMENT ME!
* @param child DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws SQLException DOCUMENT ME!
*/
@Override
public boolean addLink(final int father, final int child) throws SQLException {
final String addLink = "INSERT INTO cs_cat_link (id_from,id_to,org,domain_to) values(" // NOI18N
+ father
+ "," // NOI18N
+ child
+ ",null, (select id from cs_domain where name ='" // NOI18N
+ properties.getServerName().trim()
+ "'))"; // NOI18N
if (LOG.isDebugEnabled()) {
LOG.debug("addLink " + addLink); // NOI18N
}
// update the noLeaf Hash as the Father is no Leaf anymore
nonLeafs.add(new Integer(father));
Statement stmt = null;
try {
stmt = conPool.getConnection().createStatement();
return stmt.executeUpdate(addLink)
> 0;
} finally {
DBConnection.closeStatements(stmt);
}
}
/**
* DOCUMENT ME!
*
* @param from DOCUMENT ME!
* @param to DOCUMENT ME!
* @param user DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws SQLException java.lang.Exception
*/
@Override
public boolean deleteLink(final Node from, final Node to, final User user) throws SQLException {
if (LOG.isDebugEnabled()) {
// user check notwendig ??
LOG.debug("delete link from :" + from.toString() + " to :" + to.toString()); // NOI18N
}
final String deleteLink = "DELETE FROM cs_cat_link WHERE id_from = " // NOI18N
+ from.getId()
+ " AND id_to = " // NOI18N
+ to.getId()
+ " AND domain_to = " // NOI18N
+ "( SELECT id from cs_domain where lower(name) = lower('" // NOI18N
+ to.getDomain()
+ "') )"; // NOI18N
if (LOG.isDebugEnabled()) {
LOG.debug("deleteLink: " + deleteLink); // NOI18N
}
Statement stmt = null;
try {
stmt = conPool.getConnection().createStatement();
final int affected = stmt.executeUpdate(deleteLink);
try {
if (nodeIsLeaf(from.getId())) {
nonLeafs.remove(from.getId());
}
} catch (final SQLException ex) {
LOG.error("could not update nonLeafCache", ex); // NOI18N
}
return affected
> 0;
} finally {
DBConnection.closeStatements(stmt);
}
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws SQLException DOCUMENT ME!
*/
@Override
public int getNextNodeID() throws SQLException {
final String query = "SELECT NEXTVAL('cs_cat_node_sequence')"; // NOI18N
Statement stmt = null;
ResultSet rs = null;
try {
stmt = conPool.getConnection().createStatement();
rs = stmt.executeQuery(query);
if (rs.next()) {
return (rs.getInt(1));
} else {
return 1;
}
} finally {
DBConnection.closeResultSets(rs);
DBConnection.closeStatements(stmt);
}
}
/**
* DOCUMENT ME!
*
* @param from DOCUMENT ME!
* @param to DOCUMENT ME!
* @param user DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws SQLException DOCUMENT ME!
*/
// TODO: why is the user needed if it is not used at all
@Override
public boolean addLink(final Node from, final Node to, final User user) throws SQLException {
return addLink(from.getId(), to.getId());
}
/**
* DOCUMENT ME!
*
* @param ug DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws SQLException DOCUMENT ME!
*/
@Override
public Node[] getClassTreeNodes(final UserGroup ug) throws SQLException {
final int ug_id = idMap.getLocalUgId(ug);
final String statement = "select distinct " // NOI18N
+ "y.id as id,name,class_id,object_id,node_type,dynamic_children,sql_sort, url , p.permission as perm_id,p.ug_id,pp.key as perm_key,y.policy,iconfactory,icon,derive_permissions_from_class from " // NOI18N
+ "(" // NOI18N
+ "select " // NOI18N
+ "n.id as id,name,class_id,object_id,node_type,dynamic_children,sql_sort,n.policy,prot_prefix||server||path||object_name as url,iconfactory,icon,derive_permissions_from_class " // NOI18N
+ "from " // NOI18N
+ "cs_cat_node as n left outer join url on ( n.descr=url.id ) " // NOI18N
+ "left outer join url_base as ub on (url.url_base_id=ub.id) " // NOI18N
+ "where " // NOI18N
+ "is_root=true and node_type='C' " // NOI18N
+ ") as y " // NOI18N
+ "left outer join cs_ug_cat_node_perm as p on p.cat_node_id=y.id and ug_id=" // NOI18N
+ ug_id
+ " left outer join cs_permission as pp on p.permission=pp.id "; // NOI18N
Statement stmt = null;
ResultSet rs = null;
try {
stmt = conPool.getConnection().createStatement();
rs = stmt.executeQuery(statement);
final List<Node> nodes = nodesFromResult(rs, ug);
for (final Node n : nodes) {
n.setLeaf(nodeIsLeaf(n.getId()));
}
// TODO Remove classnodes if the class is not readable
return removeUnReadableNodes(nodes, ug);
} finally {
DBConnection.closeResultSets(rs);
DBConnection.closeStatements(stmt);
}
}
/**
* DOCUMENT ME!
*
* @param nodeId DOCUMENT ME!
* @param parentNodeId DOCUMENT ME!
*
* @throws SQLException DOCUMENT ME!
*/
@Override
@Deprecated
public void inheritNodePermission(final int nodeId, final int parentNodeId) throws SQLException {
// precondition id is set with autokey (sequence)
final String statement =
"insert into cs_ug_cat_node_perm (ug_id,cat_node_id,permission) (select ug_id," // NOI18N
+ nodeId
+ ",permission from cs_ug_cat_node_perm where cat_node_id=" // NOI18N
+ parentNodeId
+ ")"; // NOI18N
Statement stmt = null;
try {
stmt = conPool.getConnection().createStatement();
stmt.executeUpdate(statement);
} finally {
DBConnection.closeStatements(stmt);
}
}
/**
* DOCUMENT ME!
*
* @param objectId DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws SQLException DOCUMENT ME!
*/
@Override
public boolean hasNodes(final String objectId) throws SQLException {
// oId@cId
final String[] ids = objectId.split("@"); // NOI18N
final String statement = "select count(id) from cs_cat_node where object_id = " // NOI18N
+ ids[0]
+ " and class_id = " // NOI18N
+ ids[1];
Statement stmt = null;
ResultSet rs = null;
try {
stmt = conPool.getConnection().createStatement();
rs = stmt.executeQuery(statement);
if (rs.next()) {
return (rs.getInt(1) == 0);
}
} finally {
DBConnection.closeResultSets(rs);
DBConnection.closeStatements(stmt);
}
assert false : "reached unreachable code"; // NOI18N
return true;
}
/**
* DOCUMENT ME!
*
* @param ug DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws SQLException DOCUMENT ME!
*/
@Override
public Node[] getTopNodes(final UserGroup ug) throws SQLException {
LOG.info("get top nodes for UserGroup:" + ug.getName() + "@" + ug.getDomain()); // NOI18N
final int ug_id = idMap.getLocalUgId(ug);
final String statement = "select distinct " // NOI18N
+ "y.id as id,name,class_id,object_id,node_type,dynamic_children,sql_sort, url , p.permission as perm_id,p.ug_id,pp.key as perm_key,y.policy,iconfactory,icon,derive_permissions_from_class from " // NOI18N
+ "(" // NOI18N
+ "select " // NOI18N
+ "n.id as id,name,class_id,object_id,node_type,dynamic_children,sql_sort,n.policy,prot_prefix||server||path||object_name as url,iconfactory,icon,derive_permissions_from_class " // NOI18N
+ "from " // NOI18N
+ "cs_cat_node as n left outer join url on ( n.descr=url.id ) " // NOI18N
+ "left outer join url_base as ub on (url.url_base_id=ub.id) " // NOI18N
+ "where " // NOI18N
+ "is_root=true and node_type<>'C' " // NOI18N
+ ") as y " // NOI18N
+ "left outer join cs_ug_cat_node_perm as p on p.cat_node_id=y.id and ug_id=" // NOI18N
+ ug_id
+ " left outer join cs_permission as pp on p.permission=pp.id "; // NOI18N
Statement stmt = null;
ResultSet rs = null;
try {
stmt = conPool.getConnection().createStatement();
rs = stmt.executeQuery(statement);
return removeUnReadableNodes(nodesFromResult(rs, ug), ug);
// Die Knoten die nicht angezeigt werden dürfen müssen noch rausgefiltert werden
} finally {
DBConnection.closeResultSets(rs);
DBConnection.closeStatements(stmt);
}
}
/**
* DOCUMENT ME!
*
* @param n DOCUMENT ME!
* @param ug DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
private Node[] removeUnReadableNodes(final List<Node> n, final UserGroup ug) {
final List<Node> v = new ArrayList<Node>();
if (LOG.isInfoEnabled()) {
LOG.info("removeUnReadableNodes " + n.size() + " Elements before"); // NOI18N
}
for (final Node node : n) {
if (node.getPermissions().hasReadPermission(ug)) {
v.add(node);
}
}
if (LOG.isInfoEnabled()) {
LOG.info("removeUnReadableNodes " + v.size() + " Elements after"); // NOI18N
}
return v.toArray(new Node[v.size()]);
}
/**
* DOCUMENT ME!
*
* @param nodeId DOCUMENT ME!
* @param ug DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws SQLException DOCUMENT ME!
*/
@Override
public Node getNode(final int nodeId, final UserGroup ug) throws SQLException {
// beschaffe lokale ug_id
final int ug_id = idMap.getLocalUgId(ug);
Statement stmt = null;
ResultSet rs = null;
try {
final String statement =
"select y.id as id,name,class_id,object_id,node_type,dynamic_children,sql_sort, url , p.permission as perm_id,p.ug_id,pp.key as perm_key,y.policy,iconfactory,icon,derive_permissions_from_class " // NOI18N
+ "from" // NOI18N
+ " (select n.id as id,name,class_id,object_id,node_type,dynamic_children,sql_sort,n.policy,prot_prefix||server||path||object_name as url,iconfactory,icon,derive_permissions_from_class from cs_cat_node as n left outer join url on ( n.descr=url.id ) " // NOI18N
+ "left outer join url_base as ub on (url.url_base_id=ub.id) " // NOI18N
+ "where n.id=" // NOI18N
+ nodeId
+ " ) as y " // NOI18N
+ "left outer join cs_ug_cat_node_perm as p on p.cat_node_id=y.id and ug_id = " // NOI18N
+ ug_id
+ " " // NOI18N
+ "left outer join cs_permission as pp on p.permission=pp.id"; // NOI18N
stmt = conPool.getConnection().createStatement();
rs = stmt.executeQuery(statement);
final List<Node> nodes = nodesFromResult(rs, ug);
if (nodes.isEmpty()) {
return null;
} else {
return nodes.get(0);
}
} finally {
DBConnection.closeResultSets(rs);
DBConnection.closeStatements(stmt);
}
}
/**
* DOCUMENT ME!
*
* @param nodeId DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws SQLException DOCUMENT ME!
*/
@Override
public boolean nodeIsLeaf(final int nodeId) throws SQLException {
final String statement = "select count(id_from) from cs_cat_link where id_from = "
+ nodeId; // NOI18N
Statement stmt = null;
ResultSet rs = null;
try {
stmt = conPool.getConnection().createStatement();
rs = stmt.executeQuery(statement);
rs.next();
return (rs.getInt(1) == 0);
} finally {
DBConnection.closeResultSets(rs);
DBConnection.closeStatements(stmt);
}
}
/**
* DOCUMENT ME!
*
* @param nodeTable DOCUMENT ME!
* @param ug DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws SQLException Throwable DOCUMENT ME!
*/
private List<Node> nodesFromResult(final ResultSet nodeTable, final UserGroup ug) throws SQLException {
return nodesFromResult(nodeTable, ug, null);
}
/**
* DOCUMENT ME!
*
* @param nodeTable DOCUMENT ME!
* @param ug DOCUMENT ME!
* @param parentPolicy DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws SQLException Throwable DOCUMENT ME!
* @throws IllegalStateException Exception DOCUMENT ME!
*/
private List<Node> nodesFromResult(final ResultSet nodeTable, final UserGroup ug, final Policy parentPolicy)
throws SQLException {
final List<Node> nodes = new ArrayList<Node>();
final Map<String, Node> nodeHM = new HashMap<String, Node>();
char c = 'N';
while (nodeTable.next()) // add all nodes to the hashtable
{
// current Node
Node tmp = null;
int id = 0;
String name = ""; // NOI18N
String descr = null;
String dynamicChildren = null;
String artifical_id = null;
int classId = -1;
try {
if (nodeTable.getObject("class_id") != null) { // NOI18N
classId = nodeTable.getInt("class_id"); // NOI18N
}
} catch (Exception skip) {
}
boolean derivePermissionsFromClass = false;
try {
derivePermissionsFromClass = nodeTable.getBoolean("derive_permissions_from_class"); // NOI18N
} catch (Exception skip) {
}
int iconFactory = -1;
try {
if (nodeTable.getObject("iconfactory") != null) { // NOI18N
iconFactory = nodeTable.getInt("iconfactory"); // NOI18N
}
} catch (Exception skip) {
}
String icon = null;
try {
if (nodeTable.getObject("icon") != null) { // NOI18N
icon = nodeTable.getString("icon"); // NOI18N
}
} catch (Exception skip) {
}
c = nodeTable.getString("node_type").charAt(0); // alias for the leftmost character of the // NOI18N
try {
name = nodeTable.getString("name").trim(); // NOI18N
} catch (Exception skip) {
name = null;
}
try {
artifical_id = nodeTable.getString("artificial_id").trim(); // NOI18N
} catch (final Exception e) {
// artificial id not present, don't care
}
descr = nodeTable.getString("url"); // NOI18N
descr = StringTools.deleteWhitespaces(descr);
id = nodeTable.getInt("id"); // NOI18N
dynamicChildren = nodeTable.getString("dynamic_children"); // NOI18N
if (dynamicChildren != null) {
dynamicChildren = dynamicChildren.trim();
}
final String domain = properties.getServerName();
final Boolean sqlSort = nodeTable.getBoolean("sql_sort"); // NOI18N
Policy policy = null;
try {
final Object policytester = nodeTable.getObject("policy"); // NOI18N
if (policytester != null) {
final int p = nodeTable.getInt("policy"); // NOI18N
policy = policyHolder.getServerPolicy(p);
}
} catch (Exception e) {
if (LOG.isDebugEnabled()) {
LOG.debug("Policy was not in resultset. But is normal at DynamicChildrenStatements ", e); // NOI18N
}
}
if (policy == null) {
if ((c == (byte)'N') || (c == (byte)'n')) {
// Purenode
// bekommt die Policy des Parent-Knotens
if (policy == null) {
policy = parentPolicy;
}
// pureNodePolicy in runtime.properties
if (policy == null) {
policy = policyHolder.getServerPolicy(properties.getPureNodePolicy());
}
} else if ((c == (byte)'O') || (c == (byte)'o')) {
// Objectnode
// bekommt die Policy der Klasse
if (policy == null) {
try {
policy = classCache.getClass(classId).getPolicy();
} catch (Exception e) {
LOG.warn("Error at: classCache.getClass(nodeTable.getInt(\"class_id\")).getPolicy() ", e); // NOI18N
}
}
} else if ((c == (byte)'C') || (c == (byte)'c')) {
// Classnode
// classNodePolicy in runtime.properties
if (policy == null) {
policy = policyHolder.getServerPolicy(properties.getClassNodePolicy());
}
} else {
throw new IllegalStateException("Not a known node type : " + c + " ?"); // NOI18N
}
// serverPolicy in runtime.properties
if (policy == null) {
policy = policyHolder.getServerPolicy(properties.getServerPolicy());
}
// PARANOID Policy als Fallback
if (policy == null) {
LOG.warn("WARNING: This should not be neccessary. Setting fallback policy: PARANOID"); // NOI18N
policy = Policy.createParanoidPolicy();
}
}
final boolean leaf = !nonLeafs.contains(new Integer(id));
Sirius.server.localserver._class.Class metaclass = null;
// new Node according to node type
if ((c == (byte)'N') || (c == (byte)'n')) {
tmp = new MetaNode(
id,
domain,
name,
descr,
leaf,
policy,
iconFactory,
icon,
derivePermissionsFromClass,
classId,
artifical_id);
} else {
try {
metaclass = classCache.getClass(classId);
} catch (Exception e) {
// FIXME: doesn't
LOG.warn("getClass failed. cannot create objekt/classnode", e); // NOI18N
}
if ((metaclass != null) && metaclass.getPermissions().hasReadPermission(ug)) {
if ((c == (byte)'O') || (c == (byte)'o')) {
tmp = new MetaObjectNode(
id,
name,
descr,
domain,
nodeTable.getInt("object_id"), // NOI18N
classId,
leaf,
policy,
iconFactory,
icon,
derivePermissionsFromClass,
artifical_id);
} else if ((c == (byte)'C') || (c == (byte)'c')) {
tmp = new MetaClassNode(
id,
domain,
classId,
name,
descr,
leaf,
policy,
iconFactory,
icon,
derivePermissionsFromClass,
classId,
artifical_id);
} else {
throw new IllegalStateException("Nodetype not known : " + c + " ?"); // NOI18N
}
}
}
if (tmp != null) {
tmp.setDynamicChildrenStatement(dynamicChildren);
if (sqlSort != null) {
tmp.setSqlSort(sqlSort);
}
final String nodeKey = "Node:" // NOI18N
+ tmp.getId()
+ "@" // NOI18N
+ tmp.getDomain();
// Das hinzufügen zu nodes bzw. nodesHM auf doppelte Einträge braucht/kann nur gecheckt werden , wenn
// die Nodes nicht dynamisch sind. Deshalb der Check auf isDynamic) bzw auf nodeId==-1 (Das soll wieder
// raus wenn isDynamic() den richtigen Wert liefert)
if (!nodeHM.containsKey(nodeKey) || tmp.isDynamic() || (tmp.getId() == -1)) {
nodeHM.put(nodeKey, tmp);
nodes.add(tmp);
}
if (tmp.isDerivePermissionsFromClass()) {
if (LOG.isInfoEnabled()) {
LOG.info(tmp + "(" + c + "): Permissions derived from class."); // NOI18N
}
final Sirius.server.localserver._class.Class cc = classCache.getClass(tmp.getClassId());
if (cc != null) {
tmp.setPermissions(cc.getPermissions());
}
} else {
try {
final Object permId = nodeTable.getObject("perm_id"); // NOI18N
final String permKey = nodeTable.getString("perm_key"); // NOI18N
if ((permId != null) && (permKey != null)) {
final Permission pp = new Permission(nodeTable.getInt("perm_id"), permKey); // NOI18N
nodeHM.get(nodeKey).getPermissions().addPermission(ug, pp);
if (LOG.isDebugEnabled()) {
LOG.debug(
"Permission " // NOI18N
+ pp.getKey()
+ " added to node" // NOI18N
+ tmp.getId()
+ " for ug " // NOI18N
+ ug.getKey().toString());
}
}
} catch (final Exception t) {
if (LOG.isInfoEnabled()) {
LOG.info("could not set permissions for node::" + id, t); // NOI18N
}
}
}
}
} // end while
return nodes;
}
/**
* DOCUMENT ME!
*
* @param linkTable DOCUMENT ME!
*
* @return DOCUMENT ME!
*
* @throws SQLException Throwable DOCUMENT ME!
*/
private java.util.ArrayList<Link> linksFromResult(final ResultSet linkTable) throws SQLException {
final java.util.ArrayList<Link> result = new java.util.ArrayList<Link>();
final String domain = properties.getServerName();
while (linkTable.next()) {
final int id = linkTable.getInt("id"); // NOI18N
String toServer = linkTable.getString("domain"); // NOI18N
if (toServer == null) {
toServer = domain;
}
result.add(new Link(id, toServer));
}
return result;
}
/**
* DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
private HashSet<Integer> initNonLeafs() {
// find nodes that are not leafs (a link exists) String statement = "select distinct id_to from cs_cat_link as
// a where id_to in (select distinct id_from from cs_cat_link) union select distinct id from cs_cat_node where
// is_root=true ";
final String statement =
"select distinct id_from from cs_cat_link union select distinct id as id_from from cs_cat_node where dynamic_children is not null"; // NOI18N
// the non leafs are of the order 10K in wundalive
// TODO: optimisation: probably a select count() would be useful here since the normal catalogue is not used
// that much anymore resulting in far less nonleafs than before. Thus the set will probably far too large.
// In addition to that we are in the init method. An additional select count would not be to bad here.
final HashSet<Integer> nl = new HashSet<Integer>(12000);
Statement stmt = null;
ResultSet rs = null;
try {
stmt = conPool.getConnection().createStatement();
rs = stmt.executeQuery(statement);
while (rs.next()) {
nl.add(rs.getInt("id_from")); // NOI18N
}
if (LOG.isDebugEnabled()) {
LOG.debug("added # of leafentries::" + nl.size()); // NOI18N
}
} catch (SQLException ex) {
LOG.error("Error while loading Leaf property", ex); // NOI18N
} finally {
DBConnection.closeResultSets(rs);
DBConnection.closeStatements(stmt);
}
return nl;
}
//~ Inner Classes ----------------------------------------------------------
/**
* DOCUMENT ME!
*
* @version $Revision$, $Date$
*/
private static final class UserGroupIdentifiers {
//~ Static fields/initializers -----------------------------------------
private static final transient Logger LOG = Logger.getLogger(UserGroupIdentifiers.class);
//~ Instance fields ----------------------------------------------------
private final Map<String, Integer> idsByUgIdentifier = new HashMap<String, Integer>();
//~ Constructors -------------------------------------------------------
/**
* Creates a new UserGroupIdentifiers object.
*
* @param conPool DOCUMENT ME!
*/
UserGroupIdentifiers(final DBConnectionPool conPool) {
final String statement =
"select u.id, u.name||'@'||d.name as ug_identifier from cs_ug as u , cs_domain as d where u.domain=d.id and not (lower(d.name) = 'local')"; // NOI18N
Statement stmt = null;
ResultSet rs = null;
try {
stmt = conPool.getConnection().createStatement();
rs = stmt.executeQuery(statement);
while (rs.next()) {
idsByUgIdentifier.put(rs.getString("ug_identifier"), rs.getInt("id")); // NOI18N
}
} catch (final SQLException ex) {
LOG.error("Fehler beim Laden der UG Fremssystemfeferenzen", ex); // NOI18N
} finally {
DBConnection.closeResultSets(rs);
DBConnection.closeStatements(stmt);
}
}
//~ Methods ------------------------------------------------------------
/**
* DOCUMENT ME!
*
* @param ug DOCUMENT ME!
*
* @return DOCUMENT ME!
*/
int getLocalUgId(final UserGroup ug) {
// beschaffe lokale ug_id
int ug_id = ug.getId();
final Integer localId = idsByUgIdentifier.get(ug.getKey().toString());
// falls mapping vorhanden ersetzten
if (localId != null) {
ug_id = localId;
}
return ug_id;
}
}
}