1 31 32 package org.opencms.main; 33 34 import org.opencms.db.CmsUserSettings; 35 import org.opencms.file.CmsObject; 36 import org.opencms.i18n.CmsLocaleManager; 37 import org.opencms.i18n.CmsMessages; 38 import org.opencms.util.CmsFileUtil; 39 import org.opencms.util.CmsPropertyUtils; 40 import org.opencms.util.CmsStringUtil; 41 import org.opencms.util.CmsUUID; 42 43 import java.io.FileDescriptor ; 44 import java.io.FileInputStream ; 45 import java.io.IOException ; 46 import java.io.InputStreamReader ; 47 import java.io.LineNumberReader ; 48 import java.io.StreamTokenizer ; 49 import java.io.StringReader ; 50 import java.lang.reflect.InvocationTargetException ; 51 import java.lang.reflect.Method ; 52 import java.lang.reflect.Modifier ; 53 import java.util.ArrayList ; 54 import java.util.Collection ; 55 import java.util.Iterator ; 56 import java.util.List ; 57 import java.util.Locale ; 58 import java.util.Map ; 59 import java.util.TreeMap ; 60 61 import org.apache.commons.collections.ExtendedProperties; 62 63 91 public class CmsShell { 92 93 96 private class CmsCommandObject { 97 98 99 private Map m_methods; 100 101 102 private Object m_object; 103 104 109 protected CmsCommandObject(Object object) { 110 111 m_object = object; 112 initShellMethods(); 113 } 114 115 125 protected boolean executeMethod(String command, List parameters) { 126 127 String lookup = buildMethodLookup(command, parameters.size()); 129 130 List possibleMethods = (List )m_methods.get(lookup); 132 if (possibleMethods == null) { 133 return false; 134 } 135 136 Method onlyStringMethod = null; 138 Method foundMethod = null; 139 Object [] params = null; 140 Iterator i; 141 142 i = possibleMethods.iterator(); 144 while (i.hasNext()) { 145 Method method = (Method )i.next(); 146 Class [] clazz = method.getParameterTypes(); 147 boolean onlyString = true; 148 for (int j = 0; j < clazz.length; j++) { 149 if (!(clazz[j].equals(String .class))) { 150 onlyString = false; 151 break; 152 } 153 } 154 if (onlyString) { 155 onlyStringMethod = method; 156 break; 157 } 158 } 159 160 i = possibleMethods.iterator(); 163 while (i.hasNext()) { 164 Method method = (Method )i.next(); 165 if (method == onlyStringMethod) { 166 continue; 168 } 169 Class [] clazz = method.getParameterTypes(); 171 Object [] converted = new Object [clazz.length]; 172 boolean match = true; 173 for (int j = 0; j < clazz.length; j++) { 174 String value = (String )parameters.get(j); 175 if (clazz[j].equals(String .class)) { 176 converted[j] = value; 178 } else if (clazz[j].equals(boolean.class)) { 179 if (CmsStringUtil.TRUE.equalsIgnoreCase(value) || CmsStringUtil.FALSE.equalsIgnoreCase(value)) { 181 converted[j] = Boolean.valueOf(value); 182 } else { 183 match = false; 184 } 185 } else if (clazz[j].equals(CmsUUID.class)) { 186 try { 188 converted[j] = new CmsUUID(value); 189 } catch (NumberFormatException e) { 190 match = false; 191 } 192 } else if (clazz[j].equals(int.class)) { 193 try { 195 converted[j] = Integer.valueOf(value); 196 } catch (NumberFormatException e) { 197 match = false; 198 } 199 } else if (clazz[j].equals(long.class)) { 200 try { 202 converted[j] = Long.valueOf(value); 203 } catch (NumberFormatException e) { 204 match = false; 205 } 206 } else if (clazz[j].equals(float.class)) { 207 try { 209 converted[j] = Float.valueOf(value); 210 } catch (NumberFormatException e) { 211 match = false; 212 } 213 } else if (clazz[j].equals(double.class)) { 214 try { 216 converted[j] = Double.valueOf(value); 217 } catch (NumberFormatException e) { 218 match = false; 219 } 220 } 221 if (!match) { 222 break; 223 } 224 } 225 if (match) { 226 params = converted; 228 foundMethod = method; 229 break; 230 } 231 232 } 233 234 if ((foundMethod == null) && (onlyStringMethod != null)) { 235 params = parameters.toArray(); 237 foundMethod = onlyStringMethod; 238 } 239 240 if (params == null) { 241 return false; 243 } 244 245 try { 247 Object result = foundMethod.invoke(m_object, params); 248 if (result != null) { 249 if (result instanceof Collection ) { 250 Collection c = (Collection )result; 251 System.out.println(c.getClass().getName() + " (size: " + c.size() + ")"); 252 int count = 0; 253 if (result instanceof Map ) { 254 Map m = (Map )result; 255 Iterator j = m.keySet().iterator(); 256 while (j.hasNext()) { 257 Object key = j.next(); 258 System.out.println(count++ + ": " + key + "= " + m.get(key)); 259 } 260 } else { 261 Iterator j = c.iterator(); 262 while (j.hasNext()) { 263 System.out.println(count++ + ": " + j.next()); 264 } 265 } 266 } else { 267 System.out.println(result.toString()); 268 } 269 } 270 } catch (InvocationTargetException ite) { 271 System.out.println(Messages.get().getBundle(getLocale()).key( 272 Messages.GUI_SHELL_EXEC_METHOD_1, 273 new Object [] {foundMethod.getName()})); 274 ite.getTargetException().printStackTrace(System.out); 275 } catch (Throwable t) { 276 System.out.println(Messages.get().getBundle(getLocale()).key( 277 Messages.GUI_SHELL_EXEC_METHOD_1, 278 new Object [] {foundMethod.getName()})); 279 t.printStackTrace(System.out); 280 } 281 282 return true; 283 } 284 285 293 protected String getMethodHelp(String searchString) { 294 295 StringBuffer buf = new StringBuffer (512); 296 Iterator i = m_methods.keySet().iterator(); 297 while (i.hasNext()) { 298 List l = (List )m_methods.get(i.next()); 299 Iterator j = l.iterator(); 300 while (j.hasNext()) { 301 Method method = (Method )j.next(); 302 if ((searchString == null) 303 || (method.getName().toLowerCase().indexOf(searchString.toLowerCase()) > -1)) { 304 buf.append("* "); 305 buf.append(method.getName()); 306 buf.append("("); 307 Class [] params = method.getParameterTypes(); 308 for (int k = 0; k < params.length; k++) { 309 String par = params[k].getName(); 310 par = par.substring(par.lastIndexOf('.') + 1); 311 if (k != 0) { 312 buf.append(", "); 313 } 314 buf.append(par); 315 } 316 buf.append(")\n"); 317 } 318 } 319 } 320 return buf.toString(); 321 } 322 323 328 protected Object getObject() { 329 330 return m_object; 331 } 332 333 340 private String buildMethodLookup(String methodName, int paramCount) { 341 342 StringBuffer buf = new StringBuffer (32); 343 buf.append(methodName.toLowerCase()); 344 buf.append(" ["); 345 buf.append(paramCount); 346 buf.append("]"); 347 return buf.toString(); 348 } 349 350 353 private void initShellMethods() { 354 355 Map result = new TreeMap (); 356 357 Method [] methods = m_object.getClass().getMethods(); 358 for (int i = 0; i < methods.length; i++) { 359 if ((methods[i].getDeclaringClass() == m_object.getClass()) 361 && (methods[i].getModifiers() == Modifier.PUBLIC)) { 362 363 boolean onlyPrimitive = true; 365 Class [] clazz = methods[i].getParameterTypes(); 366 for (int j = 0; j < clazz.length; j++) { 367 if (!((clazz[j].equals(String .class)) 368 || (clazz[j].equals(CmsUUID.class)) 369 || (clazz[j].equals(boolean.class)) 370 || (clazz[j].equals(int.class)) 371 || (clazz[j].equals(long.class)) 372 || (clazz[j].equals(double.class)) || (clazz[j].equals(float.class)))) { 373 onlyPrimitive = false; 375 break; 376 } 377 } 378 379 if (onlyPrimitive) { 380 String lookup = buildMethodLookup(methods[i].getName(), methods[i].getParameterTypes().length); 382 List l; 383 if (result.containsKey(lookup)) { 384 l = (List )result.get(lookup); 385 } else { 386 l = new ArrayList (1); 387 } 388 l.add(methods[i]); 389 result.put(lookup, l); 390 } 391 } 392 } 393 m_methods = result; 394 } 395 } 396 397 398 public static final String SHELL_PARAM_BASE = "-base="; 399 400 401 public static final String SHELL_PARAM_DEFAULT_WEB_APP = "-defaultWebApp="; 402 403 404 public static final String SHELL_PARAM_SCRIPT = "-script="; 405 406 407 public static final String SHELL_PARAM_SERVLET_MAPPING = "-servletMapping="; 408 409 410 protected CmsObject m_cms; 411 412 413 private I_CmsShellCommands m_additionaShellCommands; 414 415 416 private List m_commandObjects; 417 418 419 private boolean m_echo; 420 421 422 private boolean m_exitCalled; 423 424 425 private CmsMessages m_messages; 426 427 428 private OpenCmsCore m_opencms; 429 430 431 private String m_prompt; 432 433 434 private CmsUserSettings m_settings; 435 436 437 private I_CmsShellCommands m_shellCommands; 438 439 448 public CmsShell( 449 String webInfPath, 450 String servletMapping, 451 String defaultWebAppName, 452 String prompt, 453 I_CmsShellCommands additionalShellCommands) { 454 455 setPrompt(prompt); 456 if (CmsStringUtil.isEmpty(servletMapping)) { 457 servletMapping = "/opencms/*"; 458 } 459 if (CmsStringUtil.isEmpty(defaultWebAppName)) { 460 defaultWebAppName = "ROOT"; 461 } 462 try { 463 m_opencms = OpenCmsCore.getInstance(); 465 Locale locale = getLocale(); 468 m_messages = Messages.get().getBundle(locale); 469 if (CmsStringUtil.isEmpty(webInfPath)) { 471 System.out.println(m_messages.key(Messages.GUI_SHELL_NO_HOME_FOLDER_SPECIFIED_0)); 472 System.out.println(); 473 webInfPath = CmsFileUtil.searchWebInfFolder(System.getProperty("user.dir")); 474 if (CmsStringUtil.isEmpty(webInfPath)) { 475 System.err.println(m_messages.key(Messages.GUI_SHELL_HR_0)); 476 System.err.println(m_messages.key(Messages.GUI_SHELL_NO_HOME_FOLDER_FOUND_0)); 477 System.err.println(); 478 System.err.println(m_messages.key(Messages.GUI_SHELL_START_DIR_LINE1_0)); 479 System.err.println(m_messages.key(Messages.GUI_SHELL_START_DIR_LINE2_0)); 480 System.err.println(m_messages.key(Messages.GUI_SHELL_HR_0)); 481 return; 482 } 483 } 484 System.out.println(Messages.get().getBundle(locale).key(Messages.GUI_SHELL_WEB_INF_PATH_1, webInfPath)); 485 m_opencms.getSystemInfo().init(webInfPath, servletMapping, null, defaultWebAppName); 487 488 String propertyPath = m_opencms.getSystemInfo().getConfigurationFileRfsPath(); 490 System.out.println(m_messages.key(Messages.GUI_SHELL_CONFIG_FILE_1, propertyPath)); 491 System.out.println(); 492 ExtendedProperties configuration = CmsPropertyUtils.loadProperties(propertyPath); 493 494 m_opencms = m_opencms.upgradeRunlevel(configuration); 496 497 m_cms = m_opencms.initCmsObject(m_opencms.getDefaultUsers().getUserGuest()); 499 500 m_settings = initSettings(); 502 503 m_shellCommands = new CmsShellCommands(); 505 m_shellCommands.initShellCmsObject(m_cms, this); 506 507 if (additionalShellCommands != null) { 509 m_additionaShellCommands = additionalShellCommands; 510 m_additionaShellCommands.initShellCmsObject(m_cms, null); 511 m_additionaShellCommands.shellStart(); 512 } else { 513 m_shellCommands.shellStart(); 514 } 515 516 m_commandObjects = new ArrayList (); 517 if (m_additionaShellCommands != null) { 518 m_commandObjects.add(new CmsCommandObject(m_additionaShellCommands)); 520 } 521 m_commandObjects.add(new CmsCommandObject(m_shellCommands)); 523 m_commandObjects.add(new CmsCommandObject(m_cms.getRequestContext())); 525 m_commandObjects.add(new CmsCommandObject(m_cms)); 527 } catch (Throwable t) { 528 t.printStackTrace(System.err); 529 } 530 } 531 532 537 public static void main(String [] args) { 538 539 boolean wrongUsage = false; 540 String webInfPath = null; 541 String script = null; 542 String servletMapping = null; 543 String defaultWebApp = null; 544 545 if (args.length > 4) { 546 wrongUsage = true; 547 } else { 548 for (int i = 0; i < args.length; i++) { 549 String arg = args[i]; 550 if (arg.startsWith(SHELL_PARAM_BASE)) { 551 webInfPath = arg.substring(SHELL_PARAM_BASE.length()); 552 } else if (arg.startsWith(SHELL_PARAM_SCRIPT)) { 553 script = arg.substring(SHELL_PARAM_SCRIPT.length()); 554 } else if (arg.startsWith(SHELL_PARAM_SERVLET_MAPPING)) { 555 servletMapping = arg.substring(SHELL_PARAM_SERVLET_MAPPING.length()); 556 } else if (arg.startsWith(SHELL_PARAM_DEFAULT_WEB_APP)) { 557 defaultWebApp = arg.substring(SHELL_PARAM_DEFAULT_WEB_APP.length()); 558 } else { 559 System.out.println(Messages.get().getBundle().key(Messages.GUI_SHELL_WRONG_USAGE_0)); 560 wrongUsage = true; 561 } 562 } 563 } 564 if (wrongUsage) { 565 System.out.println(Messages.get().getBundle().key(Messages.GUI_SHELL_USAGE_1, CmsShell.class.getName())); 566 } else { 567 FileInputStream stream = null; 568 if (script != null) { 569 try { 570 stream = new FileInputStream (script); 571 } catch (IOException exc) { 572 System.out.println(Messages.get().getBundle().key(Messages.GUI_SHELL_ERR_SCRIPTFILE_1, script)); 573 } 574 } 575 if (stream == null) { 576 stream = new FileInputStream (FileDescriptor.in); 578 } 579 CmsShell shell = new CmsShell( 580 webInfPath, 581 servletMapping, 582 defaultWebApp, 583 "${user}@${project}:${siteroot}|${uri}>", 584 null); 585 shell.start(stream); 586 } 587 } 588 589 592 public void exit() { 593 594 if (m_exitCalled) { 595 return; 596 } 597 m_exitCalled = true; 598 try { 599 if (m_additionaShellCommands != null) { 600 m_additionaShellCommands.shellExit(); 601 } else { 602 m_shellCommands.shellExit(); 603 } 604 } catch (Throwable t) { 605 t.printStackTrace(); 606 } 607 try { 608 m_opencms.shutDown(); 609 } catch (Throwable t) { 610 t.printStackTrace(); 611 } 612 } 613 614 620 public Locale getLocale() { 621 622 if (getSettings() == null) { 623 return CmsLocaleManager.getDefaultLocale(); 624 } 625 return getSettings().getLocale(); 626 } 627 628 633 public CmsMessages getMessages() { 634 635 return m_messages; 636 } 637 638 643 public CmsUserSettings getSettings() { 644 645 return m_settings; 646 } 647 648 651 public void printPrompt() { 652 653 String prompt = m_prompt; 654 prompt = CmsStringUtil.substitute(prompt, "${user}", m_cms.getRequestContext().currentUser().getName()); 655 prompt = CmsStringUtil.substitute(prompt, "${siteroot}", m_cms.getRequestContext().getSiteRoot()); 656 prompt = CmsStringUtil.substitute(prompt, "${project}", m_cms.getRequestContext().currentProject().getName()); 657 prompt = CmsStringUtil.substitute(prompt, "${uri}", m_cms.getRequestContext().getUri()); 658 System.out.print(prompt); 659 } 660 661 668 public void setLocale(Locale locale) throws CmsException { 669 670 CmsUserSettings settings = getSettings(); 671 if (settings != null) { 672 settings.setLocale(locale); 673 settings.save(m_cms); 674 m_messages = Messages.get().getBundle(locale); 675 } 676 } 677 678 683 public void start(FileInputStream fileInputStream) { 684 685 try { 686 executeCommands(fileInputStream); 688 } catch (Throwable t) { 689 t.printStackTrace(System.err); 690 } 691 } 692 693 698 protected void help(String searchString) { 699 700 String commandList; 701 boolean foundSomething = false; 702 System.out.println(); 703 704 Iterator i = m_commandObjects.iterator(); 705 while (i.hasNext()) { 706 CmsCommandObject cmdObj = (CmsCommandObject)i.next(); 707 commandList = cmdObj.getMethodHelp(searchString); 708 if (!CmsStringUtil.isEmpty(commandList)) { 709 System.out.println(m_messages.key( 710 Messages.GUI_SHELL_AVAILABLE_METHODS_1, 711 cmdObj.getObject().getClass().getName())); 712 System.out.println(commandList); 713 foundSomething = true; 714 } 715 } 716 717 if (!foundSomething) { 718 System.out.println(m_messages.key(Messages.GUI_SHELL_MATCH_SEARCHSTRING_1, searchString)); 719 } 720 } 721 722 733 protected CmsUserSettings initSettings() { 734 735 m_settings = new CmsUserSettings(m_cms); 736 return m_settings; 737 } 738 739 744 protected void setEcho(boolean echo) { 745 746 m_echo = echo; 747 } 748 749 760 protected void setPrompt(String prompt) { 761 762 m_prompt = prompt; 763 } 764 765 771 private void executeCommand(String command, List parameters) { 772 773 if (m_echo) { 774 System.out.print(command); 776 for (int i = 0; i < parameters.size(); i++) { 777 System.out.print(" " + parameters.get(i)); 778 } 779 System.out.println(); 780 } 781 782 boolean executed = false; 784 Iterator i = m_commandObjects.iterator(); 785 while (!executed && i.hasNext()) { 786 CmsCommandObject cmdObj = (CmsCommandObject)i.next(); 787 executed = cmdObj.executeMethod(command, parameters); 788 } 789 790 if (!executed) { 791 System.out.println(); 793 StringBuffer commandMsg = new StringBuffer (command).append("("); 794 for (int j = 0; j < parameters.size(); j++) { 795 commandMsg.append("value"); 796 if (j < parameters.size() - 1) { 797 commandMsg.append(", "); 798 } 799 } 800 commandMsg.append(")"); 801 802 System.out.println(m_messages.key(Messages.GUI_SHELL_METHOD_NOT_FOUND_1, commandMsg.toString())); 803 System.out.println(m_messages.key(Messages.GUI_SHELL_HR_0)); 804 ((CmsShellCommands)m_shellCommands).help(); 805 } 806 } 807 808 813 private void executeCommands(FileInputStream fileInputStream) { 814 815 try { 816 LineNumberReader lnr = new LineNumberReader (new InputStreamReader (fileInputStream)); 817 while (!m_exitCalled) { 818 printPrompt(); 819 String line = lnr.readLine(); 820 if (line == null) { 821 try { 823 Thread.sleep(500); 824 } catch (Throwable t) { 825 } 827 break; 828 } 829 if ((line != null) && line.trim().startsWith("#")) { 830 System.out.println(line); 831 continue; 832 } 833 StringReader reader = new StringReader (line); 834 StreamTokenizer st = new StreamTokenizer (reader); 835 st.eolIsSignificant(true); 836 837 List parameters = new ArrayList (); 839 while (st.nextToken() != StreamTokenizer.TT_EOF) { 840 if (st.ttype == StreamTokenizer.TT_NUMBER) { 841 parameters.add(Integer.toString(new Double (st.nval).intValue())); 842 } else { 843 parameters.add(st.sval); 844 } 845 } 846 reader.close(); 847 848 if ((parameters == null) || (parameters.size() == 0)) { 850 if (m_echo) { 851 System.out.println(); 852 } 853 continue; 854 } 855 String command = (String )parameters.get(0); 856 parameters = parameters.subList(1, parameters.size()); 857 858 executeCommand(command, parameters); 860 } 861 } catch (Throwable t) { 862 t.printStackTrace(System.err); 863 } 864 } 865 } | Popular Tags |