/*************************************************** * * cismet GmbH, Saarbruecken, Germany * * ... and it just works. * ****************************************************/ package Sirius.server.search; import Sirius.server.localserver.*; import Sirius.server.localserver._class.*; import Sirius.server.localserver.object.*; import Sirius.server.localserver.tree.*; //import Sirius.search.WundaSearch.*; //import Sirius.server.localserver.tree.node.*; import Sirius.server.middleware.types.*; import Sirius.server.newuser.*; import Sirius.server.newuser.permission.PermissionHolder; import Sirius.server.search.searchparameter.*; import Sirius.server.sql.*; import java.util.*; /** * DOCUMENT ME! * * @version $Revision$, $Date$ */ public class Seeker { //~ Instance fields -------------------------------------------------------- // public static final int MAX_HITS = 500; protected AbstractTree tree; protected DBConnectionPool conPool; protected ClassCache classCache; protected ObjectFactory objectFactory; protected ObjectHierarchy hierarchy; protected String domain; private final transient org.apache.log4j.Logger logger = org.apache.log4j.Logger.getLogger(this.getClass()); private DBServer dbServer; //~ Constructors ----------------------------------------------------------- /** * Creates a new Seeker object. * * @param dbServer DOCUMENT ME! */ public Seeker(final DBServer dbServer) { try { this.domain = dbServer.getSystemProperties().getServerName(); // reference to the catalogue to be able to deliver nodes tree = dbServer.getTree(); conPool = dbServer.getConnectionPool(); // to get classes from classIDs classCache = dbServer.getClassCache(); objectFactory = dbServer.getObjectFactory(); hierarchy = new ObjectHierarchy(conPool); } catch (Throwable e) { logger.error(e); } } // --------------------------------------------------------------------------------------------------- //~ Methods ---------------------------------------------------------------- /** * DOCUMENT ME! * * @param query DOCUMENT ME! * @param classIds DOCUMENT ME! * @param ug DOCUMENT ME! * @param recursionLevel DOCUMENT ME! * * @return DOCUMENT ME! * * @throws Throwable DOCUMENT ME! */ public SearchResult search(final Query query, final int[] classIds, final UserGroup ug, int recursionLevel) throws Throwable { // enth\u00E4lt die Anzahl der updated datasets if (query.isUpdate()) { return new SearchResult(new Integer(conPool.getDBConnection().submitUpdate(query))); // xxx performantere Bedingung einfallen lassen } if (query.getResultType() == SearchResult.NODE) { final SearchResult result = new SearchResult(new Sirius.server.middleware.types.MetaObjectNode[0]); // Objekte werden bei addAll unter der Verwendung des Filters hinzugef\u00FCgt if (recursionLevel == 0) { result.setFilter(classIds); // expandiere Klassenliste und setzte den Systemparameter cs_classids falls vorhanden SearchParameter // classParam = (SearchParameter)query.getParameter(SearchParameter.CLASSIDS); } query.setParameter( SearchParameter.CLASSIDS, StatementParametrizer.convertNumberArrayForSql(hierarchy.getExtendedClassList(classIds))); // // if(classParam!=null) // classId parameter vorhanden // classParam.setValue(StatementParametrizer.convertNumberArrayForSql(hierarchy.getExtendedClassList(classIds))); // // // Vector von Objectarrays // Zugriff auf Knoten Vector obs = null; if (query.getStatement() == null) // with caching { obs = (Vector)new DefaultResultHandler().handle(conPool.getDBConnection().submitQuery(query), query); } else // takes the queries statement { obs = (Vector)new DefaultResultHandler().handle(conPool.getDBConnection().executeQuery(query), query); } final java.util.ArrayList<Node> nodes = new java.util.ArrayList<Node>(obs.size()); // zuordnung der Objekte zu Knoten for (int i = 0; i < obs.size(); i++) { final java.lang.Object[] object = (java.lang.Object[])obs.get(i); final int object_id = new Integer(object[1].toString()).intValue(); final int class_id = new Integer(object[0].toString()).intValue(); String objectName = null; try { objectName = object[2].toString(); } catch (Exception skip) { if (logger.isDebugEnabled()) { logger.debug("ObjectName=null"); // NOI18N } } // objectid@classId // final String key = constructKey(object_id, class_id); // logger.debug("objectkey found ::"+key); if (hierarchy.classIsReferenced(class_id)) { final Collection fatherStmnts = hierarchy.getFatherStatements(class_id, object_id); // logger.debug("fatherstmnts" +fatherStmnts +" for classid" +class_id); fatherStmnts.addAll(hierarchy.getArrayFatherStatements(class_id, object_id)); // logger.debug("fatherstmnts after array" +fatherStmnts+" for classid" +class_id); final Iterator iter = fatherStmnts.iterator(); while (iter.hasNext()) { final String recursiveCall = iter.next().toString(); if (logger.isDebugEnabled()) { logger.debug("recursive invocation of the search " + recursiveCall); // NOI18N } result.addAllAndFilter( this.search( new Query( new SystemStatement(true, -1, "", false, SearchResult.NODE, recursiveCall), // NOI18N domain), classIds, ug, recursionLevel++).getNodes()); } } final PermissionHolder ph = classCache.getClass(class_id).getPermissions(); // TODO Iconfactory setzen final Node objectNode = new MetaObjectNode( -1, objectName, null, domain, object_id, class_id, true, ph.getPolicy(), -1, null, true); // Thorsten Rechte request objectNode.setPermissions(ph); // java.util.ArrayList<Node> v = tree.getObjectNodes( key, null ) ; //intValue()+"@"+domain,null // /*userGroup*/ // java.util.ArrayList<Node> v = // logger.debug("Knoten gefunden :"+v.size()); // if(v.size()>0)// aufruf in der Ausgabe ! // logger.debug("Knoten konnten hinzugef\u00FCgt werden == "+nodes.addAll(v)); // nodes.addAll(v); nodes.add(objectNode); } // logger.debug(nodes.size()+" Knoten gefunden"); Node[] n = new Node[0]; if (nodes.size() > 0) { n = nodes.toArray(new Node[nodes.size()]); } final Vector filtered = new Vector(n.length); // node Konvertierung und filtern for (int i = 0; i < n.length; i++) { // only object are found // logger.debug(n[i] + " is of type"+ n[i].getClass()); final MetaObjectNode on = (MetaObjectNode)n[i]; if (on.getPermissions().hasPermission(ug.getKey(), PermissionHolder.READPERMISSION)) // readPermission { // objectzuordnung abgeschaltet filtered.add(on); } else { logger.info("UserGroup " + ug + "has no Read Permission for node " + on); // NOI18N } } if (filtered.size() > 0) { result.addAllAndFilter((Sirius.server.middleware.types.MetaObjectNode[])filtered.toArray( new Sirius.server.middleware.types.MetaObjectNode[filtered.size()])); } return result; } else if (query.getResultType() == SearchResult.OBJECT) { Vector objects = null; if (query.getStatement() == null) // with caching { objects = (Vector)new DefaultResultHandler().handle(conPool.getDBConnection().submitQuery(query), query); } else // takes the queries statement { // query wird hier ausgefuehrt, resulat ist vector<object[]> objects = (Vector) new DefaultResultHandler().handle(conPool.getDBConnection().executeQuery(query), query); } final Sirius.server.middleware.types.MetaObject[] metaObject = new Sirius.server.middleware.types.MetaObject[objects.size()]; for (int i = 0; i < objects.size(); i++) { final int classID; final int objectID; // Query hat als resultat classID und objectID in form eines object[] geliefert final java.lang.Object[] object = (java.lang.Object[])objects.get(i); try { classID = Integer.parseInt(object[0].toString()); objectID = Integer.parseInt(object[1].toString()); } catch (Exception e) { final Exception ex = new Exception( "The results of the Query do not possess the necessary structure. Results of the Query must be tuple (class_id, object_id).", e); // NOI18N ex.setStackTrace(e.getStackTrace()); throw ex; } metaObject[i] = new Sirius.server.middleware.types.DefaultMetaObject( objectFactory.getObject(objectID, classID), domain); metaObject[i].setAllClasses(classCache.getClassHashMap()); } // hier kein Maxhits beachtet return new SearchResult(metaObject); } else // kein Knoten { // vorsicht return new SearchResult( new StringResultHandler().handle( conPool.getDBConnection().submitQuery(query), query)); } } /** * DOCUMENT ME! * * @param oid DOCUMENT ME! * @param cid DOCUMENT ME! * * @return DOCUMENT ME! */ private String constructKey(final int oid, final int cid) { return oid + "@" + cid; // NOI18N } } // end seeker