| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| package org.netbeans.modules.web.primefaces; |
| |
| import java.io.File; |
| import java.io.IOException; |
| import java.net.URI; |
| import java.net.URISyntaxException; |
| import java.net.URL; |
| import java.util.*; |
| import java.util.logging.Level; |
| import java.util.logging.Logger; |
| import java.util.prefs.Preferences; |
| import org.netbeans.api.java.classpath.ClassPath; |
| import org.netbeans.api.java.project.classpath.ProjectClassPathModifier; |
| import org.netbeans.api.project.libraries.Library; |
| import org.netbeans.api.project.libraries.LibraryManager; |
| import org.netbeans.modules.j2ee.common.ClasspathUtil; |
| import org.netbeans.modules.web.api.webmodule.WebModule; |
| import org.netbeans.modules.web.jsf.api.JsfComponentUtils; |
| import org.netbeans.modules.web.jsf.api.facesmodel.JSFVersion; |
| import org.netbeans.modules.web.jsf.spi.components.JsfComponentCustomizer; |
| import org.netbeans.modules.web.jsf.spi.components.JsfComponentImplementation; |
| import org.netbeans.modules.web.primefaces.ui.PrimefacesCustomizerPanel; |
| import org.openide.filesystems.FileObject; |
| import org.openide.filesystems.FileUtil; |
| import org.openide.filesystems.JarFileSystem; |
| import org.openide.loaders.DataFolder; |
| import org.openide.loaders.DataObject; |
| import org.openide.loaders.DataObjectNotFoundException; |
| import org.openide.util.NbBundle; |
| import org.openide.util.NbPreferences; |
| |
| /** |
| * Represents support for PrimeFaces component libraries. |
| * |
| * @author Martin Fousek <marfous@netbeans.org> |
| */ |
| public class PrimefacesImplementation implements JsfComponentImplementation { |
| |
| private PrimefacesCustomizer customizer; |
| |
| /** Framework name used also for statistics. */ |
| public static final String PRIMEFACES_NAME = "PrimeFaces"; //NOI18N |
| |
| // PrimeFaces Maven resources |
| private static final String MAVEN_PF_REPO ="default:http://repository.primefaces.org/"; //NOI18N |
| private static final String MAVEN_PF_DEP = "org.primefaces:primefaces:5.0:jar"; //NOI18N |
| |
| private static final Logger LOGGER = Logger.getLogger(PrimefacesImplementation.class.getName()); |
| private static final String PRIMEFACES_SPECIFIC_PRIME_RESOURCE = "org.primefaces.application.PrimeResource"; //NOI18N |
| private static final String PRIMEFACES_SPECIFIC_PRIME_RESOURCE_HANDLER = "org.primefaces.application.PrimeResourceHandler"; //NOI18N |
| private static final String PREFERENCES_NODE = "primefaces"; //NOI18N |
| private static final String POM_PROPERTIES_PATH = "META-INF/maven/org.primefaces/primefaces/pom.properties"; //NOI18N |
| |
| /** Preferences property name used for getting lastly used PrimeFaces library. */ |
| public static final String PROP_PREFERRED_LIBRARY = "preferred-library"; //NOI18N |
| |
| public PrimefacesImplementation() { |
| } |
| |
| @Override |
| public String getName() { |
| return PRIMEFACES_NAME; |
| } |
| |
| @NbBundle.Messages({ |
| "PrimefacesImplementation.primefaces.display.name=PrimeFaces" |
| }) |
| @Override |
| public String getDisplayName() { |
| return Bundle.PrimefacesImplementation_primefaces_display_name(); |
| } |
| |
| @Override |
| public String getDescription() { |
| return NbBundle.getMessage(PrimefacesProvider.class, "LBL_PrimeFaces_Description"); //NOI18N |
| } |
| |
| @Override |
| public Set<FileObject> extend(WebModule webModule, JsfComponentCustomizer jsfComponentCustomizer) { |
| // Add PrimeFaces library to WebModule classpath |
| extendClasspath(webModule, jsfComponentCustomizer); |
| |
| // generate PrimeFaces welcome page |
| try { |
| FileObject welcomePage = generateWelcomePage(webModule); |
| return Collections.singleton(welcomePage); |
| } catch (IOException ex) { |
| LOGGER.log(Level.WARNING, "Exception during creating welcome page and extending index", ex); //NOI18N |
| } |
| |
| return Collections.<FileObject>emptySet(); |
| } |
| |
| @Override |
| public Set<JSFVersion> getJsfVersion() { |
| return EnumSet.of(JSFVersion.JSF_2_0, JSFVersion.JSF_2_1, JSFVersion.JSF_2_2); |
| } |
| |
| @Override |
| public boolean isInWebModule(WebModule webModule) { |
| ClassPath classpath = ClassPath.getClassPath(webModule.getDocumentBase(), ClassPath.COMPILE); |
| return hasPrimeFacesResource(classpath); |
| } |
| |
| private boolean hasPrimeFacesResource(ClassPath classPath) { |
| // PRIMEFACES_SPECIFIC_PRIME_RESOURCE - PF 3.2- backward compatibility |
| return classPath.findResource(PRIMEFACES_SPECIFIC_PRIME_RESOURCE.replace('.', '/') + ".class") != null //NOI18N |
| // PRIMEFACES_SPECIFIC_PRIME_RESOURCE_HANDLER - PF 3.3+ |
| || classPath.findResource(PRIMEFACES_SPECIFIC_PRIME_RESOURCE_HANDLER.replace('.', '/') + ".class") != null; //NOI18N |
| } |
| |
| @Override |
| public JsfComponentCustomizer createJsfComponentCustomizer(WebModule webModule) { |
| if (customizer == null) { |
| customizer = new PrimefacesCustomizer(); |
| } |
| return customizer; |
| } |
| |
| @Override |
| public void remove(WebModule webModule) { |
| try { |
| List<Library> primefacesLibraries; |
| if (JsfComponentUtils.isMavenBased(webModule)) { |
| primefacesLibraries = Arrays.asList(getMavenLibrary()); |
| } else { |
| primefacesLibraries = getAllRegisteredPrimefaces(); |
| } |
| ProjectClassPathModifier.removeLibraries(primefacesLibraries.toArray( |
| new Library[primefacesLibraries.size()]), webModule.getJavaSources()[0], ClassPath.COMPILE); |
| } catch (IOException ex) { |
| LOGGER.log(Level.WARNING, "Exception during removing JSF suite from an web project", ex); //NOI18N |
| } catch (UnsupportedOperationException ex) { |
| LOGGER.log(Level.WARNING, "Exception during removing JSF suite from an web project", ex); //NOI18N |
| } |
| } |
| |
| private static void extendClasspath(WebModule webModule, JsfComponentCustomizer jsfComponentCustomizer) { |
| try { |
| Library primefacesLibrary; |
| if (JsfComponentUtils.isMavenBased(webModule)) { |
| primefacesLibrary = getMavenLibrary(); |
| } else { |
| primefacesLibrary = getPreferredLibrary(jsfComponentCustomizer); |
| if (primefacesLibrary == null) { |
| LOGGER.log(Level.SEVERE, "No PrimeFaces library found."); |
| } |
| } |
| FileObject[] javaSources = webModule.getJavaSources(); |
| ProjectClassPathModifier.addLibraries( |
| new Library[] {primefacesLibrary}, |
| javaSources[0], |
| ClassPath.COMPILE); |
| } catch (IOException ex) { |
| LOGGER.log(Level.WARNING, "Exception during extending an web project", ex); //NOI18N |
| } catch (UnsupportedOperationException ex) { |
| LOGGER.log(Level.WARNING, "Exception during extending an web project", ex); //NOI18N |
| } |
| } |
| |
| private static Library getMavenLibrary() { |
| return JsfComponentUtils.createMavenDependencyLibrary( |
| PRIMEFACES_NAME + "-maven-lib", //NOI18N |
| new String[]{MAVEN_PF_DEP}, |
| new String[]{MAVEN_PF_REPO}); |
| } |
| |
| /** |
| * Gets {@code List} of all Primefaces libraries registered in the IDE. |
| * @return list of libraries |
| */ |
| public static List<Library> getAllRegisteredPrimefaces() { |
| List<Library> libraries = new ArrayList<Library>(); |
| List<URL> content; |
| for (Library library : LibraryManager.getDefault().getLibraries()) { |
| if (!"j2se".equals(library.getType())) { //NOI18N |
| continue; |
| } |
| |
| content = library.getContent("classpath"); //NOI18N |
| if (isValidPrimefacesLibrary(content)) { |
| libraries.add(library); |
| } |
| } |
| return libraries; |
| } |
| |
| /** |
| * Checks if given library content contains mandatory Primefaces classes. |
| * @param libraryContent library content |
| * @return {@code true} if the given content contains required Primefaces class, {@code false} otherwise |
| */ |
| public static boolean isValidPrimefacesLibrary(List<URL> libraryContent) { |
| try { |
| return ClasspathUtil.containsClass(libraryContent, PRIMEFACES_SPECIFIC_PRIME_RESOURCE) |
| || ClasspathUtil.containsClass(libraryContent, PRIMEFACES_SPECIFIC_PRIME_RESOURCE_HANDLER); |
| } catch (IOException ex) { |
| LOGGER.log(Level.INFO, null, ex); |
| return false; |
| } |
| } |
| |
| /** |
| * Gets {@code NbPreferences} for Primefaces plugin. |
| * @return Preferences of the Primefaces |
| */ |
| public static Preferences getPrimefacesPreferences() { |
| return NbPreferences.forModule(PrimefacesImplementation.class).node(PrimefacesImplementation.PREFERENCES_NODE); |
| } |
| |
| private static List<URI> getPomURIs(Library library) { |
| String baseUri = "http://repository.primefaces.org/org/primefaces/primefaces/<VERSION>/primefaces-<VERSION>.pom"; //NOI18N |
| String versionItem = "version="; //NOI18N |
| List<URI> poms = new LinkedList<URI>(); |
| for (URI uri : library.getURIContent("classpath")) { //NOI18N |
| try { |
| URL archiveFileURL = FileUtil.getArchiveFile(uri.toURL()); |
| JarFileSystem jsf = new JarFileSystem(new File(archiveFileURL.toURI())); |
| FileObject resource = jsf.findResource(POM_PROPERTIES_PATH); |
| if (resource != null) { |
| String propertiesText = resource.asText(); |
| int indexOfVersion = propertiesText.indexOf(versionItem); //NOI18N |
| String version = propertiesText.substring(indexOfVersion + versionItem.length()); |
| version = version.substring(0, version.indexOf("\n")); //NOI18N |
| poms.add(new URI(baseUri.replaceAll("<VERSION>", version.trim()))); //NOI18N |
| } |
| } catch (URISyntaxException ex) { |
| LOGGER.log(Level.WARNING, "Primefaces version wasn't parsed", ex); |
| } catch (IOException ex) { |
| LOGGER.log(Level.WARNING, "Primefaces version wasn't parsed", ex); |
| } |
| } |
| return poms; |
| } |
| |
| /** |
| * Gets library selected in the customizer if was at least opened, otherwise it looks into preferences for |
| * lastly used library, otherwise it choose any registered PrimeFaces library. |
| */ |
| private static Library getPreferredLibrary(JsfComponentCustomizer jsfComponentCustomizer) { |
| // get the PrimeFaces library from customizer |
| if (jsfComponentCustomizer != null) { |
| PrimefacesCustomizerPanel panel = ((PrimefacesCustomizerPanel) jsfComponentCustomizer.getComponent()); |
| Library libarary = panel.getPrimefacesLibrary(); |
| if (libarary != null) { |
| return LibraryManager.getDefault().getLibrary(libarary.getName()); |
| } |
| } |
| |
| // search for library stored in PrimeFaces preferences |
| Library primefacesLibrary = LibraryManager.getDefault().getLibrary( |
| getPrimefacesPreferences().get(PROP_PREFERRED_LIBRARY, "")); //NOI18N |
| if (primefacesLibrary != null) { |
| return primefacesLibrary; |
| } |
| |
| // otherwise search for any registered PrimeFaces library in IDE |
| return getAllRegisteredPrimefaces().get(0); |
| } |
| |
| /** |
| * Generates PrimeFaces's welcome page in the webmodule. |
| */ |
| private static FileObject generateWelcomePage(WebModule webModule) throws IOException { |
| FileObject templateFO = FileUtil.getConfigFile("Templates/Other/welcomePrimefaces.xhtml"); //NOI18N |
| DataObject templateDO = DataObject.find(templateFO); |
| DataObject generated = templateDO.createFromTemplate( |
| DataFolder.findFolder(webModule.getDocumentBase()), |
| "welcomePrimefaces"); //NOI18N |
| JsfComponentUtils.reformat(generated); |
| |
| // update and reformat index page |
| updateIndexPage(webModule); |
| |
| return generated.getPrimaryFile(); |
| } |
| |
| /** |
| * Updates index page of the webmodule - includes link to PrimeFaces's welcome page. |
| */ |
| @NbBundle.Messages({ |
| "PrimefacesImplementation.index.welcome.primefaces.lbl=Primefaces welcome page" |
| }) |
| private static void updateIndexPage(WebModule webModule) throws DataObjectNotFoundException { |
| FileObject indexFO = webModule.getDocumentBase().getFileObject("index.xhtml"); //NOI18N |
| if (indexFO == null || !indexFO.isValid() || !indexFO.canWrite()) { |
| return; |
| } |
| |
| DataObject indexDO = DataObject.find(indexFO); |
| JsfComponentUtils.enhanceFileBody( |
| indexDO, |
| "</h:body>", //NOI18N |
| "<br />\n<h:link outcome=\"welcomePrimefaces\" value=\"" + Bundle.PrimefacesImplementation_index_welcome_primefaces_lbl() + "\" />"); //NOI18N |
| JsfComponentUtils.reformat(indexDO); |
| } |
| } |