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 }