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