-
Notifications
You must be signed in to change notification settings - Fork 874
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature: Added support for Faces 4 changed xmlns namespaces #6096
Conversation
Since Jakarte EE Faces 4 the xmls namespaces were changed from `http://xmlns.jcp.org/jsf` to `jakarta.*`. (see jakartaee/faces#1553) This change adds new namespace support for: * Generation of new JSF pages * Tag suggestion in faces xhtml editor view * Automatic addition of missing namespace declaration when new taglib is used In order to support the JSF 4.0 namespaces the `enum` `JsfVersion` in `web.jsfapi` module was introduced. It's used to map the taglib namespaces based on the projects detected JSF version. Note: There's already an enum `JSFVersion` which is not part of the api. Both enums might be merged in the future. Reference: apache#6069
…chieved with `getJsfVersion()`
What about |
@morvael I don't know exactly what this class is doing. Actually I never worked in the NetBeans code base before. I just created a new Maven WebApplication and tried to figure out what needs to be done to support the namespaces. As for that project type I'm quite sure how to setup. I'd invite you to pull the PR build |
My problem was I didn't know from where to take new schemas, as the old DbfFactory didn't have them and the new one was completely reworked class (besides I would't know how to reference it). I'm not even aware what the class does, besides that it looks to be related to this topic (was mentioned in #5470). I guess what everyone wants is for the Netbeans to: If your patch solves a & b then I'm OK with it, if only a) then it's not enough. Missing code completion and navigation is a big productivity killer in the last few versions of Netbeans when working with Jakarta 9+. Sadly, I'm a noob when it comes to fixing Netbeans code, as I would have most likely did this in my own free or even work time if I could do it. |
I built the branch for easier testing of interested folks which can be downloaded here: https://impl.it/NetBeans-dev-dev-1ebff966c4d7b3f98e208efd758a9fbdf90f0dbf-enterprise.zip |
Hi @asbachb, using GlassFish 7.0.5 and Jakarta EE 10 I test the following:
Without the PR the namespace is the oracle one: How do I test |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for working on this. I'm not an expert in J*EE, but I did a first pass - see comments inline.
@@ -1,5 +1,5 @@ | |||
#Signature file v4.1 | |||
#Version 1.54 | |||
#Version 1.55 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Incompatible API/SPI changes normally require a bump of the major version of the spec. The enterprise modules were always lenitent with this, so I'm inclined to agree to keep it, but the right way would be:
- bump major release version to 2
- bump specification version to 2.0
- update users to the new major release version and bump their specification version (compatible change)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm going to adjust this within the next review adjustments.
@@ -89,7 +90,7 @@ public LibraryType getType() { | |||
|
|||
@Override | |||
public String getDefaultNamespace() { | |||
return LibraryUtils.getCompositeLibraryURL(getLibraryName(), support.getJsfSupport().isJsf22Plus()); | |||
return LibraryUtils.getCompositeLibraryURL(getLibraryName(), support.getJsfSupport().getJsfVersion().isAtLeast(JsfVersion.JSF_2_2)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm surprised. Did they really go to URNs and did not change the composite component namespace?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actually I did not checked the context of that change tbh. I just wanted to get rid of the isJsf**Plus
methods and use something more generic.
This was one call where such a method was used so I replaced it with the corresponding call.
return rootNode; | ||
public static Node getRoot(HtmlParserResult parserResult, LibraryInfo library, JsfVersion jsfVersion) { | ||
String namespace = jsfVersion.getNamespaceUri(library.getDefaultPrefix()); | ||
return parserResult.root(namespace); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this changes the semantic. The way this is written allows using both namespaces, while the new code only allows the "right" one. I would assume, that JSF implementations will recognize also old namespaces and I think the old behavior was sane.
You then can also keep the signature to its original form.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From my understanding the old behavior only supported one namespace at a time as well.
e.g. when you create a new maven web application, add a new jsf site and add an tag which namespace is not yet present and you hit auto import you only can choose between the namespace of the used jsf version.
From my understanding if we want to provide all compatible namespaces for a jsf implementation this would be an feature which is currently not present.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I entered this into a facelets file:
<f:view
xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http://java.sun.com/jsp/jstl/core"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui"
xmlns:ui="http://java.sun.com/jsf/facelets">
<h:head>
</h:head>
<h:body>
<ui:define name="|" />
</h:body>
</f:view>
I called completion at position marked with "|". At that point JsfUtils#getRoot
is called with the DefaultLibraryInfo
FACELETS
. In my exampled I used the legacy namespace. Because the original method checks both namespaces it finds the f:view
element, with your change that would have not happenend and an empty pseudo node had been returned.
So sorry, but your change introduces a bug, you need to scan all possible namespaces for the libraries.
map.put(JSFVersion.JSF_2_3, JsfVersion.JSF_2_3); | ||
map.put(JSFVersion.JSF_3_0, JsfVersion.JSF_3_0); | ||
map.put(JSFVersion.JSF_4_0, JsfVersion.JSF_4_0); | ||
JSF_VERSION_MAPPING = Collections.unmodifiableMap(map); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason for the two version implementations?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not happy about that mapping as well.
Basically JSFVersion
is not part of the api module but of implementation module web.jsf
. So reusing JSFVersion
would have meant either to:
- Move it to
web.jsfapi
or - Add
web.jsf
as dependency
From my perspective it makes more sense to have it as part of the api, at least the feature set which is currently implemented. On the other hand I did not want to merge both classes as it would have created an even huger patchset than already.
So basically the idea would be to eliminate JSFVersion
and integrate it to JsfVersion
or somewhere else.
@@ -461,7 +462,7 @@ public static void completeFaceletsFromProject(CompletionContext context, List<C | |||
public static void completeXMLNSAttribute(CompletionContext context, List<CompletionItem> items, JsfSupportImpl jsfs) { | |||
if (context.getAttributeName().toLowerCase(Locale.ENGLISH).startsWith("xmlns")) { //NOI18N | |||
//xml namespace completion for facelets namespaces | |||
Set<String> nss = NamespaceUtils.getAvailableNss(jsfs.getLibraries(), jsfs.isJsf22Plus()); | |||
Set<String> nss = NamespaceUtils.getAvailableNss(jsfs.getLibraries(), jsfs.getJsfVersion().isAtLeast(JsfVersion.JSF_2_2)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think getAvailableNss
needs to be changed to take the version. The boolean is used to determine if only the current namespace or also legacy ones should be reported. With JSF4 this would add a third set:
- >= JSF4 would get the new namespace + legacy jcp + legacy sun
- >= JSF2.2 && < JSF4 would get legacy jcp + legacy sun
- < JSF2.2 would get legacy sun
At least that is my interpretation from looking at it.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess you're right.
Just for more context: Actually I was focusing on getting the functionality working mentioned in the isssue as I know what I can test. I did not do a all over the place, ensure that jsf 4 is supported refactoring.
I think this should be adjusted as well, but I'm not aware about the consequences and how to validate that behavior.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method is invoced when you have this situation:
<f:view
xmlns="http://www.w3.org/1999/xhtml"
xmlns:c="http:|"
</f:view>
The caret/cursor is placed at the location marked with "|" and you call for completion (I have mapped that to CTRL+Space. You should get a list of supported libraries/namespaces (screenshot from a project based on JSF 2.2):
You can see, that both the legacy namespaces and the "jcp" namespaces are returned. The order should be reversed from my POV, but that is a separate discussion. In a JSF4 project I would expect all namespaces as already described.
@@ -246,15 +247,15 @@ private static void addTypesFromPackages(CompletionContext context, CompilationC | |||
} | |||
} | |||
|
|||
public static void completeSectionsOfTemplate(final CompletionContext context, final List<CompletionItem> items, String ns, OpenTag openTag) { | |||
public static void completeSectionsOfTemplate(final CompletionContext context, final List<CompletionItem> items, String ns, OpenTag openTag, JsfVersion jsfVersion) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See my comment in JsfUtils.getRoot
: I think the final parameter is not necessary.
} | ||
|
||
private void initialize() { | ||
private void initialize(JsfVersion jsfVersion) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
See discussion in JsfUtils.getRoot
I think this is not necessary.
if (jsfSupport != null && jsfSupport.isJsf22Plus()) { | ||
ns = library.getNamespace(); | ||
} | ||
ns = jsfVersion.getNamespaceUri(prefix); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The original code used the namespace from the library - should this not be possible anymore?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
With the new JsfVersion
enum this is not necessary anymore as the namespace information is part of that enum.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is a nice addition to the codebase for providing flexible namespace support. Hopefully we will not be going through anymore namespace changes, but this will help in the future if it does happen.
Converted back to draft for now as during the raised concerns I wonder if the suggested solution with a new mapping component NetBeans bundles |
What do you mean here? Can you point me to the generated code? A quick look only shows me the generation of javadoc in |
@matthiasblaesing see https://github.com/apache/netbeans/blob/master/enterprise/web.jsf.editor/src/org/netbeans/modules/web/jsf/editor/facelets/FaceletsLibrarySupport.java#L332-L419 It does not generate code but information based on the bundled JSF RI jar. This code is base to generate the information used in This part tries to find a jsf implementation for the project:
So the two problems I currently see (there might be more):
What I already tried:
So currently I don't see another option beside mapping the namespaces manually as supposed. It's a shame as I think if we could get a JSF RI (e.g. it could be downloaded via maven) for the used JSF implementation it might work out of the box. |
Ah, so you have finally figured out what this stuff does. Too bad it's not possible to load new schemas from newer Mojarra as it requires JDK 11. Maybe they could be added locally to existing jars (just the schemas)? |
Tested my project. I seems most of the things I need are working (most important is navigation to bean). But: a) since this window shows old library names I'm afraid it won't know about new attributes and/or elements, should any be added in newer JSF standards: b) taglib 4.0 is not recognized, if declaration remains in 2.2 version it works. Maybe I'm declaring it wrong, but xml passes validation:
Other than that, great job, it's still a great improvement over old version! |
That would be a possibility. Another thing is that the module currently use some classes from the implementation itself. e.g. the schema is created based on a I guess I'll abandon this PR for now as I'm currently experimenting with another solution: I try to get the JSF implementation of the JSF version which is currently used via maven. That basically already works. Currently the question is how to handle the legacy namespaces. Per spec they're still valid. The problem is that these namespaces - at least I'm not aware of - could not be retrieved from the JSF reference implementation jar. So the module would need to define them manually and this needs a some more refactoring to do it properly. |
Please do not abandon it, something it better than nothing. We have been left out to dry for too long. You can make improved version for NB 20 or something. NB 19 would be awesome with just this PR. |
I'm actively working on an alternative solution, but I'm not 100% sure if this will hit NB19 as feature freeze will happen soon. |
This PR got replaced by #6160 |
Since Jakarte EE Faces 4 the xmls namespaces were changed from
http://xmlns.jcp.org/jsf
tojakarta.*
. (see jakartaee/faces#1553)This change adds new namespace support for:
* Generation of new JSF pages
* Tag suggestion in faces xhtml editor view
* Automatic addition of missing namespace declaration when new taglib is used
In order to support the JSF 4.0 namespaces the
enum
JsfVersion
inweb.jsfapi
module was introduced. It's used to map the taglib namespaces based on the projects detected JSF version.Note: There's already an enum
JSFVersion
which is not part of the api. Both enums might be merged in the future.Reference: #6069