001 /** 002 * Copyright 2005-2014 The Kuali Foundation 003 * 004 * Licensed under the Educational Community License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.opensource.org/licenses/ecl2.php 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 package org.kuali.rice.krad.demo.uif.components; 017 018 import java.io.File; 019 import java.lang.reflect.Method; 020 import java.net.URL; 021 import java.util.ArrayList; 022 import java.util.Arrays; 023 import java.util.Collections; 024 import java.util.Comparator; 025 import java.util.HashMap; 026 import java.util.List; 027 import java.util.Map; 028 import java.util.regex.Matcher; 029 import java.util.regex.Pattern; 030 031 import org.apache.commons.io.FileUtils; 032 import org.apache.commons.io.LineIterator; 033 import org.apache.commons.lang.StringUtils; 034 import org.kuali.rice.core.api.util.ConcreteKeyValue; 035 import org.kuali.rice.core.api.util.KeyValue; 036 import org.kuali.rice.krad.datadictionary.parse.BeanTag; 037 import org.kuali.rice.krad.datadictionary.parse.BeanTagAttribute; 038 import org.kuali.rice.krad.datadictionary.parse.BeanTags; 039 import org.kuali.rice.krad.messages.MessageService; 040 import org.kuali.rice.krad.service.KRADServiceLocatorWeb; 041 import org.kuali.rice.krad.uif.component.Component; 042 import org.kuali.rice.krad.uif.container.Group; 043 import org.kuali.rice.krad.uif.container.TabGroup; 044 import org.kuali.rice.krad.uif.control.MultiValueControl; 045 import org.kuali.rice.krad.uif.element.Header; 046 import org.kuali.rice.krad.uif.element.Message; 047 import org.kuali.rice.krad.uif.field.InputField; 048 import org.kuali.rice.krad.uif.lifecycle.ViewLifecycle; 049 import org.kuali.rice.krad.uif.lifecycle.ViewLifecycleRestriction; 050 import org.kuali.rice.krad.uif.util.ComponentFactory; 051 import org.kuali.rice.krad.uif.view.FormView; 052 import org.kuali.rice.krad.uif.widget.SyntaxHighlighter; 053 054 /** 055 * View for the ComponentLibrary demo examples of Uif Components 056 * 057 * @author Kuali Rice Team (rice.collab@kuali.org) 058 */ 059 public class ComponentLibraryView extends FormView { 060 private static final long serialVersionUID = 3981186175467661843L; 061 062 private String rootJavadocAddress; 063 private String rootDocBookAddress; 064 private String docBookAnchor; 065 private String componentName; 066 private String javaFullClassPath; 067 private String xmlFilePath; 068 private String description; 069 private String usage; 070 private String largeExampleFieldId; 071 private SyntaxHighlighter htmlCodeViewer; 072 073 public static enum ExampleSize { 074 SMALL, LARGE, XLARGE, WINDOW; 075 } 076 077 private ExampleSize exampleSize; 078 079 private Group detailsGroup; 080 081 private ComponentExhibit exhibit; 082 private List<Group> demoGroups; 083 084 /** 085 * Initializes the TabGroup that contains description and usage. Processes ths source code marked with the 086 * ex: comment tags and adds them to the ComponentExhibit for this view. 087 * 088 * {@inheritDoc} 089 */ 090 @Override 091 public void performInitialization(Object model) { 092 super.performInitialization(model); 093 094 MessageService messageService = KRADServiceLocatorWeb.getMessageService(); 095 096 //set page name 097 this.getPage().setHeaderText(this.getComponentName()); 098 099 TabGroup tabGroup = ComponentFactory.getTabGroup(); 100 List<Component> tabItems = new ArrayList<Component>(); 101 102 //Usage processing 103 Group usageGroup = ComponentFactory.getVerticalBoxGroup(); 104 105 //Usage header 106 Header usageHeader = (Header) ComponentFactory.getNewComponentInstance("Uif-SubSectionHeader"); 107 usageHeader.setHeaderLevel("H3"); 108 usageHeader.setHeaderText(messageService.getMessageText("KR-SAP", null, "componentLibrary.usage")); 109 usageHeader.setRender(false); 110 usageGroup.setHeader(usageHeader); 111 112 //Usage message 113 List<Component> usageItems = new ArrayList<Component>(); 114 Message usageMessage = ComponentFactory.getMessage(); 115 usageMessage.setMessageText(usage); 116 usageItems.add(usageMessage); 117 usageItems.add(htmlCodeViewer); 118 usageGroup.setItems(usageItems); 119 120 tabItems.add(usageGroup); 121 122 //Documentation processing 123 if (javaFullClassPath != null) { 124 processDocumentationTab(tabItems); 125 } 126 127 //set tabGroup items 128 tabGroup.setItems(tabItems); 129 130 tabGroup.addStyleClass("demo-componentDetailsTabs"); 131 132 //Add tabGroup to detailsGroup 133 List<Component> detailsItems = new ArrayList<Component>(); 134 detailsItems.addAll(detailsGroup.getItems()); 135 detailsItems.add(tabGroup); 136 detailsGroup.setItems(detailsItems); 137 138 //exhibit setup 139 List<String> sourceCode = new ArrayList<String>(); 140 141 //process source 142 processXmlSource(sourceCode); 143 144 //setup exhibit 145 exhibit.setDemoSourceCode(sourceCode); 146 exhibit.setDemoGroups(this.getDemoGroups()); 147 148 if (this.getExampleSize() != null && 149 (this.getExampleSize().equals(ExampleSize.LARGE) || this.getExampleSize().equals(ExampleSize.XLARGE))) { 150 exhibit.getTabGroup().addStyleClass("demo-noTabs"); 151 Group headerRightGroup = ViewLifecycle.getView().getPage().getHeader().getRightGroup(); 152 for (Component item : headerRightGroup.getItems()) { 153 if (item instanceof InputField && ((InputField) item).getControl() instanceof MultiValueControl && item 154 .getId().equals(this.getLargeExampleFieldId())) { 155 //List<ConcreteKeyValue> keyValues = new ArrayList<ConcreteKeyValue>(); 156 List<KeyValue> values = new ArrayList<KeyValue>(); 157 for (Group demoGroup : demoGroups) { 158 values.add(new ConcreteKeyValue(demoGroup.getId(), demoGroup.getHeader().getHeaderText())); 159 } 160 161 //values.addAll(keyValues); 162 ((MultiValueControl) ((InputField) item).getControl()).setOptions(values); 163 item.setRender(true); 164 } 165 } 166 } 167 168 if(this.getExampleSize() != null && this.getExampleSize().equals(ExampleSize.XLARGE)){ 169 this.addStyleClass("demo-xLargeLibraryView"); 170 } 171 172 //Add detailsGroup and exhibit to page 173 List<Component> pageItems = new ArrayList<Component>(); 174 pageItems.addAll(this.getPage().getItems()); 175 pageItems.add(exhibit); 176 pageItems.add(detailsGroup); 177 this.getPage().setItems(pageItems); 178 } 179 180 /** 181 * Builds out the documentation tab content by auto-generating the content for properties and documentation and 182 * adds it to the tabItems list 183 * 184 * @param tabItems list of tab items for component details 185 */ 186 private void processDocumentationTab(List<Component> tabItems) { 187 MessageService messageService = KRADServiceLocatorWeb.getMessageService(); 188 189 try { 190 Class<?> componentClass = Class.forName(javaFullClassPath); 191 Method methodsArray[] = componentClass.getMethods(); 192 193 //get top level documentation for this class 194 String classMessage = messageService.getMessageText("KR-SAP", null, javaFullClassPath); 195 196 if (classMessage == null) { 197 classMessage = "NO DOCUMENTATION AVAILABLE/FOUND... we are working on it!"; 198 } 199 200 //scrub class message of @link and @code 201 classMessage = classMessage.replaceAll("\\{[@#]link (.*?)\\}", "<i>$1</i>"); 202 classMessage = classMessage.replaceAll("\\{[@#]code (.*?)\\}", "<i>$1</i>"); 203 204 //Generate schema and bean Id reference table 205 String schemaTable = 206 "<table class='demo-schemaIdDocTable'><tr><th>Schema Name</th>" + "<th>Uif Bean Id</th></tr>"; 207 if (componentClass.isAnnotationPresent(BeanTag.class)) { 208 BeanTag beanTag = componentClass.getAnnotation(BeanTag.class); 209 schemaTable = schemaTable + 210 "<tr><td>" + beanTag.name() + "</td><td>" + beanTag.parent() + "</td></tr>"; 211 schemaTable = schemaTable + "</table>"; 212 } else if (componentClass.isAnnotationPresent(BeanTags.class)) { 213 BeanTags beanTags = componentClass.getAnnotation(BeanTags.class); 214 BeanTag[] beanTagArray = beanTags.value(); 215 for (BeanTag beanTag : beanTagArray) { 216 schemaTable = schemaTable + 217 "<tr><td>" + beanTag.name() + "</td><td>" + beanTag.parent() + "</td></tr>"; 218 } 219 schemaTable = schemaTable + "</table>"; 220 } else { 221 schemaTable = ""; 222 } 223 224 String componentName = StringUtils.defaultIfBlank(StringUtils.defaultString(getComponentName()) + " ", ""); 225 226 String javadocTitle = messageService.getMessageText("KR-SAP", null, "componentLibrary.javaDoc"); 227 String kradGuideTitle = messageService.getMessageText("KR-SAP", null, "componentLibrary.kradGuide"); 228 String devDocumentationTitle = messageService.getMessageText("KR-SAP", null, 229 "componentLibrary.devDocumentation"); 230 String beanDefsTitle = messageService.getMessageText("KR-SAP", null, "componentLibrary.beanDefs"); 231 232 //build documentation links from javadoc address and docbook address/anchor 233 String docLinkDiv = "<div class='demo-docLinks'> " 234 + "<label>Additional Resources:</label><a class='demo-documentationLink'" 235 + " href='" 236 + getRootJavadocAddress() 237 + javaFullClassPath.replace('.', '/') 238 + ".html' target='_blank'>" 239 + javadocTitle 240 + "</a>" 241 + "<a class='demo-documentationLink'" 242 + " href='" 243 + getRootDocBookAddress() 244 + getDocBookAnchor() 245 + "' target='_blank'>" 246 + kradGuideTitle 247 + "</a>" 248 + "</div>"; 249 250 //initialize the documentation content 251 String documentationMessageContent = 252 "<H3 class=\"uif-documentationHeader\">" + componentName + devDocumentationTitle + "</H3>" + 253 docLinkDiv + classMessage + "<H3>" + beanDefsTitle + "</H3>" + schemaTable; 254 255 List<String> propertyDescriptions = new ArrayList<String>(); 256 Map<String, List<String>> inheritedProperties = new HashMap<String, List<String>>(); 257 258 List<Method> methods = Arrays.asList(methodsArray); 259 260 //alphabetize the methods by name 261 Collections.sort(methods, new Comparator<Method>() { 262 @Override 263 public int compare(Method method1, Method method2) { 264 String name1 = getPropName(method1); 265 String name2 = getPropName(method2); 266 return name1.compareTo( 267 name2); //To change body of implemented methods use File | Settings | File Templates. 268 } 269 }); 270 271 //Process all methods on this class 272 for (Method method : methods) { 273 BeanTagAttribute attribute = method.getAnnotation(BeanTagAttribute.class); 274 if (attribute != null) { 275 //property variables 276 String name = getPropName(method); 277 String methodClass = method.getDeclaringClass().getName(); 278 String returnType = method.getReturnType().getName(); 279 returnType = returnType.replaceAll("<.*?>", ""); 280 String returnTypeShort = returnType.substring(returnType.lastIndexOf(".") + 1); 281 282 //get property documentation message 283 String key = methodClass + "|" + name + "|" + returnTypeShort; 284 String propertyMessage = messageService.getMessageText("KR-SAP", null, key); 285 286 if (propertyMessage == null) { 287 propertyMessage = "NO DOCUMENTATION AVAILABLE... we are working on it!"; 288 } 289 290 //scrub property message of @link and @code 291 propertyMessage = propertyMessage.replaceAll("\\{[@#]link (.*?)\\}", "<i>$1</i>"); 292 propertyMessage = propertyMessage.replaceAll("\\{[@#]code (.*?)\\}", "<i>$1</i>"); 293 294 //wrap in link if a kuali type 295 if (returnType.startsWith("org.kuali")) { 296 returnTypeShort = "<a href='" 297 + getRootJavadocAddress() 298 + returnType.replace('.', '/') 299 + ".html' target='_blank'>" 300 + returnTypeShort 301 + "</a>"; 302 } 303 304 //html propertyMessage content 305 propertyMessage = "<div class='demo-propertyItem'>" 306 + "<h4 class='demo-propertyName'>" 307 + name 308 + "</h4>" 309 + "<div class='demo-propertyType'>" 310 + returnTypeShort 311 + "</div>" 312 + "<div class='demo-propertyDesc'>" 313 + propertyMessage 314 + "</div></div>"; 315 316 if (!methodClass.equals(javaFullClassPath)) { 317 //if this method comes from a parent and not this class, put it in the inheritedPropertiesMap 318 List<String> classProperties = inheritedProperties.get(methodClass); 319 if (classProperties == null) { 320 classProperties = new ArrayList<String>(); 321 } 322 classProperties.add(propertyMessage); 323 inheritedProperties.put(methodClass, classProperties); 324 } else { 325 propertyDescriptions.add(propertyMessage); 326 } 327 } 328 } 329 330 documentationMessageContent = 331 documentationMessageContent + "<H3>Properties</H3><div class='demo-propertiesContent'>"; 332 for (String desc : propertyDescriptions) { 333 documentationMessageContent = documentationMessageContent + desc; 334 } 335 documentationMessageContent = documentationMessageContent + "</div>"; 336 337 Group documentationGroup = ComponentFactory.getVerticalBoxGroup(); 338 339 //properties header 340 Header documentationHeader = (Header) ComponentFactory.getNewComponentInstance("Uif-SubSectionHeader"); 341 documentationHeader.setHeaderLevel("H3"); 342 documentationHeader.setHeaderText(messageService.getMessageText("KR-SAP", null, 343 "componentLibrary.documentation")); 344 documentationHeader.setRender(false); 345 documentationGroup.setHeader(documentationHeader); 346 347 List<Component> propertiesItems = new ArrayList<Component>(); 348 Message propertiesMessage = ComponentFactory.getMessage(); 349 propertiesMessage.setParseComponents(false); 350 propertiesMessage.setMessageText(documentationMessageContent); 351 propertiesItems.add(propertiesMessage); 352 353 //create the inherited properties disclosures 354 if (!inheritedProperties.isEmpty()) { 355 356 //todo sort alphabetically here? 357 for (String className : inheritedProperties.keySet()) { 358 String messageContent = ""; 359 List<String> inheritedPropertyDescriptions = inheritedProperties.get(className); 360 361 for (String desc : inheritedPropertyDescriptions) { 362 messageContent = messageContent + desc; 363 } 364 365 Group iPropertiesGroup = ComponentFactory.getVerticalBoxGroup(); 366 367 //inherited properties header 368 Header iPropHeader = (Header) ComponentFactory.getNewComponentInstance("Uif-SubSectionHeader"); 369 iPropHeader.setHeaderLevel("H3"); 370 iPropHeader.setHeaderText(messageService.getMessageText("KR-SAP", null, 371 "componentLibrary.inheritedFrom") + " " + className); 372 //iPropHeader.setRender(false); 373 iPropertiesGroup.setHeader(iPropHeader); 374 iPropertiesGroup.getDisclosure().setRender(true); 375 iPropertiesGroup.getDisclosure().setDefaultOpen(false); 376 377 List<Component> iPropertiesItems = new ArrayList<Component>(); 378 Message iPropertiesMessage = ComponentFactory.getMessage(); 379 iPropertiesMessage.setParseComponents(false); 380 iPropertiesMessage.setMessageText(messageContent); 381 iPropertiesItems.add(iPropertiesMessage); 382 iPropertiesGroup.setItems(iPropertiesItems); 383 384 propertiesItems.add(iPropertiesGroup); 385 } 386 } 387 388 documentationGroup.setItems(propertiesItems); 389 390 tabItems.add(documentationGroup); 391 } catch (Exception e) { 392 throw new RuntimeException("Error loading class: " + javaFullClassPath, e); 393 } 394 } 395 396 /** 397 * Gets the property name from the method by stripping get/is and making the first letter lowercase 398 * 399 * @param method the Method object 400 * @return the property name for the Method passed in 401 */ 402 private String getPropName(Method method) { 403 String name = method.getName(); 404 405 if (name.startsWith("get")) { 406 name = name.replaceFirst("get", ""); 407 } else { 408 name = name.replaceFirst("is", ""); 409 } 410 411 name = Character.toLowerCase(name.charAt(0)) + name.substring(1); 412 413 return name; 414 } 415 416 /** 417 * Process xml source code to be consumed by the exhibit component 418 * 419 * @param sourceCode list of sourceCode to be filled in, in order the group exhibit examples appear 420 */ 421 private void processXmlSource(List<String> sourceCode) { 422 Map<String, String> idSourceMap = new HashMap<String, String>(); 423 if (xmlFilePath != null) { 424 try { 425 //Get the source file 426 URL fileUrl = ComponentLibraryView.class.getClassLoader().getResource(xmlFilePath); 427 File file = new File(fileUrl.toURI()); 428 Pattern examplePattern = Pattern.compile("ex:(.*?)(\\s|(-->))"); 429 430 boolean readingSource = false; 431 String currentSource = ""; 432 String currentId = ""; 433 434 LineIterator lineIt = FileUtils.lineIterator(file); 435 while (lineIt.hasNext()) { 436 String line = lineIt.next(); 437 if (line.contains("ex:") && !readingSource) { 438 //found a ex: tag and are not already reading source 439 readingSource = true; 440 441 Matcher matcher = examplePattern.matcher(line); 442 if (matcher.find()) { 443 currentId = matcher.group(1); 444 } 445 446 currentSource = idSourceMap.get(currentId) != null ? idSourceMap.get(currentId) : ""; 447 448 if (!currentSource.isEmpty()) { 449 currentSource = currentSource + "\n"; 450 } 451 } else if (line.contains("ex:") && readingSource) { 452 //stop reading source on second ex tag 453 readingSource = false; 454 idSourceMap.put(currentId, currentSource); 455 } else if (readingSource) { 456 //when reading source just continue to add it 457 currentSource = currentSource + line + "\n"; 458 } 459 460 } 461 } catch (Exception e) { 462 throw new RuntimeException( 463 "file not found or error while reading: " + xmlFilePath + " for source reading", e); 464 } 465 } 466 467 for (Group demoGroup : demoGroups) { 468 //add source to the source list by order that demo groups appear 469 String groupId = demoGroup.getId(); 470 String source = idSourceMap.get(groupId); 471 if (source != null) { 472 //translate the source to something that can be displayed 473 sourceCode.add(translateSource(source)); 474 } 475 } 476 } 477 478 /** 479 * Translates the source by removing chracters that the dom will misinterpret as html and to ensure 480 * source spacing is correct 481 * 482 * @param source the original source 483 * @return that translated source used in the SyntaxHighlighter of the exhibit 484 */ 485 private String translateSource(String source) { 486 //convert characters to ascii equivalent 487 source = source.replace("<", "<"); 488 source = source.replace(">", ">"); 489 source = source.replaceAll("[ \\t]", " "); 490 491 Pattern linePattern = Pattern.compile("(( )*).*?(\\n)+"); 492 Matcher matcher = linePattern.matcher(source); 493 int toRemove = -1; 494 495 //find the line with the least amount of spaces 496 while (matcher.find()) { 497 String spaces = matcher.group(1); 498 499 int count = StringUtils.countMatches(spaces, " "); 500 if (toRemove == -1 || count < toRemove) { 501 toRemove = count; 502 } 503 } 504 505 matcher.reset(); 506 String newSource = ""; 507 508 //remove the min number of spaces from each line to get them to align left properly in the viewer 509 while (matcher.find()) { 510 String line = matcher.group(); 511 newSource = newSource + line.replaceFirst("( ){" + toRemove + "}", ""); 512 } 513 514 //remove very last newline 515 newSource = newSource.replaceAll("\\n$", ""); 516 //replace remaining newlines with ascii equivalent 517 newSource = newSource.replace("\n", "
"); 518 519 return newSource; 520 } 521 522 /** 523 * ComponentLibraryView constructor 524 */ 525 public ComponentLibraryView() { 526 demoGroups = new ArrayList<Group>(); 527 } 528 529 /** 530 * The name of the component (to be used by this page's header) 531 * 532 * @return componentName the name of the component being demoed 533 */ 534 public String getComponentName() { 535 return componentName; 536 } 537 538 /** 539 * Sets the componentName 540 * 541 * @param componentName 542 */ 543 public void setComponentName(String componentName) { 544 this.componentName = componentName; 545 } 546 547 /** 548 * Set the java path to the class being used by this component 549 * TODO not yet used 550 * 551 * @return the java path to the class 552 */ 553 public String getJavaFullClassPath() { 554 return javaFullClassPath; 555 } 556 557 /** 558 * Get the java full class path 559 * 560 * @param javaFullClassPath 561 */ 562 public void setJavaFullClassPath(String javaFullClassPath) { 563 this.javaFullClassPath = javaFullClassPath; 564 } 565 566 /** 567 * The xml file path that contains the source being used for this demo, must start with / (relative path) 568 * 569 * @return the xml file path 570 */ 571 public String getXmlFilePath() { 572 return xmlFilePath; 573 } 574 575 /** 576 * Set the xml file path 577 * 578 * @param xmlFilePath 579 */ 580 public void setXmlFilePath(String xmlFilePath) { 581 this.xmlFilePath = xmlFilePath; 582 } 583 584 /** 585 * The description of the component being demoed by this view 586 * 587 * @return the description 588 */ 589 public String getDescription() { 590 return description; 591 } 592 593 /** 594 * Sets the description 595 * 596 * @param description 597 */ 598 public void setDescription(String description) { 599 this.description = description; 600 } 601 602 /** 603 * Gets the usage description and examples of how to use this component 604 * 605 * @return the usage text 606 */ 607 public String getUsage() { 608 return usage; 609 } 610 611 /** 612 * Set the usage text 613 * 614 * @param usage 615 */ 616 public void setUsage(String usage) { 617 this.usage = usage; 618 } 619 620 /** 621 * The details group that will contain the description, usage, and properties tabGroup 622 * 623 * @return the details group 624 */ 625 @ViewLifecycleRestriction 626 public Group getDetailsGroup() { 627 return detailsGroup; 628 } 629 630 /** 631 * Set the details group 632 * 633 * @param detailsGroup 634 */ 635 public void setDetailsGroup(Group detailsGroup) { 636 this.detailsGroup = detailsGroup; 637 } 638 639 /** 640 * Gets the exhibit that will display the example, source code, and tabs to switch between examples 641 * 642 * @return the ComponentExhibit for this component demo view 643 */ 644 @ViewLifecycleRestriction 645 public ComponentExhibit getExhibit() { 646 return exhibit; 647 } 648 649 /** 650 * Set the ComponentExhibit for this demo 651 * 652 * @param exhibit 653 */ 654 public void setExhibit(ComponentExhibit exhibit) { 655 this.exhibit = exhibit; 656 } 657 658 /** 659 * List of groups that will demostrate the functionality fo the component being demonstrated, these groups are 660 * copied directly into componentExhibit - this is an ease of use property 661 * 662 * @return the demoGroups 663 */ 664 @ViewLifecycleRestriction 665 public List<Group> getDemoGroups() { 666 return demoGroups; 667 } 668 669 /** 670 * Set the demoGroups used for demonstrating features of the component 671 * 672 * @param demoGroups 673 */ 674 public void setDemoGroups(List<Group> demoGroups) { 675 this.demoGroups = demoGroups; 676 } 677 678 /** 679 * The root address to the javadoc for Rice 680 * 681 * @return the javadoc root address 682 */ 683 public String getRootJavadocAddress() { 684 return rootJavadocAddress; 685 } 686 687 /** 688 * Set the root address to the javadoc for Rice 689 * 690 * @param rootJavadocAddress 691 */ 692 public void setRootJavadocAddress(String rootJavadocAddress) { 693 this.rootJavadocAddress = rootJavadocAddress; 694 } 695 696 /** 697 * Get the root address to the docbook for KRAD 698 * 699 * @return KRAD's docbook address (url) 700 */ 701 public String getRootDocBookAddress() { 702 return rootDocBookAddress; 703 } 704 705 /** 706 * Set the docbook root address 707 * 708 * @param rootDocBookAddress 709 */ 710 public void setRootDocBookAddress(String rootDocBookAddress) { 711 this.rootDocBookAddress = rootDocBookAddress; 712 } 713 714 /** 715 * The anchor in the docbook this component is described at (do not include #) 716 * 717 * @return the anchor name 718 */ 719 public String getDocBookAnchor() { 720 if (docBookAnchor == null) { 721 return ""; 722 } else { 723 return "#" + docBookAnchor; 724 } 725 } 726 727 /** 728 * Set the docBookAnchor name for the component described by this view 729 * 730 * @param docBookAnchor 731 */ 732 public void setDocBookAnchor(String docBookAnchor) { 733 this.docBookAnchor = docBookAnchor; 734 } 735 736 public ExampleSize getExampleSize() { 737 return exampleSize; 738 } 739 740 public void setExampleSize(ExampleSize exampleSize) { 741 this.exampleSize = exampleSize; 742 } 743 744 public String getLargeExampleFieldId() { 745 return largeExampleFieldId; 746 } 747 748 public void setLargeExampleFieldId(String largeExampleFieldId) { 749 this.largeExampleFieldId = largeExampleFieldId; 750 } 751 752 /** 753 * Html code viewer SyntaxHighlighter for displaying the html output by each example 754 * 755 * @return the SyntaxHighlighter 756 */ 757 @ViewLifecycleRestriction 758 public SyntaxHighlighter getHtmlCodeViewer() { 759 return htmlCodeViewer; 760 } 761 762 /** 763 * @see org.kuali.rice.krad.demo.uif.components.ComponentLibraryView#getHtmlCodeViewer() 764 */ 765 public void setHtmlCodeViewer(SyntaxHighlighter htmlCodeViewer) { 766 this.htmlCodeViewer = htmlCodeViewer; 767 } 768 }