001/* 002 * Copyright (c) 2004-2010 The Regents of the University of California. 003 * All rights reserved. 004 * 005 * '$Author: barseghian $' 006 * '$Date: 2013-01-17 00:52:56 +0000 (Thu, 17 Jan 2013) $' 007 * '$Revision: 31343 $' 008 * 009 * Permission is hereby granted, without written agreement and without 010 * license or royalty fees, to use, copy, modify, and distribute this 011 * software and its documentation for any purpose, provided that the above 012 * copyright notice and the following two paragraphs appear in all copies 013 * of this software. 014 * 015 * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 016 * FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 017 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 018 * THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 019 * SUCH DAMAGE. 020 * 021 * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 022 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 023 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 024 * PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 025 * CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 026 * ENHANCEMENTS, OR MODIFICATIONS. 027 * 028 */ 029 030package org.kepler.gui; 031 032import java.lang.reflect.Constructor; 033import java.lang.reflect.InvocationTargetException; 034import java.util.Iterator; 035import java.util.List; 036import java.util.Stack; 037import java.util.Vector; 038 039import javax.swing.JTree; 040import javax.swing.tree.TreeModel; 041import javax.swing.tree.TreePath; 042 043import org.apache.commons.logging.Log; 044import org.apache.commons.logging.LogFactory; 045import org.kepler.authentication.AuthenticationException; 046import org.kepler.configuration.ConfigurationManager; 047import org.kepler.configuration.ConfigurationProperty; 048import org.kepler.objectmanager.library.LibraryManager; 049import org.kepler.objectmanager.lsid.KeplerLSID; 050import org.kepler.objectmanager.repository.Repository; 051import org.kepler.objectmanager.repository.RepositoryException; 052import org.kepler.objectmanager.repository.RepositoryManager; 053 054import ptolemy.kernel.ComponentEntity; 055import ptolemy.kernel.util.IllegalActionException; 056import ptolemy.kernel.util.NamedObj; 057import ptolemy.moml.EntityLibrary; 058 059/** 060 * class to search the library. This class uses a simple name comparator to 061 * determine results. It uses a depth first traversal of the tree. 062 * 063 *@author berkley 064 *@since February 17, 2005 065 */ 066public class SimpleLibrarySearcher extends LibrarySearcher { 067 private static final Log log = LogFactory 068 .getLog(SimpleLibrarySearcher.class.getName()); 069 private static final boolean isDebugging = log.isDebugEnabled(); 070 071 // the stack to create the return paths with 072 private Stack<Object> _pathStack; 073 private boolean skipRepositoryOntology = false; 074 075 /** 076 * constructor 077 * 078 *@param library 079 * Description of the Parameter 080 *@param searchPane 081 * Description of the Parameter 082 */ 083 public SimpleLibrarySearcher(JTree library, LibrarySearchPane searchPane) { 084 super(library, searchPane); 085 } 086 087 /** 088 * Set true if want not to display remote ontology 089 */ 090 public void setSkipReposiotryOntology(boolean skipRepositoryOntology){ 091 this.skipRepositoryOntology = skipRepositoryOntology; 092 } 093 094 /** 095 * search for val in the library 096 * 097 *@param val 098 * Description of the Parameter 099 *@param authenticate 100 * if true prompt user to login if necessary 101 *@return Description of the Return Value 102 * @throws AuthenticationException 103 * @throws RepositoryException 104 */ 105 public LibrarySearchResults search(String value, boolean authenticate) 106 throws IllegalActionException, RepositoryException, AuthenticationException { 107 if (isDebugging) { 108 log.debug("search(" + value + ")"); 109 } 110 111 Long searchTime = System.currentTimeMillis(); 112 113 value = value.trim(); 114 115 // need to reset the results before doing the search 116 _results = new LibrarySearchResults(); 117 if (value.trim().equals("")) { 118 return _results; 119 } 120 121 // We'll need the tree model for the search 122 TreeModel model = _library.getModel(); 123 124 // check if the search string is a KeplerLSID 125 if (KeplerLSID.isKeplerLSIDFormat(value)) { 126 if (isDebugging) 127 log.debug("User is searching for an LSID"); 128 129 try { 130 KeplerLSID lsid = new KeplerLSID(value); 131 Vector<KeplerLSID> lsids = new Vector<KeplerLSID>(1); 132 lsids.add(lsid); 133 if (isDebugging) 134 log.debug("Searching for " + lsid); 135 136 Vector<Integer> liids = LibraryManager.getInstance() 137 .getLiidsFor(lsids); 138 findLiids(liids, model); 139 } catch (Exception e) { 140 Vector<Integer> liids = LibraryManager.getInstance().getIndex() 141 .getSearcher().search(value); 142 findLiids(liids, model); 143 } 144 145 } else { 146 Vector<Integer> liids = LibraryManager.getInstance().getIndex() 147 .getSearcher().search(value); 148 if (isDebugging) 149 log.debug("Index search generated " + liids.size() 150 + " results in " 151 + (System.currentTimeMillis() - searchTime) + "ms"); 152 searchTime = System.currentTimeMillis(); 153 findLiids(liids, model); 154 if (isDebugging) 155 log.debug("Model search generated " + _results.size() 156 + " results in " 157 + (System.currentTimeMillis() - searchTime) + "ms"); 158 159 } 160 searchTime = System.currentTimeMillis(); 161 if (isDebugging) 162 log.debug("Start Repository Search"); 163 try { 164 RepositoryManager rm = null; 165 try { 166 rm = RepositoryManager.getInstance(); 167 } catch (Exception e) { 168 // TODO Auto-generated catch block 169 e.printStackTrace(); 170 } 171 172 for (Repository r : rm.getRepositories()) { 173 if (r.includeInSearch()) { 174 if (isDebugging) { 175 log.debug("Searching remote repository " + r.getName()); 176 } 177 178 // use EcogridRepositoryLibrarySearcher as the default 179 String className = "org.kepler.objectmanager.repository.EcogridRepositoryLibrarySearcher"; 180 List propList = ConfigurationManager.getInstance() 181 .getProperties( 182 ConfigurationManager.getModule("gui")); 183 List reposSearcherList = ConfigurationProperty 184 .findProperties(propList, "name", 185 "repositorySearcher", true); 186 if (reposSearcherList != null 187 && reposSearcherList.size() > 0) { 188 className = ((ConfigurationProperty) reposSearcherList 189 .get(0)).getProperty("value").getValue(); 190 } 191 192 // Use reflection to instantiate the class 193 Class searchClass = Class.forName(className); 194 195 Class[] args = new Class[] { JTree.class, 196 LibrarySearchPane.class, String.class }; 197 198 // create a constructor 199 Constructor constructor = searchClass.getConstructor(args); 200 201 // set the args 202 Object[] argImp = new Object[] { _library, _searchPane, 203 r.getName() }; 204 205 RepositorySearcher reposSearcher = (RepositorySearcher) constructor 206 .newInstance(argImp); 207 reposSearcher.setSkipOntology(skipRepositoryOntology); 208 // search the ecogrid repository 209 // you must call this or the 210 // default repository name of 'defaultRepository' is used. 211 log.debug("calling search using RepositorySearcher of class:"+className); 212 Iterator itr = null; 213 try{ 214 itr = reposSearcher.search(value, authenticate).iterator(); 215 while (itr.hasNext()) { 216 TreePath p = (TreePath) itr.next(); 217 if (!_results.contains(p)) { 218 _results.add(p); 219 } 220 } 221 }catch(AuthenticationException ae){ 222 if (ae.getType() != AuthenticationException.USER_CANCEL) { 223 throw ae; 224 } 225 log.debug("caught AuthenticationException of type USER_CANCEL, taking no action, proceed..."); 226 } 227 } 228 } 229 if (isDebugging) 230 log.debug("End Repository Search: " 231 + (System.currentTimeMillis() - searchTime) + "ms"); 232 233 } catch (InvocationTargetException e) { 234 // TODO Auto-generated catch block 235 e.printStackTrace(); 236 } catch (ClassNotFoundException e) { 237 // TODO Auto-generated catch block 238 e.printStackTrace(); 239 } catch (SecurityException e) { 240 // TODO Auto-generated catch block 241 e.printStackTrace(); 242 } catch (NoSuchMethodException e) { 243 // TODO Auto-generated catch block 244 e.printStackTrace(); 245 } catch (IllegalArgumentException e) { 246 // TODO Auto-generated catch block 247 e.printStackTrace(); 248 } catch (InstantiationException e) { 249 // TODO Auto-generated catch block 250 e.printStackTrace(); 251 } catch (IllegalAccessException e) { 252 // TODO Auto-generated catch block 253 e.printStackTrace(); 254 } 255 256 return _results; 257 } 258 259 /** 260 * pre-reads the library so searches will be faster. When the momlparser 261 * hits an error in the moml, it rebuilds the model which in turn collapses 262 * the entire library JTree. This presearches the tree which causes the 263 * parse errors to get thrown before the first search so the tree won't be 264 * collapsed the first time you search. 265 */ 266 protected void init() { 267 _pathStack = new Stack<Object>(); 268 } 269 270 /** 271 * Search the tree model and add any components that match any of the 272 * supplied KeplerLSIDs to the results. This method does not match 273 * EntityLibraries but only checks leaf nodes that are ComponentEntities. 274 * 275 * @param lsids 276 * @param model 277 */ 278 private void findLiids(Vector<Integer> liids, TreeModel model) { 279 if (isDebugging) 280 log.debug("findLsids(" + liids + " " + model.getRoot() + ""); 281 282 Object o = model.getRoot(); 283 284 // start from the root 285 _pathStack = new Stack<Object>(); 286 287 _pathStack.push(o); 288 289 for (int i = 0; i < model.getChildCount(o); i++) { 290 Object child = model.getChild(o, i); 291 if (child instanceof NamedObj) { 292 NamedObj nobjChild = (NamedObj) child; 293 String name = nobjChild.getName(); 294 if (name.startsWith("_")) 295 continue; 296 297 _pathStack.push(child); 298 299 if (nobjChild instanceof EntityLibrary) { 300 findLiids(liids, (EntityLibrary) nobjChild); 301 } else if (nobjChild instanceof ComponentEntity) { 302 checkLiid((ComponentEntity) nobjChild, liids); 303 } 304 } 305 } 306 } 307 308 /** 309 * Recursive helper function for findLsids(Vector<KeplerLSID> lsids, 310 * TreeModel model) 311 * 312 * @param lsids 313 * @param entity 314 */ 315 private void findLiids(Vector<Integer> liids, EntityLibrary entity) { 316 if (isDebugging) 317 log.debug("findLsids(" + liids + " " + entity.getName() + ")"); 318 319 // loop through the children of the entity 320 for (Iterator i = entity.containedObjectsIterator(); i.hasNext();) { 321 NamedObj e = (NamedObj) i.next(); 322 String name = e.getName(); 323 if (name.startsWith("_")) 324 continue; 325 326 _pathStack.push(e); 327 328 if (e instanceof EntityLibrary) { 329 // recurse 330 findLiids(liids, (EntityLibrary) e); 331 } else if (e instanceof ComponentEntity) { 332 // leaf node 333 checkLiid((ComponentEntity) e, liids); 334 popstack(); 335 } else { 336 popstack(); 337 } 338 } 339 popstack(); 340 341 } 342 343 /** 344 * Check to see if the supplied NamedObj matches any of the LIIDs in the 345 * supplied list. 346 * 347 * @param nobj 348 * @param lsids 349 */ 350 private boolean checkLiid(ComponentEntity e, Vector<Integer> liids) { 351 if (isDebugging) 352 log.debug("checkLsid(" + e.getName() + " " + liids + ")"); 353 int thisLiid = LibraryManager.getLiidFor(e); 354 if (thisLiid != -1) { 355 Integer iLiid = new Integer(thisLiid); 356 if (isDebugging) 357 log.debug(iLiid); 358 if (liids.contains(iLiid)) { 359 if (isDebugging) 360 log.debug("MATCH"); 361 addStackTopToResult(); 362 return true; 363 } 364 } 365 return false; 366 } 367 368 /** 369 * pop the top off the stackeroo 370 */ 371 private void popstack() { 372 if (!_pathStack.empty()) { 373 _pathStack.pop(); 374 } 375 } 376 377 /** 378 * adds the path at the top of the stack to the result 379 */ 380 private void addStackTopToResult() { 381 _results.add(createPathFromStack()); 382 } 383 384 /** 385 * return the path as a TreePath 386 * 387 *@return Description of the Return Value 388 */ 389 private TreePath createPathFromStack() { 390 return new TreePath(_pathStack.toArray()); 391 } 392}