Skip to content

Commit

Permalink
Merge branch 'issues/1066'
Browse files Browse the repository at this point in the history
  • Loading branch information
stephanrauh committed Nov 26, 2019
1 parent b8cad10 commit 953aee6
Show file tree
Hide file tree
Showing 2 changed files with 91 additions and 67 deletions.
139 changes: 80 additions & 59 deletions src/main/java/net/bootsfaces/listeners/AddResourcesListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -58,8 +58,8 @@
import net.bootsfaces.utils.BsfUtils;

/**
* This class adds the resource needed by BootsFaces and ensures that they are loaded in the correct order. It replaces
* the former HeadListener.
* This class adds the resource needed by BootsFaces and ensures that they are
* loaded in the correct order. It replaces the former HeadListener.
*
* @author Stephan Rauh
*/
Expand All @@ -73,39 +73,45 @@ public class AddResourcesListener implements SystemEventListener {
private static final String BASIC_JS_RESOURCE_KEY = "net.bootsfaces.listeners.AddResourcesListener.BasicJSResourceFiles";

/**
* Version of FontAwesome. By default, version 4.7.0 is used. If you specify the subfont ("solid", "regular",
* "light" or "brand"), the version number is automatically set to 5.2.0.
* Version of FontAwesome. By default, version 4.7.0 is used. If you specify the
* subfont ("solid", "regular", "light" or "brand"), the version number is
* automatically set to 5.2.0.
*/
private static final String FONTAWESOME_VERSION = "net.bootsfaces.listeners.AddResourcesListener.FontAwesomeVersion";

/**
* List of components using a non-default version of FontAwesome. Needed to detect whether FontAwesome 4 (the
* default version) needs to be imported or not.
* List of components using a non-default version of FontAwesome. Needed to
* detect whether FontAwesome 4 (the default version) needs to be imported or
* not.
*/
private static final String FONTAWESOME_NEW_VERSION = "net.bootsfaces.listeners.AddResourcesListener.FontAwesomeNewVersion";

/**
* This entry of the view map is set to true if there's at least one Fontawesome icon
* This entry of the view map is set to true if there's at least one Fontawesome
* icon
*/
private static final String FONTAWESOME_USED = "net.bootsfaces.listeners.AddResourcesListener.FontAwesomeIsUsed";

/**
* Components can request JS resources by registering them in the ViewMap, using the RESOURCE_KEY.
* Components can request JS resources by registering them in the ViewMap, using
* the RESOURCE_KEY.
*/
private static final String RESOURCE_KEY = "net.bootsfaces.listeners.AddResourcesListener.ResourceFiles";

/**
* Components can request themed CSS resources by registering them in the ViewMap, using the THEME_RESOURCE_KEY.
* Components can request themed CSS resources by registering them in the
* ViewMap, using the THEME_RESOURCE_KEY.
*/
private static final String THEME_RESOURCE_KEY = "net.bootsfaces.listeners.AddResourcesListener.ThemedResourceFiles";

/**
* Components can request extended CSS resources by registering them in the ViewMap, using the EXT_RESOURCE_KEY.
* Components can request extended CSS resources by registering them in the
* ViewMap, using the EXT_RESOURCE_KEY.
*/
private static final String EXT_RESOURCE_KEY = "net.bootsfaces.listeners.AddResourcesListener.ExtResourceFiles";

private static final String SCRIPT_RENDERER = "javax.faces.resource.Script",
CSS_RENDERER = "javax.faces.resource.Stylesheet";
CSS_RENDERER = "javax.faces.resource.Stylesheet";

static {
LOGGER.info("This application is running on BootsFaces " + C.BSFVERSION + "-" + C.BSFRELEASE_STATUS);
Expand All @@ -120,7 +126,8 @@ public boolean isListenerForSource(Object source) {
}

/**
* Trigger adding the resources if and only if the event has been fired by UIViewRoot.
* Trigger adding the resources if and only if the event has been fired by
* UIViewRoot.
*/
public void processEvent(SystemEvent event) throws AbortProcessingException {
FacesContext context = FacesContext.getCurrentInstance();
Expand All @@ -135,12 +142,14 @@ public void processEvent(SystemEvent event) throws AbortProcessingException {
}

/**
* Check if there is almost one bootsfaces component in page. If yes, load the correct items.
* Check if there is almost one bootsfaces component in page. If yes, load the
* correct items.
*
* To ensure that, it checks first the viewMap to find specific bootsfaces key. If it found nothing, it check
* for components that has as a resource lib, the "bsf" lib.
* To ensure that, it checks first the viewMap to find specific bootsfaces key.
* If it found nothing, it check for components that has as a resource lib, the
* "bsf" lib.
*
* @param root the UIViewRoot
* @param root the UIViewRoot
* @param context the faces context
* @return
*/
Expand Down Expand Up @@ -168,10 +177,11 @@ private boolean ensureExistBootsfacesComponent(UIViewRoot root, FacesContext con
}

/**
* Check all components in page to find one that has as resource library the target library. I use this method
* to check existence of a BsF component because, at this level, the getComponentResource returns always null
* Check all components in page to find one that has as resource library the
* target library. I use this method to check existence of a BsF component
* because, at this level, the getComponentResource returns always null
*
* @param parent the parent component
* @param parent the parent component
* @param targetLib the lib to search
* @return
*/
Expand Down Expand Up @@ -225,7 +235,7 @@ private void addMetaTags(UIViewRoot root, FacesContext context) {
/**
* Add the required CSS files and the FontAwesome CDN link.
*
* @param root The UIViewRoot of the JSF tree.
* @param root The UIViewRoot of the JSF tree.
* @param context The current FacesContext
*/
private void addCSS(UIViewRoot root, FacesContext context) {
Expand Down Expand Up @@ -350,7 +360,7 @@ private String loadTheme(UIViewRoot root, FacesContext context) {

if (themeResource == null) {
throw new FacesException("Error loading theme, cannot find \"" + "css/" + theme + "/" + filename
+ "\" resource of \"" + C.BSF_LIBRARY + "\" library");
+ "\" resource of \"" + C.BSF_LIBRARY + "\" library");
} else {
String name = "css/" + theme + "/" + filename;
createAndAddComponent(root, context, CSS_RENDERER, name, C.BSF_LIBRARY);
Expand Down Expand Up @@ -382,7 +392,7 @@ private String getTheme(FacesContext context) {
/**
* Add the required Javascript files and the FontAwesome CDN link.
*
* @param root The UIViewRoot of the JSF tree.
* @param root The UIViewRoot of the JSF tree.
* @param context The current FacesContext
*/
private void addJavascript(UIViewRoot root, FacesContext context) {
Expand Down Expand Up @@ -432,7 +442,7 @@ private void addJavascript(UIViewRoot root, FacesContext context) {
}

private Map<String, Object> addMandatoryLibraries(UIViewRoot root, FacesContext context, boolean loadJQuery,
boolean loadJQueryUI) {
boolean loadJQueryUI) {

/*
* We used to check if a single component needs the bsf.js, jsf or jquery
Expand All @@ -455,7 +465,7 @@ private Map<String, Object> addMandatoryLibraries(UIViewRoot root, FacesContext
String file = entry.getValue();
String library = entry.getKey().substring(0, entry.getKey().length() - file.length() - 1);
if (!"jq/jquery.js".equals(file) || !C.BSF_LIBRARY.equals(library) || !file.startsWith("jq/ui")
|| loadJQueryUI) {
|| loadJQueryUI) {
createAndAddComponent(root, context, SCRIPT_RENDERER, file, library);
}
}
Expand All @@ -469,7 +479,7 @@ private Map<String, Object> addMandatoryLibraries(UIViewRoot root, FacesContext
String file = entry.getValue();
String library = entry.getKey().substring(0, entry.getKey().length() - file.length() - 1);
if (!"jq/jquery.js".equals(file) || !C.BSF_LIBRARY.equals(library) || !file.startsWith("jq/ui")
|| loadJQueryUI) {
|| loadJQueryUI) {
createAndAddComponent(root, context, SCRIPT_RENDERER, file, library);
}
}
Expand Down Expand Up @@ -502,7 +512,7 @@ private void addResourceIfNecessary(UIViewRoot root, FacesContext context, UICom
// remove old
root.removeComponentResource(context, c, "head");

// add new
// add new
root.addComponentResource(context, output, "head");
return;
}
Expand Down Expand Up @@ -580,7 +590,8 @@ public static void setFontAwesomeVersion(int version, Object uiComponent) {
}
}

LOGGER.log(Level.FINER, "by setFontAwesomeVersion - viewMap(FONTAWESOME_VERSION) is {0}", viewMap.get(FONTAWESOME_VERSION));
LOGGER.log(Level.FINER, "by setFontAwesomeVersion - viewMap(FONTAWESOME_VERSION) is {0}",
viewMap.get(FONTAWESOME_VERSION));
}

@SuppressWarnings("unchecked")
Expand Down Expand Up @@ -626,12 +637,14 @@ private boolean needsFontAwesome4() {
}

/**
* Remove duplicate resource files. For some reason, many resource files are added more than once, especially
* when AJAX is used. The method removes the duplicate files.
* Remove duplicate resource files. For some reason, many resource files are
* added more than once, especially when AJAX is used. The method removes the
* duplicate files.
*
* TODO: Verify if the duplicate resource files are a bug of BootsFaces or of the Mojarra library itself.
* TODO: Verify if the duplicate resource files are a bug of BootsFaces or of
* the Mojarra library itself.
*
* @param root The current UIViewRoot
* @param root The current UIViewRoot
* @param context The current FacesContext
*/
private void removeDuplicateResources(UIViewRoot root, FacesContext context) {
Expand Down Expand Up @@ -667,16 +680,18 @@ public int compare(UIComponent o1, UIComponent o2) {
String name = (String) c.getAttributes().get("name");
String library = (String) c.getAttributes().get("library");
String url = (String) c.getAttributes().get("url");
LOGGER.log(Level.FINER, "-1 " + c.getClientId() + " " + name + " " + library + " " + url + " " + c.getClass().getSimpleName());
LOGGER.log(Level.FINER, "-1 " + c.getClientId() + " " + name + " " + library + " " + url + " "
+ c.getClass().getSimpleName());
}
}

/**
* Remove Bootstrap CSS files (called if the context param "net.bootsfaces.get_bootstrap_from_cdn" is set). Only
* needed for Default Theme (Bootstrap) and custom themes, other themes would get default theme look and feel
* otherwise.
* Remove Bootstrap CSS files (called if the context param
* "net.bootsfaces.get_bootstrap_from_cdn" is set). Only needed for Default
* Theme (Bootstrap) and custom themes, other themes would get default theme
* look and feel otherwise.
*
* @param root The current UIViewRoot
* @param root The current UIViewRoot
* @param context The current FacesContext
*/
private void removeBootstrapResources(UIViewRoot root, FacesContext context) {
Expand All @@ -688,7 +703,7 @@ private void removeBootstrapResources(UIViewRoot root, FacesContext context) {
String library = (String) resource.getAttributes().get("library");
if (C.BSF_LIBRARY.equals(library) && name != null) {
if (name.endsWith("bootstrap.min.css") || name.endsWith("bootstrap.css")
|| name.endsWith("core.css") || name.endsWith("theme.css")) {
|| name.endsWith("core.css") || name.endsWith("theme.css")) {
resource.setInView(false);
root.removeComponentResource(context, resource);
}
Expand All @@ -708,11 +723,12 @@ private void removeBootstrapResources(UIViewRoot root, FacesContext context) {
}

/**
* Make sure jQuery is loaded before jQueryUI, and that every other Javascript is loaded later. Also make sure
* that the BootsFaces resource files are loaded prior to other resource files, giving the developer the
* opportunity to overwrite a CSS or JS file.
* Make sure jQuery is loaded before jQueryUI, and that every other Javascript
* is loaded later. Also make sure that the BootsFaces resource files are loaded
* prior to other resource files, giving the developer the opportunity to
* overwrite a CSS or JS file.
*
* @param root The current UIViewRoot
* @param root The current UIViewRoot
* @param context The current FacesContext
*/
private void enforceCorrectLoadOrder(UIViewRoot root, FacesContext context) {
Expand Down Expand Up @@ -793,10 +809,11 @@ private void enforceCorrectLoadOrder(UIViewRoot root, FacesContext context) {
}

/**
* Look whether a b:iconAwesome component is used. If so, the font-awesome.css is removed from the resource list
* because it's loaded from the CDN.
* Look whether a b:iconAwesome component is used. If so, the font-awesome.css
* is removed from the resource list because it's loaded from the CDN.
*
* @return true, if the font-awesome.css is found in the resource list. Note the side effect of this method!
* @return true, if the font-awesome.css is found in the resource list. Note the
* side effect of this method!
*/
private boolean isFontAwesomeComponentUsedAndRemoveIt() {
FacesContext fc = FacesContext.getCurrentInstance();
Expand Down Expand Up @@ -848,28 +865,30 @@ private UIComponent findHeader(UIViewRoot root) {
}

/**
* Registers a JS file that needs to be included in the header of the HTML file, but after jQuery and AngularJS.
* Registers a JS file that needs to be included in the header of the HTML file,
* but after jQuery and AngularJS.
*
* @param library The name of the sub-folder of the resources folder.
* @param library The name of the sub-folder of the resources folder.
* @param resource The name of the resource file within the library folder.
*/
public static void addResourceToHeadButAfterJQuery(String library, String resource) {
addResource(resource, library, library + "#" + resource, RESOURCE_KEY);
}

/**
* Registers a core JS file that needs to be included in the header of the HTML file, but after jQuery and
* AngularJS.
* Registers a core JS file that needs to be included in the header of the HTML
* file, but after jQuery and AngularJS.
*
* @param library The name of the sub-folder of the resources folder.
* @param library The name of the sub-folder of the resources folder.
* @param resource The name of the resource file within the library folder.
*/
public static void addBasicJSResource(String library, String resource) {
addResource(resource, library, resource, BASIC_JS_RESOURCE_KEY);
}

/**
* Registers a themed CSS file that needs to be included in the header of the HTML file.
* Registers a themed CSS file that needs to be included in the header of the
* HTML file.
*
* @param resource The name of the resource file within the library folder.
*/
Expand All @@ -888,7 +907,8 @@ public static void addThemedCSSResource(String resource) {
}

/**
* Registers a Extension CSS file that needs to be included in the header of the HTML file.
* Registers a Extension CSS file that needs to be included in the header of the
* HTML file.
*
* @param resource The name of the resource file within the library folder.
*/
Expand Down Expand Up @@ -930,12 +950,12 @@ private String evalELIfPossible(String expression) {
}

private void createAndAddComponent(UIViewRoot root, FacesContext context, String rendererType, String name,
String library) {
String library) {
createAndAddComponent(root, context, rendererType, name, library, null);
}

private void createAndAddComponent(UIViewRoot root, FacesContext context, String rendererType, String name,
String library, String position) {
String library, String position) {

// if (library != null && BSF_LIBRARY.equals(library)) {
// boolean loadBsfResource =
Expand Down Expand Up @@ -965,20 +985,21 @@ private boolean isFalseOrNo(String param) {
}

/**
* Add the default datatables.net resource if and only if the user doesn't bring their own copy, and if they
* didn't disallow it in the web.xml by setting the context paramter net.bootsfaces.get_datatable_from_cdn to
* true.
* Add the default datatables.net resource if and only if the user doesn't bring
* their own copy, and if they didn't disallow it in the web.xml by setting the
* context paramter net.bootsfaces.get_datatable_from_cdn to true.
*
* @param defaultFilename The URL of the file to be loaded
* @param type either "js" or "css"
* @param type either "js" or "css"
*/
public static void addDatatablesResourceIfNecessary(String defaultFilename, String type) {
boolean loadDatatables = shouldLibraryBeLoaded(P_GET_DATATABLE_FROM_CDN, true);
// Do we have to add datatables.min.{css|js}, or are the resources already there?
// Do we have to add datatables.min.{css|js}, or are the resources already
// there?
FacesContext context = FacesContext.getCurrentInstance();
UIViewRoot root = context.getViewRoot();

String[] positions = {"head", "body", "form"};
String[] positions = { "head", "body", "form" };
for (String position : positions) {
if (loadDatatables) {
List<UIComponent> availableResources = root.getComponentResources(context, position);
Expand Down
19 changes: 11 additions & 8 deletions src/main/java/net/bootsfaces/listeners/InternalFALink.java
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
*/
@FacesComponent("net.bootsfaces.component.internalFALink.InternalFALink")
public class InternalFALink extends UIComponentBase {

private static final Logger LOGGER = Logger.getLogger(InternalFALink.class.getName());

/**
Expand All @@ -60,22 +60,25 @@ public InternalFALink() {
@Override
public void encodeBegin(FacesContext fc) throws IOException {
final String FA_VERSION = "4.7.0";
final String FONTAWESOME_CDN_URL = "//maxcdn.bootstrapcdn.com/font-awesome/" + FA_VERSION + "/css/font-awesome.min.css";
final String FONTAWESOME_CDN_URL = "//maxcdn.bootstrapcdn.com/font-awesome/" + FA_VERSION
+ "/css/font-awesome.min.css";

ResponseWriter responseWriter = fc.getResponseWriter();

LOGGER.log(Level.FINER, "do encodeBegin - version is {0} / needsVersion4 is {1}", new Object[]{version, needsVersion4});


LOGGER.log(Level.FINER, "do encodeBegin - version is {0} / needsVersion4 is {1}",
new Object[] { version, needsVersion4 });

if (version.contains("5")) {
responseWriter.append(
"<link type=\"text/css\" rel=\"stylesheet\" href=\"https://use.fontawesome.com/releases/v5.2.0/css/all.css\" crossorigin=\"anonymous\"/>");
"<link type=\"text/css\" rel=\"stylesheet\" href=\"https://use.fontawesome.com/releases/v5.2.0/css/all.css\" crossorigin=\"anonymous\"/>");
responseWriter.append(
"<link type=\"text/css\" rel=\"stylesheet\" href=\"https://use.fontawesome.com/releases/v5.2.0/css/solid.css\" crossorigin=\"anonymous\"/>");
"<link type=\"text/css\" rel=\"stylesheet\" href=\"https://use.fontawesome.com/releases/v5.2.0/css/solid.css\" crossorigin=\"anonymous\"/>");

}
if (version.contains("4")) {
if (needsVersion4) {
responseWriter.append("<link type=\"text/css\" rel=\"stylesheet\" href=\"" + FONTAWESOME_CDN_URL + "\" crossorigin=\"anonymous\"/>");
responseWriter.append("<link type=\"text/css\" rel=\"stylesheet\" href=\"" + FONTAWESOME_CDN_URL
+ "\" crossorigin=\"anonymous\"/>");
}
}
}
Expand Down

0 comments on commit 953aee6

Please sign in to comment.