├── .gitignore ├── BootsFacesGeneratorDemo ├── .project └── src │ ├── BootsFaces.jsfdsl │ └── main │ ├── java │ └── net │ │ └── bootsfaces │ │ └── component │ │ ├── ComponentsEnum.java │ │ ├── accordion │ │ ├── Accordion.java │ │ ├── AccordionBeanInfo.java │ │ └── AccordionRenderer.java │ │ ├── alert │ │ ├── Alert.java │ │ ├── AlertBeanInfo.java │ │ ├── AlertCore.java │ │ └── AlertRenderer.java │ │ ├── badge │ │ ├── Badge.java │ │ ├── BadgeBeanInfo.java │ │ └── BadgeRenderer.java │ │ ├── button │ │ ├── Button.java │ │ ├── ButtonBeanInfo.java │ │ └── ButtonRenderer.java │ │ ├── socialMediaButton │ │ ├── SocialMediaButton.java │ │ ├── SocialMediaButtonBeanInfo.java │ │ ├── SocialMediaButtonCore.java │ │ └── SocialMediaButtonRenderer.java │ │ └── socialShare │ │ ├── SocialShare.java │ │ ├── SocialShareBeanInfo.java │ │ ├── SocialShareCore.java │ │ └── SocialShareRenderer.java │ └── meta │ └── META-INF │ ├── .gitignore │ └── bootsfaces-generated.taglib.xml ├── BootsFacesWeb ├── .project └── src │ └── main │ └── webapp │ ├── AccordionAttributes.xhtml │ └── layout │ └── AlertAttributes.xhtml ├── JSFLibraryGeneratorUpdateSite ├── artifacts.jar ├── content.jar ├── features │ └── de.beyondjava.xtext.jsf.sdk_1.0.2.201806071814.jar └── plugins │ ├── de.beyondjava.xtext.jsf.ui_1.0.2.201806071814.jar │ └── de.beyondjava.xtext.jsf_1.0.2.201806071814.jar ├── LICENSE ├── README.md ├── de.beyondjava.xtext.jsf.sdk ├── .project ├── build.properties └── feature.xml ├── de.beyondjava.xtext.jsf.tests ├── .classpath ├── .gitignore ├── .project ├── META-INF │ └── MANIFEST.MF ├── build.properties └── de.beyondjava.xtext.jsf.tests.launch ├── de.beyondjava.xtext.jsf.ui ├── .classpath ├── .project ├── META-INF │ └── MANIFEST.MF ├── build.properties ├── plugin.xml ├── plugin.xml_gen └── src │ └── de │ └── beyondjava │ └── xtext │ └── jsf │ └── ui │ ├── ComponentLanguageUiModule.java │ ├── contentassist │ └── ComponentLanguageProposalProvider.xtend │ ├── handler │ └── GenerationHandler.java │ ├── labeling │ ├── ComponentLanguageDescriptionLabelProvider.xtend │ └── ComponentLanguageLabelProvider.xtend │ ├── outline │ └── ComponentLanguageOutlineTreeProvider.xtend │ └── quickfix │ └── ComponentLanguageQuickfixProvider.xtend ├── de.beyondjava.xtext.jsf ├── .antlr-generator-3.2.0-patch.jar ├── .classpath ├── .gitignore ├── .project ├── META-INF │ └── MANIFEST.MF ├── TaglibImporter.java ├── build.properties ├── model │ └── generated │ │ ├── ComponentLanguage.ecore │ │ └── ComponentLanguage.genmodel ├── plugin.xml ├── plugin.xml_gen ├── src │ ├── TaglibImporter.java │ └── de │ │ └── beyondjava │ │ └── xtext │ │ └── jsf │ │ ├── ComponentLanguage.xtext │ │ ├── ComponentLanguageRuntimeModule.java │ │ ├── ComponentLanguageStandaloneSetup.java │ │ ├── GenerateComponentLanguage.mwe2 │ │ ├── formatting │ │ ├── ComponentLanguageFormatter.xtend │ │ └── JavaFormatter.java │ │ ├── generator │ │ ├── AttributesDocumentationGenerator.xtend │ │ ├── BeanInfoGenerator.xtend │ │ ├── ComponentCoreGenerator.xtend │ │ ├── ComponentGenerator.xtend │ │ ├── ComponentLanguageGenerator.xtend │ │ ├── ComponentListGenerator.xtend │ │ ├── ComponentUpdateGenerator.xtend │ │ ├── DocumentationGenerator.xtend │ │ ├── PartialTaglibGenerator.xtend │ │ ├── RendererGenerator.xtend │ │ ├── TaglibGenerator.xtend │ │ ├── UITestGenerator.xtend │ │ └── template.xhtml │ │ ├── scoping │ │ └── ComponentLanguageScopeProvider.xtend │ │ └── validation │ │ └── ComponentLanguageValidator.xtend └── taglib.xml └── plugins └── readme.md /.gitignore: -------------------------------------------------------------------------------- 1 | *.class 2 | BootsFacesGeneratorDemo/src-gen/ 3 | de.beyondjava.xtext.jsf/src-gen/ 4 | de.beyondjava.xtext.jsf.sdk/src-gen/ 5 | de.beyondjava.xtext.jsf.tests/src-gen/ 6 | de.beyondjava.xtext.jsf.ui/src-gen/ 7 | de.beyondjava.xtext.jsf.ui/bin/ 8 | xtend-gen/ 9 | .settings/ 10 | .launch/ 11 | .bin/ 12 | .DS_Store 13 | 14 | # Mobile Tools for Java (J2ME) 15 | .mtj.tmp/ 16 | 17 | # Package Files # 18 | *.war 19 | *.ear 20 | 21 | # virtual machine crash logs, see http://www.java.com/en/download/help/error_hotspot.xml 22 | hs_err_pid* 23 | -------------------------------------------------------------------------------- /BootsFacesGeneratorDemo/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | BootsFacesGeneratorDemo 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.xtext.ui.shared.xtextBuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.xtext.ui.shared.xtextNature 16 | 17 | 18 | -------------------------------------------------------------------------------- /BootsFacesGeneratorDemo/src/main/java/net/bootsfaces/component/accordion/AccordionBeanInfo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-15 by Riccardo Massera (TheCoder4.Eu), Stephan Rauh (http://www.beyondjava.net) and Dario D'Urzo. 3 | * 4 | * This file is part of BootsFaces. 5 | * 6 | * BootsFaces is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BootsFaces is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with BootsFaces. If not, see . 18 | */ 19 | package net.bootsfaces.component.accordion; 20 | 21 | import net.bootsfaces.beans.BsfBeanInfo; 22 | 23 | /** 24 | * BeanInfo class to provide mapping of snake-case attributes to camelCase ones 25 | * 26 | * @author durzod 27 | */ 28 | public class AccordionBeanInfo extends BsfBeanInfo { 29 | /** 30 | * Get the reference decorated class 31 | */ 32 | @Override 33 | public Class getDecoratedClass() { 34 | return Accordion.class; 35 | } 36 | } -------------------------------------------------------------------------------- /BootsFacesGeneratorDemo/src/main/java/net/bootsfaces/component/accordion/AccordionRenderer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-15 by Riccardo Massera (TheCoder4.Eu), Stephan Rauh (http://www.beyondjava.net) and Dario D'Urzo. 3 | * 4 | * This file is part of BootsFaces. 5 | * 6 | * BootsFaces is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BootsFaces is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with BootsFaces. If not, see . 18 | */ 19 | package net.bootsfaces.component.accordion; 20 | 21 | import java.io.IOException; 22 | import java.util.Arrays; 23 | import java.util.List; 24 | 25 | import javax.faces.FacesException; 26 | import javax.faces.component.UIComponent; 27 | import javax.faces.context.FacesContext; 28 | import javax.faces.context.ResponseWriter; 29 | import javax.faces.render.FacesRenderer; 30 | 31 | import net.bootsfaces.component.panel.Panel; 32 | import net.bootsfaces.render.CoreRenderer; 33 | 34 | /** This class generates the HTML code of <b:accordion />. */ 35 | @FacesRenderer(componentFamily = "net.bootsfaces.component", rendererType = "net.bootsfaces.component.accordion.Accordion") 36 | public class AccordionRenderer extends CoreRenderer { 37 | 38 | /** 39 | * Override encodeChildren because the children rendering is driven by the 40 | * custom encode of accordion component 41 | */ 42 | @Override 43 | public void encodeChildren(FacesContext context, UIComponent component) throws IOException { 44 | // Children are already rendered in encodeBegin() 45 | } 46 | 47 | /** 48 | * Force true to prevent JSF child rendering 49 | */ 50 | @Override 51 | public boolean getRendersChildren() { 52 | return true; 53 | } 54 | 55 | /** 56 | * This methods generates the HTML code of the current b:accordion. 57 | * encodeBegin generates the start of the component. After the, 58 | * the JSF framework calls encodeChildren() to generate the 59 | * HTML code between the beginning and the end of the component. For 60 | * instance, in the case of a panel component the content of the panel is 61 | * generated by encodeChildren(). After that, 62 | * encodeEnd() is called to generate the rest of the HTML code. 63 | * 64 | * @param context 65 | * the FacesContext. 66 | * @param component 67 | * the current b:accordion. 68 | * @throws IOException 69 | * thrown if something goes wrong when writing the HTML code. 70 | */ 71 | @Override 72 | public void encodeBegin(FacesContext context, UIComponent component) throws IOException { 73 | if (!component.isRendered()) { 74 | return; 75 | } 76 | Accordion accordion = (Accordion) component; 77 | ResponseWriter rw = context.getResponseWriter(); 78 | String clientId = accordion.getClientId(); 79 | String accordionClientId = clientId.replace(":", "_"); 80 | 81 | List expandedIds = (null != accordion.getExpandedPanels()) 82 | ? Arrays.asList(accordion.getExpandedPanels().split(",")) : null; 83 | 84 | rw.startElement("div", accordion); 85 | rw.writeAttribute("class", "panel-group", null); 86 | rw.writeAttribute("id", accordionClientId, "id"); 87 | 88 | if (accordion.getChildren() != null && accordion.getChildren().size() > 0) { 89 | for (UIComponent _child : accordion.getChildren()) { 90 | if (_child instanceof Panel && ((Panel) _child).isCollapsible()) { 91 | Panel _childPane = (Panel) _child; 92 | _childPane.setAccordionParent(accordionClientId); 93 | if (null != expandedIds && expandedIds.contains(_childPane.getClientId())) 94 | _childPane.setCollapsed(false); 95 | else 96 | _childPane.setCollapsed(true); 97 | _childPane.encodeAll(context); 98 | } else { 99 | throw new FacesException("Accordion must contains only collapsible panel components", null); 100 | } 101 | } 102 | } 103 | } 104 | 105 | /** 106 | * This methods generates the HTML code of the current b:accordion. 107 | * encodeBegin generates the start of the component. After the, 108 | * the JSF framework calls encodeChildren() to generate the 109 | * HTML code between the beginning and the end of the component. For 110 | * instance, in the case of a panel component the content of the panel is 111 | * generated by encodeChildren(). After that, 112 | * encodeEnd() is called to generate the rest of the HTML code. 113 | * 114 | * @param context 115 | * the FacesContext. 116 | * @param component 117 | * the current b:accordion. 118 | * @throws IOException 119 | * thrown if something goes wrong when writing the HTML code. 120 | */ 121 | @Override 122 | public void encodeEnd(FacesContext context, UIComponent component) throws IOException { 123 | if (!component.isRendered()) { 124 | return; 125 | } 126 | ResponseWriter rw = context.getResponseWriter(); 127 | rw.endElement("div"); 128 | } 129 | } 130 | -------------------------------------------------------------------------------- /BootsFacesGeneratorDemo/src/main/java/net/bootsfaces/component/alert/Alert.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-16 by Riccardo Massera (TheCoder4.Eu) and Stephan Rauh (http://www.beyondjava.net). 3 | * 4 | * This file is part of BootsFaces. 5 | * 6 | * BootsFaces is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BootsFaces is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with BootsFaces. If not, see . 18 | */ 19 | package net.bootsfaces.component.alert; 20 | 21 | import javax.faces.context.FacesContext; 22 | import javax.faces.event.AbortProcessingException; 23 | import javax.faces.event.ComponentSystemEvent; 24 | import javax.faces.event.ListenerFor; 25 | import javax.faces.event.ListenersFor; 26 | import javax.faces.event.PostAddToViewEvent; 27 | 28 | import javax.el.ValueExpression; 29 | import javax.faces.application.ResourceDependencies; 30 | import javax.faces.application.ResourceDependency; 31 | import javax.faces.component.FacesComponent; 32 | import javax.faces.component.UIComponentBase; 33 | 34 | import net.bootsfaces.listeners.AddResourcesListener; 35 | import net.bootsfaces.render.Tooltip; 36 | import net.bootsfaces.utils.BsfUtils; 37 | 38 | /** This class holds the attributes of <b:alert />. */ 39 | @ResourceDependencies({ @ResourceDependency(library = "bsf", name = "js/alert.js", target = "body") }) 40 | @ListenersFor({ @ListenerFor(systemEventClass = PostAddToViewEvent.class) }) 41 | @FacesComponent("net.bootsfaces.component.alert.Alert") 42 | public class Alert extends UIComponentBase implements net.bootsfaces.render.IHasTooltip { 43 | 44 | public static final String COMPONENT_TYPE = "net.bootsfaces.component.alert.Alert"; 45 | 46 | public static final String COMPONENT_FAMILY = "net.bootsfaces.component"; 47 | 48 | public static final String DEFAULT_RENDERER = "net.bootsfaces.component.alert.Alert"; 49 | 50 | public Alert() { 51 | Tooltip.addResourceFiles(); 52 | AddResourcesListener.addThemedCSSResource("core.css"); 53 | AddResourcesListener.addThemedCSSResource("alerts.css"); 54 | 55 | setRendererType(DEFAULT_RENDERER); 56 | } 57 | 58 | public void processEvent(ComponentSystemEvent event) throws AbortProcessingException { 59 | if (isAutoUpdate()) { 60 | if (FacesContext.getCurrentInstance().isPostback()) { 61 | FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().add(getClientId()); 62 | } 63 | super.processEvent(event); 64 | } 65 | } 66 | 67 | public String getFamily() { 68 | return COMPONENT_FAMILY; 69 | } 70 | 71 | public void setValueExpression(String name, ValueExpression binding) { 72 | name = BsfUtils.snakeCaseToCamelCase(name); 73 | super.setValueExpression(name, binding); 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /BootsFacesGeneratorDemo/src/main/java/net/bootsfaces/component/alert/AlertBeanInfo.java: -------------------------------------------------------------------------------- 1 | package net.bootsfaces.component.alert; 2 | 3 | import net.bootsfaces.beans.BsfBeanInfo; 4 | 5 | /** 6 | * BeanInfo class to provide mapping of snake-case attributes to camelCase ones 7 | * 8 | * @author durzod 9 | */ 10 | public class AlertBeanInfo extends BsfBeanInfo { 11 | /** 12 | * Get the reference decorated class 13 | */ 14 | @Override 15 | public Class getDecoratedClass() { 16 | return Alert.class; 17 | } 18 | } -------------------------------------------------------------------------------- /BootsFacesGeneratorDemo/src/main/java/net/bootsfaces/component/alert/AlertRenderer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-16 by Riccardo Massera (TheCoder4.Eu) and Stephan Rauh (http://www.beyondjava.net). 3 | * 4 | * This file is part of BootsFaces. 5 | * 6 | * BootsFaces is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BootsFaces is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with BootsFaces. If not, see . 18 | */ 19 | 20 | package net.bootsfaces.component.alert; 21 | 22 | import java.io.IOException; 23 | import java.util.Map; 24 | 25 | import javax.faces.component.UIComponent; 26 | import javax.faces.context.FacesContext; 27 | import javax.faces.context.ResponseWriter; 28 | import javax.faces.render.FacesRenderer; 29 | 30 | import net.bootsfaces.render.CoreRenderer; 31 | import net.bootsfaces.render.Tooltip; 32 | 33 | /** This class generates the HTML code of <b:alert />. */ 34 | @FacesRenderer(componentFamily = "net.bootsfaces.component", rendererType = "net.bootsfaces.component.alert.Alert") 35 | public class AlertRenderer extends CoreRenderer { 36 | 37 | /** 38 | * This methods generates the HTML code of the current b:alert. 39 | * encodeBegin generates the start of the component. After the, 40 | * the JSF framework calls encodeChildren() to generate the 41 | * HTML code between the beginning and the end of the component. For 42 | * instance, in the case of a panel component the content of the panel is 43 | * generated by encodeChildren(). After that, 44 | * encodeEnd() is called to generate the rest of the HTML code. 45 | * 46 | * @param context 47 | * the FacesContext. 48 | * @param component 49 | * the current b:alert. 50 | * @throws IOException 51 | * thrown if something goes wrong when writing the HTML code. 52 | */ 53 | @Override 54 | public void encodeBegin(FacesContext context, UIComponent component) throws IOException { 55 | if (!component.isRendered()) { 56 | return; 57 | } 58 | Alert alert = (Alert) component; 59 | ResponseWriter rw = context.getResponseWriter(); 60 | String clientId = alert.getClientId(); 61 | Map attrs = alert.getAttributes(); 62 | 63 | String sev = alert.getSeverity(); 64 | 65 | String t = alert.getTitle(); 66 | boolean closbl = alert.isClosable(); 67 | 68 | rw.startElement("div", alert); 69 | rw.writeAttribute("id", clientId, "id"); 70 | Tooltip.generateTooltip(context, component, rw); 71 | 72 | String style = alert.getStyle(); 73 | if (null != style) 74 | rw.writeAttribute("style", style, "style"); 75 | 76 | String styleClass = alert.getStyleClass(); 77 | if (null == styleClass) 78 | styleClass = ""; 79 | else 80 | styleClass = " " + styleClass; 81 | 82 | if (sev != null) { 83 | rw.writeAttribute("class", "alert alert-" + sev + " fadein" + styleClass, "class"); 84 | } else { 85 | rw.writeAttribute("class", "alert fadein" + styleClass, "class"); 86 | } 87 | if (closbl) { 88 | rw.startElement("button", alert); 89 | rw.writeAttribute("type", "button", "type"); 90 | rw.writeAttribute("class", "close", "class"); 91 | rw.writeAttribute("data-dismiss", "alert", "data-dismiss"); 92 | rw.write("×"); 93 | rw.endElement("button"); 94 | } 95 | if (t != null) { 96 | rw.startElement("strong", alert); 97 | rw.writeText(t, null); 98 | rw.endElement("strong"); 99 | rw.startElement("br", alert); 100 | rw.endElement("br"); 101 | } 102 | } 103 | 104 | /** 105 | * This methods generates the HTML code of the current b:alert. 106 | * encodeBegin generates the start of the component. After the, 107 | * the JSF framework calls encodeChildren() to generate the 108 | * HTML code between the beginning and the end of the component. For 109 | * instance, in the case of a panel component the content of the panel is 110 | * generated by encodeChildren(). After that, 111 | * encodeEnd() is called to generate the rest of the HTML code. 112 | * 113 | * @param context 114 | * the FacesContext. 115 | * @param component 116 | * the current b:alert. 117 | * @throws IOException 118 | * thrown if something goes wrong when writing the HTML code. 119 | */ 120 | @Override 121 | public void encodeEnd(FacesContext context, UIComponent component) throws IOException { 122 | if (!component.isRendered()) { 123 | return; 124 | } 125 | Alert alert = (Alert) component; 126 | ResponseWriter rw = context.getResponseWriter(); 127 | rw.endElement("div"); 128 | Tooltip.activateTooltips(context, alert); 129 | } 130 | } 131 | -------------------------------------------------------------------------------- /BootsFacesGeneratorDemo/src/main/java/net/bootsfaces/component/badge/BadgeBeanInfo.java: -------------------------------------------------------------------------------- 1 | package net.bootsfaces.component.badge; 2 | 3 | import net.bootsfaces.beans.BsfBeanInfo; 4 | 5 | /** 6 | * BeanInfo class to provide mapping of snake-case attributes to camelCase ones 7 | * 8 | * @author durzod 9 | */ 10 | public class BadgeBeanInfo extends BsfBeanInfo { 11 | /** 12 | * Get the reference decorated class 13 | */ 14 | @Override 15 | public Class getDecoratedClass() { 16 | return Badge.class; 17 | } 18 | } -------------------------------------------------------------------------------- /BootsFacesGeneratorDemo/src/main/java/net/bootsfaces/component/badge/BadgeRenderer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-16 by Riccardo Massera (TheCoder4.Eu) and Stephan Rauh (http://www.beyondjava.net). 3 | * 4 | * This file is part of BootsFaces. 5 | * 6 | * BootsFaces is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BootsFaces is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with BootsFaces. If not, see . 18 | */ 19 | 20 | package net.bootsfaces.component.badge; 21 | 22 | import java.io.IOException; 23 | 24 | import javax.faces.component.UIComponent; 25 | import javax.faces.context.FacesContext; 26 | import javax.faces.context.ResponseWriter; 27 | import javax.faces.render.FacesRenderer; 28 | 29 | import net.bootsfaces.render.CoreRenderer; 30 | import net.bootsfaces.render.Tooltip; 31 | 32 | /** This class generates the HTML code of <b:badge />. */ 33 | @FacesRenderer(componentFamily = "net.bootsfaces.component", rendererType = "net.bootsfaces.component.badge.Badge") 34 | public class BadgeRenderer extends CoreRenderer { 35 | 36 | /** 37 | * This methods generates the HTML code of the current b:badge. 38 | * 39 | * @param context 40 | * the FacesContext. 41 | * @param component 42 | * the current b:badge. 43 | * @throws IOException 44 | * thrown if something goes wrong when writing the HTML code. 45 | */ 46 | @Override 47 | public void encodeBegin(FacesContext context, UIComponent component) throws IOException { 48 | if (!component.isRendered()) { 49 | return; 50 | } 51 | Badge badge = (Badge) component; 52 | ResponseWriter rw = context.getResponseWriter(); 53 | String clientId = badge.getClientId(); 54 | 55 | if (!component.isRendered()) { 56 | return; 57 | } 58 | String styleClass = badge.getStyleClass(); 59 | String style = badge.getStyle(); 60 | String val = getValue2Render(context, badge); 61 | 62 | generateBadge(context, badge, rw, clientId, styleClass, style, val, null); 63 | } 64 | 65 | protected void generateBadge(FacesContext context, UIComponent component, ResponseWriter rw, String clientId, 66 | String styleClass, String style, String val, String suffix) throws IOException { 67 | 68 | rw.startElement("span", component); 69 | if (null != suffix) { 70 | clientId = clientId + suffix; 71 | } 72 | rw.writeAttribute("id", clientId, "id"); 73 | if (styleClass == null) 74 | styleClass = "badge"; 75 | else 76 | styleClass += " badge"; 77 | Tooltip.generateTooltip(context, component, rw); 78 | rw.writeAttribute("class", styleClass, "class"); 79 | if (null != style) 80 | rw.writeAttribute("style", style, "style"); 81 | if (val != null) { 82 | rw.writeText(val, null); 83 | } 84 | rw.endElement("span"); 85 | Tooltip.activateTooltips(context, component); 86 | } 87 | 88 | } -------------------------------------------------------------------------------- /BootsFacesGeneratorDemo/src/main/java/net/bootsfaces/component/button/ButtonBeanInfo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2016 Dario D'Urzo and Stephan Rauh 3 | * 4 | * This file is part of BootsFaces. 5 | * 6 | * BootsFaces is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BootsFaces is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with BootsFaces. If not, see . 18 | */ 19 | package net.bootsfaces.component.button; 20 | 21 | import net.bootsfaces.beans.BsfBeanInfo; 22 | 23 | /** 24 | * BeanInfo class to provide mapping of snake-case attributes to camelCase ones 25 | * 26 | * @author durzod 27 | */ 28 | public class ButtonBeanInfo extends BsfBeanInfo { 29 | /** 30 | * Get the reference decorated class 31 | */ 32 | @Override 33 | public Class getDecoratedClass() { 34 | return Button.class; 35 | } 36 | } -------------------------------------------------------------------------------- /BootsFacesGeneratorDemo/src/main/java/net/bootsfaces/component/button/ButtonRenderer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-15 by Riccardo Massera (TheCoder4.Eu) and Stephan Rauh (http://www.beyondjava.net). 3 | * 4 | * This file is part of BootsFaces. 5 | * 6 | * BootsFaces is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BootsFaces is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with BootsFaces. If not, see . 18 | */ 19 | package net.bootsfaces.component.button; 20 | 21 | import javax.faces.FacesException; 22 | import javax.faces.application.ConfigurableNavigationHandler; 23 | import javax.faces.application.NavigationCase; 24 | import javax.faces.application.ProjectStage; 25 | import javax.faces.component.*; 26 | import java.io.IOException; 27 | import java.util.ArrayList; 28 | import java.util.LinkedHashMap; 29 | import java.util.List; 30 | import java.util.Map; 31 | 32 | import javax.faces.context.FacesContext; 33 | import javax.faces.context.ResponseWriter; 34 | import javax.faces.render.FacesRenderer; 35 | 36 | import net.bootsfaces.C; 37 | import net.bootsfaces.component.icon.IconRenderer; 38 | import net.bootsfaces.render.CoreRenderer; 39 | import net.bootsfaces.render.H; 40 | import net.bootsfaces.render.Tooltip; 41 | import net.bootsfaces.utils.BsfUtils; 42 | 43 | /** This class generates the HTML code of <b:button />. */ 44 | @FacesRenderer(componentFamily = "net.bootsfaces.component", rendererType = "net.bootsfaces.component.button.Button") 45 | public class ButtonRenderer extends CoreRenderer { 46 | /** 47 | * Renders the button.
48 | * General layout of the generated HTML code:
49 | * <button class="btn btn-large" href="#"%gt;<i 50 | * class="icon-star"></i> Star</button> 51 | * 52 | * @param context 53 | * the current FacesContext 54 | * @throws IOException 55 | * thrown if something's wrong with the ResponseWriter 56 | */ 57 | @Override 58 | public void encodeEnd(FacesContext context, UIComponent component) throws IOException { 59 | if (!component.isRendered()) { 60 | return; 61 | } 62 | Button button = (Button) component; 63 | encodeHTML(context, button); 64 | } 65 | 66 | /** 67 | * Encode the HTML code of the button. 68 | * 69 | * @param context 70 | * the current FacesContext 71 | * @throws IOException 72 | * thrown if something's wrong with the ResponseWriter 73 | */ 74 | public void encodeHTML(FacesContext context, Button button) throws IOException { 75 | ResponseWriter rw = context.getResponseWriter(); 76 | String clientId = button.getClientId(); 77 | 78 | Object value = button.getValue(); 79 | String style = button.getStyle(); 80 | 81 | rw.startElement("button", button); 82 | rw.writeAttribute("id", clientId, "id"); 83 | rw.writeAttribute("name", clientId, "name"); 84 | rw.writeAttribute("type", "button", null); 85 | if (BsfUtils.isStringValued(button.getDir())) { 86 | rw.writeAttribute("dir", button.getDir(), "dir"); 87 | } 88 | if (style != null) { 89 | rw.writeAttribute("style", style, "style"); 90 | } 91 | rw.writeAttribute("class", getStyleClasses(button), "class"); 92 | 93 | Tooltip.generateTooltip(context, button, rw); 94 | 95 | final String clickHandler = encodeClick(context, button); 96 | if (null != clickHandler && clickHandler.length() > 0) { 97 | rw.writeAttribute("onclick", clickHandler, null); 98 | } 99 | if (BsfUtils.isStringValued(button.getDismiss())) { 100 | rw.writeAttribute("data-dismiss", button.getDismiss(), null); 101 | } 102 | if (button.isDisabled()) { 103 | rw.writeAttribute("disabled", "disabled", null); 104 | } 105 | 106 | // Encode attributes (HTML 4 pass-through + DHTML) 107 | renderPassThruAttributes(context, button, H.ALLBUTTON); 108 | 109 | String icon = button.getIcon(); 110 | String faicon = button.getIconAwesome(); 111 | boolean fa = false; // flag to indicate wether the selected icon set is 112 | // Font Awesome or not. 113 | if (faicon != null) { 114 | icon = faicon; 115 | fa = true; 116 | } 117 | if (icon != null) { 118 | Object ialign = button.getIconAlign(); // Default Left 119 | if (ialign != null && ialign.equals("right")) { 120 | rw.writeText(value + " ", null); 121 | IconRenderer.encodeIcon(rw, button, icon, fa); 122 | } else { 123 | IconRenderer.encodeIcon(rw, button, icon, fa); 124 | rw.writeText(" " + value, null); 125 | } 126 | 127 | } else { 128 | rw.writeText(value, null); 129 | } 130 | 131 | Tooltip.activateTooltips(context, button); 132 | rw.endElement("button"); 133 | } 134 | 135 | /** 136 | * Renders the Javascript code dealing with the click event. If the 137 | * developer provides their own onclick handler, is precedes the generated 138 | * Javascript code. 139 | * 140 | * @param context 141 | * The current FacesContext. 142 | * @param attrs 143 | * the attribute list 144 | * @return some Javascript code, such as 145 | * "window.location.href='/targetView.jsf';" 146 | */ 147 | private String encodeClick(FacesContext context, Button button) { 148 | String js; 149 | String userClick = button.getOnclick(); 150 | if (userClick != null) { 151 | js = userClick; 152 | } // +COLON; } 153 | else { 154 | js = ""; 155 | } 156 | 157 | String fragment = button.getFragment(); 158 | String outcome = button.getOutcome(); 159 | if (null != outcome && outcome.contains("#")) { 160 | if (null != fragment && fragment.length() > 0) { 161 | throw new FacesException( 162 | "Please define the URL fragment either in the fragment attribute or in the outcome attribute, but not both"); 163 | } 164 | int pos = outcome.indexOf("#"); 165 | fragment = outcome.substring(pos); 166 | outcome = outcome.substring(0, pos); 167 | } 168 | 169 | if (outcome == null || outcome.equals("")) { 170 | if (null != fragment && fragment.length() > 0) { 171 | if (!fragment.startsWith("#")) { 172 | fragment = "#" + fragment; 173 | } 174 | js += "window.location.href='" + fragment + "';"; 175 | return js; 176 | } 177 | } 178 | 179 | if (outcome == null || outcome.equals("") || outcome.equals("@none")) 180 | return js; 181 | 182 | if (canOutcomeBeRendered(button, fragment, outcome)) { 183 | outcome = (outcome == null) ? context.getViewRoot().getViewId() : outcome; 184 | 185 | String url = determineTargetURL(context, button, outcome); 186 | 187 | if (url != null) { 188 | if (url.startsWith("alert(")) { 189 | js = url; 190 | } else { 191 | if (fragment != null) { 192 | if (fragment.startsWith("#")) { 193 | url += fragment; 194 | } else { 195 | url += "#" + fragment; 196 | } 197 | } 198 | js += "window.location.href='" + url + "';"; 199 | } 200 | } 201 | } 202 | 203 | return js; 204 | } 205 | 206 | /** 207 | * Do we have to suppress the target URL? 208 | * 209 | * @param attrs 210 | * the component's attribute list 211 | * @param fragment 212 | * the fragment of the URL behind the hash (outcome#fragment) 213 | * @param outcome 214 | * the value of the outcome attribute 215 | * @return true if the outcome can be rendered. 216 | */ 217 | private boolean canOutcomeBeRendered(Button button, String fragment, String outcome) { 218 | boolean renderOutcome = true; 219 | if (null == outcome && button.getAttributes() != null && button.getAttributes().containsKey("ng-click")) { 220 | String ngClick = (String) button.getAttributes().get("ng-click"); 221 | if (null != ngClick && (ngClick.length() > 0)) { 222 | if (fragment == null) { 223 | renderOutcome = false; 224 | } 225 | } 226 | } 227 | return renderOutcome; 228 | } 229 | 230 | /** 231 | * Translate the outcome attribute value to the target URL. 232 | * 233 | * @param context 234 | * the current FacesContext 235 | * @param outcome 236 | * the value of the outcome attribute 237 | * @return the target URL of the navigation rule (or the outcome if there's 238 | * not navigation rule) 239 | */ 240 | private String determineTargetURL(FacesContext context, Button button, String outcome) { 241 | ConfigurableNavigationHandler cnh = (ConfigurableNavigationHandler) context.getApplication() 242 | .getNavigationHandler(); 243 | NavigationCase navCase = cnh.getNavigationCase(context, null, outcome); 244 | /* 245 | * Param Name: javax.faces.PROJECT_STAGE Default Value: The default 246 | * value is ProjectStage#Production but IDE can set it differently in 247 | * web.xml Expected Values: Development, Production, SystemTest, 248 | * UnitTest Since: 2.0 249 | * 250 | * If we cannot get an outcome we use an Alert to give a feedback to the 251 | * Developer if this build is in the Development Stage 252 | */ 253 | if (navCase == null) { 254 | if (FacesContext.getCurrentInstance().getApplication().getProjectStage().equals(ProjectStage.Development)) { 255 | return "alert('WARNING! " + C.W_NONAVCASE_BUTTON + "');"; 256 | } else { 257 | return ""; 258 | } 259 | } // throw new FacesException("The outcome '"+outcome+"' cannot be 260 | // resolved."); } 261 | String vId = navCase.getToViewId(context); 262 | 263 | Map> params = getParams(navCase, button); 264 | String url; 265 | url = context.getApplication().getViewHandler().getBookmarkableURL(context, vId, params, 266 | button.isIncludeViewParams() || navCase.isIncludeViewParams()); 267 | return url; 268 | } 269 | 270 | /** 271 | * Find all parameters to include by looking at nested uiparams and params 272 | * of navigation case 273 | */ 274 | protected static Map> getParams(NavigationCase navCase, Button button) { 275 | Map> params = new LinkedHashMap>(); 276 | 277 | // UIParams 278 | for (UIComponent child : button.getChildren()) { 279 | if (child.isRendered() && (child instanceof UIParameter)) { 280 | UIParameter uiParam = (UIParameter) child; 281 | 282 | if (!uiParam.isDisable()) { 283 | List paramValues = params.get(uiParam.getName()); 284 | if (paramValues == null) { 285 | paramValues = new ArrayList(); 286 | params.put(uiParam.getName(), paramValues); 287 | } 288 | 289 | paramValues.add(String.valueOf(uiParam.getValue())); 290 | } 291 | } 292 | } 293 | 294 | // NavCase Params 295 | Map> navCaseParams = navCase.getParameters(); 296 | if (navCaseParams != null && !navCaseParams.isEmpty()) { 297 | for (Map.Entry> entry : navCaseParams.entrySet()) { 298 | String key = entry.getKey(); 299 | 300 | // UIParams take precedence 301 | if (!params.containsKey(key)) { 302 | params.put(key, entry.getValue()); 303 | } 304 | } 305 | } 306 | 307 | return params; 308 | } 309 | 310 | /** 311 | * Collects the CSS classes of the button. 312 | * 313 | * @param attrs 314 | * the attribute list. 315 | * @return the CSS classes (separated by a space). 316 | */ 317 | private static String getStyleClasses(Button button) { 318 | StringBuilder sb; 319 | sb = new StringBuilder(40); // optimize int 320 | sb.append("btn"); 321 | String size = button.getSize(); 322 | if (size != null) { 323 | sb.append(" btn-").append(size); 324 | } 325 | 326 | String look = button.getLook(); 327 | if (look != null) { 328 | sb.append(" btn-").append(look); 329 | } else { 330 | sb.append(" btn-default"); 331 | } 332 | 333 | if (button.isDisabled()) { 334 | sb.append(" " + "disabled"); 335 | } 336 | // TODO add styleClass and class support 337 | String sclass = button.getStyleClass(); 338 | if (sclass != null) { 339 | sb.append(" ").append(sclass); 340 | } 341 | 342 | return sb.toString().trim(); 343 | } 344 | 345 | /** 346 | * Detects whether an attribute is a default value or not. Method 347 | * temporarily copied from CoreRenderer. Should be replaced by a call of 348 | * CoreRenderer in the long run. 349 | * 350 | * @param value 351 | * the value to be checked 352 | * @return true if the value is not the default value 353 | */ 354 | protected boolean shouldRenderAttribute(Object value) { 355 | if (value == null) 356 | return false; 357 | 358 | if (value instanceof Boolean) { 359 | return ((Boolean) value).booleanValue(); 360 | } else if (value instanceof Number) { 361 | Number number = (Number) value; 362 | 363 | if (value instanceof Integer) 364 | return number.intValue() != Integer.MIN_VALUE; 365 | else if (value instanceof Double) 366 | return number.doubleValue() != Double.MIN_VALUE; 367 | else if (value instanceof Long) 368 | return number.longValue() != Long.MIN_VALUE; 369 | else if (value instanceof Byte) 370 | return number.byteValue() != Byte.MIN_VALUE; 371 | else if (value instanceof Float) 372 | return number.floatValue() != Float.MIN_VALUE; 373 | else if (value instanceof Short) 374 | return number.shortValue() != Short.MIN_VALUE; 375 | } 376 | 377 | return true; 378 | } 379 | 380 | } 381 | -------------------------------------------------------------------------------- /BootsFacesGeneratorDemo/src/main/java/net/bootsfaces/component/socialMediaButton/SocialMediaButton.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-16 by Riccardo Massera (TheCoder4.Eu), Dario D'Urzo and Stephan Rauh (http://www.beyondjava.net). 3 | * 4 | * This file is part of BootsFaces. 5 | * 6 | * BootsFaces is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BootsFaces is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with BootsFaces. If not, see . 18 | */ 19 | 20 | package net.bootsfaces.component.socialMediaButton; 21 | 22 | import javax.el.ValueExpression; 23 | import javax.faces.application.ResourceDependencies; 24 | import javax.faces.application.ResourceDependency; 25 | import javax.faces.component.*; 26 | import net.bootsfaces.render.Tooltip; 27 | import net.bootsfaces.utils.BsfUtils; 28 | 29 | /** This class holds the attributes of <b:socialMediaButton />. */ 30 | @FacesComponent("net.bootsfaces.component.socialMediaButton.SocialMediaButton") 31 | public class SocialMediaButton extends SocialMediaButtonCore 32 | implements net.bootsfaces.render.IHasTooltip, net.bootsfaces.render.IResponsive { 33 | 34 | public static final String COMPONENT_TYPE = "net.bootsfaces.component.socialMediaButton.SocialMediaButton"; 35 | 36 | public static final String COMPONENT_FAMILY = "net.bootsfaces.component"; 37 | 38 | public static final String DEFAULT_RENDERER = "net.bootsfaces.component.socialMediaButton.SocialMediaButton"; 39 | 40 | public SocialMediaButton() { 41 | Tooltip.addResourceFiles(); 42 | AddResourcesListener.addThemedCSSResource("core.css"); 43 | AddResourcesListener.addThemedCSSResource("bsf.css"); 44 | setRendererType(DEFAULT_RENDERER); 45 | } 46 | 47 | public String getFamily() { 48 | return COMPONENT_FAMILY; 49 | } 50 | 51 | /** 52 | * Manage EL-expression for snake-case attributes 53 | */ 54 | public void setValueExpression(String name, ValueExpression binding) { 55 | name = BsfUtils.snakeCaseToCamelCase(name); 56 | super.setValueExpression(name, binding); 57 | } 58 | 59 | } 60 | -------------------------------------------------------------------------------- /BootsFacesGeneratorDemo/src/main/java/net/bootsfaces/component/socialMediaButton/SocialMediaButtonBeanInfo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-15 by Riccardo Massera (TheCoder4.Eu) and Stephan Rauh (http://www.beyondjava.net). 3 | * 4 | * This file is part of BootsFaces. 5 | * 6 | * BootsFaces is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BootsFaces is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with BootsFaces. If not, see . 18 | */ 19 | 20 | package net.bootsfaces.component.socialMediaButton; 21 | 22 | import net.bootsfaces.beans.BsfBeanInfo; 23 | 24 | /** 25 | * BeanInfo class to provide mapping 26 | * of snake-case attributes to camelCase ones 27 | * 28 | * @author Dario D'Urzo 29 | */ 30 | public class SocialMediaButtonBeanInfo extends BsfBeanInfo { 31 | 32 | /** 33 | * Get the reference decorated class 34 | */ 35 | @Override 36 | public Class getDecoratedClass() { 37 | return SocialMediaButton.class; 38 | } 39 | } 40 | 41 | -------------------------------------------------------------------------------- /BootsFacesGeneratorDemo/src/main/java/net/bootsfaces/component/socialMediaButton/SocialMediaButtonCore.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-16 by Riccardo Massera (TheCoder4.Eu), Dario D'Urzo and Stephan Rauh (http://www.beyondjava.net). 3 | * 4 | * This file is part of BootsFaces. 5 | * 6 | * BootsFaces is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BootsFaces is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with BootsFaces. If not, see . 18 | */ 19 | 20 | package net.bootsfaces.component.socialMediaButton; 21 | 22 | import javax.el.ValueExpression; 23 | import javax.faces.component.*; 24 | import net.bootsfaces.render.Tooltip; 25 | import net.bootsfaces.utils.BsfUtils; 26 | 27 | /** This class holds the attributes of <b:socialMediaButton />. */ 28 | public class SocialMediaButton extends UIComponentBase implements net.bootsfaces.render.IHasTooltip { 29 | 30 | protected enum PropertyKeys { 31 | twitter, update; 32 | String toString; 33 | 34 | PropertyKeys(String toString) { 35 | this.toString = toString; 36 | } 37 | 38 | PropertyKeys() { 39 | } 40 | 41 | public String toString() { 42 | return ((this.toString != null) ? this.toString : super.toString()); 43 | } 44 | } 45 | 46 | /** 47 | * Is it a Twitter button?

48 | * @return Returns the value of the attribute, or null, if it hasn't been set by the JSF file. 49 | */ 50 | public boolean isTwitter() { 51 | return (boolean) (Boolean) getStateHelper().eval(PropertyKeys.twitter, false); 52 | } 53 | 54 | /** 55 | * Is it a Twitter button?

56 | * Usually this method is called internally by the JSF engine. 57 | */ 58 | public void setTwitter(boolean _twitter) { 59 | getStateHelper().put(PropertyKeys.twitter, _twitter); 60 | } 61 | 62 | /** 63 | * Component(s) to be updated with ajax.

64 | * @return Returns the value of the attribute, or null, if it hasn't been set by the JSF file. 65 | */ 66 | public String getUpdate() { 67 | return (String) getStateHelper().eval(PropertyKeys.update); 68 | } 69 | 70 | /** 71 | * Component(s) to be updated with ajax.

72 | * Usually this method is called internally by the JSF engine. 73 | */ 74 | public void setUpdate(String _update) { 75 | getStateHelper().put(PropertyKeys.update, _update); 76 | } 77 | 78 | } 79 | -------------------------------------------------------------------------------- /BootsFacesGeneratorDemo/src/main/java/net/bootsfaces/component/socialMediaButton/SocialMediaButtonRenderer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-15 by Riccardo Massera (TheCoder4.Eu) and Stephan Rauh (http://www.beyondjava.net). 3 | * 4 | * This file is part of BootsFaces. 5 | * 6 | * BootsFaces is free software: you can redistribute it and/or modify 7 | * it under the terms of the GNU Lesser General Public License as published by 8 | * the Free Software Foundation, either version 3 of the License, or 9 | * (at your option) any later version. 10 | * 11 | * BootsFaces is distributed in the hope that it will be useful, 12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 | * GNU Lesser General Public License for more details. 15 | * 16 | * You should have received a copy of the GNU Lesser General Public License 17 | * along with BootsFaces. If not, see . 18 | */ 19 | 20 | package net.bootsfaces.component.socialMediaButton; 21 | 22 | import javax.faces.component.*; 23 | import java.io.IOException; 24 | import java.util.Map; 25 | 26 | import javax.faces.context.FacesContext; 27 | import javax.faces.context.ResponseWriter; 28 | import javax.faces.render.FacesRenderer; 29 | 30 | import net.bootsfaces.render.CoreRenderer; 31 | import net.bootsfaces.render.Tooltip; 32 | 33 | /** This class generates the HTML code of <b:socialMediaButton />. */ 34 | @FacesRenderer(componentFamily = "net.bootsfaces.component", rendererType = "net.bootsfaces.component.socialMediaButton.SocialMediaButton") 35 | public class SocialMediaButtonRenderer extends CoreRenderer { 36 | 37 | /** 38 | * This methods generates the HTML code of the current b:socialMediaButton. 39 | * encodeBegin generates the start of the component. After the, the JSF framework calls encodeChildren() 40 | * to generate the HTML code between the beginning and the end of the component. For instance, in the case of a panel component 41 | * the content of the panel is generated by encodeChildren(). After that, encodeEnd() is called 42 | * to generate the rest of the HTML code. 43 | * @param context the FacesContext. 44 | * @param component the current b:socialMediaButton. 45 | * @throws IOException thrown if something goes wrong when writing the HTML code. 46 | */ 47 | @Override 48 | public void encodeBegin(FacesContext context, UIComponent component) throws IOException { 49 | if (!component.isRendered()) { 50 | return; 51 | } 52 | SocialMediaButton socialMediaButton = (SocialMediaButton) component; 53 | ResponseWriter rw = context.getResponseWriter(); 54 | String clientId = socialMediaButton.getClientId(); 55 | 56 | // put custom code here 57 | // Simple demo widget that simply renders every attribute value 58 | rw.startElement("socialMediaButton", socialMediaButton); 59 | Tooltip.generateTooltip(context, socialMediaButton, rw); 60 | 61 | rw.writeAttribute("id", socialMediaButton.getId(), "id"); 62 | rw.writeAttribute("rendered", String.valueOf(socialMediaButton.isRendered()), "rendered"); 63 | rw.writeAttribute("twitter", String.valueOf(socialMediaButton.isTwitter()), "twitter"); 64 | rw.writeAttribute("update", socialMediaButton.getUpdate(), "update"); 65 | rw.writeText("Dummy content of b:socialMediaButton", null); 66 | 67 | } 68 | 69 | /** 70 | * This methods generates the HTML code of the current b:socialMediaButton. 71 | * encodeBegin generates the start of the component. After the, the JSF framework calls encodeChildren() 72 | * to generate the HTML code between the beginning and the end of the component. For instance, in the case of a panel component 73 | * the content of the panel is generated by encodeChildren(). After that, encodeEnd() is called 74 | * to generate the rest of the HTML code. 75 | * @param context the FacesContext. 76 | * @param component the current b:socialMediaButton. 77 | * @throws IOException thrown if something goes wrong when writing the HTML code. 78 | */ 79 | @Override 80 | public void encodeEnd(FacesContext context, UIComponent component) throws IOException { 81 | if (!component.isRendered()) { 82 | return; 83 | } 84 | SocialMediaButton socialMediaButton = (SocialMediaButton) component; 85 | ResponseWriter rw = context.getResponseWriter(); 86 | String clientId = socialMediaButton.getClientId(); 87 | rw.endElement("socialMediaButton"); 88 | Tooltip.activateTooltips(fc, c); 89 | 90 | } 91 | 92 | } 93 | -------------------------------------------------------------------------------- /BootsFacesGeneratorDemo/src/main/java/net/bootsfaces/component/socialShare/SocialShare.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2017 Riccardo Massera (TheCoder4.Eu), Dario D'Urzo and Stephan Rauh (http://www.beyondjava.net). 3 | * 4 | * This file is part of BootsFaces. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package net.bootsfaces.component.socialShare; 20 | 21 | import javax.faces.context.FacesContext; 22 | import javax.faces.event.AbortProcessingException; 23 | import javax.faces.event.ComponentSystemEvent; 24 | import javax.faces.event.ListenerFor; 25 | import javax.faces.event.ListenersFor; 26 | import javax.faces.event.PostAddToViewEvent; 27 | 28 | import javax.el.ValueExpression; 29 | import javax.faces.component.FacesComponent; 30 | 31 | import net.bootsfaces.C; 32 | import net.bootsfaces.listeners.AddResourcesListener; 33 | import net.bootsfaces.render.Tooltip; 34 | import net.bootsfaces.utils.BsfUtils; 35 | 36 | /** This class holds the attributes of <b:socialShare />. */ 37 | @ListenersFor({ @ListenerFor(systemEventClass = PostAddToViewEvent.class) }) 38 | @FacesComponent(SocialShare.COMPONENT_TYPE) 39 | public class SocialShare extends SocialShareCore { 40 | 41 | public static final String COMPONENT_TYPE = C.BSFCOMPONENT + ".socialShare.SocialShare"; 42 | 43 | public static final String COMPONENT_FAMILY = C.BSFCOMPONENT; 44 | 45 | public static final String DEFAULT_RENDERER = "net.bootsfaces.component.socialShare.SocialShare"; 46 | 47 | public SocialShare() { 48 | Tooltip.addResourceFiles(); 49 | AddResourcesListener.addExtCSSResource("jssocials.css"); 50 | AddResourcesListener.addResourceToHeadButAfterJQuery(C.BSF_LIBRARY, "js/jssocials.min.js"); 51 | setRendererType(DEFAULT_RENDERER); 52 | } 53 | 54 | public void processEvent(ComponentSystemEvent event) throws AbortProcessingException { 55 | if (FacesContext.getCurrentInstance().isPostback()) { 56 | FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().add(getClientId()); 57 | } 58 | super.processEvent(event); 59 | } 60 | 61 | public String getFamily() { 62 | return COMPONENT_FAMILY; 63 | } 64 | 65 | /** 66 | * Manage EL-expression for snake-case attributes 67 | */ 68 | public void setValueExpression(String name, ValueExpression binding) { 69 | name = BsfUtils.snakeCaseToCamelCase(name); 70 | super.setValueExpression(name, binding); 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /BootsFacesGeneratorDemo/src/main/java/net/bootsfaces/component/socialShare/SocialShareBeanInfo.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2017 Riccardo Massera (TheCoder4.Eu) and Stephan Rauh (http://www.beyondjava.net). 3 | * 4 | * This file is part of BootsFaces. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package net.bootsfaces.component.socialShare; 20 | 21 | import net.bootsfaces.beans.BsfBeanInfo; 22 | 23 | /** 24 | * BeanInfo class to provide mapping 25 | * of snake-case attributes to camelCase ones 26 | * 27 | * @author Dario D'Urzo 28 | */ 29 | public class SocialShareBeanInfo extends BsfBeanInfo { 30 | 31 | /** 32 | * Get the reference decorated class 33 | */ 34 | @Override 35 | public Class getDecoratedClass() { 36 | return SocialShare.class; 37 | } 38 | } 39 | 40 | -------------------------------------------------------------------------------- /BootsFacesGeneratorDemo/src/main/java/net/bootsfaces/component/socialShare/SocialShareRenderer.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014-2017 Riccardo Massera (TheCoder4.Eu) and Stephan Rauh (http://www.beyondjava.net). 3 | * 4 | * This file is part of BootsFaces. 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 | * See the License for the specific language governing permissions and 16 | * limitations under the License. 17 | */ 18 | 19 | package net.bootsfaces.component.socialShare; 20 | 21 | import java.io.IOException; 22 | 23 | import javax.faces.component.UIComponent; 24 | import javax.faces.context.FacesContext; 25 | import javax.faces.context.ResponseWriter; 26 | import javax.faces.render.FacesRenderer; 27 | 28 | import net.bootsfaces.render.CoreRenderer; 29 | import net.bootsfaces.utils.BsfUtils; 30 | 31 | /** This class generates the HTML code of <b:socialShare />. */ 32 | @FacesRenderer(componentFamily = "net.bootsfaces.component", rendererType = "net.bootsfaces.component.socialShare.SocialShare") 33 | public class SocialShareRenderer extends CoreRenderer { 34 | 35 | /** 36 | * This methods generates the HTML code of the current b:socialShare. 37 | * 38 | * @param context 39 | * the FacesContext. 40 | * @param component 41 | * the current b:socialShare. 42 | * @throws IOException 43 | * thrown if something goes wrong when writing the HTML code. 44 | */ 45 | @Override 46 | public void encodeBegin(FacesContext context, UIComponent component) throws IOException { 47 | if (!component.isRendered()) { 48 | return; 49 | } 50 | SocialShare socialShare = (SocialShare) component; 51 | ResponseWriter rw = context.getResponseWriter(); 52 | String clientId = socialShare.getClientId(); 53 | 54 | if (!BsfUtils.isStringValued(socialShare.getShares())) { 55 | return; 56 | } 57 | 58 | beginResponsiveWrapper(component, rw); 59 | 60 | rw.startElement("div", socialShare); 61 | rw.writeAttribute("id", clientId + "_wrapper", "id"); 62 | 63 | // Create the div container 64 | rw.startElement("div", socialShare); 65 | rw.writeAttribute("id", clientId, "id"); 66 | if (BsfUtils.isStringValued(socialShare.getStyle())) 67 | rw.writeAttribute("style", socialShare.getStyle(), "style"); 68 | rw.writeAttribute("class", socialShare.getStyleClass(), "class"); 69 | rw.endElement("div"); 70 | 71 | rw.endElement("div"); 72 | 73 | // decode shares 74 | String shares = ""; 75 | String[] _share = socialShare.getShares().split(","); 76 | for (int i = 0; i < _share.length; i++) { 77 | _share[i] = "'" + _share[i] + "'"; 78 | shares += _share[i]; 79 | if (i < _share.length - 1) 80 | shares += ","; 81 | } 82 | 83 | String showCount = socialShare.getShowCount(); 84 | if (!"false".equalsIgnoreCase(showCount) && !"true".equalsIgnoreCase(showCount) 85 | && BsfUtils.isStringValued(showCount)) 86 | showCount = "'" + showCount + "'"; 87 | 88 | String scriptId = "#" + BsfUtils.escapeJQuerySpecialCharsInSelector(clientId); 89 | rw.startElement("script", socialShare); 90 | rw.writeText("$(function () { " + 91 | // social share section 92 | "$('" + scriptId + "').jsSocials({ " 93 | + (BsfUtils.isStringValued(socialShare.getUrl()) ? "url: '" + socialShare.getUrl() + "', " : "") 94 | + (BsfUtils.isStringValued(socialShare.getText()) ? "text: '" + socialShare.getText() + "', " : "") 95 | + (BsfUtils.isStringValued(socialShare.getShareIn()) ? "shareIn: '" + socialShare.getShareIn() + "', " : "") 96 | + (BsfUtils.isStringValued(showCount) ? "showCount: " + showCount + ", " : "") 97 | + (socialShare.isShowLabel() ? "showLabel: true, " : "showLabel: false,") + "shares: [" + shares + "] " 98 | + "});" 99 | + (socialShare.isDisableBlock() ? 100 | // no block 101 | "" : 102 | // overlay 103 | "$('" + scriptId + "_wrapper').block({" 104 | + " message: '" + socialShare.getBlockMessage() 105 | + "'," 106 | + " css: { " + " border: 'none', " 107 | + " padding: '8px', " 108 | + " backgroundColor: '#000', " 109 | + " '-webkit-border-radius': '10px', " 110 | + " '-moz-border-radius': '10px', " 111 | + " 'border-radius': '10px', " 112 | + " opacity: 1, " 113 | + " color: '#fff', " + " fontSize: '12px', " 114 | + " cursor: 'default', " 115 | + " top: '40%', " 116 | + " left: '35%' " 117 | + " }, " 118 | + " overlayCSS: { " 119 | + " backgroundColor: '#000', " 120 | + " opacity: 0.6, " 121 | + " cursor: 'default' " 122 | + " } " 123 | + "}); " 124 | + "$('" + scriptId 125 | + "_wrapper').click(function() { $('" + scriptId + "_wrapper').unblock(); }); ") 126 | + "});", null); 127 | 128 | rw.endElement("script"); 129 | } 130 | 131 | @Override 132 | public void encodeEnd(FacesContext context, UIComponent component) throws IOException { 133 | endResponsiveWrapper(component, context.getResponseWriter()); 134 | } 135 | } 136 | -------------------------------------------------------------------------------- /BootsFacesGeneratorDemo/src/main/meta/META-INF/.gitignore: -------------------------------------------------------------------------------- 1 | /bootsfaces-b.taglib.xml 2 | -------------------------------------------------------------------------------- /BootsFacesWeb/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | BootsFacesWeb 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /BootsFacesWeb/src/main/webapp/AccordionAttributes.xhtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 11 | 12 | Attributes of <b:accordion > 13 | 14 |

15 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 |
AttributeDefault valueDescription
col-lg
colLg (alternative writing)
-1 Integer value to specify how many columns to span on large screens (≥1200 pixels wide). The number may optionally be followed by "column" or "columns". Alternative legal values: half, one-third, two-thirds, one-fourth, three-fourths.
col-md
colMd (alternative writing)
-1 Integer value to specify how many columns to span on medium screens (≥992 pixels wide). The number may optionally be followed by "column" or "columns". Alternative legal values: half, one-third, two-thirds, one-fourth, three-fourths.
col-sm
colSm (alternative writing)
-1 Integer value to specify how many columns to span on small screens (≥768p pixels wide). The number may optionally be followed by "column" or "columns". Alternative legal values: half, one-third, two-thirds, one-fourth, three-fourths.
col-xs
colXs (alternative writing)
-1 Integer value to specify how many columns to span on tiny screens (≤ 767 pixels wide). The number may optionally be followed by "column" or "columns". Alternative legal values: half, one-third, two-thirds, one-fourth, three-fourths.
content-disabled
contentDisabled (alternative writing)
false Enables or disables every child element of this container. By default, child elements are enabled.
display block If you use the "visible" attribute, the value of this attribute is added. Legal values: block, inline, inline-block. Default: block.
expanded-panels
expandedPanels (alternative writing)
(none)Comma separated list of child panel id that need to render expanded.
hidden(none)This column is hidden on a certain screen size and below. Legal values: lg, md, sm, xs.
id(none)Unique identifier of the component in a namingContainer.
large-screen
largeScreen (alternative writing)
-1 Alternative spelling to col-lg. Integer value to specify how many columns to span on large screens (≥1200 pixels wide). The number may optionally be followed by "column" or "columns". Alternative legal values: half, one-third, two-thirds, one-fourth, three-fourths.
medium-screen
mediumScreen (alternative writing)
-1 Alternative spelling to col-md. Integer value to specify how many columns to span on medium screens (≥992 pixels wide). The number may optionally be followed by "column" or "columns". Alternative legal values: half, one-third, two-thirds, one-fourth, three-fourths.
offset(none)Integer value to specify how many columns to offset.
offset-lg
offsetLg (alternative writing)
(none)Integer value to specify how many columns to offset.
offset-md
offsetMd (alternative writing)
(none)Integer value to specify how many columns to offset.
offset-sm
offsetSm (alternative writing)
(none)Integer value to specify how many columns to offset.
offset-xs
offsetXs (alternative writing)
(none)Integer value to specify how many columns to offset.
renderedfalseBoolean value to specify the rendering of the component, when set to false the component will not be rendered.
small-screen
smallScreen (alternative writing)
-1 Alternative spelling to col-sm. Integer value to specify how many columns to span on small screens (≥768p pixels wide). The number may optionally be followed by "column" or "columns". Alternative legal values: half, one-third, two-thirds, one-fourth, three-fourths.
span(none)Integer value to specify how many columns to span on medium screens (≥992 pixels). The number may optionally be followed by "column" or "columns". Alternative legal values: half, one-third, two-thirds, one-fourth, three-fourths.
style(none)Inline style of the input element.
style-class
styleClass (alternative writing)
(none)Style class of this element.
tiny-screen
tinyScreen (alternative writing)
-1 Alternative spelling to col-xs. Integer value to specify how many columns to span on tiny screens (≤ 767 pixels wide). The number may optionally be followed by "column" or "columns". Alternative legal values: half, one-third, two-thirds, one-fourth, three-fourths.
tooltip(none)The text of the tooltip.
tooltip-container
tooltipContainer (alternative writing)
body Where is the tooltip div generated? That's primarily a technical value that can be used to fix rendering errors in special cases. Also see data-container in the documentation of Bootstrap. The default value is body.
tooltip-delay
tooltipDelay (alternative writing)
0 The tooltip is shown and hidden with a delay. This value is the delay in milliseconds. Defaults to 0 (no delay).
tooltip-delay-hide
tooltipDelayHide (alternative writing)
0 The tooltip is hidden with a delay. This value is the delay in milliseconds. Defaults to 0 (no delay).
tooltip-delay-show
tooltipDelayShow (alternative writing)
0 The tooltip is shown with a delay. This value is the delay in milliseconds. Defaults to 0 (no delay).
tooltip-position
tooltipPosition (alternative writing)
(none)Where is the tooltip to be displayed? Possible values: "top", "bottom", "right", "left", "auto", "auto top", "auto bottom", "auto right" and "auto left". Default to "bottom".
visible(none)This column is shown on a certain screen size and above. Legal values: lg, md, sm, xs.
172 |
173 | 174 | 175 | -------------------------------------------------------------------------------- /BootsFacesWeb/src/main/webapp/layout/AlertAttributes.xhtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 11 | 12 | Attributes of <b:alert > 13 | 14 |
15 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 |
AttributeDefault valueDescription
binding(none)An EL expression referring to a server side UIComponent instance in a backing bean.
closablefalseIf true close button will be displayed.
col-lg
colLg (alternative writing)
-1 Integer value to specify how many columns to span on large screens (≥1200 pixels wide). The number may optionally be followed by "column" or "columns". Alternative legal values: half, one-third, two-thirds, one-fourth, three-fourths.
col-md
colMd (alternative writing)
-1 Integer value to specify how many columns to span on medium screens (≥992 pixels wide). The number may optionally be followed by "column" or "columns". Alternative legal values: half, one-third, two-thirds, one-fourth, three-fourths.
col-sm
colSm (alternative writing)
-1 Integer value to specify how many columns to span on small screens (≥768p pixels wide). The number may optionally be followed by "column" or "columns". Alternative legal values: half, one-third, two-thirds, one-fourth, three-fourths.
col-xs
colXs (alternative writing)
-1 Integer value to specify how many columns to span on tiny screens (≤ 767 pixels wide). The number may optionally be followed by "column" or "columns". Alternative legal values: half, one-third, two-thirds, one-fourth, three-fourths.
display block If you use the "visible" attribute, the value of this attribute is added. Legal values: block, inline, inline-block. Default: block.
hidden(none)This column is hidden on a certain screen size and below. Legal values: lg, md, sm, xs.
id(none)Unique identifier of the component in a namingContainer.
large-screen
largeScreen (alternative writing)
-1 Alternative spelling to col-lg. Integer value to specify how many columns to span on large screens (≥1200 pixels wide). The number may optionally be followed by "column" or "columns". Alternative legal values: half, one-third, two-thirds, one-fourth, three-fourths.
medium-screen
mediumScreen (alternative writing)
-1 Alternative spelling to col-md. Integer value to specify how many columns to span on medium screens (≥992 pixels wide). The number may optionally be followed by "column" or "columns". Alternative legal values: half, one-third, two-thirds, one-fourth, three-fourths.
offset(none)Integer value to specify how many columns to offset.
offset-lg
offsetLg (alternative writing)
(none)Integer value to specify how many columns to offset.
offset-md
offsetMd (alternative writing)
(none)Integer value to specify how many columns to offset.
offset-sm
offsetSm (alternative writing)
(none)Integer value to specify how many columns to offset.
offset-xs
offsetXs (alternative writing)
(none)Integer value to specify how many columns to offset.
renderedfalseBoolean value to specify the rendering of the component, when set to false the component will not be rendered.
severity(none)Severity of the Alert, can be success, info, warning, danger. Default is warning.
small-screen
smallScreen (alternative writing)
-1 Alternative spelling to col-sm. Integer value to specify how many columns to span on small screens (≥768p pixels wide). The number may optionally be followed by "column" or "columns". Alternative legal values: half, one-third, two-thirds, one-fourth, three-fourths.
span(none)Integer value to specify how many columns to span on medium screens (≥992 pixels). The number may optionally be followed by "column" or "columns". Alternative legal values: half, one-third, two-thirds, one-fourth, three-fourths.
style(none)Inline style of the input element.
style-class
styleClass (alternative writing)
(none)Style class of this element.
tiny-screen
tinyScreen (alternative writing)
-1 Alternative spelling to col-xs. Integer value to specify how many columns to span on tiny screens (≤ 767 pixels wide). The number may optionally be followed by "column" or "columns". Alternative legal values: half, one-third, two-thirds, one-fourth, three-fourths.
title(none)Bold Title displayed before your message.
tooltip(none)The text of the tooltip.
tooltip-container
tooltipContainer (alternative writing)
body Where is the tooltip div generated? That's primarily a technical value that can be used to fix rendering errors in special cases. Also see data-container in the documentation of Bootstrap. The default value is body.
tooltip-delay
tooltipDelay (alternative writing)
0 The tooltip is shown and hidden with a delay. This value is the delay in milliseconds. Defaults to 0 (no delay).
tooltip-delay-hide
tooltipDelayHide (alternative writing)
0 The tooltip is hidden with a delay. This value is the delay in milliseconds. Defaults to 0 (no delay).
tooltip-delay-show
tooltipDelayShow (alternative writing)
0 The tooltip is shown with a delay. This value is the delay in milliseconds. Defaults to 0 (no delay).
tooltip-position
tooltipPosition (alternative writing)
(none)Where is the tooltip to be displayed? Possible values: "top", "bottom", "right", "left", "auto", "auto top", "auto bottom", "auto right" and "auto left". Default to "bottom".
visible(none)This column is shown on a certain screen size and above. Legal values: lg, md, sm, xs.
182 |
183 |
184 |
185 | -------------------------------------------------------------------------------- /JSFLibraryGeneratorUpdateSite/artifacts.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanrauh/JSFLibraryGenerator/bdd7680f32cc8ce85599b7e447700e3ce1d739ee/JSFLibraryGeneratorUpdateSite/artifacts.jar -------------------------------------------------------------------------------- /JSFLibraryGeneratorUpdateSite/content.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanrauh/JSFLibraryGenerator/bdd7680f32cc8ce85599b7e447700e3ce1d739ee/JSFLibraryGeneratorUpdateSite/content.jar -------------------------------------------------------------------------------- /JSFLibraryGeneratorUpdateSite/features/de.beyondjava.xtext.jsf.sdk_1.0.2.201806071814.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanrauh/JSFLibraryGenerator/bdd7680f32cc8ce85599b7e447700e3ce1d739ee/JSFLibraryGeneratorUpdateSite/features/de.beyondjava.xtext.jsf.sdk_1.0.2.201806071814.jar -------------------------------------------------------------------------------- /JSFLibraryGeneratorUpdateSite/plugins/de.beyondjava.xtext.jsf.ui_1.0.2.201806071814.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanrauh/JSFLibraryGenerator/bdd7680f32cc8ce85599b7e447700e3ce1d739ee/JSFLibraryGeneratorUpdateSite/plugins/de.beyondjava.xtext.jsf.ui_1.0.2.201806071814.jar -------------------------------------------------------------------------------- /JSFLibraryGeneratorUpdateSite/plugins/de.beyondjava.xtext.jsf_1.0.2.201806071814.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanrauh/JSFLibraryGenerator/bdd7680f32cc8ce85599b7e447700e3ce1d739ee/JSFLibraryGeneratorUpdateSite/plugins/de.beyondjava.xtext.jsf_1.0.2.201806071814.jar -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "{}" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright {yyyy} {name of copyright owner} 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # JSFLibraryGenerator 2 | A little XText project that's intended to make it simpler to create a JSF component library. 3 | 4 | Creating a JSF library becomes - after a while - quite a repetive task. You have to maintain the taglib, you have to create the 5 | component classes and you have to implement the renderer. Plus, the taglib doesn't read easily. Did I already mention the documentation pages? 6 | 7 | The goal of this project is to generate these artifacts from a simple, legible and maintainable DSL language. 8 | 9 | #State of the art 10 | The XText/Xtend plugin is based on a *.jsfdsl file which describes the entire component suite of a JSF library. The *.jsfdsl 11 | file, in turn, can be generated from a standard JSF taglib file by running the TaglibImporter class. The folder BootsFacesGeneratorDemo contains the 12 | *.jsfdsl generated by the TaglibImporter and the component skeletons of each of the 38 components of BootsFaces 0.6.7. 13 | 14 | When you've installed the plugin in Eclipse (simply put the two files of the eclipse folders into the plugins folder of Eclipse), 15 | you can generate the JSF component skeletons simply by editing and saving the *.jsfdsl file. Currently, it renders 16 | - the component 17 | - the renderer 18 | - a taglib file which is complete, but only covers a single component 19 | - and a documentation skeleton. 20 | 21 | #What's left to do 22 | - add the required CSS and Javascript files to the DSL and generate the @ResourceDependencies annotations 23 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf.sdk/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | de.beyondjava.xtext.jsf.sdk 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.pde.FeatureBuilder 10 | 11 | 12 | 13 | 14 | 15 | org.eclipse.pde.FeatureNature 16 | 17 | 18 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf.sdk/build.properties: -------------------------------------------------------------------------------- 1 | bin.includes =feature.xml 2 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf.sdk/feature.xml: -------------------------------------------------------------------------------- 1 | 2 | 6 | 7 | 13 | 14 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf.tests/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf.tests/.gitignore: -------------------------------------------------------------------------------- 1 | /bin/ 2 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf.tests/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | de.beyondjava.xtext.jsf.tests 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.pde.ManifestBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.pde.SchemaBuilder 20 | 21 | 22 | 23 | 24 | org.eclipse.xtext.ui.shared.xtextBuilder 25 | 26 | 27 | 28 | 29 | 30 | org.eclipse.jdt.core.javanature 31 | org.eclipse.pde.PluginNature 32 | org.eclipse.xtext.ui.shared.xtextNature 33 | 34 | 35 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf.tests/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Bundle-ManifestVersion: 2 3 | Bundle-Name: de.beyondjava.xtext.jsf.tests 4 | Bundle-Vendor: My Company 5 | Bundle-Version: 1.0.0.qualifier 6 | Bundle-SymbolicName: de.beyondjava.xtext.jsf.tests; singleton:=true 7 | Bundle-ActivationPolicy: lazy 8 | Require-Bundle: de.beyondjava.xtext.jsf, 9 | de.beyondjava.xtext.jsf.ui, 10 | org.eclipse.core.runtime, 11 | org.eclipse.xtext.junit4, 12 | org.eclipse.xtext.xbase.lib, 13 | org.eclipse.ui.workbench;resolution:=optional, 14 | org.objectweb.asm;bundle-version="[5.0.1,6.0.0)";resolution:=optional 15 | Import-Package: org.apache.log4j, 16 | org.junit;version="4.5.0", 17 | org.junit.runner;version="4.5.0", 18 | org.junit.runner.manipulation;version="4.5.0", 19 | org.junit.runner.notification;version="4.5.0", 20 | org.junit.runners;version="4.5.0", 21 | org.junit.runners.model;version="4.5.0", 22 | org.hamcrest.core 23 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 24 | Export-Package: de.beyondjava.xtext.jsf 25 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf.tests/build.properties: -------------------------------------------------------------------------------- 1 | source.. = src/,\ 2 | src-gen/,\ 3 | xtend-gen/ 4 | bin.includes = META-INF/,\ 5 | . 6 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf.tests/de.beyondjava.xtext.jsf.tests.launch: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf.ui/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf.ui/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | de.beyondjava.xtext.jsf.ui 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.pde.ManifestBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.pde.SchemaBuilder 20 | 21 | 22 | 23 | 24 | org.eclipse.xtext.ui.shared.xtextBuilder 25 | 26 | 27 | 28 | 29 | 30 | org.eclipse.jdt.core.javanature 31 | org.eclipse.pde.PluginNature 32 | org.eclipse.xtext.ui.shared.xtextNature 33 | 34 | 35 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf.ui/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Bundle-ManifestVersion: 2 3 | Bundle-Name: de.beyondjava.xtext.jsf.ui 4 | Bundle-Vendor: BootsFaces 5 | Bundle-Version: 1.0.2.qualifier 6 | Bundle-SymbolicName: de.beyondjava.xtext.jsf.ui; singleton:=true 7 | Bundle-ActivationPolicy: lazy 8 | Require-Bundle: de.beyondjava.xtext.jsf;visibility:=reexport, 9 | org.eclipse.xtext.ui, 10 | org.eclipse.ui.editors;bundle-version="3.5.0", 11 | org.eclipse.ui.ide;bundle-version="3.5.0", 12 | org.eclipse.xtext.ui.shared, 13 | org.eclipse.ui, 14 | org.eclipse.xtext.builder, 15 | org.eclipse.xtext.xbase.lib, 16 | org.eclipse.xtext.common.types.ui, 17 | org.eclipse.xtext.ui.codetemplates.ui, 18 | org.eclipse.compare 19 | Import-Package: org.apache.log4j 20 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 21 | Export-Package: de.beyondjava.xtext.jsf.ui.quickfix, 22 | de.beyondjava.xtext.jsf.ui.contentassist, 23 | de.beyondjava.xtext.jsf.ui.internal, 24 | de.beyondjava.xtext.jsf.ui.contentassist.antlr, 25 | de.beyondjava.xtext.jsf.ui.contentassist.antlr.internal 26 | Bundle-Activator: de.beyondjava.xtext.jsf.ui.internal.ComponentLanguageActivator 27 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf.ui/build.properties: -------------------------------------------------------------------------------- 1 | source.. = src/,\ 2 | src-gen/,\ 3 | xtend-gen/ 4 | bin.includes = META-INF/,\ 5 | .,\ 6 | plugin.xml 7 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf.ui/src/de/beyondjava/xtext/jsf/ui/ComponentLanguageUiModule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 3 | */ 4 | package de.beyondjava.xtext.jsf.ui; 5 | 6 | import org.eclipse.ui.plugin.AbstractUIPlugin; 7 | 8 | /** 9 | * Use this class to register components to be used within the IDE. 10 | */ 11 | public class ComponentLanguageUiModule extends de.beyondjava.xtext.jsf.ui.AbstractComponentLanguageUiModule { 12 | public ComponentLanguageUiModule(AbstractUIPlugin plugin) { 13 | super(plugin); 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf.ui/src/de/beyondjava/xtext/jsf/ui/contentassist/ComponentLanguageProposalProvider.xtend: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 3 | */ 4 | package de.beyondjava.xtext.jsf.ui.contentassist 5 | 6 | import de.beyondjava.xtext.jsf.ui.contentassist.AbstractComponentLanguageProposalProvider 7 | 8 | /** 9 | * See https://www.eclipse.org/Xtext/documentation/304_ide_concepts.html#content-assist 10 | * on how to customize the content assistant. 11 | */ 12 | class ComponentLanguageProposalProvider extends AbstractComponentLanguageProposalProvider { 13 | } 14 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf.ui/src/de/beyondjava/xtext/jsf/ui/handler/GenerationHandler.java: -------------------------------------------------------------------------------- 1 | package de.beyondjava.xtext.jsf.ui.handler; 2 | 3 | import org.eclipse.core.commands.AbstractHandler; 4 | import org.eclipse.core.commands.ExecutionEvent; 5 | import org.eclipse.core.commands.ExecutionException; 6 | import org.eclipse.core.commands.IHandler; 7 | import org.eclipse.core.resources.IFile; 8 | import org.eclipse.core.resources.IFolder; 9 | import org.eclipse.core.resources.IProject; 10 | import org.eclipse.core.runtime.CoreException; 11 | import org.eclipse.core.runtime.NullProgressMonitor; 12 | import org.eclipse.emf.common.util.URI; 13 | import org.eclipse.emf.ecore.resource.Resource; 14 | import org.eclipse.emf.ecore.resource.ResourceSet; 15 | import org.eclipse.jface.viewers.ISelection; 16 | import org.eclipse.jface.viewers.IStructuredSelection; 17 | import org.eclipse.ui.handlers.HandlerUtil; 18 | import org.eclipse.xtext.builder.EclipseResourceFileSystemAccess; 19 | import org.eclipse.xtext.generator.IGenerator; 20 | import org.eclipse.xtext.resource.IResourceDescriptions; 21 | import org.eclipse.xtext.ui.resource.IResourceSetProvider; 22 | 23 | import com.google.inject.Inject; 24 | import com.google.inject.Provider; 25 | 26 | public class GenerationHandler extends AbstractHandler implements IHandler { 27 | 28 | @Inject 29 | private IGenerator generator; 30 | 31 | @Inject 32 | private Provider fileAccessProvider; 33 | 34 | @Inject 35 | IResourceDescriptions resourceDescriptions; 36 | 37 | @Inject 38 | IResourceSetProvider resourceSetProvider; 39 | 40 | @Override 41 | public Object execute(ExecutionEvent event) throws ExecutionException { 42 | 43 | ISelection selection = HandlerUtil.getCurrentSelection(event); 44 | if (selection instanceof IStructuredSelection) { 45 | IStructuredSelection structuredSelection = (IStructuredSelection) selection; 46 | Object firstElement = structuredSelection.getFirstElement(); 47 | if (firstElement instanceof IFile) { 48 | IFile file = (IFile) firstElement; 49 | IProject project = file.getProject(); 50 | IFolder srcGenFolder = project.getFolder("src-gen"); 51 | if (!srcGenFolder.exists()) { 52 | try { 53 | srcGenFolder.create(true, true, 54 | new NullProgressMonitor()); 55 | } catch (CoreException e) { 56 | return null; 57 | } 58 | } 59 | 60 | final EclipseResourceFileSystemAccess fsa = fileAccessProvider.get(); 61 | fsa.setOutputPath(srcGenFolder.getFullPath().toString()); 62 | 63 | URI uri = URI.createPlatformResourceURI(file.getFullPath().toString(), true); 64 | ResourceSet rs = resourceSetProvider.get(project); 65 | Resource r = rs.getResource(uri, true); 66 | generator.doGenerate(r, fsa); 67 | 68 | } 69 | } 70 | return null; 71 | } 72 | 73 | @Override 74 | public boolean isEnabled() { 75 | return true; 76 | } 77 | 78 | } -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf.ui/src/de/beyondjava/xtext/jsf/ui/labeling/ComponentLanguageDescriptionLabelProvider.xtend: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 3 | */ 4 | package de.beyondjava.xtext.jsf.ui.labeling 5 | 6 | //import org.eclipse.xtext.resource.IEObjectDescription 7 | 8 | /** 9 | * Provides labels for IEObjectDescriptions and IResourceDescriptions. 10 | * 11 | * See https://www.eclipse.org/Xtext/documentation/304_ide_concepts.html#label-provider 12 | */ 13 | class ComponentLanguageDescriptionLabelProvider extends org.eclipse.xtext.ui.label.DefaultDescriptionLabelProvider { 14 | 15 | // Labels and icons can be computed like this: 16 | 17 | // override text(IEObjectDescription ele) { 18 | // ele.name.toString 19 | // } 20 | // 21 | // override image(IEObjectDescription ele) { 22 | // ele.EClass.name + '.gif' 23 | // } 24 | } 25 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf.ui/src/de/beyondjava/xtext/jsf/ui/labeling/ComponentLanguageLabelProvider.xtend: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 3 | */ 4 | package de.beyondjava.xtext.jsf.ui.labeling 5 | 6 | import com.google.inject.Inject 7 | 8 | /** 9 | * Provides labels for EObjects. 10 | * 11 | * See https://www.eclipse.org/Xtext/documentation/304_ide_concepts.html#label-provider 12 | */ 13 | class ComponentLanguageLabelProvider extends org.eclipse.xtext.ui.label.DefaultEObjectLabelProvider { 14 | 15 | @Inject 16 | new(org.eclipse.emf.edit.ui.provider.AdapterFactoryLabelProvider delegate) { 17 | super(delegate); 18 | } 19 | 20 | // Labels and icons can be computed like this: 21 | 22 | // def text(Greeting ele) { 23 | // 'A greeting to ' + ele.name 24 | // } 25 | // 26 | // def image(Greeting ele) { 27 | // 'Greeting.gif' 28 | // } 29 | } 30 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf.ui/src/de/beyondjava/xtext/jsf/ui/outline/ComponentLanguageOutlineTreeProvider.xtend: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 3 | */ 4 | package de.beyondjava.xtext.jsf.ui.outline 5 | 6 | /** 7 | * Customization of the default outline structure. 8 | * 9 | * See https://www.eclipse.org/Xtext/documentation/304_ide_concepts.html#outline 10 | */ 11 | class ComponentLanguageOutlineTreeProvider extends org.eclipse.xtext.ui.editor.outline.impl.DefaultOutlineTreeProvider { 12 | 13 | } 14 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf.ui/src/de/beyondjava/xtext/jsf/ui/quickfix/ComponentLanguageQuickfixProvider.xtend: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 3 | */ 4 | package de.beyondjava.xtext.jsf.ui.quickfix 5 | 6 | //import org.eclipse.xtext.ui.editor.quickfix.Fix 7 | //import org.eclipse.xtext.ui.editor.quickfix.IssueResolutionAcceptor 8 | //import org.eclipse.xtext.validation.Issue 9 | 10 | /** 11 | * Custom quickfixes. 12 | * 13 | * See https://www.eclipse.org/Xtext/documentation/304_ide_concepts.html#quick-fixes 14 | */ 15 | class ComponentLanguageQuickfixProvider extends org.eclipse.xtext.ui.editor.quickfix.DefaultQuickfixProvider { 16 | 17 | // @Fix(MyDslValidator::INVALID_NAME) 18 | // def capitalizeName(Issue issue, IssueResolutionAcceptor acceptor) { 19 | // acceptor.accept(issue, 'Capitalize name', 'Capitalize the name.', 'upcase.png') [ 20 | // context | 21 | // val xtextDocument = context.xtextDocument 22 | // val firstLetter = xtextDocument.get(issue.offset, 1) 23 | // xtextDocument.replace(issue.offset, 1, firstLetter.toUpperCase) 24 | // ] 25 | // } 26 | } 27 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/.antlr-generator-3.2.0-patch.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/stephanrauh/JSFLibraryGenerator/bdd7680f32cc8ce85599b7e447700e3ce1d739ee/de.beyondjava.xtext.jsf/.antlr-generator-3.2.0-patch.jar -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/.classpath: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/.gitignore: -------------------------------------------------------------------------------- 1 | .settings/ 2 | src-gen/ 3 | bin/ 4 | .DS_Store -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/.project: -------------------------------------------------------------------------------- 1 | 2 | 3 | de.beyondjava.xtext.jsf 4 | 5 | 6 | 7 | 8 | 9 | org.eclipse.jdt.core.javabuilder 10 | 11 | 12 | 13 | 14 | org.eclipse.pde.ManifestBuilder 15 | 16 | 17 | 18 | 19 | org.eclipse.pde.SchemaBuilder 20 | 21 | 22 | 23 | 24 | org.eclipse.xtext.ui.shared.xtextBuilder 25 | 26 | 27 | 28 | 29 | 30 | org.eclipse.jdt.core.javanature 31 | org.eclipse.pde.PluginNature 32 | org.eclipse.xtext.ui.shared.xtextNature 33 | 34 | 35 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/META-INF/MANIFEST.MF: -------------------------------------------------------------------------------- 1 | Manifest-Version: 1.0 2 | Bundle-ManifestVersion: 2 3 | Bundle-Name: de.beyondjava.xtext.jsf 4 | Bundle-Vendor: BootsFaces 5 | Bundle-Version: 1.0.2.qualifier 6 | Bundle-SymbolicName: de.beyondjava.xtext.jsf; singleton:=true 7 | Bundle-ActivationPolicy: lazy 8 | Require-Bundle: org.eclipse.xtext;visibility:=reexport, 9 | org.eclipse.equinox.common;bundle-version="3.5.0", 10 | org.eclipse.xtext.util, 11 | org.eclipse.emf.ecore, 12 | org.eclipse.emf.common, 13 | org.eclipse.xtext.xbase.lib, 14 | org.antlr.runtime, 15 | org.eclipse.xtext.common.types, 16 | org.objectweb.asm;bundle-version="[5.0.1,6.0.0)";resolution:=optional, 17 | org.eclipse.jdt.core;bundle-version="3.11.2", 18 | org.eclipse.jface.text;bundle-version="3.10.0", 19 | org.eclipse.core.runtime;bundle-version="3.11.1", 20 | org.eclipse.core.resources;bundle-version="3.10.1" 21 | Import-Package: org.apache.log4j 22 | Bundle-RequiredExecutionEnvironment: JavaSE-1.8 23 | Export-Package: de.beyondjava.xtext.jsf, 24 | de.beyondjava.xtext.jsf.services, 25 | de.beyondjava.xtext.jsf.componentLanguage, 26 | de.beyondjava.xtext.jsf.componentLanguage.impl, 27 | de.beyondjava.xtext.jsf.componentLanguage.util, 28 | de.beyondjava.xtext.jsf.serializer, 29 | de.beyondjava.xtext.jsf.parser.antlr, 30 | de.beyondjava.xtext.jsf.parser.antlr.internal, 31 | de.beyondjava.xtext.jsf.validation, 32 | de.beyondjava.xtext.jsf.scoping, 33 | de.beyondjava.xtext.jsf.generator, 34 | de.beyondjava.xtext.jsf.formatting 35 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/TaglibImporter.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileNotFoundException; 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | import java.util.Scanner; 9 | 10 | public class TaglibImporter { 11 | private static Map inheritedAttributes = new HashMap() { 12 | { 13 | put("rendered", null); 14 | put("value", null); 15 | put("converter", null); 16 | } 17 | }; 18 | 19 | private static Map defaultValues= new HashMap() { 20 | { 21 | put("backdrop", "true"); 22 | put("closeOnEscape", "true"); 23 | put("collapsible", "true"); 24 | } 25 | }; 26 | 27 | 28 | 29 | 30 | private static Map derivedFrom = new HashMap() { 31 | { 32 | put("alert", "UIComponentBase"); 33 | put("badge", "UIComponentBase"); 34 | put("button", "HtmlOutcomeTargetButton"); 35 | put("buttonGroup", "net.bootsfaces.component.GenContainerDiv"); 36 | put("buttonToolbar", "net.bootsfaces.component.GenContainerDiv"); 37 | put("commandButton", "HtmlCommandButton"); 38 | put("datePicker", "HtmlInputText"); 39 | put("dropButton", "UIComponentBase"); 40 | put("dropMenu", "UIComponentBase"); 41 | put("fetchBeanInfos", "UIComponentBase"); 42 | put("icon", "UIComponentBase"); 43 | put("iconAwesome", "UIComponentBase"); 44 | put("inputSecret", "net.bootsfaces.component.InputText"); 45 | put("inputText", "HtmlInputText"); 46 | put("label", "UIComponentBase"); 47 | put("listLinks", "net.bootsfaces.component.LinksContainer"); 48 | put("messages", "UIMessages"); 49 | put("modal", "UIComponentBase"); 50 | put("navBar", "UIComponentBase"); 51 | put("navBarLinks", "net.bootsfaces.component.LinksContainer"); 52 | put("navCommandLink", "UICommand"); 53 | put("navLink", "HtmlOutcomeTargetLink"); 54 | put("poll", "HtmlCommandButton"); 55 | put("selectBooleanCheckbox", "HtmlInputText"); 56 | put("selectOneMenu", "HtmlInputText"); 57 | put("slider", "HtmlInputText"); 58 | put("tab", "UIOutput"); 59 | put("tabView", "UIOutput"); 60 | put("thumbnail", "UIComponentBase"); 61 | } 62 | }; 63 | 64 | private static Map hasChildren = new HashMap() { 65 | { 66 | put("alert", null); 67 | put("buttonGroup", null); 68 | put("buttonToolbar", null); 69 | put("column", null); 70 | put("container", null); 71 | put("dropButton", null); 72 | put("dropMenu", null); 73 | put("jumbotron", null); 74 | put("listLinks", null); 75 | put("modal", null); 76 | put("navBar", null); 77 | put("navBarLinks", null); 78 | put("panel", null); 79 | put("pillLinks", null); 80 | put("row", null); 81 | put("tabLinks", null); 82 | put("thumbnail", null); 83 | put("well", null); 84 | } 85 | }; 86 | 87 | private static Map inputWidgets = new HashMap() { 88 | { 89 | put("commandButton", null); 90 | put("datePicker", null); 91 | put("inputText", null); 92 | put("navCommandLink", null); 93 | put("panel", null); 94 | put("poll", null); 95 | put("selectBooleanCheckbox", null); 96 | put("slider", null); 97 | put("tab", null); 98 | put("tabView", null); 99 | } 100 | }; 101 | 102 | public static void main(String[] args) throws FileNotFoundException { 103 | String content = new Scanner(new File("taglib.xml")).useDelimiter("\\Z").next(); 104 | content = content.replaceAll("(?s)", ""); 105 | content = content.replace("", ""); 107 | String[] tags = content.split("|"); 108 | 109 | List dsl = new ArrayList<>(); 110 | for (String tag : tags) { 111 | if (tag.contains("")) { 112 | dsl.add(analyseTag(tag)); 113 | // break; 114 | } 115 | } 116 | Collections.sort(dsl); 117 | for (String s : dsl) 118 | System.out.println(s); 119 | } 120 | 121 | private static String analyseTag(String tag) { 122 | String result = ""; 123 | String tagname = ""; 124 | List attributeDSL = new ArrayList<>(); 125 | boolean firstAttribute = true; 126 | boolean hasTooltip = false; 127 | String parts[] = tag.split("||"); 128 | for (String part : parts) { 129 | part = part.trim(); 130 | if (part.contains("")) { 131 | int pos = part.indexOf(""); 132 | part = part.substring(pos); 133 | part = part.replace("", ""); 134 | tagname = part; 135 | result += ("widget " + tagname); 136 | } else if (part.startsWith("")) { 137 | String component = part.replace("", "").trim(); 138 | String cc[] = component.split("|"); 139 | for (String c : cc) { 140 | c = c.trim(); 141 | if (c.startsWith("")) { 142 | c = c.replace("", "").trim(); 143 | result += ("\r\n implemented_by " + c); 144 | } else if (c.startsWith("")) { 145 | c = c.replace("", "").trim(); 146 | result += "\r\n rendered_by " + c; 147 | } 148 | 149 | } 150 | } else if (part.startsWith("")) { 151 | firstAttribute = false; 152 | String attribute = part.replace("", "").trim(); 153 | String[] properties = attribute.split("|||"); 154 | String name = ""; 155 | String required = ""; 156 | String type = ""; 157 | String description = ""; 158 | String inherited = ""; 159 | for (String property : properties) { 160 | property = property.trim(); 161 | if (property.startsWith("")) { 162 | name = property.replace("", ""); 163 | String[] nn = name.split("-"); 164 | name = nn[0]; 165 | for (int i = 1; i < nn.length; i++) { 166 | String n = nn[i]; 167 | name += n.substring(0, 1).toUpperCase() + n.substring(1); 168 | } 169 | if (name.startsWith("tooltip")) 170 | hasTooltip = true; 171 | if (inheritedAttributes.containsKey(name)) 172 | inherited = " inherited"; 173 | } 174 | if (property.startsWith("")) { 175 | description = name = property.replace("", ""); 176 | description = eliminateWhiteSpace(description); 177 | description = description.replace("\"", "\\\""); 178 | description = " \"" + description + "\""; 179 | } 180 | if (property.startsWith("")) { 181 | property = property.replace("", "").trim(); 182 | if ("true".equals(property)) { 183 | required = " mandatory"; 184 | } 185 | } 186 | if (property.startsWith("")) { 187 | property = property.replace("", "").trim(); 188 | if (!"java.lang.String".equals(property)) { 189 | type = property.replace("java.lang.", ""); 190 | } 191 | } 192 | } 193 | String defaultValue=""; 194 | if (defaultValues.containsKey(name)) { 195 | defaultValue = " default \"" + defaultValues.get(name) + "\""; 196 | } 197 | if (name.equals("tooltipDelay") || name.equals("tooltipDelayHide")|| name.equals("tooltipDelayShow")) { 198 | type="Integer"; 199 | } 200 | attributeDSL.add(" " + fixedLength(name, 20) 201 | + fixedLength(type + defaultValue + required + inherited, 50) + description); 202 | } 203 | 204 | } 205 | if (inputWidgets.containsKey(tagname)) { 206 | result += "\r\n processes_input"; 207 | } 208 | if (derivedFrom.containsKey(tagname)) { 209 | result += "\r\n extends " + derivedFrom.get(tagname); 210 | } 211 | if (hasChildren.containsKey(tagname)) { 212 | result += "\r\n has_children"; 213 | } 214 | if (hasTooltip) { 215 | result += "\r\n has_tooltip"; 216 | } 217 | result += "\r\n"; 218 | result += (" {"); 219 | if (!firstAttribute) 220 | result += "\r\n"; 221 | Collections.sort(attributeDSL); 222 | for (String a : attributeDSL) { 223 | result += a + "\r\n"; 224 | } 225 | result += "}\r\n"; 226 | result += "\r\n"; 227 | return result; 228 | } 229 | 230 | private static String eliminateWhiteSpace(String description) { 231 | String[] dd = description.split("\r\n"); 232 | String result = ""; 233 | for (String d : dd) { 234 | result += " " + d.trim(); 235 | } 236 | return result.trim(); 237 | } 238 | 239 | private static String fixedLength(String s, int length) { 240 | return (s.trim() + " ").substring(0, length); 241 | } 242 | 243 | } 244 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/build.properties: -------------------------------------------------------------------------------- 1 | source.. = src/,\ 2 | src-gen/,\ 3 | xtend-gen/ 4 | bin.includes = model/,\ 5 | META-INF/,\ 6 | .,\ 7 | plugin.xml 8 | additional.bundles = org.eclipse.xtext.xbase,\ 9 | org.eclipse.xtext.generator,\ 10 | org.apache.commons.logging,\ 11 | org.eclipse.emf.codegen.ecore,\ 12 | org.eclipse.emf.mwe.utils,\ 13 | org.eclipse.emf.mwe2.launch,\ 14 | org.eclipse.xtext.common.types,\ 15 | org.objectweb.asm -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/model/generated/ComponentLanguage.ecore: -------------------------------------------------------------------------------- 1 | 2 | 5 | 6 | 8 | 9 | 10 | 11 | 13 | 14 | 15 | 16 | 18 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 28 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/model/generated/ComponentLanguage.genmodel: -------------------------------------------------------------------------------- 1 | 2 | 8 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/plugin.xml_gen: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/src/TaglibImporter.java: -------------------------------------------------------------------------------- 1 | import java.io.File; 2 | import java.io.FileNotFoundException; 3 | import java.util.ArrayList; 4 | import java.util.Collections; 5 | import java.util.HashMap; 6 | import java.util.List; 7 | import java.util.Map; 8 | import java.util.Scanner; 9 | 10 | public class TaglibImporter { 11 | private static Map inheritedAttributes = new HashMap() { 12 | { 13 | put("rendered", null); 14 | put("value", null); 15 | put("converter", null); 16 | } 17 | }; 18 | 19 | private static Map defaultValues= new HashMap() { 20 | { 21 | put("backdrop", "true"); 22 | put("closeOnEscape", "true"); 23 | put("collapsible", "true"); 24 | } 25 | }; 26 | 27 | 28 | 29 | 30 | private static Map derivedFrom = new HashMap() { 31 | { 32 | put("alert", "UIComponentBase"); 33 | put("badge", "UIComponentBase"); 34 | put("button", "HtmlOutcomeTargetButton"); 35 | put("buttonGroup", "net.bootsfaces.component.GenContainerDiv"); 36 | put("buttonToolbar", "net.bootsfaces.component.GenContainerDiv"); 37 | put("commandButton", "HtmlCommandButton"); 38 | put("datePicker", "HtmlInputText"); 39 | put("dropButton", "UIComponentBase"); 40 | put("dropMenu", "UIComponentBase"); 41 | put("fetchBeanInfos", "UIComponentBase"); 42 | put("icon", "UIComponentBase"); 43 | put("iconAwesome", "UIComponentBase"); 44 | put("inputSecret", "net.bootsfaces.component.InputText"); 45 | put("inputText", "HtmlInputText"); 46 | put("label", "UIComponentBase"); 47 | put("listLinks", "net.bootsfaces.component.LinksContainer"); 48 | put("messages", "UIMessages"); 49 | put("modal", "UIComponentBase"); 50 | put("navBar", "UIComponentBase"); 51 | put("navBarLinks", "net.bootsfaces.component.LinksContainer"); 52 | put("navCommandLink", "UICommand"); 53 | put("navLink", "HtmlOutcomeTargetLink"); 54 | put("poll", "HtmlCommandButton"); 55 | put("selectBooleanCheckbox", "HtmlInputText"); 56 | put("selectOneMenu", "HtmlInputText"); 57 | put("slider", "HtmlInputText"); 58 | put("tab", "UIOutput"); 59 | put("tabView", "UIOutput"); 60 | put("thumbnail", "UIComponentBase"); 61 | } 62 | }; 63 | 64 | private static Map hasChildren = new HashMap() { 65 | { 66 | put("alert", null); 67 | put("buttonGroup", null); 68 | put("buttonToolbar", null); 69 | put("column", null); 70 | put("container", null); 71 | put("dropButton", null); 72 | put("dropMenu", null); 73 | put("jumbotron", null); 74 | put("listLinks", null); 75 | put("modal", null); 76 | put("navBar", null); 77 | put("navBarLinks", null); 78 | put("panel", null); 79 | put("pillLinks", null); 80 | put("row", null); 81 | put("tabLinks", null); 82 | put("thumbnail", null); 83 | put("well", null); 84 | } 85 | }; 86 | 87 | private static Map inputWidgets = new HashMap() { 88 | { 89 | put("commandButton", null); 90 | put("datePicker", null); 91 | put("inputText", null); 92 | put("navCommandLink", null); 93 | put("panel", null); 94 | put("poll", null); 95 | put("selectBooleanCheckbox", null); 96 | put("slider", null); 97 | put("tab", null); 98 | put("tabView", null); 99 | } 100 | }; 101 | 102 | public static void main(String[] args) throws FileNotFoundException { 103 | String content = new Scanner(new File("taglib.xml")).useDelimiter("\\Z").next(); 104 | content = content.replaceAll("(?s)", ""); 105 | content = content.replace("", ""); 107 | String[] tags = content.split("|"); 108 | 109 | List dsl = new ArrayList<>(); 110 | for (String tag : tags) { 111 | if (tag.contains("")) { 112 | dsl.add(analyseTag(tag)); 113 | // break; 114 | } 115 | } 116 | Collections.sort(dsl); 117 | for (String s : dsl) 118 | System.out.println(s); 119 | } 120 | 121 | private static String analyseTag(String tag) { 122 | String result = ""; 123 | String tagname = ""; 124 | List attributeDSL = new ArrayList<>(); 125 | boolean firstAttribute = true; 126 | boolean hasTooltip = false; 127 | String parts[] = tag.split("||"); 128 | for (String part : parts) { 129 | part = part.trim(); 130 | if (part.contains("")) { 131 | int pos = part.indexOf(""); 132 | part = part.substring(pos); 133 | part = part.replace("", ""); 134 | tagname = part; 135 | result += ("widget " + tagname); 136 | } else if (part.startsWith("")) { 137 | String component = part.replace("", "").trim(); 138 | String cc[] = component.split("|"); 139 | for (String c : cc) { 140 | c = c.trim(); 141 | if (c.startsWith("")) { 142 | c = c.replace("", "").trim(); 143 | result += ("\r\n implemented_by " + c); 144 | } else if (c.startsWith("")) { 145 | c = c.replace("", "").trim(); 146 | result += "\r\n rendered_by " + c; 147 | } 148 | 149 | } 150 | } else if (part.startsWith("")) { 151 | firstAttribute = false; 152 | String attribute = part.replace("", "").trim(); 153 | String[] properties = attribute.split("|||"); 154 | String name = ""; 155 | String required = ""; 156 | String type = ""; 157 | String description = ""; 158 | String inherited = ""; 159 | for (String property : properties) { 160 | property = property.trim(); 161 | if (property.startsWith("")) { 162 | name = property.replace("", ""); 163 | String[] nn = name.split("-"); 164 | name = nn[0]; 165 | for (int i = 1; i < nn.length; i++) { 166 | String n = nn[i]; 167 | name += n.substring(0, 1).toUpperCase() + n.substring(1); 168 | } 169 | if (name.startsWith("tooltip")) 170 | hasTooltip = true; 171 | if (inheritedAttributes.containsKey(name)) 172 | inherited = " inherited"; 173 | } 174 | if (property.startsWith("")) { 175 | description = name = property.replace("", ""); 176 | description = eliminateWhiteSpace(description); 177 | description = description.replace("\"", "\\\""); 178 | description = " \"" + description + "\""; 179 | } 180 | if (property.startsWith("")) { 181 | property = property.replace("", "").trim(); 182 | if ("true".equals(property)) { 183 | required = " mandatory"; 184 | } 185 | } 186 | if (property.startsWith("")) { 187 | property = property.replace("", "").trim(); 188 | if (!"java.lang.String".equals(property)) { 189 | type = property.replace("java.lang.", ""); 190 | } 191 | } 192 | } 193 | String defaultValue=""; 194 | if (defaultValues.containsKey(name)) { 195 | defaultValue = " default \"" + defaultValues.get(name) + "\""; 196 | } 197 | if (name.equals("tooltipDelay") || name.equals("tooltipDelayHide")|| name.equals("tooltipDelayShow")) { 198 | type="Integer"; 199 | } 200 | attributeDSL.add(" " + fixedLength(name, 20) 201 | + fixedLength(type + defaultValue + required + inherited, 50) + description); 202 | } 203 | 204 | } 205 | if (inputWidgets.containsKey(tagname)) { 206 | result += "\r\n processes_input"; 207 | } 208 | if (derivedFrom.containsKey(tagname)) { 209 | result += "\r\n extends " + derivedFrom.get(tagname); 210 | } 211 | if (hasChildren.containsKey(tagname)) { 212 | result += "\r\n has_children"; 213 | } 214 | if (hasTooltip) { 215 | result += "\r\n has_tooltip"; 216 | } 217 | result += "\r\n"; 218 | result += (" {"); 219 | if (!firstAttribute) 220 | result += "\r\n"; 221 | Collections.sort(attributeDSL); 222 | for (String a : attributeDSL) { 223 | result += a + "\r\n"; 224 | } 225 | result += "}\r\n"; 226 | result += "\r\n"; 227 | return result; 228 | } 229 | 230 | private static String eliminateWhiteSpace(String description) { 231 | String[] dd = description.split("\r\n"); 232 | String result = ""; 233 | for (String d : dd) { 234 | result += " " + d.trim(); 235 | } 236 | return result.trim(); 237 | } 238 | 239 | private static String fixedLength(String s, int length) { 240 | return (s.trim() + " ").substring(0, length); 241 | } 242 | 243 | } 244 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/src/de/beyondjava/xtext/jsf/ComponentLanguage.xtext: -------------------------------------------------------------------------------- 1 | grammar de.beyondjava.xtext.jsf.ComponentLanguage with org.eclipse.xtext.common.Terminals 2 | 3 | generate componentLanguage "http://www.beyondjava.de/xtext/jsf/ComponentLanguage" 4 | 5 | Domainmodel: 6 | (elements+=AttributeList)* 7 | (elements+=Component)*; 8 | 9 | AttributeList: 10 | 'attribute_list' name=ID 11 | '{' 12 | (attributes+=Attribute)* 13 | '}'; 14 | 15 | 16 | Component: 17 | 'widget' name=ID 18 | ('implemented_by ' implementedBy+=QualifiedName)? 19 | ('rendered_by ' renderedBy+=QualifiedName)? 20 | (processesInput='processes_input')? 21 | ('extends' extends=QualifiedName)? 22 | (hasChildren='has_children')? 23 | (hasTooltip='has_tooltip')? 24 | (isReponsive='is_responsive')? 25 | ('description' description=STRING)? 26 | '{' 27 | (attributes+=Attribute)* 28 | ('+' attributeLists += ID)* 29 | '}'; 30 | 31 | Attribute: 32 | name=CSSID (type=Attributetype)? ('default' defaultValue=STRING)? (required='mandatory')? (inherited='inherited')? (desc=STRING)?; 33 | 34 | QualifiedName: 35 | ID ('.' ID)*; 36 | 37 | CSSID: 38 | ID ('-' ID)*; 39 | 40 | Attributetype: 41 | 'String' 42 | | 'Boolean' 43 | | 'Integer' 44 | | 'Float' 45 | | 'javax.el.MethodExpression' 46 | | 'javax.faces.event.ActionListener' 47 | | 'javax.faces.component.UIComponent' 48 | | 'javax.el.ValueExpression' 49 | | 'javax.faces.event.ValueChangeListener' 50 | | 'java.faces.convert.Converter' 51 | | 'java.util.List' 52 | | 'javax.faces.validator.Validator' 53 | | 'TreeNodeEventListener' 54 | | 'Map<' QualifiedName ',' QualifiedName '>' 55 | | 'Drawing' 56 | | 'java.lang.Object' 57 | | 'ScrollSpyEventListener' 58 | | 'Node'; 59 | 60 | 61 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/src/de/beyondjava/xtext/jsf/ComponentLanguageRuntimeModule.java: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 3 | */ 4 | package de.beyondjava.xtext.jsf; 5 | 6 | /** 7 | * Use this class to register components to be used at runtime / without the Equinox extension registry. 8 | */ 9 | public class ComponentLanguageRuntimeModule extends de.beyondjava.xtext.jsf.AbstractComponentLanguageRuntimeModule { 10 | 11 | } 12 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/src/de/beyondjava/xtext/jsf/ComponentLanguageStandaloneSetup.java: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 3 | */ 4 | package de.beyondjava.xtext.jsf; 5 | 6 | /** 7 | * Initialization support for running Xtext languages 8 | * without equinox extension registry 9 | */ 10 | public class ComponentLanguageStandaloneSetup extends ComponentLanguageStandaloneSetupGenerated{ 11 | 12 | public static void doSetup() { 13 | new ComponentLanguageStandaloneSetup().createInjectorAndDoEMFRegistration(); 14 | } 15 | } 16 | 17 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/src/de/beyondjava/xtext/jsf/GenerateComponentLanguage.mwe2: -------------------------------------------------------------------------------- 1 | module de.beyondjava.xtext.jsf.GenerateComponentLanguage 2 | 3 | import org.eclipse.emf.mwe.utils.* 4 | import org.eclipse.xtext.generator.* 5 | import org.eclipse.xtext.ui.generator.* 6 | 7 | var grammarURI = "classpath:/de/beyondjava/xtext/jsf/ComponentLanguage.xtext" 8 | var fileExtensions = "jsfdsl" 9 | var projectName = "de.beyondjava.xtext.jsf" 10 | var runtimeProject = "../${projectName}" 11 | var generateXtendStub = true 12 | var encoding = "UTF-8" 13 | 14 | Workflow { 15 | bean = StandaloneSetup { 16 | scanClassPath = true 17 | platformUri = "${runtimeProject}/.." 18 | // The following two lines can be removed, if Xbase is not used. 19 | registerGeneratedEPackage = "org.eclipse.xtext.xbase.XbasePackage" 20 | registerGenModelFile = "platform:/resource/org.eclipse.xtext.xbase/model/Xbase.genmodel" 21 | } 22 | 23 | component = DirectoryCleaner { 24 | directory = "${runtimeProject}/src-gen" 25 | } 26 | 27 | component = DirectoryCleaner { 28 | directory = "${runtimeProject}/model/generated" 29 | } 30 | 31 | component = DirectoryCleaner { 32 | directory = "${runtimeProject}.ui/src-gen" 33 | } 34 | 35 | component = DirectoryCleaner { 36 | directory = "${runtimeProject}.tests/src-gen" 37 | } 38 | 39 | component = Generator { 40 | pathRtProject = runtimeProject 41 | pathUiProject = "${runtimeProject}.ui" 42 | pathTestProject = "${runtimeProject}.tests" 43 | projectNameRt = projectName 44 | projectNameUi = "${projectName}.ui" 45 | encoding = encoding 46 | language = auto-inject { 47 | uri = grammarURI 48 | 49 | // Java API to access grammar elements (required by several other fragments) 50 | fragment = grammarAccess.GrammarAccessFragment auto-inject {} 51 | 52 | // generates Java API for the generated EPackages 53 | fragment = ecore.EMFGeneratorFragment auto-inject {} 54 | 55 | // the old serialization component 56 | // fragment = parseTreeConstructor.ParseTreeConstructorFragment auto-inject {} 57 | 58 | // serializer 2.0 59 | fragment = serializer.SerializerFragment auto-inject { 60 | generateStub = false 61 | } 62 | 63 | // a custom ResourceFactory for use with EMF 64 | fragment = resourceFactory.ResourceFactoryFragment auto-inject {} 65 | 66 | // The antlr parser generator fragment. 67 | fragment = parser.antlr.XtextAntlrGeneratorFragment auto-inject { 68 | // options = { 69 | // backtrack = true 70 | // } 71 | } 72 | 73 | // Xtend-based API for validation 74 | fragment = validation.ValidatorFragment auto-inject { 75 | // composedCheck = "org.eclipse.xtext.validation.ImportUriValidator" 76 | // composedCheck = "org.eclipse.xtext.validation.NamesAreUniqueValidator" 77 | } 78 | 79 | // old scoping and exporting API 80 | // fragment = scoping.ImportURIScopingFragment auto-inject {} 81 | // fragment = exporting.SimpleNamesFragment auto-inject {} 82 | 83 | // scoping and exporting API 84 | fragment = scoping.ImportNamespacesScopingFragment auto-inject {} 85 | fragment = exporting.QualifiedNamesFragment auto-inject {} 86 | fragment = builder.BuilderIntegrationFragment auto-inject {} 87 | 88 | // generator API 89 | fragment = generator.GeneratorFragment auto-inject {} 90 | 91 | // formatter API 92 | fragment = formatting.FormatterFragment auto-inject {} 93 | 94 | // labeling API 95 | fragment = labeling.LabelProviderFragment auto-inject {} 96 | 97 | // outline API 98 | fragment = outline.OutlineTreeProviderFragment auto-inject {} 99 | fragment = outline.QuickOutlineFragment auto-inject {} 100 | 101 | // quickfix API 102 | fragment = quickfix.QuickfixProviderFragment auto-inject {} 103 | 104 | // content assist API 105 | fragment = contentAssist.ContentAssistFragment auto-inject {} 106 | 107 | // generates a more lightweight Antlr parser and lexer tailored for content assist 108 | fragment = parser.antlr.XtextAntlrUiGeneratorFragment auto-inject {} 109 | 110 | // generates junit test support classes into Generator#pathTestProject 111 | fragment = junit.Junit4Fragment auto-inject {} 112 | 113 | // rename refactoring 114 | fragment = refactoring.RefactorElementNameFragment auto-inject {} 115 | 116 | // provides the necessary bindings for java types integration 117 | fragment = types.TypesGeneratorFragment auto-inject {} 118 | 119 | // generates the required bindings only if the grammar inherits from Xbase 120 | fragment = xbase.XbaseGeneratorFragment auto-inject {} 121 | 122 | // generates the required bindings only if the grammar inherits from Xtype 123 | fragment = xbase.XtypeGeneratorFragment auto-inject {} 124 | 125 | // provides a preference page for template proposals 126 | fragment = templates.CodetemplatesGeneratorFragment auto-inject {} 127 | 128 | // provides a compare view 129 | fragment = compare.CompareFragment auto-inject {} 130 | } 131 | } 132 | } 133 | 134 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/src/de/beyondjava/xtext/jsf/formatting/ComponentLanguageFormatter.xtend: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 3 | */ 4 | package de.beyondjava.xtext.jsf.formatting 5 | 6 | import org.eclipse.xtext.formatting.impl.AbstractDeclarativeFormatter 7 | import org.eclipse.xtext.formatting.impl.FormattingConfig 8 | // import com.google.inject.Inject; 9 | // import de.beyondjava.xtext.jsf.services.ComponentLanguageGrammarAccess 10 | 11 | /** 12 | * This class contains custom formatting declarations. 13 | * 14 | * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#formatting 15 | * on how and when to use it. 16 | * 17 | * Also see {@link org.eclipse.xtext.xtext.XtextFormattingTokenSerializer} as an example 18 | */ 19 | class ComponentLanguageFormatter extends AbstractDeclarativeFormatter { 20 | 21 | // @Inject extension ComponentLanguageGrammarAccess 22 | 23 | override protected void configureFormatting(FormattingConfig c) { 24 | // It's usually a good idea to activate the following three statements. 25 | // They will add and preserve newlines around comments 26 | // c.setLinewrap(0, 1, 2).before(SL_COMMENTRule) 27 | // c.setLinewrap(0, 1, 2).before(ML_COMMENTRule) 28 | // c.setLinewrap(0, 1, 1).after(ML_COMMENTRule) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/src/de/beyondjava/xtext/jsf/formatting/JavaFormatter.java: -------------------------------------------------------------------------------- 1 | package de.beyondjava.xtext.jsf.formatting; 2 | 3 | import java.util.Map; 4 | 5 | import org.eclipse.core.resources.IProject; 6 | import org.eclipse.jdt.core.IJavaProject; 7 | import org.eclipse.jdt.core.JavaCore; 8 | import org.eclipse.jdt.core.ToolFactory; 9 | import org.eclipse.jdt.core.formatter.CodeFormatter; 10 | import org.eclipse.jface.text.Document; 11 | import org.eclipse.jface.text.IDocument; 12 | import org.eclipse.text.edits.TextEdit; 13 | 14 | public class JavaFormatter { 15 | 16 | public static String format(String sourcecode, IProject currentProject) { 17 | Object codeFormatter = createCodeFormatter(currentProject); 18 | String formattedSourceCode = 19 | formatCode(sourcecode, codeFormatter); 20 | return formattedSourceCode; 21 | } 22 | 23 | private static Object createCodeFormatter(IProject project) { 24 | IJavaProject javaProject = JavaCore.create(project); 25 | Map options = javaProject.getOptions(true); 26 | return ToolFactory.createCodeFormatter(options); 27 | } 28 | 29 | private static String formatCode(String contents, Object codeFormatter) { 30 | if (codeFormatter instanceof CodeFormatter) { 31 | IDocument doc = new Document(contents); 32 | TextEdit edit = ((CodeFormatter) codeFormatter).format(CodeFormatter.K_COMPILATION_UNIT, doc.get(), 0, 33 | doc.get().length(), 0, null); 34 | if (edit != null) { 35 | try { 36 | edit.apply(doc); 37 | contents = doc.get(); 38 | } catch (Exception e) { 39 | System.out.println(e); 40 | } 41 | } 42 | } 43 | return contents; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/src/de/beyondjava/xtext/jsf/generator/AttributesDocumentationGenerator.xtend: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by XItext 3 | */ 4 | package de.beyondjava.xtext.jsf.generator 5 | 6 | import de.beyondjava.xtext.jsf.componentLanguage.Attribute 7 | import de.beyondjava.xtext.jsf.componentLanguage.AttributeList 8 | import de.beyondjava.xtext.jsf.componentLanguage.Component 9 | import java.io.File 10 | import java.io.FileWriter 11 | import java.net.URI 12 | import java.util.ArrayList 13 | import java.util.Collections 14 | import java.util.Comparator 15 | import java.util.HashMap 16 | import java.util.Map 17 | import org.eclipse.core.runtime.FileLocator 18 | import org.eclipse.core.runtime.URIUtil 19 | import org.eclipse.emf.ecore.resource.Resource 20 | import org.eclipse.xtext.generator.IFileSystemAccess 21 | import org.eclipse.xtext.generator.IFileSystemAccessExtension2 22 | import org.eclipse.xtext.generator.IGenerator 23 | import org.eclipse.emf.common.util.EList 24 | 25 | /** 26 | * Generates code from your model files on save. 27 | * 28 | * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation 29 | */ 30 | class AttributesDocumentationGenerator implements IGenerator { 31 | 32 | override void doGenerate(Resource resource, IFileSystemAccess fsa) { 33 | var attributeLists = collectAttributeLists(resource) 34 | for (e : resource.allContents.toIterable.filter(Component)) { 35 | fsa.generateFile("net/bootsfaces/component/" + e.name.toFirstLower + "/" + e.name.toFirstUpper + 36 | "Attributes.xhtml", e.compile(attributeLists)) 37 | var webProject = fsa.findWebProjectFolder 38 | if (null != webProject) { 39 | var targetFileAsString = e.name.findDocumentationFolder(webProject) 40 | if (null != targetFileAsString) { 41 | var targetFile = new File(targetFileAsString.toString) 42 | targetFile.delete(); 43 | val writer = new FileWriter(targetFile) 44 | writer.append(e.compile(attributeLists).toString.replace("\t", " ")); 45 | writer.close(); 46 | } 47 | } 48 | } 49 | } 50 | 51 | def collectAttributeLists(Resource resource) { 52 | var attributeLists = new HashMap() 53 | for (e : resource.allContents.toIterable.filter(AttributeList)) { 54 | attributeLists.put(e.name, e.attributes) 55 | } 56 | return attributeLists 57 | } 58 | 59 | def allAttributes(Component widget, Map> lists) { 60 | var attributes = new ArrayList(); 61 | for (e : widget.attributes) { 62 | attributes.add(e); 63 | } 64 | for (e : widget.attributeLists) { 65 | var list = lists.get(e) 66 | for (a:list) { 67 | attributes.add(a) 68 | } 69 | } 70 | Collections.sort(attributes, new Comparator(){ 71 | override compare(Attribute o1, Attribute o2) { 72 | return o1.name.compareTo(o2.name) 73 | } 74 | 75 | }) 76 | return attributes; 77 | } 78 | 79 | def findWebProjectFolder(IFileSystemAccess fsa) { 80 | 81 | var messages = "Looking for web folder\n"; 82 | var uri = (fsa as IFileSystemAccessExtension2).getURI("../../BootsFacesWeb/src/main/webapp"); 83 | var eclipseURL = URIUtil.toURL(new URI(uri.toString())); 84 | var file = FileLocator.toFileURL(eclipseURL); 85 | var pathname = file.toString().replace("file:", ""); 86 | messages += "web folder = " + pathname + "\n"; 87 | if (new File(pathname).exists()) { 88 | messages += "Exists!\n"; 89 | fsa.generateFile("messages", messages) 90 | return pathname; 91 | } 92 | messages += "Does not exist!"; 93 | fsa.generateFile("messages.txt", messages) 94 | return null; 95 | } 96 | 97 | def findDocumentationFolder(String widget, String pathname) { 98 | 99 | var docFolder = new File(pathname); 100 | if (docFolder.exists()) { 101 | var targetFolder = findDocumentationFolder(docFolder, widget); 102 | 103 | if (null != targetFolder) { 104 | return targetFolder; 105 | } 106 | } 107 | return null; 108 | } 109 | 110 | def findDocumentationFolder(File docFolder, String widget) { 111 | var files = docFolder.listFiles(); 112 | for (File f : files) { 113 | if (f.isDirectory) { 114 | var target = findDocumentationFolder(f, widget); 115 | if (null != target) { 116 | return target; 117 | } 118 | } else { 119 | var filename = f.name; 120 | var targetFileName = widget.toFirstUpper + "Attributes.xhtml"; 121 | if (targetFileName.equalsIgnoreCase(filename)) { 122 | return f.absolutePath; 123 | } 124 | 125 | } 126 | } 127 | return null; 128 | } 129 | 130 | def compile(Component widget, HashMap> attributeLists) ''' 131 | 132 | 133 | 139 | 140 | 141 | 142 | Attributes of <b:«widget.name.toFirstLower» > 143 | 144 |
145 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | «FOR f : widget.allAttributes(attributeLists)» 156 | «f.generateAttribute» 157 | «ENDFOR» 158 | 159 |
AttributeDefault valueDescription
160 |
161 |
162 |
163 | ''' 164 | 165 | def generateAttribute( 166 | Attribute a) ''' 167 | 168 | «a.name»«a.name.alternativeWriting» 169 | «IF a.defaultValue!=null» «a.defaultValue» «ELSEIF a.type=="Boolean"»false«ELSEIF a.type=="Integer"»0 «ELSE»(none)«ENDIF» 170 | «IF a.desc != null»«a.desc.replace("\\\"", "\"").replace("<", "<").replace(">", ">")»«ENDIF» 171 | 172 | ''' 173 | 174 | def alternativeWriting(String s) { 175 | if (s.contains('-')) { 176 | return "
" + toCamelCase(s) + " (alternative writing)" 177 | } 178 | return "" 179 | } 180 | 181 | def toCamelCase(String s) { 182 | var pos = 0 as int 183 | var cc = s 184 | while (cc.contains('-')) { 185 | pos = cc.indexOf('-'); 186 | cc = cc.substring(0, pos) + cc.substring(pos + 1, pos + 2).toUpperCase() + cc.substring(pos + 2); 187 | } 188 | return cc 189 | } 190 | 191 | } 192 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/src/de/beyondjava/xtext/jsf/generator/BeanInfoGenerator.xtend: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 3 | */ 4 | package de.beyondjava.xtext.jsf.generator 5 | 6 | import de.beyondjava.xtext.jsf.componentLanguage.Component 7 | import org.eclipse.emf.ecore.resource.Resource 8 | import org.eclipse.xtext.generator.IFileSystemAccess 9 | import org.eclipse.xtext.generator.IGenerator 10 | 11 | /** 12 | * Generates code from your model files on save. 13 | * 14 | * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation 15 | */ 16 | class BeanInfoGenerator implements IGenerator { 17 | 18 | override void doGenerate(Resource resource, IFileSystemAccess fsa) { 19 | for (e : resource.allContents.toIterable.filter(Component)) { 20 | fsa.generateFile("net/bootsfaces/component/"+e.name.toFirstLower + "/" +e.name.toFirstUpper + "BeanInfo.java", e.compile) 21 | } 22 | } 23 | 24 | def compile(Component e) ''' 25 | «e.generateCopyrightHeader» 26 | package net.bootsfaces.component.«e.name.toFirstLower»; 27 | 28 | import net.bootsfaces.beans.BsfBeanInfo; 29 | 30 | /** 31 | * BeanInfo class to provide mapping 32 | * of snake-case attributes to camelCase ones 33 | * 34 | * @author Dario D'Urzo 35 | */ 36 | public class «e.name.toFirstUpper»BeanInfo extends «parentClass(e)» { 37 | 38 | /** 39 | * Get the reference decorated class 40 | */ 41 | @Override 42 | public Class getDecoratedClass() { 43 | return «e.name.toFirstUpper».class; 44 | } 45 | } 46 | 47 | ''' 48 | 49 | def parentClass(Component component) { 50 | return "BsfBeanInfo"; 51 | } 52 | 53 | def generateCopyrightHeader(Component e) ''' 54 | /** 55 | * Copyright 2014 - 17 by Riccardo Massera (TheCoder4.Eu) and Stephan Rauh (http://www.beyondjava.net). 56 | * 57 | * This file is part of BootsFaces. 58 | * 59 | * Licensed under the Apache License, Version 2.0 (the "License"); 60 | * you may not use this file except in compliance with the License. 61 | * You may obtain a copy of the License at 62 | * 63 | * http://www.apache.org/licenses/LICENSE-2.0 64 | * 65 | * Unless required by applicable law or agreed to in writing, software 66 | * distributed under the License is distributed on an "AS IS" BASIS, 67 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 68 | * See the License for the specific language governing permissions and 69 | * limitations under the License. 70 | */ 71 | ''' 72 | 73 | } 74 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/src/de/beyondjava/xtext/jsf/generator/ComponentCoreGenerator.xtend: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 3 | */ 4 | package de.beyondjava.xtext.jsf.generator 5 | 6 | import de.beyondjava.xtext.jsf.componentLanguage.Attribute 7 | import de.beyondjava.xtext.jsf.componentLanguage.AttributeList 8 | import de.beyondjava.xtext.jsf.componentLanguage.Component 9 | import de.beyondjava.xtext.jsf.formatting.JavaFormatter 10 | import java.util.ArrayList 11 | import java.util.Collections 12 | import java.util.Comparator 13 | import java.util.HashMap 14 | import java.util.List 15 | import java.util.Map 16 | import org.eclipse.core.resources.ResourcesPlugin 17 | import org.eclipse.core.runtime.Path 18 | import org.eclipse.emf.common.util.EList 19 | import org.eclipse.emf.ecore.resource.Resource 20 | import org.eclipse.xtext.generator.IFileSystemAccess 21 | import org.eclipse.xtext.generator.IGenerator 22 | 23 | /** 24 | * Generates code from your model files on save. 25 | * 26 | * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation 27 | */ 28 | class ComponentCoreGenerator implements IGenerator { 29 | 30 | def collectAttributeLists(Resource resource) { 31 | var attributeLists = new HashMap() 32 | for (e : resource.allContents.toIterable.filter(AttributeList)) { 33 | attributeLists.put(e.name, e.attributes) 34 | } 35 | return attributeLists 36 | } 37 | 38 | def allAttributes(Component widget, Map> lists) { 39 | var attributes = new ArrayList(); 40 | for (e : widget.attributes) { 41 | attributes.add(e); 42 | } 43 | for (e : widget.attributeLists) { 44 | var list = lists.get(e) 45 | for (a:list) { 46 | attributes.add(a) 47 | } 48 | } 49 | Collections.sort(attributes, new Comparator(){ 50 | override compare(Attribute o1, Attribute o2) { 51 | return o1.name.compareTo(o2.name) 52 | } 53 | 54 | }) 55 | return attributes; 56 | } 57 | 58 | override void doGenerate(Resource resource, IFileSystemAccess fsa) { 59 | var attributeLists = collectAttributeLists(resource) 60 | for (e : resource.allContents.toIterable.filter(Component)) { 61 | 62 | val platformString = resource.URI.toPlatformString(true); 63 | val myFile = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(platformString)); 64 | val project = myFile.getProject(); 65 | var generated = e.compile(attributeLists) 66 | var formatted = JavaFormatter.format(generated.toString, project); 67 | 68 | fsa.generateFile("net/bootsfaces/component/" + e.name.toFirstLower + "/" + e.name.toFirstUpper + 69 | "Core.java", formatted) 70 | } 71 | } 72 | 73 | def compile(Component e, HashMap> attributeLists) ''' 74 | «e.generateCopyrightHeader» 75 | package net.bootsfaces.component.«e.name.toFirstLower»; 76 | 77 | import javax.faces.component.*; 78 | «IF e.hasTooltip!=null» 79 | import net.bootsfaces.render.Tooltip; 80 | «ENDIF» 81 | import net.bootsfaces.utils.BsfUtils; 82 | 83 | 84 | /** This class holds the attributes of <b:«e.name» />. */ 85 | public abstract class «e.name.toFirstUpper»Core extends «parentClass(e)» «IF e.hasTooltip!=null» implements net.bootsfaces.render.IHasTooltip «ENDIF» { 86 | 87 | «e.generateProperties(attributeLists)» 88 | 89 | «FOR f : e.allAttributes(attributeLists)» 90 | «IF f.inherited==null» 91 | «f.generateAccessors» 92 | «ENDIF» 93 | «ENDFOR» 94 | } 95 | 96 | ''' 97 | 98 | def parentClass(Component component) { 99 | if (component.extends != null) { 100 | return component.extends; 101 | } 102 | if (component.processesInput != null) { 103 | return "UIInput"; 104 | } 105 | return "UIOutput"; 106 | } 107 | 108 | def generateAccessors( 109 | Attribute e) ''' 110 | 111 | /** 112 | * «if (e.desc!=null) e.desc.replace("<", "<").replace(">", ">")»

113 | * @return Returns the value of the attribute, or «e.getDefaultValueForDocumentation», if it hasn't been set by the JSF file. 114 | */ 115 | public «e.attributeType» «e.getter» { 116 | return «optionalTypeCast(e)» («realType(e.objectType)»)getStateHelper().eval(«e.name.propertyKey.validIdentifier»«e.defaultValueTerm»); 117 | } 118 | 119 | /** 120 | * «if (e.desc!=null) e.desc.replace("<", "<").replace(">", ">")»

121 | * Usually this method is called internally by the JSF engine. 122 | */ 123 | public void set«e.name.toCamelCase.toFirstUpper»(«e.attributeType» _«e.name.toCamelCase») { 124 | getStateHelper().put(«e.name.propertyKey.validIdentifier», _«e.name.toCamelCase»); 125 | } 126 | 127 | ''' 128 | 129 | def validIdentifier(String s) { 130 | if ("for".equals(s)) { 131 | return "_for"; 132 | } 133 | return s; 134 | } 135 | 136 | def getPropertyKey(String s) { 137 | if (s.propertyKeyValue.startsWith("\"")) { 138 | return s.propertyKeyValue; 139 | } else { 140 | return "PropertyKeys." + s.propertyKeyValue.validIdentifier; 141 | } 142 | 143 | } 144 | 145 | def getPropertyKeyValue(String s) { 146 | if (s == "static") { 147 | return "\"" + s + "\""; 148 | } else { 149 | return s.toCamelCase; 150 | } 151 | } 152 | 153 | def getDefaultValueTerm(Attribute a) { 154 | if (a.defaultValue != null && a.type == null) 155 | ', "' + a.defaultValue + '"' 156 | else if (a.defaultValue != null && a.type == "String") 157 | ', "' + a.defaultValue + '"' 158 | else if (a.defaultValue != null) 159 | ', ' + a.defaultValue 160 | else if ("Integer".equals(a.type)) 161 | ', 0' 162 | else if ("Float".equals(a.type)) 163 | ', 0.0d' 164 | else if("Boolean".equals(a.type)) ', false' else '' 165 | } 166 | 167 | def getDefaultValueForDocumentation(Attribute a) { 168 | if (a.defaultValue != null && a.type == null) 169 | '"' + a.defaultValue + '"' 170 | else if (a.defaultValue != null && a.type == "String") 171 | '"' + a.defaultValue.replace("<", "<").replace(">", ">") + '"' 172 | else if (a.defaultValue != null) 173 | a.defaultValue 174 | else if ("Integer".equals(a.type)) 175 | '0' 176 | else if ("Float".equals(a.type)) 177 | '0.0d' 178 | else if("Boolean".equals(a.type)) ', false' else 'null' 179 | } 180 | 181 | def optionalTypeCast(Attribute e) { 182 | if(e.objectType != e.attributeType) '(' + e.attributeType + ')' else '' 183 | } 184 | 185 | def realType(String e) { 186 | if("Float" == e) return "Double"; 187 | return e; 188 | } 189 | 190 | def getGetter(Attribute f) { 191 | if ("Boolean".equals(f.type)) { 192 | '''is«f.name.toCamelCase.toFirstUpper»()''' 193 | } else { 194 | '''get«f.name.toCamelCase.toFirstUpper»()''' 195 | } 196 | } 197 | 198 | def getObjectType(Attribute a) { 199 | if(null == a.type) "String" else a.type; 200 | } 201 | 202 | def getAttributeType(Attribute a) { 203 | if (null == a.type) 204 | "String" 205 | else if ("Boolean".equals(a.type)) 206 | "boolean" 207 | else if("Integer".equals(a.type)) "int" 208 | else if("Float".equals(a.type)) "double" else a.type; 209 | } 210 | 211 | def generateCopyrightHeader(Component e) ''' 212 | /** 213 | * Copyright 2014 - 17 by Riccardo Massera (TheCoder4.Eu) and Stephan Rauh (http://www.beyondjava.net). 214 | * 215 | * This file is part of BootsFaces. 216 | * 217 | * Licensed under the Apache License, Version 2.0 (the "License"); 218 | * you may not use this file except in compliance with the License. 219 | * You may obtain a copy of the License at 220 | * 221 | * http://www.apache.org/licenses/LICENSE-2.0 222 | * 223 | * Unless required by applicable law or agreed to in writing, software 224 | * distributed under the License is distributed on an "AS IS" BASIS, 225 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 226 | * See the License for the specific language governing permissions and 227 | * limitations under the License. 228 | */ 229 | 230 | ''' 231 | 232 | def List notInherited(List elements) { 233 | val result = newArrayList() 234 | elements.forEach [ a | 235 | if ((a.inherited == null) && (!a.name.propertyKeyValue.startsWith("\""))) { 236 | result.add(a) 237 | } 238 | ] 239 | result 240 | } 241 | 242 | def generateProperties(Component e, HashMap> attributeLists) ''' 243 | protected enum PropertyKeys { 244 | «FOR f : e.allAttributes(attributeLists).notInherited SEPARATOR ',' AFTER ';'» 245 | «" "»«f.name.propertyKeyValue.validIdentifier» 246 | «ENDFOR» 247 | 248 | String toString; 249 | 250 | PropertyKeys(String toString) { 251 | this.toString = toString; 252 | } 253 | 254 | PropertyKeys() {} 255 | 256 | public String toString() { 257 | return ((this.toString != null) ? this.toString : super.toString()); 258 | } 259 | } 260 | ''' 261 | 262 | def toCamelCase(String s) { 263 | var pos = 0 as int 264 | var cc = s 265 | while (cc.contains('-')) { 266 | pos = cc.indexOf('-'); 267 | cc = cc.substring(0, pos) + cc.substring(pos + 1, pos + 2).toUpperCase() + cc.substring(pos + 2); 268 | } 269 | return cc 270 | } 271 | 272 | } 273 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/src/de/beyondjava/xtext/jsf/generator/ComponentGenerator.xtend: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 3 | */ 4 | package de.beyondjava.xtext.jsf.generator 5 | 6 | import de.beyondjava.xtext.jsf.componentLanguage.Attribute 7 | import de.beyondjava.xtext.jsf.componentLanguage.AttributeList 8 | import de.beyondjava.xtext.jsf.componentLanguage.Component 9 | import de.beyondjava.xtext.jsf.formatting.JavaFormatter 10 | import java.util.ArrayList 11 | import java.util.Collections 12 | import java.util.Comparator 13 | import java.util.HashMap 14 | import java.util.List 15 | import java.util.Map 16 | import org.eclipse.core.resources.ResourcesPlugin 17 | import org.eclipse.core.runtime.Path 18 | import org.eclipse.emf.common.util.EList 19 | import org.eclipse.emf.ecore.resource.Resource 20 | import org.eclipse.xtext.generator.IFileSystemAccess 21 | import org.eclipse.xtext.generator.IGenerator 22 | 23 | /** 24 | * Generates code from your model files on save. 25 | * 26 | * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation 27 | */ 28 | class ComponentGenerator implements IGenerator { 29 | 30 | def collectAttributeLists(Resource resource) { 31 | var attributeLists = new HashMap() 32 | for (e : resource.allContents.toIterable.filter(AttributeList)) { 33 | attributeLists.put(e.name, e.attributes) 34 | } 35 | return attributeLists 36 | } 37 | 38 | def allAttributes(Component widget, Map> lists) { 39 | var attributes = new ArrayList(); 40 | for (e : widget.attributes) { 41 | attributes.add(e); 42 | } 43 | for (e : widget.attributeLists) { 44 | var list = lists.get(e) 45 | for (a : list) { 46 | attributes.add(a) 47 | } 48 | } 49 | Collections.sort(attributes, new Comparator() { 50 | override compare(Attribute o1, Attribute o2) { 51 | return o1.name.compareTo(o2.name) 52 | } 53 | 54 | }) 55 | return attributes; 56 | } 57 | 58 | override void doGenerate(Resource resource, IFileSystemAccess fsa) { 59 | var attributeLists = collectAttributeLists(resource) 60 | for (e : resource.allContents.toIterable.filter(Component)) { 61 | val platformString = resource.URI.toPlatformString(true); 62 | val myFile = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(platformString)); 63 | val project = myFile.getProject(); 64 | var autoUpdatable = false; 65 | for (a : e.attributes) { 66 | if (a.name == "auto-update") { 67 | autoUpdatable = true; 68 | } 69 | } 70 | var generated = e.compile(attributeLists, autoUpdatable) 71 | var formatted = JavaFormatter.format(generated.toString, project); 72 | fsa.generateFile( 73 | "net/bootsfaces/component/" + e.name.toFirstLower + "/" + e.name.toFirstUpper + ".java", 74 | formatted 75 | ) 76 | } 77 | } 78 | 79 | def compile(Component e, HashMap> attributeLists, boolean autoUpdatable) ''' 80 | «e.generateCopyrightHeader» 81 | package net.bootsfaces.component.«e.name.toFirstLower»; 82 | 83 | «IF autoUpdatable» 84 | import javax.faces.event.AbortProcessingException; 85 | import javax.faces.event.ComponentSystemEvent; 86 | import javax.faces.event.ListenerFor; 87 | import javax.faces.event.ListenersFor; 88 | import javax.faces.event.PostAddToViewEvent; 89 | «ENDIF» 90 | import javax.el.ValueExpression; 91 | import javax.faces.application.ResourceDependencies; 92 | import javax.faces.application.ResourceDependency; 93 | import javax.faces.component.*; 94 | «IF e.hasTooltip!=null» 95 | import net.bootsfaces.render.Tooltip; 96 | «ENDIF» 97 | «IF e.hasTooltip!=null» 98 | import net.bootsfaces.render.IResponsive; 99 | «ENDIF» 100 | import net.bootsfaces.utils.BsfUtils; 101 | 102 | 103 | /** This class holds the attributes of <b:«e.name» />. */ 104 | «IF autoUpdatable» 105 | @ListenersFor({ @ListenerFor(systemEventClass = PostAddToViewEvent.class) }) 106 | «ENDIF» 107 | @FacesComponent("net.bootsfaces.component.«e.name.toFirstLower».«e.name.toFirstUpper»") 108 | public class «e.name.toFirstUpper» extends «e.name.toFirstUpper»Core 109 | «IF e.hasTooltip !=null || e.isReponsive != null» implements «ENDIF» 110 | «IF e.hasTooltip !=null» net.bootsfaces.render.IHasTooltip «ENDIF» 111 | «IF e.isReponsive!=null», net.bootsfaces.render.IResponsive «ENDIF» { 112 | 113 | «e.generateMetadata(autoUpdatable)» 114 | } 115 | 116 | ''' 117 | 118 | def parentClass(Component component) { 119 | if (component.extends != null) { 120 | return component.extends; 121 | } 122 | if (component.processesInput != null) { 123 | return "UIInput"; 124 | } 125 | return "UIOutput"; 126 | } 127 | 128 | def validIdentifier(String s) { 129 | if ("for".equals(s)) { 130 | return "_for"; 131 | } 132 | return s; 133 | } 134 | 135 | def getPropertyKey(String s) { 136 | if (s.propertyKeyValue.startsWith("\"")) { 137 | return s.propertyKeyValue; 138 | } else { 139 | return "PropertyKeys." + s.propertyKeyValue.validIdentifier; 140 | } 141 | 142 | } 143 | 144 | def getPropertyKeyValue(String s) { 145 | if (s == "static") { 146 | return "\"" + s + "\""; 147 | } else { 148 | return s.toCamelCase; 149 | } 150 | } 151 | 152 | def getDefaultValueTerm(Attribute a) { 153 | if (a.defaultValue != null && a.type == null) 154 | ', "' + a.defaultValue + '"' 155 | else if (a.defaultValue != null && a.type == "String") 156 | ', "' + a.defaultValue.replace("<", "<").replace(">", ">") + '"' 157 | else if (a.defaultValue != null) 158 | ', ' + a.defaultValue 159 | else if ("Integer".equals(a.type)) 160 | ', 0' 161 | else if ("Float".equals(a.type)) 162 | ', 0.0d' 163 | else if("Boolean".equals(a.type)) ', false' else '' 164 | } 165 | 166 | def optionalTypeCast(Attribute e) { 167 | if(e.objectType != e.attributeType) '(' + e.attributeType + ')' else '' 168 | } 169 | 170 | def getGetter(Attribute f) { 171 | if ("Boolean".equals(f.type)) { 172 | '''is«f.name.toCamelCase.toFirstUpper»()''' 173 | } else { 174 | '''get«f.name.toCamelCase.toFirstUpper»()''' 175 | } 176 | } 177 | 178 | def getObjectType(Attribute a) { 179 | if(null == a.type) "String" else a.type; 180 | } 181 | 182 | def getAttributeType(Attribute a) { 183 | if (null == a.type) 184 | "String" 185 | else if ("Boolean".equals(a.type)) 186 | "boolean" 187 | else if("Integer".equals(a.type)) "int" 188 | else if("Float".equals(a.type)) "double" 189 | else a.type; 190 | } 191 | 192 | def generateMetadata( 193 | Component e, boolean autoUpdatable) ''' 194 | public static final String COMPONENT_TYPE = "net.bootsfaces.component.«e.name.toFirstLower».«e.name.toFirstUpper»"; 195 | 196 | public static final String COMPONENT_FAMILY = "net.bootsfaces.component"; 197 | 198 | public static final String DEFAULT_RENDERER = "net.bootsfaces.component.«e.name.toFirstLower».«e.name.toFirstUpper»"; 199 | 200 | public «e.name.toFirstUpper»() { 201 | «IF e.hasTooltip!=null» 202 | «" Tooltip.addResourceFiles();"» 203 | «ENDIF» 204 | AddResourcesListener.addThemedCSSResource("core.css"); 205 | AddResourcesListener.addThemedCSSResource("bsf.css"); 206 | setRendererType(DEFAULT_RENDERER); 207 | } 208 | 209 | public String getFamily() { 210 | return COMPONENT_FAMILY; 211 | } 212 | 213 | /** 214 | * Manage EL-expression for snake-case attributes 215 | */ 216 | public void setValueExpression(String name, ValueExpression binding) { 217 | name = BsfUtils.snakeCaseToCamelCase(name); 218 | super.setValueExpression(name, binding); 219 | } 220 | 221 | «IF autoUpdatable» 222 | public void processEvent(ComponentSystemEvent event) throws AbortProcessingException { 223 | if (isAutoUpdate()) { 224 | if (FacesContext.getCurrentInstance().isPostback()) { 225 | FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().add(getClientId()); 226 | } 227 | super.processEvent(event); 228 | } 229 | } 230 | «ENDIF» 231 | ''' 232 | 233 | def generateCopyrightHeader(Component e) ''' 234 | /** 235 | * Copyright 2014-17 by Riccardo Massera (TheCoder4.Eu) and Stephan Rauh (http://www.beyondjava.net). 236 | * 237 | * This file is part of BootsFaces. 238 | * 239 | * Licensed under the Apache License, Version 2.0 (the "License"); 240 | * you may not use this file except in compliance with the License. 241 | * You may obtain a copy of the License at 242 | * 243 | * http://www.apache.org/licenses/LICENSE-2.0 244 | * 245 | * Unless required by applicable law or agreed to in writing, software 246 | * distributed under the License is distributed on an "AS IS" BASIS, 247 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 248 | * See the License for the specific language governing permissions and 249 | * limitations under the License. 250 | */ 251 | 252 | ''' 253 | 254 | def List notInherited(List elements) { 255 | val result = newArrayList() 256 | elements.forEach [ a | 257 | if ((a.inherited == null) && (!a.name.propertyKeyValue.startsWith("\""))) { 258 | result.add(a) 259 | } 260 | ] 261 | result 262 | } 263 | 264 | def generateProperties(Component e, HashMap> attributeLists) ''' 265 | protected enum PropertyKeys { 266 | «FOR f : e.allAttributes(attributeLists).notInherited SEPARATOR ',' AFTER ';'» 267 | «" "»«f.name.propertyKeyValue.validIdentifier» 268 | «ENDFOR» 269 | 270 | String toString; 271 | 272 | PropertyKeys(String toString) { 273 | this.toString = toString; 274 | } 275 | 276 | PropertyKeys() {} 277 | 278 | public String toString() { 279 | return ((this.toString != null) ? this.toString : super.toString()); 280 | } 281 | } 282 | ''' 283 | 284 | def toCamelCase(String s) { 285 | var pos = 0 as int 286 | var cc = s 287 | while (cc.contains('-')) { 288 | pos = cc.indexOf('-'); 289 | cc = cc.substring(0, pos) + cc.substring(pos + 1, pos + 2).toUpperCase() + cc.substring(pos + 2); 290 | } 291 | return cc 292 | } 293 | 294 | } 295 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/src/de/beyondjava/xtext/jsf/generator/ComponentLanguageGenerator.xtend: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 3 | */ 4 | package de.beyondjava.xtext.jsf.generator 5 | 6 | import org.eclipse.emf.ecore.resource.Resource 7 | import org.eclipse.xtext.generator.IFileSystemAccess 8 | import org.eclipse.xtext.generator.IGenerator 9 | 10 | /** 11 | * Generates code from your model files on save. 12 | * 13 | * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation 14 | */ 15 | class ComponentLanguageGenerator implements IGenerator { 16 | 17 | override void doGenerate(Resource resource, IFileSystemAccess fsa) { 18 | var start = System.nanoTime; 19 | System.out.println("Starting to generate the JSF components."); 20 | new TaglibGenerator().doGenerate(resource, fsa); 21 | new PartialTaglibGenerator().doGenerate(resource, fsa); 22 | new ComponentCoreGenerator().doGenerate(resource, fsa); 23 | new ComponentGenerator().doGenerate(resource, fsa); 24 | new ComponentListGenerator().doGenerate(resource, fsa); 25 | new ComponentUpdateGenerator().doGenerate(resource, fsa); 26 | new RendererGenerator().doGenerate(resource, fsa); 27 | new DocumentationGenerator().doGenerate(resource, fsa); 28 | new AttributesDocumentationGenerator().doGenerate(resource, fsa); 29 | new BeanInfoGenerator().doGenerate(resource, fsa); 30 | // new UITestGenerator().doGenerate(resource, fsa); 31 | var time = System.nanoTime-start 32 | var ms=(time/1000) / 1000.0d 33 | System.out.println("Finished generating the JSF components. Time: " + ms + " ms"); 34 | } 35 | 36 | } -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/src/de/beyondjava/xtext/jsf/generator/ComponentListGenerator.xtend: -------------------------------------------------------------------------------- 1 | /* 2 | 3 | * generated by Xtext 4 | */ 5 | package de.beyondjava.xtext.jsf.generator 6 | 7 | import de.beyondjava.xtext.jsf.componentLanguage.Component 8 | import de.beyondjava.xtext.jsf.formatting.JavaFormatter 9 | import org.eclipse.core.resources.ResourcesPlugin 10 | import org.eclipse.core.runtime.Path 11 | import org.eclipse.emf.ecore.resource.Resource 12 | import org.eclipse.xtext.generator.IFileSystemAccess 13 | import org.eclipse.xtext.generator.IGenerator 14 | 15 | /** 16 | * Generates code from your model files on save. 17 | * 18 | * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation 19 | */ 20 | class ComponentListGenerator implements IGenerator { 21 | 22 | override void doGenerate(Resource resource, IFileSystemAccess fsa) { 23 | val platformString = resource.URI.toPlatformString(true); 24 | var content = resource.compile(); 25 | val myFile = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(platformString)); 26 | val project = myFile.getProject(); 27 | var formatted = JavaFormatter.format(content.toString, project); 28 | 29 | fsa.generateFile("../src/main/java/net/bootsfaces/component/ComponentsEnum.java", formatted); 30 | } 31 | 32 | def compile(Resource resource) ''' 33 | /** 34 | * Copyright 2014 - 17 by Riccardo Massera (TheCoder4.Eu) and Stephan Rauh (http://www.beyondjava.net). 35 | * 36 | * This file is part of BootsFaces. 37 | * 38 | * Licensed under the Apache License, Version 2.0 (the "License"); 39 | * you may not use this file except in compliance with the License. 40 | * You may obtain a copy of the License at 41 | * 42 | * http://www.apache.org/licenses/LICENSE-2.0 43 | * 44 | * Unless required by applicable law or agreed to in writing, software 45 | * distributed under the License is distributed on an "AS IS" BASIS, 46 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 47 | * See the License for the specific language governing permissions and 48 | * limitations under the License. 49 | */ 50 | package net.bootsfaces.component; 51 | 52 | public enum ComponentsEnum { 53 | «FOR e : resource.allContents.toIterable.filter(Component) SEPARATOR ","» 54 | «e.compile» 55 | «ENDFOR» 56 | ; 57 | private String tag; 58 | 59 | private String tagname; 60 | 61 | private String classname; 62 | 63 | ComponentsEnum(String tag, String tagname, String classname) { 64 | this.tag = tag; 65 | this.tagname = tagname; 66 | this.classname = classname; 67 | } 68 | 69 | public String tag() { 70 | return tag; 71 | } 72 | 73 | public String tagname() { 74 | return tagname; 75 | } 76 | 77 | public String classname() { 78 | return classname; 79 | } 80 | } 81 | ''' 82 | 83 | def compile(Component widget) { 84 | var lower = widget.name.toFirstLower; 85 | var name = lower; 86 | if (lower.equals("switch")) { 87 | name = "switchComponent"; 88 | } 89 | var classname = "net.bootsfaces.component." + lower + "." + widget.name.toFirstUpper; 90 | var line = name + "(\" 0) { 42 | var start = contentToMerge.substring(0, index) 43 | index = generatedContent.indexOf("protected enum PropertyKeys {") 44 | if (index > 0) { 45 | var end = generatedContent.substring(index); 46 | var oldindex = contentToMerge.indexOf("protected enum PropertyKeys {") 47 | var oldEnd = contentToMerge.substring(oldindex); 48 | if (!end.withoutWhiteSpace().equals(oldEnd.withoutWhiteSpace())) { 49 | var merged = start + end; 50 | val platformString = resource.URI.toPlatformString(true); 51 | val myFile = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(platformString)); 52 | val project = myFile.getProject(); 53 | merged = JavaFormatter.format(merged, project); 54 | 55 | if (target.toString().endsWith("Core.java")) { 56 | fsa.generateFile( 57 | "../src/main/java/net/bootsfaces/component/" + e.name.toFirstLower + "/" + 58 | e.name.toFirstUpper + "Core.java", merged) 59 | } else { 60 | fsa.generateFile( 61 | "../src/main/java/net/bootsfaces/component/" + e.name.toFirstLower + "/" + 62 | e.name.toFirstUpper + ".java", merged) 63 | } 64 | } 65 | } 66 | } 67 | } 68 | 69 | } 70 | } 71 | 72 | def insertAutoUpdateListener(Resource resource, IFileSystemAccess fsa) { 73 | for (e : resource.allContents.toIterable.filter(Component)) { 74 | var autoUpdatable = false; 75 | for (a : e.attributes) { 76 | if (a.name == "auto-update") { 77 | autoUpdatable = true; 78 | } 79 | } 80 | 81 | if (autoUpdatable) { 82 | 83 | var filename = "../src/main/java/net/bootsfaces/component/" + e.name.toFirstLower + "/" + 84 | e.name.toFirstUpper + ".java"; 85 | 86 | var target = findSourceFolderParentClass(fsa, e) 87 | System.out.println(target + " " + filename) 88 | if (null != target) { 89 | var modified = false; 90 | var contentToMerge = readFile(target) 91 | 92 | if (!contentToMerge.contains("@ListenerFor")) { 93 | var before = contentToMerge.indexOf("@FacesComponent"); 94 | contentToMerge = contentToMerge.substring(0, before) + 95 | "@ListenersFor({ @ListenerFor(systemEventClass = PostAddToViewEvent.class) })\n" + 96 | contentToMerge.substring(before); 97 | modified = true; 98 | } 99 | 100 | if (!contentToMerge.contains("import javax.faces.event.AbortProcessingException;")) { 101 | var insert = ''' 102 | import javax.faces.event.AbortProcessingException; 103 | import javax.faces.event.ComponentSystemEvent; 104 | import javax.faces.event.ListenerFor; 105 | import javax.faces.event.ListenersFor; 106 | import javax.faces.event.PostAddToViewEvent; 107 | 108 | ''' 109 | var before = contentToMerge.indexOf("import "); 110 | 111 | contentToMerge = contentToMerge.substring(0, before) + insert + 112 | contentToMerge.substring(before); 113 | modified = true; 114 | } 115 | 116 | if (!contentToMerge.contains("processEvent")) { 117 | var insert = ''' 118 | public void processEvent(ComponentSystemEvent event) throws AbortProcessingException { 119 | if (isAutoUpdate()) { 120 | if (FacesContext.getCurrentInstance().isPostback()) { 121 | FacesContext.getCurrentInstance().getPartialViewContext().getRenderIds().add(getClientId()); 122 | } 123 | super.processEvent(event); 124 | } 125 | } 126 | 127 | ''' 128 | var before = contentToMerge.indexOf(" protected enum PropertyKeys {"); 129 | if (before < 0) { 130 | before = contentToMerge.indexOf("public String getFamily() {"); 131 | } 132 | if (before < 0) { 133 | before = contentToMerge.lastIndexOf("}"); 134 | } 135 | contentToMerge = contentToMerge.substring(0, before) + " " + insert + 136 | contentToMerge.substring(before); 137 | modified = true; 138 | } 139 | if (modified) { 140 | fsa.generateFile(filename, contentToMerge) 141 | } 142 | 143 | } 144 | } 145 | } 146 | } 147 | 148 | def withoutWhiteSpace(String s) { 149 | var r = s.replace(" ", ""); 150 | r = r.replace("\t", ""); 151 | r = r.replace("\n", ""); 152 | r = r.replace("\r", ""); 153 | r = r.replace("*", ""); // ignore changes of Javadoc formatting 154 | return r; 155 | } 156 | 157 | def findGeneratedSourceFolder(IFileSystemAccess fsa, Component e) { 158 | var uri = (fsa as IFileSystemAccessExtension2).getURI( 159 | "net/bootsfaces/component/" + e.name.toFirstLower + "/" + e.name.toFirstUpper + "Core.java"); 160 | var eclipseURL = URIUtil.toURL(new URI(uri.toString())); 161 | var file = FileLocator.toFileURL(eclipseURL); 162 | var pathname = file.toString().replace("file:", ""); 163 | if (new File(pathname).exists()) { 164 | return pathname; 165 | } 166 | return null; 167 | } 168 | 169 | def findSourceFolderParentClass(IFileSystemAccess fsa, Component e) { 170 | var uri = (fsa as IFileSystemAccessExtension2).getURI( 171 | "../src/main/java/net/bootsfaces/component/" + e.name.toFirstLower + "/" + e.name.toFirstUpper + ".java"); 172 | var eclipseURL = URIUtil.toURL(new URI(uri.toString())); 173 | var file = FileLocator.toFileURL(eclipseURL); 174 | var pathname = file.toString().replace("file:", ""); 175 | if (new File(pathname).exists()) { 176 | return pathname; 177 | } 178 | 179 | return null; 180 | } 181 | 182 | def findSourceFolder(IFileSystemAccess fsa, Component e) { 183 | var uri = (fsa as IFileSystemAccessExtension2).getURI( 184 | "../src/main/java/net/bootsfaces/component/" + e.name.toFirstLower + "/" + e.name.toFirstUpper + 185 | "Core.java"); 186 | var eclipseURL = URIUtil.toURL(new URI(uri.toString())); 187 | var file = FileLocator.toFileURL(eclipseURL); 188 | var pathname = file.toString().replace("file:", ""); 189 | if (new File(pathname).exists()) { 190 | return pathname; 191 | } 192 | // provide for backward compatibility (0.8.1-SNAPSHOT didn't emply the ComponentCore.java files) 193 | pathname = pathname.replace("Core.java", ".java"); 194 | if (new File(pathname).exists()) { 195 | return pathname; 196 | } 197 | return null; 198 | } 199 | 200 | def readFile(String filename) { 201 | var br = null as BufferedReader; 202 | var content = "" 203 | 204 | try { 205 | var sCurrentLine = null as String; 206 | br = new BufferedReader(new FileReader(filename)); 207 | while ((sCurrentLine = br.readLine()) != null) { 208 | content += sCurrentLine + "\n"; 209 | } 210 | 211 | } catch (IOException e) { 212 | e.printStackTrace(); 213 | } finally { 214 | try { 215 | if(br != null) br.close(); 216 | } catch (IOException ex) { 217 | ex.printStackTrace(); 218 | } 219 | } 220 | return content 221 | } 222 | } 223 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/src/de/beyondjava/xtext/jsf/generator/DocumentationGenerator.xtend: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by XItext 3 | */ 4 | package de.beyondjava.xtext.jsf.generator 5 | 6 | import de.beyondjava.xtext.jsf.componentLanguage.Attribute 7 | import de.beyondjava.xtext.jsf.componentLanguage.Component 8 | import org.eclipse.emf.ecore.resource.Resource 9 | import org.eclipse.xtext.generator.IFileSystemAccess 10 | import org.eclipse.xtext.generator.IGenerator 11 | 12 | /** 13 | * Generates code from your model files on save. 14 | * 15 | * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation 16 | */ 17 | class DocumentationGenerator implements IGenerator { 18 | 19 | override void doGenerate(Resource resource, IFileSystemAccess fsa) { 20 | for (e : resource.allContents.toIterable.filter(Component)) { 21 | fsa.generateFile("net/bootsfaces/component/" + e.name.toFirstLower + "/" + e.name.toFirstUpper + 22 | ".xhtml", e.compile) 23 | } 24 | } 25 | 26 | def compile(Component widget) ''' 27 | 28 | 29 | 35 | 36 | 37 | 42 |

«widget.name.toFirstUpper» (<b:«widget.name.toFirstLower» />)

43 | 44 |

Describe in a few words what <b:«widget.name.toFirstLower»> is about.

45 |

Basic usage

46 |

Put a short description in simple words here.

47 | 48 | 49 | 50 | Skinning 51 | 52 |
    53 |
  • Tell the world which CSS classes can be used to change the 54 | look of the component.
  • 55 |
56 |
57 | 58 | 61 |
62 |
63 |
64 |
65 | 66 | 67 | ''' 68 | } -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/src/de/beyondjava/xtext/jsf/generator/PartialTaglibGenerator.xtend: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 3 | */ 4 | package de.beyondjava.xtext.jsf.generator 5 | 6 | import de.beyondjava.xtext.jsf.componentLanguage.Attribute 7 | import de.beyondjava.xtext.jsf.componentLanguage.AttributeList 8 | import de.beyondjava.xtext.jsf.componentLanguage.Component 9 | import java.util.ArrayList 10 | import java.util.Collections 11 | import java.util.Comparator 12 | import java.util.HashMap 13 | import java.util.Map 14 | import org.eclipse.emf.common.util.EList 15 | import org.eclipse.emf.ecore.resource.Resource 16 | import org.eclipse.xtext.generator.IFileSystemAccess 17 | import org.eclipse.xtext.generator.IGenerator 18 | 19 | /** 20 | * Generates code from your model files on save. 21 | * 22 | * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation 23 | */ 24 | class PartialTaglibGenerator implements IGenerator { 25 | 26 | def collectAttributeLists(Resource resource) { 27 | var attributeLists = new HashMap() 28 | for (e : resource.allContents.toIterable.filter(AttributeList)) { 29 | attributeLists.put(e.name, e.attributes) 30 | } 31 | return attributeLists 32 | } 33 | 34 | def allAttributes(Component widget, Map> lists) { 35 | var attributes = new ArrayList(); 36 | for (e : widget.attributes) { 37 | attributes.add(e); 38 | } 39 | for (e : widget.attributeLists) { 40 | var list = lists.get(e) 41 | for (a:list) { 42 | attributes.add(a) 43 | } 44 | } 45 | Collections.sort(attributes, new Comparator(){ 46 | override compare(Attribute o1, Attribute o2) { 47 | return o1.name.compareTo(o2.name) 48 | } 49 | 50 | }) 51 | return attributes; 52 | } 53 | 54 | override void doGenerate(Resource resource, IFileSystemAccess fsa) { 55 | var attributeLists = collectAttributeLists(resource) 56 | for (e : resource.allContents.toIterable.filter(Component)) { 57 | fsa.generateFile("net/bootsfaces/component/" + e.name.toFirstLower + "/" + e.name.toFirstUpper + 58 | ".taglib.xml", e.compile(attributeLists)) 59 | } 60 | } 61 | 62 | def compile(Component widget, HashMap> attributeLists) ''' 63 | 64 | 69 | http://bootsfaces.net/ui 70 | 71 | 72 | «widget.name.toFirstLower» 73 | 74 | net.bootsfaces.component.«widget.name.toFirstLower».«widget.name.toFirstUpper» 75 | 76 | «FOR f : widget.allAttributes(attributeLists)» 77 | «f.generateAttribute» 78 | «ENDFOR» 79 | 80 | 81 | 82 | ''' 83 | 84 | def generateAttribute(Attribute a) ''' 85 | 86 | «IF a.desc != null»«ENDIF» 87 | «a.name» 88 | «a.requiredToBoolean» 89 | «a.generateAttributeType» 90 | 91 | «IF a.name.contains("-")» 92 | 93 | «IF a.desc != null»«ENDIF» 94 | «a.name.toCamelCase» 95 | «a.requiredToBoolean» 96 | «a.generateAttributeType» 97 | 98 | «ENDIF» 99 | ''' 100 | 101 | def toCamelCase(String s) { 102 | var pos = 0 as int 103 | var cc = s 104 | while (cc.contains('-')) { 105 | pos = cc.indexOf('-'); 106 | cc = cc.substring(0, pos) + cc.substring(pos+1, pos+2).toUpperCase() + cc.substring(pos+2); 107 | } 108 | return cc 109 | } 110 | 111 | def requiredToBoolean(Attribute a) { 112 | if (a.required==null) return "false" 113 | else return "true" 114 | } 115 | 116 | def generateAttributeType(Attribute a) { 117 | '''«IF a.type == null»java.lang.String« 118 | ELSEIF a.type == 'Boolean'»java.lang.Boolean« 119 | ELSEIF a.type == 'Integer'»java.lang.Integer« 120 | ELSE»«a.type»«ENDIF»''' 121 | } 122 | 123 | } -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/src/de/beyondjava/xtext/jsf/generator/RendererGenerator.xtend: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 3 | */ 4 | package de.beyondjava.xtext.jsf.generator 5 | 6 | import de.beyondjava.xtext.jsf.componentLanguage.Attribute 7 | import de.beyondjava.xtext.jsf.componentLanguage.AttributeList 8 | import de.beyondjava.xtext.jsf.componentLanguage.Component 9 | import de.beyondjava.xtext.jsf.formatting.JavaFormatter 10 | import java.util.ArrayList 11 | import java.util.Collections 12 | import java.util.Comparator 13 | import java.util.HashMap 14 | import java.util.Map 15 | import org.eclipse.core.resources.ResourcesPlugin 16 | import org.eclipse.core.runtime.Path 17 | import org.eclipse.emf.common.util.EList 18 | import org.eclipse.emf.ecore.resource.Resource 19 | import org.eclipse.xtext.generator.IFileSystemAccess 20 | import org.eclipse.xtext.generator.IGenerator 21 | 22 | /** 23 | * Generates code from your model files on save. 24 | * 25 | * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation 26 | */ 27 | class RendererGenerator implements IGenerator { 28 | 29 | def collectAttributeLists(Resource resource) { 30 | var attributeLists = new HashMap() 31 | for (e : resource.allContents.toIterable.filter(AttributeList)) { 32 | attributeLists.put(e.name, e.attributes) 33 | } 34 | return attributeLists 35 | } 36 | 37 | def allAttributes(Component widget, Map> lists) { 38 | var attributes = new ArrayList(); 39 | for (e : widget.attributes) { 40 | attributes.add(e); 41 | } 42 | for (e : widget.attributeLists) { 43 | var list = lists.get(e) 44 | for (a:list) { 45 | attributes.add(a) 46 | } 47 | } 48 | Collections.sort(attributes, new Comparator(){ 49 | override compare(Attribute o1, Attribute o2) { 50 | return o1.name.compareTo(o2.name) 51 | } 52 | 53 | }) 54 | return attributes; 55 | } 56 | 57 | override void doGenerate(Resource resource, IFileSystemAccess fsa) { 58 | var attributeLists = collectAttributeLists(resource) 59 | for (e : resource.allContents.toIterable.filter(Component)) { 60 | val platformString = resource.URI.toPlatformString(true); 61 | var content = e.compile(attributeLists); 62 | val myFile = ResourcesPlugin.getWorkspace().getRoot().getFile(new Path(platformString)); 63 | val project = myFile.getProject(); 64 | var formatted = JavaFormatter.format(content.toString, project); 65 | fsa.generateFile("net/bootsfaces/component/"+e.name.toFirstLower + "/" + e.name.toFirstUpper + "Renderer.java", formatted) 66 | } 67 | } 68 | 69 | def compile(Component e, HashMap> attributeLists) ''' 70 | /** 71 | * Copyright 2014 - 17 by Riccardo Massera (TheCoder4.Eu) and Stephan Rauh (http://www.beyondjava.net). 72 | * 73 | * This file is part of BootsFaces. 74 | * 75 | * Licensed under the Apache License, Version 2.0 (the "License"); 76 | * you may not use this file except in compliance with the License. 77 | * You may obtain a copy of the License at 78 | * 79 | * http://www.apache.org/licenses/LICENSE-2.0 80 | * 81 | * Unless required by applicable law or agreed to in writing, software 82 | * distributed under the License is distributed on an "AS IS" BASIS, 83 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 84 | * See the License for the specific language governing permissions and 85 | * limitations under the License. 86 | */ 87 | 88 | package net.bootsfaces.component.«e.name.toFirstLower»; 89 | 90 | import javax.faces.component.*; 91 | import java.io.IOException; 92 | import java.util.Map; 93 | 94 | import javax.faces.context.FacesContext; 95 | import javax.faces.context.ResponseWriter; 96 | import javax.faces.render.FacesRenderer; 97 | 98 | import net.bootsfaces.render.CoreRenderer; 99 | import net.bootsfaces.render.Tooltip; 100 | 101 | 102 | /** This class generates the HTML code of <b:«e.name» />. */ 103 | @FacesRenderer(componentFamily = "net.bootsfaces.component", rendererType = "net.bootsfaces.component.«e.name.toFirstLower».«e.widgetClass»") 104 | public class «e.widgetClass»Renderer extends CoreRenderer { 105 | «IF e.processesInput!=null» 106 | «generateDecodeMethod(e)» 107 | «ENDIF» 108 | 109 | «generateEncodeBeginMethod(e, attributeLists)» 110 | 111 | «IF e.hasChildren!=null» 112 | «generateEncodeEndMethod(e)» 113 | «ENDIF» 114 | 115 | } 116 | ''' 117 | 118 | def generateDecodeMethod(Component e) 119 | ''' 120 | /** 121 | * This methods receives and processes input made by the user. More specifically, it ckecks whether the 122 | * user has interacted with the current b:«e.widget». The default implementation simply stores 123 | * the input value in the list of submitted values. If the validation checks are passed, 124 | * the values in the submittedValues list are store in the backend bean. 125 | * @param context the FacesContext. 126 | * @param component the current b:«e.widget». 127 | */ 128 | @Override 129 | public void decode(FacesContext context, UIComponent component) { 130 | «e.widgetClass» «e.widget» = («e.widgetClass») component; 131 | 132 | «e.returnIfDisabled» 133 | 134 | decodeBehaviors(context, «e.widget»); 135 | 136 | String clientId = «e.widget».getClientId(context); 137 | String submittedValue = (String) context.getExternalContext().getRequestParameterMap().get(clientId); 138 | 139 | if (submittedValue != null) { 140 | «e.widget».setSubmittedValue(submittedValue); 141 | } 142 | } 143 | ''' 144 | 145 | def getReturnIfDisabled(Component component) { 146 | if (component.attributes.exists[a | "disabled" == a.name]) 147 | { 148 | return ''' 149 | if («component.widget».isDisabled() || «component.widget».isReadonly()) { 150 | return; 151 | } 152 | ''' 153 | } 154 | "" 155 | } 156 | 157 | 158 | def generateEncodeBeginMethod(Component e, HashMap> attributeLists) 159 | ''' 160 | /** 161 | * This methods generates the HTML code of the current b:«e.widget». 162 | «IF e.hasChildren!=null» 163 | * encodeBegin generates the start of the component. After the, the JSF framework calls encodeChildren() 164 | * to generate the HTML code between the beginning and the end of the component. For instance, in the case of a panel component 165 | * the content of the panel is generated by encodeChildren(). After that, encodeEnd() is called 166 | * to generate the rest of the HTML code. 167 | «ENDIF» 168 | * @param context the FacesContext. 169 | * @param component the current b:«e.widget». 170 | * @throws IOException thrown if something goes wrong when writing the HTML code. 171 | */ 172 | @Override 173 | public void encodeBegin(FacesContext context, UIComponent component) throws IOException { 174 | if (!component.isRendered()) { 175 | return; 176 | } 177 | «e.widgetClass» «e.widget» = («e.widgetClass») component; 178 | ResponseWriter rw = context.getResponseWriter(); 179 | String clientId = «e.widget».getClientId(); 180 | 181 | // put custom code here 182 | // Simple demo widget that simply renders every attribute value 183 | rw.startElement("«e.widget»", «e.widget»); 184 | «IF e.hasTooltip!=null» 185 | Tooltip.generateTooltip(context, «e.widget», rw); 186 | «ENDIF» 187 | 188 | «FOR f : e.allAttributes(attributeLists)» 189 | rw.writeAttribute("«f.name»", «parameterAsString(e, f)», "«f.name»"); 190 | «ENDFOR» 191 | rw.writeText("Dummy content of b:«e.widget»", null); 192 | «IF e.hasChildren==null» 193 | rw.endElement("«e.widget»"); 194 | «IF e.hasTooltip!=null» 195 | Tooltip.activateTooltips(context, «e.widget»); 196 | «ENDIF» 197 | «ENDIF» 198 | 199 | } 200 | ''' 201 | 202 | def generateEncodeEndMethod(Component e) 203 | ''' 204 | /** 205 | * This methods generates the HTML code of the current b:«e.widget». 206 | «IF e.hasChildren!=null» 207 | * encodeBegin generates the start of the component. After the, the JSF framework calls encodeChildren() 208 | * to generate the HTML code between the beginning and the end of the component. For instance, in the case of a panel component 209 | * the content of the panel is generated by encodeChildren(). After that, encodeEnd() is called 210 | * to generate the rest of the HTML code. 211 | «ENDIF» 212 | * @param context the FacesContext. 213 | * @param component the current b:«e.widget». 214 | * @throws IOException thrown if something goes wrong when writing the HTML code. 215 | */ 216 | @Override 217 | public void encodeEnd(FacesContext context, UIComponent component) throws IOException { 218 | if (!component.isRendered()) { 219 | return; 220 | } 221 | «e.widgetClass» «e.widget» = («e.widgetClass») component; 222 | ResponseWriter rw = context.getResponseWriter(); 223 | String clientId = «e.widget».getClientId(); 224 | rw.endElement("«e.widget»"); 225 | «IF e.hasTooltip != null» 226 | Tooltip.activateTooltips(context, component); 227 | «ENDIF» 228 | 229 | } 230 | ''' 231 | 232 | /** Boolean parameters are rendered slightly unexpected by JSF, so it's better to pass the desired String for the sake of clarity */ 233 | def parameterAsString(Component e, Attribute f) { 234 | if ("Boolean"==f.type) 235 | '''String.valueOf(«e.widget»«getGetter(f)»)''' 236 | else 237 | '''«e.widget»«getGetter(f)»''' 238 | } 239 | 240 | 241 | 242 | def getGetter(Attribute f) 243 | { 244 | if ("Boolean".equals(f.type)) { 245 | '''.is«f.name.toFirstUpper»()''' 246 | } 247 | else { 248 | '''.get«f.name.toFirstUpper»()''' 249 | } 250 | } 251 | 252 | 253 | def widgetClass(Component c) { 254 | '''«c.name.toFirstUpper»''' 255 | } 256 | 257 | def widget(Component c) { 258 | '''«c.name.toFirstLower»''' 259 | } 260 | } 261 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/src/de/beyondjava/xtext/jsf/generator/TaglibGenerator.xtend: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 3 | */ 4 | package de.beyondjava.xtext.jsf.generator 5 | 6 | import de.beyondjava.xtext.jsf.componentLanguage.Attribute 7 | import de.beyondjava.xtext.jsf.componentLanguage.AttributeList 8 | import de.beyondjava.xtext.jsf.componentLanguage.Component 9 | import java.util.ArrayList 10 | import java.util.Collections 11 | import java.util.Comparator 12 | import java.util.HashMap 13 | import java.util.Map 14 | import org.eclipse.emf.common.util.EList 15 | import org.eclipse.emf.ecore.resource.Resource 16 | import org.eclipse.xtext.generator.IFileSystemAccess 17 | import org.eclipse.xtext.generator.IGenerator 18 | 19 | /** 20 | * Generates code from your model files on save. 21 | * 22 | * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation 23 | */ 24 | class TaglibGenerator implements IGenerator { 25 | 26 | def collectAttributeLists(Resource resource) { 27 | var attributeLists = new HashMap() 28 | for (e : resource.allContents.toIterable.filter(AttributeList)) { 29 | attributeLists.put(e.name, e.attributes) 30 | } 31 | return attributeLists 32 | } 33 | 34 | def allAttributes(Component widget, Map> lists) { 35 | var attributes = new ArrayList(); 36 | for (e : widget.attributes) { 37 | attributes.add(e); 38 | } 39 | for (e : widget.attributeLists) { 40 | var list = lists.get(e) 41 | for (a:list) { 42 | attributes.add(a) 43 | } 44 | } 45 | Collections.sort(attributes, new Comparator(){ 46 | override compare(Attribute o1, Attribute o2) { 47 | return o1.name.compareTo(o2.name) 48 | } 49 | 50 | }) 51 | return attributes; 52 | } 53 | 54 | override void doGenerate(Resource resource, IFileSystemAccess fsa) { 55 | var attributeLists = collectAttributeLists(resource) 56 | fsa.generateFile("../src/main/meta/META-INF/bootsfaces-b.taglib.xml", resource.compile(attributeLists)); 57 | } 58 | 59 | def compile(Resource resource, HashMap> attributeLists) ''' 60 | 61 | 67 | http://bootsfaces.net/ui 68 | «FOR e : resource.allContents.toIterable.filter(Component)» 69 | «e.compile(attributeLists)» 70 | «ENDFOR» 71 | 72 | ''' 73 | 74 | def compile(Component widget, HashMap> attributeLists) ''' 75 | 76 | 77 | 78 | «widget.name.toFirstLower» 79 | 80 | net.bootsfaces.component.«widget.name.toFirstLower».«widget.name.toFirstUpper» 81 | 82 | «FOR f : widget.allAttributes(attributeLists)» 83 | «f.generateAttribute» 84 | «ENDFOR» 85 | 86 | ''' 87 | 88 | def generateAttribute(Attribute a) ''' 89 | 90 | «IF a.desc != null»«ENDIF» 91 | «a.name» 92 | «a.requiredToBoolean» 93 | «a.generateAttributeType» 94 | 95 | «IF a.name.contains("-")» 96 | 97 | «IF a.desc != null»«ENDIF» 98 | «a.name.toCamelCase» 99 | «a.requiredToBoolean» 100 | «a.generateAttributeType» 101 | 102 | «ENDIF» 103 | ''' 104 | 105 | def toCamelCase(String s) { 106 | var pos = 0 as int 107 | var cc = s 108 | while (cc.contains('-')) { 109 | pos = cc.indexOf('-'); 110 | cc = cc.substring(0, pos) + cc.substring(pos+1, pos+2).toUpperCase() + cc.substring(pos+2); 111 | } 112 | return cc 113 | } 114 | 115 | def requiredToBoolean(Attribute a) { 116 | if (a.required==null) return "false" 117 | else return "true" 118 | } 119 | 120 | def generateAttributeType(Attribute a) { 121 | '''«IF a.type == null»java.lang.String« 122 | ELSEIF a.type == 'Boolean'»java.lang.Boolean« 123 | ELSEIF a.type == 'Integer'»java.lang.Integer« 124 | ELSEIF a.type == 'Float'»java.lang.Double« 125 | ELSEIF a.type.startsWith("Map<")»java.util.Map« 126 | ELSE»«a.type»«ENDIF»''' 127 | } 128 | 129 | } -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/src/de/beyondjava/xtext/jsf/generator/UITestGenerator.xtend: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by XItext 3 | */ 4 | package de.beyondjava.xtext.jsf.generator 5 | 6 | import de.beyondjava.xtext.jsf.componentLanguage.Attribute 7 | import de.beyondjava.xtext.jsf.componentLanguage.AttributeList 8 | import de.beyondjava.xtext.jsf.componentLanguage.Component 9 | import java.util.ArrayList 10 | import java.util.Collections 11 | import java.util.Comparator 12 | import java.util.HashMap 13 | import java.util.Map 14 | import org.eclipse.emf.common.util.EList 15 | import org.eclipse.emf.ecore.resource.Resource 16 | import org.eclipse.xtext.generator.IFileSystemAccess 17 | import org.eclipse.xtext.generator.IGenerator 18 | 19 | /** 20 | * Generates code from your model files on save. 21 | * 22 | * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#code-generation 23 | */ 24 | class UITestGenerator implements IGenerator { 25 | 26 | override void doGenerate(Resource resource, IFileSystemAccess fsa) { 27 | for (e : resource.allContents.toIterable.filter(Component)) { 28 | var attributeLists = collectAttributeLists(resource) 29 | var content = e.compile(attributeLists) 30 | var eclipseFileName = "net/bootsfaces/component/" + e.name.toFirstLower + "/" + e.name.toFirstUpper + 31 | "Test.java" 32 | fsa.generateFile(eclipseFileName, content) 33 | } 34 | } 35 | 36 | def compile(Component widget, HashMap> attributeLists) ''' 37 | /** 38 | * Copyright 2014 - 17 by Riccardo Massera (TheCoder4.Eu) and Stephan Rauh (http://www.beyondjava.net). 39 | * 40 | * This file is part of BootsFaces. 41 | * 42 | * Licensed under the Apache License, Version 2.0 (the "License"); 43 | * you may not use this file except in compliance with the License. 44 | * You may obtain a copy of the License at 45 | * 46 | * http://www.apache.org/licenses/LICENSE-2.0 47 | * 48 | * Unless required by applicable law or agreed to in writing, software 49 | * distributed under the License is distributed on an "AS IS" BASIS, 50 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 51 | * See the License for the specific language governing permissions and 52 | * limitations under the License. 53 | */ 54 | package net.bootsfaces.healthcheck.«widget.name.toFirstLower»; 55 | 56 | import java.io.IOException; 57 | 58 | import javax.faces.context.FacesContext; 59 | import javax.faces.context.ResponseWriter; 60 | import javax.faces.bean.ManagedBean; 61 | 62 | import net.bootsfaces.healthcheck.StringResponseWriter; 63 | import net.bootsfaces.healthcheck.UITest; 64 | import net.bootsfaces.component.«widget.name.toFirstLower».«widget.name.toFirstUpper»; 65 | import net.bootsfaces.component.«widget.name.toFirstLower».«widget.name.toFirstUpper»Renderer; 66 | 67 | @ManagedBean 68 | public class «widget.name.toFirstUpper»Test extends UITest { 69 | public void test1(FacesContext context) throws IOException { 70 | «widget.name.toFirstUpper» component = new «widget.name.toFirstUpper»(); 71 | «FOR f : widget.allAttributes(attributeLists)» 72 | «f.generateAttribute» 73 | «ENDFOR» 74 | new «widget.name.toFirstUpper»Renderer().encodeBegin(context, component); 75 | new «widget.name.toFirstUpper»Renderer().encodeChildren(context, component); 76 | new «widget.name.toFirstUpper»Renderer().encodeEnd(context, component); 77 | } 78 | public void test2(FacesContext context) throws IOException { 79 | «widget.name.toFirstUpper» component = new «widget.name.toFirstUpper»(); 80 | «FOR f : widget.allAttributes(attributeLists)» 81 | «if ("true".equals(f.required)) { 82 | f.generateAttribute 83 | }» 84 | «ENDFOR» 85 | new «widget.name.toFirstUpper»Renderer().encodeBegin(context, component); 86 | new «widget.name.toFirstUpper»Renderer().encodeChildren(context, component); 87 | new «widget.name.toFirstUpper»Renderer().encodeEnd(context, component); 88 | } 89 | public void test3(FacesContext context) throws IOException { 90 | // add your own implementation 91 | } 92 | public void test4(FacesContext context) throws IOException { 93 | // add your own implementation 94 | } 95 | public void test5(FacesContext context) throws IOException { 96 | // add your own implementation 97 | } 98 | } 99 | ''' 100 | 101 | def generateAttribute(Attribute a) { 102 | if (a.dummyValue != null) { 103 | return "component.set" + a.name.toFirstUpper.toCamelCase + "(" + a.dummyValue + ");"; 104 | } 105 | } 106 | 107 | def toCamelCase(String s) { 108 | var pos = 0 as int 109 | var cc = s 110 | while (cc.contains('-')) { 111 | pos = cc.indexOf('-'); 112 | cc = cc.substring(0, pos) + cc.substring(pos + 1, pos + 2).toUpperCase() + cc.substring(pos + 2); 113 | } 114 | return cc 115 | } 116 | 117 | def dummyValue(Attribute a) { 118 | if (a.type == "String") { 119 | return '"' + a.name + '"'; 120 | } 121 | if (a.type == "Boolean") { 122 | return "true"; 123 | } 124 | if (a.type == "Integer") { 125 | return a.name.length; 126 | } 127 | return null; 128 | } 129 | 130 | def collectAttributeLists(Resource resource) { 131 | var attributeLists = new HashMap() 132 | for (e : resource.allContents.toIterable.filter(AttributeList)) { 133 | attributeLists.put(e.name, e.attributes) 134 | } 135 | return attributeLists 136 | } 137 | 138 | def allAttributes(Component widget, Map> lists) { 139 | var attributes = new ArrayList(); 140 | for (e : widget.attributes) { 141 | attributes.add(e); 142 | } 143 | for (e : widget.attributeLists) { 144 | var list = lists.get(e) 145 | for (a : list) { 146 | attributes.add(a) 147 | } 148 | } 149 | Collections.sort(attributes, new Comparator() { 150 | override compare(Attribute o1, Attribute o2) { 151 | return o1.name.compareTo(o2.name) 152 | } 153 | 154 | }) 155 | return attributes; 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/src/de/beyondjava/xtext/jsf/generator/template.xhtml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 9 | 10 | 11 | 16 |

«widget.name.toFirstUpper» (<b:«widget.name.toFirstLower» />)

17 | 18 |

Describe in a few words what <b:«widget.name.toFirstLower»> is about.

19 |

Basic usage

20 |

Put a short description in simple words here.

21 | 22 | 23 | Attributes of <b:«widget.name.toFirstLower» > 24 | 25 | 26 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 44 | 45 | 46 |
AttributeDefault valueDescription
label(none)This attribute is optional. If you provide it, the 40 | «widget.name.toFirstLower» is preceded by a Bootstrap 42 | label. 43 |
47 |
48 |
49 | 50 | 51 | Skinning 52 | 53 | 54 |
    55 |
  • Tell the world which CSS classes can be used to change the 56 | look of the component.
  • 57 |
58 |
59 |
60 | 61 | 64 |
65 |
66 |
67 |
68 |
69 |
70 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/src/de/beyondjava/xtext/jsf/scoping/ComponentLanguageScopeProvider.xtend: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 3 | */ 4 | package de.beyondjava.xtext.jsf.scoping 5 | 6 | /** 7 | * This class contains custom scoping description. 8 | * 9 | * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#scoping 10 | * on how and when to use it. 11 | * 12 | */ 13 | class ComponentLanguageScopeProvider extends org.eclipse.xtext.scoping.impl.AbstractDeclarativeScopeProvider { 14 | 15 | } 16 | -------------------------------------------------------------------------------- /de.beyondjava.xtext.jsf/src/de/beyondjava/xtext/jsf/validation/ComponentLanguageValidator.xtend: -------------------------------------------------------------------------------- 1 | /* 2 | * generated by Xtext 3 | */ 4 | package de.beyondjava.xtext.jsf.validation 5 | 6 | //import org.eclipse.xtext.validation.Check 7 | 8 | /** 9 | * This class contains custom validation rules. 10 | * 11 | * See https://www.eclipse.org/Xtext/documentation/303_runtime_concepts.html#validation 12 | */ 13 | class ComponentLanguageValidator extends AbstractComponentLanguageValidator { 14 | 15 | // public static val INVALID_NAME = 'invalidName' 16 | // 17 | // @Check 18 | // def checkGreetingStartsWithCapital(Greeting greeting) { 19 | // if (!Character.isUpperCase(greeting.name.charAt(0))) { 20 | // warning('Name should start with a capital', 21 | // MyDslPackage.Literals.GREETING__NAME, 22 | // INVALID_NAME) 23 | // } 24 | // } 25 | } 26 | -------------------------------------------------------------------------------- /plugins/readme.md: -------------------------------------------------------------------------------- 1 | # Installation 2 | Simply drop the two jar files into the plugins folder of Eclipse. 3 | 4 | # Compatibility 5 | The plugin is developed with the most current Eclipse version on Mac OSX. At the time of writing, that was Eclipse Neon. The plugin may also work with other versions of Eclipse, and it probably also works on other operation system, but there's no guarantee. Use at own risk. 6 | 7 | # How to use: preparations 8 | Checkout the projects https://github.com/TheCoder4eu/BootsFaces-OSP and https://github.com/TheCoder4eu/BootsFacesWeb into a common folder. The correct folder structure is important, because the plugin modifies files in both projects. It generates both skeletons of the source code and skeletons of the documentation. 9 | 10 | cd (your folder of choice) 11 | mkdir developmenent 12 | cd development 13 | git clone https://github.com/TheCoder4eu/BootsFacesWeb.git 14 | git clone https://github.com/TheCoder4eu/BootsFaces-OSP.git 15 | 16 | After that, you can import both project into Eclipse. The easiest way is to import them as Maven projects, but you can also import them as Gradle projects. 17 | 18 | # How to use: developing components 19 | Now you can open the file xtext/BootsFaces.jsfdsl in the BootsFaces-OSP project. The package explorer has a new context menu which is visible for jsfdsl files. Click "generate JSF components". The sourcecode and (in most cases) the attribute list in the BootsFacesWeb project are now updated. Otherwise, you find the generated files in the folder src-gen. Copy the files to the appropriate folders. Suppose you're creating a widget called "MyWidget". The target folders of the files are: 20 | 21 | * Put MyWidget.java, MyWidgetCore.java, MyWidgetRenderer.java and MyWidgetBeanInfo.java into BootsFaces-OSP/src/main/java/net/bootsfaces/components/myWidget. 22 | * Put MyWidget.xhtml and MyWidgetAttributes.xhtml into BootsFacesWeb/src/main/webapp/forms. You may also choose one the neighbar folder, if your widget is about the layout, if it's a Bootstrap component, if it focuses on mobile targets or if it is built on jQueryUI. 23 | * Add a menu entry pointing to the new documentation file MyWidget.xhtml in BootsFacesWeb/src/main/webapp/appLayout/NavBarTop.xhtml. 24 | * Ignore the file MyWidget.taglib.xml. The widget is added to the taglib automatically. The partial taglib file was needed in earlier versions. 25 | * Ignore the file MyWidgetTest.java. This file will (hopefully) play an important role in future versions. Currently, it's not needed. 26 | 27 | Now you can deploy BootsFacesWeb to a Tomcat and open your new documentation page (http://127.0.0.1/BootsFacesWeb/forms/MyWidget.xhtml). If you add the widget to the page, it already generates code. You won't see it unless you inspect the HTML source code of the page because the default renderer simply generates a pseudo HTML widget called and generates every attribute. However, that should be a good starting point to implement useful HTML code. 28 | --------------------------------------------------------------------------------